画布奇怪的问题,当失去一切得快2倍

时间:2018-05-27 22:03:00

标签: javascript html5 canvas

所以我有一个简单的游戏,比如一个乒乓球比赛,扔球,只是一个简单的游戏,目前通过一些colision检查,会发生的是,当我输掉游戏时,玩家变得更快,就像它得到两个时间更快,球也是。 无法弄清楚造成这种情况的原因,有什么帮助?

目前我有一个简单的html,我按照这个顺序加载3个脚本文件(player.js,ball.js,index.js)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="reset.css">
</head>
<body>
    <canvas id="myCanvas">
        Your browser doesn't support canvas
    </canvas>
    <script src="models/player.js"></script>
    <script src="models/ball.js"></script>    
    <script src="index.js"></script>        
</body>
</html>

player.js

// defines player configuration behaviour
const PLAYER_WIDTH = 200;
const Y_OFFSET = 100;
const PLAYER_HEIGHT = 30;
const SPEED = 6;

function Player(x = ctx.canvas.width/2 - PLAYER_WIDTH/2, y = ctx.canvas.height - Y_OFFSET, width = PLAYER_WIDTH, height = PLAYER_HEIGHT, color = 'rgba(0,0,0)') {
    this.left = false;
    this.right = false;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.color = color;

    this.movePlayer = function(deltaX) {
        this.x += deltaX;
    }

    this.drawPlayer = function() {
        ctx.fillStyle = this.color;        
        ctx.fillRect(this.x, this.y, this.width, this.height);        
    }
}

ball.js

// defines player configuration behaviour
const BALL_POSITION_Y = 100;
const RADIUS = 12;
const BALL_SPEED = 6;

function Ball(x = ctx.canvas.width/2, y = ctx.canvas.height - Y_OFFSET - RADIUS, radius = RADIUS, color = 'rgb(100,149,237)', speed = BALL_SPEED) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speed = speed;

    this.drawBall = function() {
        ctx.fillStyle = this.color;        
        ctx.beginPath();
        ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
        ctx.fill();
    }

    // for inital game started
    this.moveBallWithPlayer = function(deltaX) {
        this.x += deltaX;
    }

    this.moveBallY = function(flag) {
        this.y = this.y + flag;
    }

    this.moveBallX = function(flag) {
        this.x = this.x + flag;
    }
}

主要代码,index.js(gamelogic)

var canvas;
var ctx;
var player;
var ball;
var gameStarted;
var flagY;
var flagX;
var angle;

function init() {
    canvas = document.getElementById('myCanvas')
    if (canvas.getContext) {
        ctx = canvas.getContext('2d')
        setCanvasSize(ctx)
        player = new Player()
        ball = new Ball()
        attachKeyboardListeners()     
        draw();   
    }
}

function draw() {
    flagX = -1;
    flagY = -1;
    angle = 35;
    gameStarted = false
    player = new Player();
    ball = new Ball();
    animate()
}

function animate () {
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    drawIce()    
    player.drawPlayer();
    ball.drawBall();
    playerMovementeHandler()

    if(gameStarted) {
        ballMovementHandler();            
    }

    window.requestAnimationFrame(animate);    
}

function playerMovementeHandler() {
    if(player.left === true) {
        if(player.x > 0) {
            player.movePlayer(-SPEED);
            if(!gameStarted) {
                ball.moveBallWithPlayer(-SPEED);
            }            
        }
    }

    if(player.right === true) {
        if(player.x + player.width < ctx.canvas.width) {
            player.movePlayer(SPEED);            
            if(!gameStarted) {
                ball.moveBallWithPlayer(SPEED);
            }      
        }
    }
}

function ballMovementHandler() {
    if(ball.y - ball.radius <= 0) {
        flagY = 1;
    }
    if(ball.y + ball.radius === player.y) {
        if(ball.x + ball.radius >= player.x && ball.x < player.x + player.width) {
            flagY = -1;            
        }
        else {
            draw();
        }
    }
    if(ball.x - ball.radius <= 0) {
        flagX = 1;
    }
    if(ball.x + ball.radius >= ctx.canvas.width) {
        flagX = -1;
    }
    radians = angle * Math.PI/ 180;
    ball.moveBallY(Math.sin(radians) * ball.speed * flagY);
    ball.moveBallX(Math.cos(radians) * ball.speed * flagX);  
}

function drawIce() {
    ctx.fillStyle = 'rgb(134,214,216)'
    ctx.fillRect(0,ctx.canvas.height - Y_OFFSET + player.height + 10, ctx.canvas.width, Y_OFFSET)
}

function setCanvasSize() {
    ctx.canvas.width = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
}


function keyboardEvent(keyCode, keyStatus) {
    switch(keyCode) {
        case 37: 
            player.left = keyStatus;
            break;
        case 39: 
            player.right = keyStatus;
            break;
        case 32:
            gameStarted = true;
            break;
    }
}

function attachKeyboardListeners() {
    document.addEventListener('keydown', function(e) {
        keyboardEvent(e.keyCode, true)
    })  
    document.addEventListener('keyup', function(e) {
        keyboardEvent(e.keyCode, false)   
    }) 
}

  init();

1 个答案:

答案 0 :(得分:1)

问题是,一旦玩家输了,你就会调用draw()来重置状态,然后在绘制功能中调用animate()。这意味着每次玩家输掉时,你都会开始一个新的动画循环,并且每帧的球移动功能将被调用两次(每次丢失后3次,4次等)。

我已更新您的代码以调用绘制函数“reset”,并在init()中调用“animate”一次。

// player.js
// defines player configuration behaviour
const PLAYER_WIDTH = 200;
const Y_OFFSET = 100;
const PLAYER_HEIGHT = 30;
const SPEED = 6;

function Player(x = ctx.canvas.width/2 - PLAYER_WIDTH/2, y = ctx.canvas.height - Y_OFFSET, width = PLAYER_WIDTH, height = PLAYER_HEIGHT, color = 'rgba(0,0,0)') {
    this.left = false;
    this.right = false;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.color = color;

    this.movePlayer = function(deltaX) {
        this.x += deltaX;
    }

    this.drawPlayer = function() {
        ctx.fillStyle = this.color;        
        ctx.fillRect(this.x, this.y, this.width, this.height);        
    }
}

// ball.js
// defines player configuration behaviour
const BALL_POSITION_Y = 100;
const RADIUS = 12;
const BALL_SPEED = 6;

function Ball(x = ctx.canvas.width/2, y = ctx.canvas.height - Y_OFFSET - RADIUS, radius = RADIUS, color = 'rgb(100,149,237)', speed = BALL_SPEED) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speed = speed;

    this.drawBall = function() {
        ctx.fillStyle = this.color;        
        ctx.beginPath();
        ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
        ctx.fill();
    }

    // for inital game started
    this.moveBallWithPlayer = function(deltaX) {
        this.x += deltaX;
    }

    this.moveBallY = function(flag) {
        this.y = this.y + flag;
    }

    this.moveBallX = function(flag) {
        this.x = this.x + flag;
    }
}

// game code
var canvas;
var ctx;
var player;
var ball;
var gameStarted;
var flagY;
var flagX;
var angle;

function init() {
    canvas = document.getElementById('myCanvas')
    if (canvas.getContext) {
        ctx = canvas.getContext('2d')
        setCanvasSize(ctx)
        player = new Player()
        ball = new Ball()
        attachKeyboardListeners()     
        reset();
        animate();
    }
}

function reset() {
    flagX = -1;
    flagY = -1;
    angle = 35;
    gameStarted = false
    player = new Player();
    ball = new Ball();
}

function animate () {
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    drawIce()    
    player.drawPlayer();
    ball.drawBall();
    playerMovementeHandler()

    if(gameStarted) {
        ballMovementHandler();            
    }

    window.requestAnimationFrame(animate);    
}

function playerMovementeHandler() {
    if(player.left === true) {
        if(player.x > 0) {
            player.movePlayer(-SPEED);
            if(!gameStarted) {
                ball.moveBallWithPlayer(-SPEED);
            }            
        }
    }

    if(player.right === true) {
        if(player.x + player.width < ctx.canvas.width) {
            player.movePlayer(SPEED);            
            if(!gameStarted) {
                ball.moveBallWithPlayer(SPEED);
            }      
        }
    }
}

function ballMovementHandler() {
    if(ball.y - ball.radius <= 0) {
        flagY = 1;
    }
    if(ball.y + ball.radius === player.y) {
        if(ball.x + ball.radius >= player.x && ball.x < player.x + player.width) {
            flagY = -1;            
        }
        else {
            reset();
        }
    }
    if(ball.x - ball.radius <= 0) {
        flagX = 1;
    }
    if(ball.x + ball.radius >= ctx.canvas.width) {
        flagX = -1;
    }
    radians = angle * Math.PI/ 180;
    ball.moveBallY(Math.sin(radians) * ball.speed * flagY);
    ball.moveBallX(Math.cos(radians) * ball.speed * flagX);  
}

function drawIce() {
    ctx.fillStyle = 'rgb(134,214,216)'
    ctx.fillRect(0,ctx.canvas.height - Y_OFFSET + player.height + 10, ctx.canvas.width, Y_OFFSET)
}

function setCanvasSize() {
    ctx.canvas.width = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
}


function keyboardEvent(keyCode, keyStatus) {
    switch(keyCode) {
        case 37: 
            player.left = keyStatus;
            break;
        case 39: 
            player.right = keyStatus;
            break;
        case 32:
            gameStarted = true;
            break;
    }
}

function attachKeyboardListeners() {
    document.addEventListener('keydown', function(e) {
        keyboardEvent(e.keyCode, true)
    })  
    document.addEventListener('keyup', function(e) {
        keyboardEvent(e.keyCode, false)   
    }) 
}

  init();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="reset.css">
</head>
<body>
    <canvas id="myCanvas">
        Your browser doesn't support canvas
    </canvas>
</body>
</html>