0

我有以下问题:我正在尝试用 JavaScript 制作一个简单的游戏。游戏的想法是有一个画布,一个在里面弹跳的球和一个从左到右的小垫子来击球。我已经这样做了,它工作正常:

var canvasBg;
var contextBg;

var canvasBall;
var contextBall;


function Drawable() {

    this.initialize = function(x,y) {
        this.x = x;
        this.y = y;
    };

    this.draw = function() {

    };
}

function Ball() {

    var dx = 2;
    var dy = 2;

    var radius = 5;

    this.draw = function() {

        contextBall.beginPath();
        contextBall.clearRect(0,0,canvasBall.width,canvasBall.height);
        contextBall.closePath();

        contextBall.beginPath();
        contextBall.fillStyle = "#0000ff";
        contextBall.arc(this.x, this.y, radius, 0, Math.PI*2, true);
        contextBall.closePath();
        contextBall.fill();

        // the code seems to stop here
        if(this.x<0 || this.x>300)
            dx = -dx;
        if(this.y<0 || this.y>150)
            dy = -dy;

        if((this.x+radius)>pad.x && (this.x-radius)<(pad.x+50) && (this.y+radius)>pad.y && (this.y-radius)<(pad.y+10)) {
            dy = -dy;
        } 

        if(this.y>(pad.y-2) && this.y<(pad.y+12) && (this.x+radius)>pad.x && (this.x-radius)<(pad.x+50)) {
            dx = -dx;
        }

        this.x += dx;
        this.y += dy;
    };

}

Ball.prototype = new Drawable();

KEY_CODES = {

    37: 'left',
    39: 'right',
};

KEY_STATUS = {};

for (code in KEY_CODES) {

    KEY_STATUS[ KEY_CODES[ code ]] = false;
}

document.onkeydown = function(e) {
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
    if (KEY_CODES[keyCode]) {
        e.preventDefault();
        KEY_STATUS[KEY_CODES[keyCode]] = true;
    }
};

document.onkeyup = function(e) {
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
        if (KEY_CODES[keyCode]) {
        e.preventDefault();
        KEY_STATUS[KEY_CODES[keyCode]] = false;
    }
};

function Pad() {

    var hSpeed = 5;
    this.padWidth = 50;
    this.padHeight = 10;

    this.draw = function() {

        contextBg.clearRect(0,0,canvasBg.width,canvasBg.height);
        contextBg.fillStyle = "#ffffff";
        contextBg.fillRect(this.x,this.y,this.padWidth,this.padHeight);

    };

    this.move = function() {
        if(KEY_STATUS.left || KEY_STATUS.right) {
            contextBg.clearRect(0,0,canvasBg.width,canvasBg.height);

            if(KEY_STATUS.left) {
                this.x -= hSpeed;
            if (this.x <= 0)
                this.x = 0;
            } else if (KEY_STATUS.right) {
                this.x += hSpeed;
            if (this.x >= 300-this.padWidth)
                this.x = 300 - this.padWidth;
            }
            this.draw();
        }
    };
}

Pad.prototype = new Drawable();


function init() {

        canvasBg = document.getElementById('display');
        contextBg = this.canvasBg.getContext('2d');

        canvasBall = document.getElementById('ball');
        contextBall = this.canvasBall.getContext('2d');

        ball = new Ball();
        ball.initialize(10,10);

        pad = new Pad();
        pad.initialize(120,80);

        setInterval(function(){animate();},30);

}

function animate() {
        ball.draw();
        pad.draw();
        pad.move();
};

但是,我决定尝试改进我的代码,并创建了一个 GamePlay 类:

var game = new GamePlay();

function Drawable() {

    this.initialize = function(x,y) {
        this.x = x;
        this.y = y;
    };

    this.draw = function() {

    };
}

function Ball() {

    var dx = 2;
    var dy = 2;

    var radius = 5;

    this.draw = function() {

        this.context.beginPath();
        this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
        this.context.closePath();

        this.context.beginPath();
        this.context.fillStyle = "#0000ff";
        this.context.arc(this.x, this.y, radius, 0, Math.PI*2, true);
        this.context.closePath();
        this.context.fill();



        if(this.x<0 || this.x>300)
            dx = -dx;
        if(this.y<0 || this.y>150)
            dy = -dy;

        if((this.x+radius)>pad.x && (this.x-radius)<(pad.x+50) && (this.y+radius)>pad.y && (this.y-radius)<(pad.y+10)) {
            dy = -dy;
        } 

        if(this.y>(pad.y-2) && this.y<(pad.y+12) && (this.x+radius)>pad.x && (this.x-radius)<(pad.x+50)) {
            dx = -dx;
        }


        this.x += dx;
        this.y += dy;
    };

}

Ball.prototype = new Drawable();

KEY_CODES = {

    37: 'left',
    39: 'right',
};

KEY_STATUS = {};

for (code in KEY_CODES) {

    KEY_STATUS[ KEY_CODES[ code ]] = false;
}

document.onkeydown = function(e) {
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
    if (KEY_CODES[keyCode]) {
        e.preventDefault();
        KEY_STATUS[KEY_CODES[keyCode]] = true;
    }
};

document.onkeyup = function(e) {
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
        if (KEY_CODES[keyCode]) {
        e.preventDefault();
        KEY_STATUS[KEY_CODES[keyCode]] = false;
    }
};

function Pad() {

    var hSpeed = 5;
    this.padWidth = 50;
    this.padHeight = 10;

    this.draw = function() {

        this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
        this.context.fillStyle = "#ffffff";
        this.context.fillRect(this.x,this.y,this.padWidth,this.padHeight);

    };

    this.move = function() {
        if(KEY_STATUS.left || KEY_STATUS.right) {
            this.context.clearRect(0,0,this.canvas.width,this.canvas.height);

            if(KEY_STATUS.left) {
                this.x -= hSpeed;
            if (this.x <= 0)
                this.x = 0;
            } else if (KEY_STATUS.right) {
                this.x += hSpeed;
            if (this.x >= 300-this.padWidth)
                this.x = 300 - this.padWidth;
            }
            this.draw();
        }
    };
}

Pad.prototype = new Drawable();

function GamePlay() {

    var ball;
    var pad;

    this.setUpGame = function() {

        this.canvasBg = document.getElementById('display');
        this.contextBg = this.canvasBg.getContext('2d');

        this.canvasBall = document.getElementById('ball');
        this.contextBall = this.canvasBall.getContext('2d');

        Ball.prototype.canvas = this.canvasBall;
        Ball.prototype.context = this.contextBall;

        Pad.prototype.canvas = this.canvasBg;
        Pad.prototype.context = this.contextBg;

        ball = new Ball();
        ball.initialize(10,10);

        pad = new Pad();
        pad.initialize(120,80);

    };


    var animate = function() {
        ball.draw();
        pad.draw();
        pad.move();
    };

    this.startGame = function() {
        setInterval(function(){animate();},30);
    };

}

function init() {
    game.setUpGame();
    game.startGame();
}

但是,它只在其初始化坐标上画了一个球,然后似乎停在那里。我尝试通过在代码中的某些点上放置 alert() 来进行一些手动测试,我发现它似乎停止在球的 draw 方法中间并跳过调用 pad.draw() 和 pad.move() 在 animate( )。我不知道出了什么问题,我猜这是原型的问题。我是 JavaScript 新手,这种基于原型的 OOP 对我来说仍然有点困惑。谢谢。

4

2 回答 2

1

我尝试了代码并发现了下一个问题:

  1. 函数init- 希望在 html 完全加载后调用
  2. Ball.draw函数引用对象pad,它没有在其上下文中定义,使用game.pad
  3. var animate = function创建本地“私有”变量,将其更改为this.animate = function
  4. 在 setInterval 调用适当的函数setInterval(function(){game.animate();},30);
  5. var game = new GamePlay();GamePlay在定义之前调用,将这个字符串移到下面

在进行这些更改后,它可以在控制台中正常工作

于 2013-10-24T21:16:55.300 回答
0

我相信这是因为您在绘制方法中误用了路径。

首先,您不需要.clearRect.beginPathand包装.closePath

其次,可能导致您的脚本出错的原因是您在绘制圆圈.fill之后使用。应该在使用之前和之后使用你不需要使用,因为它已经为你关闭了你的路径。.closePath.fill.closePath.fill.closePath

于 2013-10-24T20:53:50.667 回答