我的课程有什么问题 - 短期课程

时间:2017-03-03 21:52:11

标签: javascript html5 canvas web nan

代码说明:Car对象会根据鼠标位置定期更新其位置和方向。我是requestAnimationFrame函数,可以更平滑地渲染帧。

问题: 当我在绘图功能内部时,汽车对象的x和y坐标是NAN。 汽车没有在画布上展示。

代码:

<!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>

1 个答案:

答案 0 :(得分:1)

这里有几件事情......

首先,requestAnimationFrame(drawIt)在页面加载时运行。如果鼠标尚未移动,则mousex和mousey为NaN。此外,drawIt继续调用自己,所以如果你看一下控制台,它就会不断重复NaN。我不确定你的目标是什么,但你可能想检查myCar.x和ourCar.y的有效值,如果没有任何设置则返回。

至于图像,首先,就像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);