var Context = {
canvas: null,
context: null,
create: function(canvas_tag_id, size){
this.canvas = document.getElementById(canvas_tag_id);
this.canvas.width = size[0];
this.canvas.height = size[1];
this.context = this.canvas.getContext('2d');
return this.context;
},
fps:1/30
};
$(function(){
// Initialize
Context.create('canvas', [798, 652]);
var s_size = [Context.canvas.width, Context.canvas.height]; // screen size
function Player(){
this.rect = [0, s_size[1]-40, 20, 40];
this.color = 'blue';
this.create = function(){
// function for creating player object
Context.context.beginPath();
Context.context.fillStyle = this.color;
Context.context.rect(
this.rect[0], this.rect[1], this.rect[2], this.rect[3]);
Context.context.fill();
};
this.control = function(){
// player movement control function
if (event.which == 39 || event.keyCode == 39){
alert(this.rect);
}
};
this.update = function(){
this.rect[0] += 1;
}
}
// player instance creation
var archie = new Player();
// game loop functions
function events(){
// Keydown events
function keydown(){
window.addEventListener('keydown', archie.control);
}
keydown();
}
function update(){
archie.update();
}
function render(){
Context.context.clearRect(0, 0, canvas.width, canvas.height);
archie.create();
}
function game(){
events();
update();
render();
}
setInterval(game, Context.fps);
});
As you can see the problem isn't the organization of the code but the event handler, because the player class's update method is working just fine even though it's created after the event handler. what exactly is the problem here and how do i solve it?
Inside the event handler, this
is always the element the event handler was bound to, not the constructor for the function passed in.
To write your code a lot shorter, you're doing
var Player = function() {
this.rect = "something";
this.control = function(){
if (event.which == 39 || event.keyCode == 39){
alert(this.rect); // NOPE ... this is the element
}
};
}
var archie = new Player(); // create instance
window.addEventListener('keydown', archie.control); // some function in the instance
If you just have to have the object as the this
value, use bind
window.addEventListener('keydown', archie.control.bind(archie));
Also note that your event handler callback is missing the event
argument, and relying on the global event
, which is not supported in all browsers (Firefox), so you should be doing
this.control = function(event) {...
Another solution I often use is to store this
value in another variable ex. self
and use that copy in every place so it could be:
var Player = function() {
var self = this;
self.rect = "something";
self.control = function(event){
if (event.which == 39 || event.keyCode == 39){
alert(self.rect);
}
};
}
This give you guarantee of use what you want, because this
is based on context of method execution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.