Reputation: 383
So i'm making a html canvas game in angular that will have lots of script files and I want to make it with optimal readability and performance.
Here is my code so far:
import { Component, OnInit } from '@angular/core';
import { Player } from './scripts/entities';
declare let $: any;
@Component({
selector: 'app-game-screen',
templateUrl: './game-screen.component.html',
styleUrls: ['./game-screen.component.scss']
})
export class GameScreenComponent implements OnInit {
constructor() { }
ngOnInit() {
//Draw canvas
let sw = $("#container").width(); // Screen width
let sh = $("#container").height(); // Screen height
//Player canvas
let canvas: any = document.querySelector("#gameScreen");
canvas.width = sw;
canvas.height = sh;
let ctx = canvas.getContext("2d");
//Test canvas
let testCanvas: any = document.querySelector("#testScreen");
testCanvas.width = sw;
testCanvas.height = sh;
let test = testCanvas.getContext("2d");
//function to clear canvas
function clearCanvas(screen) {
screen.clearRect(0, 0, canvas.width, canvas.height);
}
//!Draw canvas
// Entities - player, enemies, bosses
const player = new Player('Player', sw / 2, sh / 2, sw / 10, sh / 7, ctx);
player.draw();
const posMarker = new Player('Position indicator', sw / 2, sh / 2, 5, 5, test);
posMarker.boxColor = 'red';
posMarker.draw();
// ! Entities - player, enemies, bosses
//Controls
document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);
let rightPressed = false;
let leftPressed = false;
let upPressed = false;
let downPressed = false;
function keyDownHandler(event) {
if (event.keyCode == 39) {
rightPressed = true;
}
else if (event.keyCode == 37) {
leftPressed = true;
}
if (event.keyCode == 40) {
downPressed = true;
}
else if (event.keyCode == 38) {
upPressed = true;
}
}
function keyUpHandler(event) {
if (event.keyCode == 39) {
rightPressed = false;
}
else if (event.keyCode == 37) {
leftPressed = false;
}
if (event.keyCode == 40) {
downPressed = false;
}
else if (event.keyCode == 38) {
upPressed = false;
}
}
function controlMove() {
clearCanvas(ctx);
if (rightPressed) {
player.x += 10;
}
else if (leftPressed) {
player.x -= player.speed;
}
if (downPressed) {
player.y += player.speed;
}
else if (upPressed) {
player.y -= player.speed;
}
//Border limitations
if (player.x - player.w / 2 < 0) { player.x = player.w / 2 }
if (player.x + player.w / 2 > sw) { player.x = sw - player.w / 2 }
if (player.y - player.h / 2 < 0) { player.y = player.h / 2 }
if (player.y + player.h / 2 > sh) { player.y = sh - player.h / 2 }
//!Border limitations
player.draw();
requestAnimationFrame(controlMove);
}
controlMove();
// ! Controls
}
}
Let's say i want this whole part about controls in another external file. How would I go on about doing that?
//Controls
document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);
let rightPressed = false;
let leftPressed = false;
let upPressed = false;
let downPressed = false;
function keyDownHandler(event) {
if (event.keyCode == 39) {
rightPressed = true;
}
else if (event.keyCode == 37) {
leftPressed = true;
}
if (event.keyCode == 40) {
downPressed = true;
}
else if (event.keyCode == 38) {
upPressed = true;
}
}
function keyUpHandler(event) {
if (event.keyCode == 39) {
rightPressed = false;
}
else if (event.keyCode == 37) {
leftPressed = false;
}
if (event.keyCode == 40) {
downPressed = false;
}
else if (event.keyCode == 38) {
upPressed = false;
}
}
function controlMove() {
clearCanvas(ctx);
if (rightPressed) {
player.x += 10;
}
else if (leftPressed) {
player.x -= player.speed;
}
if (downPressed) {
player.y += player.speed;
}
else if (upPressed) {
player.y -= player.speed;
}
//Border limitations
if (player.x - player.w / 2 < 0) { player.x = player.w / 2 }
if (player.x + player.w / 2 > sw) { player.x = sw - player.w / 2 }
if (player.y - player.h / 2 < 0) { player.y = player.h / 2 }
if (player.y + player.h / 2 > sh) { player.y = sh - player.h / 2 }
//!Border limitations
player.draw();
requestAnimationFrame(controlMove);
}
controlMove();
// ! Controls
What do I do about my functions referencing variables like player.x and player.y (while trying to maintain performance)?
And is it possible to initialize these event listeners somehow other than in the main file, to reduce clutter.
document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);
Upvotes: 1
Views: 914
Reputation: 4300
1st of all, use the OnPush change detection strategy. Especially in a game in which you want to optimize performance.
@Component({
selector: 'app-game-screen',
templateUrl: './game-screen.component.html',
styleUrls: ['./game-screen.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GameScreenComponent implements OnInit {
This might require you to trigger change detection yourself on some occasions, so you better have a look at this article, which explains it.
https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html
If you want to separate the controls into a separate file, then you should probably just make a one singleton service (aka. GameStore) that holds your player.x and player.y and other app wide data and then another service, which accesses GameStore-s player values, detects or waits for notification of keystrokes and handles them (aka. GameController).
I usually use Observables in my Stores, aka.
export class GameStoreService {
private _player: BehaviorSubject<PlayerModel> = new BehaviorSubject(null);
setPlayer( _player: PlayerModel ) {
this._player.next( _player );
}
get player() {
return this._player.asObservable();
}
}
Which anyone can subscribe to and push to.
Concerning the listeners in anything other than the main file
document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);
Do use HostListeners for these, but you cannot set them in any file, I think this SO thread had a good explanation of what's going on
Is it possible to use HostListener in a Service?
Upvotes: 1