我的节目有什么问题 - 短节目
What's wrong with my program - short program
代码说明:Car对象根据鼠标位置定时更新自己的位置和方向。我是 requestAnimationFrame 函数,用于更平滑地渲染帧。
问题:
当我在绘图函数中时,汽车对象的 x 和 y 坐标是 NAN。
canvas 上没有显示汽车。
代码:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
overflow:hidden;
}
</style>
</head>
<body>
<canvas id="myCanvas">
</canvas>
<script>
// requestAnimationFrame initialization with cross-browser compatibility
(function(){
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
// canvas and context objects
var myCanvas = document.getElementById("myCanvas");
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
var ctx = myCanvas.getContext("2d");
myCanvas.addEventListener('mousemove', updateMousePos, false);
//mouse position coordinates
var mousex;
var mousey;
//constructor for a Car object with methods to update position, orientation, and draw the car
function Car(x, y, orientation, id, type) {
//x and y are the cooredinates of the center of a car object
this.x = x;
this.y = y;
this.type = type;
this.speed = 5; //default speed = 5
this.isAlive = 1;
this.stillExists = 1;
this.id = id;
this.orientation = orientation;
this.img = new Image();
this.img.source = 'car1.png';
this.img.width = 200;
this.img.height = 100;
//this method computes a new positin and orientation of our car.
this.updatePosAndOrien = function(){
//caclcuate car orientation using mousex and mousey and x y position of our car using atan2
var targetX = mousex - this.x;
var targetY = mousey - this.y;
var trgtOrien = Math.atan2(targetY, targetX);
this.orientation = trgtOrien;
//calculate new positon of car using speed and current location of car
var dx = mousex -this.x;
var dy = mousey - this.y;
//distance between mouse and car
var distance = Math.sqrt(dx*dx + dy*dy);
//Now we compute xspeed and yspeed of car - which are displacements along x and y axis
var factor = distance / this.speed;
var xspeed = dx / factor;
var yspeed = dy / factor;
//set new positon of car
this.x = this.x + xspeed;
this.y = this.y+ yspeed;
};
//draw method that draws the car on canvas
this.draw = function() {
this.img.x = this.x;
this.img.y = this.y;
this.img.orientation = this.orientation;
this.img.onload = function() {
ctx.save();//save context
//translate context origin to center of image
ctx.translate(Math.round(this.x), Math.round(this.y));
ctx.rotate(this.orientation); //rotate context
ctx.drawImage(img, -(this.width/2), -(this.height/2),
this.width, this.height);//draw img
ctx.restore(); //restore context
}
};
}
/*this function update mouse position upon mouse movement*/
function updateMousePos(evt) {
var rect = myCanvas.getBoundingClientRect();
mousex = evt.clientX - rect.left;
mousey = evt.clientY - rect.top;
//log mouse position
console.log("mouse postion: "+mousex+", "+mousey);
}
//defining car and starting the rendering
var ourCar = new Car(300, 400, 2, 111, 1);
console.log("car: "+ourCar.x+", "+ourCar.y);
/*This function draws everything using requestFrameAnimation(). */
function drawIt() {
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
//update orientation of player
ourCar.updatePosAndOrien();
console.log("car in drawIt: "+ourCar.x+", "+ourCar.y); //prints NAN for both
//Draw car
console.log("drawing the car");
ourCar.draw();
requestAnimationFrame(drawIt);
}
//start rendering
requestAnimationFrame(drawIt);
</script>
</body>
</html>
这里发生了几件事...
首先,requestAnimationFrame(drawIt) 在页面加载时运行。如果鼠标尚未移动,则 mousex 和 mousey 为 NaN。此外,drawIt 继续调用自身,因此如果您查看控制台,它只会不断重复 NaN。我不确定你的 objective 是什么,但你可能想检查 ourCar.x 和 ourCar.y 以及 return 的有效值(如果没有任何集合的话)。
关于图片,首先,正如xufox所说,你使用的是img而不是this.img。但是,由于此时您在一个函数中,您不想使用它,因为它指的是实际的 img 标签本身。您应该在该函数之外设置一个变量并将其设置为等于此值。
其次,为了让img.onload触发,你需要设置图片的src属性。
JS Fiddle 和下面的代码以及注释和控制台消息来说明,以及为使其正常工作而进行的更新,您可能需要根据您的需要进行重构。
https://jsfiddle.net/2dd4rv9u/
// canvas and context objects
var myCanvas = document.getElementById("myCanvas");
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
var ctx = myCanvas.getContext("2d");
myCanvas.addEventListener('mousemove', updateMousePos, false);
//mouse position coordinates
var mousex;
var mousey;
//constructor for a Car object with methods to update position, orientation, and draw the car
function Car(x, y, orientation, id, type) {
//x and y are the cooredinates of the center of a car object
this.x = x;
this.y = y;
this.type = type;
this.speed = 5; //default speed = 5
this.isAlive = 1;
this.stillExists = 1;
this.id = id;
this.orientation = orientation;
this.img = new Image();
this.img.source = 'http://www.iconsdb.com/icons/preview/black/car-xxl.png';
this.img.width = 200;
this.img.height = 100;
//this method computes a new positin and orientation of our car.
this.updatePosAndOrien = function(){
//caclcuate car orientation using mousex and mousey and x y position of our car using atan2
var targetX = mousex - this.x;
var targetY = mousey - this.y;
var trgtOrien = Math.atan2(targetY, targetX);
this.orientation = trgtOrien;
//calculate new positon of car using speed and current location of car
var dx = mousex -this.x;
var dy = mousey - this.y;
//distance between mouse and car
var distance = Math.sqrt(dx*dx + dy*dy);
//Now we compute xspeed and yspeed of car - which are displacements along x and y axis
var factor = distance / this.speed;
var xspeed = dx / factor;
var yspeed = dy / factor;
//set new positon of car
this.x = this.x + xspeed;
this.y = this.y+ yspeed;
};
//draw method that draws the car on canvas
this.draw = function() {
this.img.x = this.x;
this.img.y = this.y;
this.img.orientation = this.orientation;
var self = this;
this.img.onload = function() {
console.log('DRAWING');
console.log(this);
console.log(this.img);
console.log(self.img.x);
ctx.save();//save context
//translate context origin to center of image
ctx.translate(Math.round(self.x), Math.round(self.y));
ctx.rotate(self.orientation); //rotate context
// I set these to 0 because I didn't check the math and wanted to show
// that the car would draw
ctx.drawImage(self.img, 0, 0);//draw img
ctx.restore(); //restore context
}
this.img.src = this.img.source;
};
}
/*this function update mouse position upon mouse movement*/
function updateMousePos(evt) {
var rect = myCanvas.getBoundingClientRect();
mousex = evt.clientX - rect.left;
mousey = evt.clientY - rect.top;
//log mouse position
console.log("mouse postion: "+mousex+", "+mousey);
}
//defining car and starting the rendering
var ourCar = new Car(300, 400, 2, 111, 1);
console.log("car: "+ourCar.x+", "+ourCar.y);
/*This function draws everything using requestFrameAnimation(). */
function drawIt() {
if (isNaN(ourCar.x)) return;
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
//update orientation of player
ourCar.updatePosAndOrien();
console.log("car in drawIt: "+ourCar.x+", "+ourCar.y); //prints NAN for both
//Draw car
console.log("drawing the car");
ourCar.draw();
requestAnimationFrame(drawIt);
}
//start rendering
requestAnimationFrame(drawIt);
代码说明:Car对象根据鼠标位置定时更新自己的位置和方向。我是 requestAnimationFrame 函数,用于更平滑地渲染帧。
问题: 当我在绘图函数中时,汽车对象的 x 和 y 坐标是 NAN。 canvas 上没有显示汽车。
代码:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
overflow:hidden;
}
</style>
</head>
<body>
<canvas id="myCanvas">
</canvas>
<script>
// requestAnimationFrame initialization with cross-browser compatibility
(function(){
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
// canvas and context objects
var myCanvas = document.getElementById("myCanvas");
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
var ctx = myCanvas.getContext("2d");
myCanvas.addEventListener('mousemove', updateMousePos, false);
//mouse position coordinates
var mousex;
var mousey;
//constructor for a Car object with methods to update position, orientation, and draw the car
function Car(x, y, orientation, id, type) {
//x and y are the cooredinates of the center of a car object
this.x = x;
this.y = y;
this.type = type;
this.speed = 5; //default speed = 5
this.isAlive = 1;
this.stillExists = 1;
this.id = id;
this.orientation = orientation;
this.img = new Image();
this.img.source = 'car1.png';
this.img.width = 200;
this.img.height = 100;
//this method computes a new positin and orientation of our car.
this.updatePosAndOrien = function(){
//caclcuate car orientation using mousex and mousey and x y position of our car using atan2
var targetX = mousex - this.x;
var targetY = mousey - this.y;
var trgtOrien = Math.atan2(targetY, targetX);
this.orientation = trgtOrien;
//calculate new positon of car using speed and current location of car
var dx = mousex -this.x;
var dy = mousey - this.y;
//distance between mouse and car
var distance = Math.sqrt(dx*dx + dy*dy);
//Now we compute xspeed and yspeed of car - which are displacements along x and y axis
var factor = distance / this.speed;
var xspeed = dx / factor;
var yspeed = dy / factor;
//set new positon of car
this.x = this.x + xspeed;
this.y = this.y+ yspeed;
};
//draw method that draws the car on canvas
this.draw = function() {
this.img.x = this.x;
this.img.y = this.y;
this.img.orientation = this.orientation;
this.img.onload = function() {
ctx.save();//save context
//translate context origin to center of image
ctx.translate(Math.round(this.x), Math.round(this.y));
ctx.rotate(this.orientation); //rotate context
ctx.drawImage(img, -(this.width/2), -(this.height/2),
this.width, this.height);//draw img
ctx.restore(); //restore context
}
};
}
/*this function update mouse position upon mouse movement*/
function updateMousePos(evt) {
var rect = myCanvas.getBoundingClientRect();
mousex = evt.clientX - rect.left;
mousey = evt.clientY - rect.top;
//log mouse position
console.log("mouse postion: "+mousex+", "+mousey);
}
//defining car and starting the rendering
var ourCar = new Car(300, 400, 2, 111, 1);
console.log("car: "+ourCar.x+", "+ourCar.y);
/*This function draws everything using requestFrameAnimation(). */
function drawIt() {
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
//update orientation of player
ourCar.updatePosAndOrien();
console.log("car in drawIt: "+ourCar.x+", "+ourCar.y); //prints NAN for both
//Draw car
console.log("drawing the car");
ourCar.draw();
requestAnimationFrame(drawIt);
}
//start rendering
requestAnimationFrame(drawIt);
</script>
</body>
</html>
这里发生了几件事...
首先,requestAnimationFrame(drawIt) 在页面加载时运行。如果鼠标尚未移动,则 mousex 和 mousey 为 NaN。此外,drawIt 继续调用自身,因此如果您查看控制台,它只会不断重复 NaN。我不确定你的 objective 是什么,但你可能想检查 ourCar.x 和 ourCar.y 以及 return 的有效值(如果没有任何集合的话)。
关于图片,首先,正如xufox所说,你使用的是img而不是this.img。但是,由于此时您在一个函数中,您不想使用它,因为它指的是实际的 img 标签本身。您应该在该函数之外设置一个变量并将其设置为等于此值。
其次,为了让img.onload触发,你需要设置图片的src属性。
JS Fiddle 和下面的代码以及注释和控制台消息来说明,以及为使其正常工作而进行的更新,您可能需要根据您的需要进行重构。
https://jsfiddle.net/2dd4rv9u/
// canvas and context objects
var myCanvas = document.getElementById("myCanvas");
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
var ctx = myCanvas.getContext("2d");
myCanvas.addEventListener('mousemove', updateMousePos, false);
//mouse position coordinates
var mousex;
var mousey;
//constructor for a Car object with methods to update position, orientation, and draw the car
function Car(x, y, orientation, id, type) {
//x and y are the cooredinates of the center of a car object
this.x = x;
this.y = y;
this.type = type;
this.speed = 5; //default speed = 5
this.isAlive = 1;
this.stillExists = 1;
this.id = id;
this.orientation = orientation;
this.img = new Image();
this.img.source = 'http://www.iconsdb.com/icons/preview/black/car-xxl.png';
this.img.width = 200;
this.img.height = 100;
//this method computes a new positin and orientation of our car.
this.updatePosAndOrien = function(){
//caclcuate car orientation using mousex and mousey and x y position of our car using atan2
var targetX = mousex - this.x;
var targetY = mousey - this.y;
var trgtOrien = Math.atan2(targetY, targetX);
this.orientation = trgtOrien;
//calculate new positon of car using speed and current location of car
var dx = mousex -this.x;
var dy = mousey - this.y;
//distance between mouse and car
var distance = Math.sqrt(dx*dx + dy*dy);
//Now we compute xspeed and yspeed of car - which are displacements along x and y axis
var factor = distance / this.speed;
var xspeed = dx / factor;
var yspeed = dy / factor;
//set new positon of car
this.x = this.x + xspeed;
this.y = this.y+ yspeed;
};
//draw method that draws the car on canvas
this.draw = function() {
this.img.x = this.x;
this.img.y = this.y;
this.img.orientation = this.orientation;
var self = this;
this.img.onload = function() {
console.log('DRAWING');
console.log(this);
console.log(this.img);
console.log(self.img.x);
ctx.save();//save context
//translate context origin to center of image
ctx.translate(Math.round(self.x), Math.round(self.y));
ctx.rotate(self.orientation); //rotate context
// I set these to 0 because I didn't check the math and wanted to show
// that the car would draw
ctx.drawImage(self.img, 0, 0);//draw img
ctx.restore(); //restore context
}
this.img.src = this.img.source;
};
}
/*this function update mouse position upon mouse movement*/
function updateMousePos(evt) {
var rect = myCanvas.getBoundingClientRect();
mousex = evt.clientX - rect.left;
mousey = evt.clientY - rect.top;
//log mouse position
console.log("mouse postion: "+mousex+", "+mousey);
}
//defining car and starting the rendering
var ourCar = new Car(300, 400, 2, 111, 1);
console.log("car: "+ourCar.x+", "+ourCar.y);
/*This function draws everything using requestFrameAnimation(). */
function drawIt() {
if (isNaN(ourCar.x)) return;
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
//update orientation of player
ourCar.updatePosAndOrien();
console.log("car in drawIt: "+ourCar.x+", "+ourCar.y); //prints NAN for both
//Draw car
console.log("drawing the car");
ourCar.draw();
requestAnimationFrame(drawIt);
}
//start rendering
requestAnimationFrame(drawIt);