Reputation: 395
Whenever I call moveAvatar()
, this.vx
and this.vy
are are undefined.
How?
How it works in plain JS application:
Game starts: set an interval that calls draw()
over and over, drawing on the canvas. I'm perplexed as to why this wouldn't work using typescript.
vx
and vy
are both defined, and assigned values. You can even print them out...
I literally ported this code from a pure JS application that works fine.
I have a feeling it has something to do with how angular treats intervals. Please let me know!! Thanks!
import {
Component,
OnInit
} from '@angular/core';
@Component({
selector: 'app-avoid',
templateUrl: './avoid.component.html',
styleUrls: ['./avoid.component.css']
})
export class AvoidComponent implements OnInit {
avatarImage;
enemy;
x = 30;
y = 30;
_x = 300;
_y = 300;
score = 0;
vx: number = 0;
vy: number = 0;
scoreTracker;
gameCanvas;
frames;
gameStatus = false;
hud = {
score: 0,
left: 0,
right: 0,
up: 0,
down: 0
};
backstage;
time = 0;
level = 1;
enemySpeed = 0.5;
levelTracker;
constructor() {
}
ngOnInit() {
let body = document.querySelector('body');
body.addEventListener("keyup", this.moveAvatar);
this.gameCanvas = document.getElementById("gameCanvas");
this.scoreTracker = document.getElementById("score");
this.levelTracker = document.getElementById('level');
this.enemy = this.getEnemy();
this.avatarImage = this.getAvatar();
}
levelUp() {
this.level++;
this.enemySpeed += 0.25;
this.levelTracker.innerText = this.level.toString();
}
startCanvas() {
this.backstage = document.createElement("canvas");
this.backstage.width = this.gameCanvas.width;
this.backstage.height = this.gameCanvas.height;
if (this.frames != null) {
this.gameOver();
}
this.backstage.getContext("2d", {
alpha: false
}).drawImage(this.avatarImage, this.x, this.y);
this.backstage.getContext("2d", {
alpha: false
}).drawImage(this.enemy, this._x, this._y)
this.gameCanvas.getContext("2d", {
alpha: false
}).drawImage(this.backstage, 0, 0);
this.time = 0;
const that = this;
this.frames = setInterval(() => {
that.Draw();
}, 100);
}
getAvatar() {
var avatarImage = new Image(30, 30);
avatarImage.src = "../assets/images/avatar.png";
return avatarImage;
}
getEnemy() {
var enemy = new Image();
enemy.src = "../assets/images/enemy.png"
return enemy;
}
moveAvatar(key) {
switch (key.keyCode) {
case 37:
this.vx--;
break;
case 38:
this.vy--;
break;
case 39:
this.vx++;
break;
case 40:
this.vy++;
break;
}
}
Follow() {
if (this.x > this._x) {
this._x += this.enemySpeed;
} else if (this.x < this._x) {
this._x -= this.enemySpeed;
}
if (this.y > this._y) {
this._y += this.enemySpeed;
} else if (this.y < this._y) {
this._y -= this.enemySpeed;
}
}
Draw() {
this.time++;
this.Accelerate();
this.Follow();
if (this.x < 0 || this.y < 0 || this.y > 520 || this.x > 770) {
this.gameOver();
return;
}
this.score += 1;
this.scoreTracker.value = this.score;
this.backstage.width += 0;
this.gameCanvas.width += 0;
this.backstage.getContext("2d", {
alpha: false
}).drawImage(this.avatarImage, this.x, this.y);
this.backstage.getContext("2d", {
alpha: false
}).drawImage(this.enemy, this._x, this._y);
this.gameCanvas.getContext("2d", {
alpha: false
}).drawImage(this.backstage, 0, 0);
if (this.x <= this._x + 20 && this.x >= this._x - 20) {
if (this.y <= this._y + 20 && this.y >= this._y - 20) {
this.gameOver();
}
}
if (this.score % 500 === 0) {
this.levelUp();
}
}
Accelerate() {
this.x += this.vx;
this.y += this.vy;
}
gameOver() {
clearInterval(this.frames);
this.x = 30;
this.y = 30;
this._x = 300;
this._y = 300;
this.score = 0;
this.scoreTracker.value = 0;
this.level = 1;
this.enemySpeed = 0.5;
this.levelTracker.innerText = "1";
}
}
Upvotes: 1
Views: 300
Reputation: 783
Alternative to above correct answer, you can also use Renderer module to achieve the same. this.renderer.listen('keyup', target, callbackfn)
; Instead of manually adding the listeners, you let angular create and destroy the listeners.
Upvotes: 1
Reputation: 1605
call it like this
body.addEventListener('keyup', (ev) => this.moveAvatar(ev));
(OR)
body.addEventListener('keyup', this.moveAvatar.bind(this));
Upvotes: 3