在Javascript中,为什么我无法绘制我的对象的多个实例?

时间:2012-04-20 15:40:50

标签: javascript html5 class canvas multiple-instances

我正在尝试使用HTML5和javascript中的canvas标签创建一个基本的游戏引擎。

但是我在以下代码中创建两个不同的Balle类实例时遇到了麻烦,我看不出原因。

<html>
<head>
<title>
</title>
<script>
// Description des Classes

// Classe Point2D
function Point2D (x, y)
{
    this.x = x;
    this.y = y;
}

// Classe Box2D
function Box2D (x, y, width, height)
{
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

//Classe CanvasObject
function CanvasObject(context) {
    this.context = context;
    this.fillStyle = "#ffff00";
    this.lineWidth = 1;
    this.strokeStyle = "black";
    this.boundingBox2D = new Box2D (0, 0, 0, 0);
}

// Détection de collision par boîte 2D.
CanvasObject.prototype.collides = function (b) {
    var left = (this.boundingBox2D.x < b.boundingBox2D.x + b.boundingBox2D.width);
    var right = (this.boundingBox2D.x + this.boundingBox2D.width > b.boundingBox2D.x);
    var top = (this.boundingBox2D.y + this.boundingBox2D.height > b.boundingBox2D.y);
    var bottom = (this.boundingBox2D.y < b.boundingBox2D.y + b.boundingBox2D.height);

    return left && right && top && bottom;
};

// Classe Arc
// Paramètres :
//    context <-- Contexte d'animation
function Arc(context)
{
    this.context = context;
    this.center = new Point2D(0, 0);
    this.start = 0;
    this.end = 0;
    this.radius = 0;
    this.counterClockwise = false;
}

// Héritage de CanvasObject
Arc.prototype = new CanvasObject(this.context);

// Fonction mettant à jour la bounding box autour de la balle
// Nécessaire car c'est un cercle...
Arc.prototype.update = function () {
    this.boundingBox2D.x = this.center.x - this.radius;
    this.boundingBox2D.y = this.center.y - this.radius;
    this.boundingBox2D.width = 2 * this.radius;
    this.boundingBox2D.height = 2 * this.radius;
};

// Méthode pour dessiner
Arc.prototype.draw = function () {
    this.context.beginPath();
    this.context.arc (this.center.x, this.center.y, this.radius, this.start, this.end, this.counterClockWise);
    this.context.closePath();
    this.context.fillStyle = this.fillStyle;
    this.context.fill();
    this.context.lineWidth = this.lineWidth;
    this.context.strokeStyle = this.strokeStyle;
    this.context.stroke();    
};

// Classe Balle
function Balle (context) {
    this.context = context;
    this.start = 0;
    this.end = 2 * Math.PI;
}

Balle.prototype = new Arc(this.context);


// FIN DÉCLARATION DE CLASSE

// Fonction permettant d'établir le FPS du browser
window.requestAnimFrame = (function(callback){
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){
        window.setTimeout(callback, 1000 / 60);
    };
})();

// Declare global variables
var lastTime;

// Objets
var balle;
var testArc;

var canvas;
var context;

var pressedKeys;
var d;
var log;

function initialize()
{
    canvas = document.getElementById("c");
    context = canvas.getContext("2d");

    pressedKeys = [];
    d = document.getElementById("divTest");
    log = document.getElementById("log");

    var date = new Date();
    lastTime = date.getTime();

    // Initialize the global variables
    balle = new Balle (context);
    balle.center.x = canvas.width / 2;
    balle.center.y = canvas.height / 2;
    balle.radius = 10;
    balle.speed = 75;
    balle.pixelPerFrame = 0;
    balle.dX = 1;
    balle.dY = 1;
    balle.nitro = 1;
    balle.fillStyle = "#ff0000";
    balle.lineWidth = 1;

    testArc = new Balle (context);

    testArc.center.x = canvas.width *.75;
    testArc.center.y = canvas.height * .75;
    testArc.radius = 25;
    testArc.lineWidth = 3;
}


// Update position of objects
function update()
{
    var date = new Date();
    var time = date.getTime();
    var timeDiff = time - lastTime;

    var ppfFactor = timeDiff / 1000;

    updateBalle(ppfFactor);

    lastTime = time;
}

// Mise à jour de la balle
// Paramètres :
// ppfFactor : pixelPerFrame factor
function updateBalle(ppfFactor)
{


    balle.pixelPerFrame = balle.speed * ppfFactor;

    if (pressedKeys[17])
        balle.nitro = 5;
    else
        balle.nitro = 1;

    if (pressedKeys[37] || pressedKeys[39])
        if (pressedKeys[39])
            balle.dX = 1;
        else
            balle.dX = -1;
    else
        balle.dX = 0;

//    if (!balle.collides (testArc))
        balle.center.x = balle.center.x + (balle.pixelPerFrame * balle.dX * balle.nitro);

    if (pressedKeys[38] || pressedKeys[40])
        if (pressedKeys[40])
            balle.dY = 1;
        else
            balle.dY = -1;
    else
        balle.dY = 0;

//    if (!balle.collides (testArc))
        balle.center.y = balle.center.y + (balle.pixelPerFrame * balle.dY * balle.nitro);

    balle.update();
    testArc.update();    

}

// draw objects
function draw()
{
    // clear
    context.clearRect(0, 0, canvas.width, canvas.height);

    testArc.draw();
    balle.draw();
}

// Boucle continue d'animation
function animate(){

    // update
    update();

    // draw
    draw();

    // request new frame
    requestAnimFrame(function(){
        animate();
    });
}


window.onload = function(){
    // initialize stage
    initialize();

    animate();
};


window.onkeydown = function (e)
{
    var e = window.event || e;

    if (d)
        d.innerHTML = "Key Code : " + e.keyCode + " Collision : " + balle.collides(testArc);

    pressedKeys[e.keyCode] = true;
}

window.onkeyup = function (e)
{
    var e = window.event || e;

    pressedKeys[e.keyCode] = false;
}

</script>
</head>
<body>
<canvas id="c" width="640" height="480">
</canvas>
<div id="divTest"></div>
<ul id="log">
</ul>
</body>
</html>

感谢您的帮助

1 个答案:

答案 0 :(得分:3)

这是因为你完成继承的方式,特别是这一行:

Balle.prototype = new Arc(this.context);

这意味着Balle类的所有实例将共享与其原型相同的Arc类实例,因此当您更新一个balle的中心时,它们都会更新。

你应该研究一种更好的处理继承的方法,一种流行的方法是John Resig的方法http://ejohn.org/blog/simple-javascript-inheritance/