Javascript Canvas Game - 如何知道对象何时穿过自己的路径?

时间:2016-11-12 15:23:37

标签: javascript canvas

我是Javascript的新手。我正在尝试制作类似于Snake的画布游戏,但没有果实

如果玩家穿过自己的路径,游戏就结束了。以下是我的代码。你知道我怎么能确定红色矩形何时穿过它自己的路径并使用游戏而不是函数?

谢谢!



var player;
var touch = 0;

function startGame() {
  myGameArea.start();
  player = new component(30, 30, "red", 270, 270);
}

var myGameArea = {
  canvas: document.createElement("canvas"),
  start: function() {
    this.canvas.width = 600;
    this.canvas.height = 600;
    this.context = this.canvas.getContext("2d");
    document.body.insertBefore(this.canvas, document.body.childNodes[0]);
    this.interval = setInterval(updateGameArea, 20);
    window.addEventListener('keydown', function(e) {
      myGameArea.key = e.keyCode;

    })
  },
  clear: function() {
    this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }
}

function component(width, height, color, x, y) {
  this.gamearea = myGameArea;
  this.width = width;
  this.height = height;
  this.speedX = 0;
  this.speedY = 0;
  this.x = x;
  this.y = y;
  this.update = function() {
    ctx = myGameArea.context;
    ctx.fillStyle = color;
    ctx.fillRect(this.x, this.y, this.width, this.height);

  }
  this.newPos = function() {
    this.x += this.speedX;
    this.y += this.speedY;
  }
}

function updateGameArea() {
  /*myGameArea.clear();*/
  player.speedX = 0;
  player.speedY = 0;
  if (myGameArea.key == 37) {
    player.speedX = -10;
  }
  if (myGameArea.key == 39) {
    player.speedX = 10;
  }
  if (myGameArea.key == 38) {
    player.speedY = -10;
  }
  if (myGameArea.key == 40) {
    player.speedY = 10;
  }
  if (player.x <= 0 || player.x >= 570 || player.y <= 0 || player.y >= 570) { //When the player goes out of the canvas
    gameOver();
  }
  player.newPos();
  player.update();
}

function gameOver() {

  var r = confirm("GAME OVER. Restart?");
  if (r == true) {
    window.location.reload();

  } else {
    window.open("https://www.google.ca");
  }

}
&#13;
canvas {
  padding-left: 0;
  padding-right: 0;
  margin-left: auto;
  margin-right: auto;
  display: block;
  background-color: #000;
}
&#13;
<body onload="startGame()">
</body>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

数组作为队列。

传统上这种游戏的使用方式是使用称为队列的特殊数组类型。就像真正的队列一样,你在一端添加了项目,在另一端添加了项目,或者先进先出去了。

Javascript没有队列的特殊数组类型,但它具有实现队列所需的所有功能。

推送和转移

Array.push(item); // pushes an item onto the top of the array
Array.shift(); // removes an item from the start of the queue

因此对于蛇游戏来说,将头部想象成队列的末尾。每次向前移动一个你在队列中放置另一个项目。在另一端,如果数组的长度超过蛇的长度,则删除一个项目;

var snake = [];
var snakeLength = 10;
function snakeMove(x,y){  // position to move head
   checkForHit(x,y); // see below
   snake.push({x:x,y:y}); // put another headpiece on the queue
   if(snake.length > snakeLength){ // is the length longer than it should be
       snake.shift();    // remove a tail item
   }
}

要绘制蛇,只需迭代每个部分,将其绘制在X,y位置

要测试蛇是否自行运行,请使用以下功能

function checkForHit(x,y){
    for(var i = 0; i < snake.length; i++){
       if(snake[i].x === x && snake[i].y === y){
           // Snake has hit its self
       }
    }
}

当蛇吃东西时,它传统上长度增长。只需增加长度变量即可轻松完成。 snakeLength += 1使队列更长。

一个演示,因为我没有玩过这么长时间的游戏原因。

&#13;
&#13;
 "use strict";

var score = 0;
var canvas =  document.createElement("canvas");
var scoreE =  document.createElement("div");
scoreE.style.color = "white";
scoreE.style.font = "16px arial";
scoreE.style.position = "absolute";
scoreE.style.top = "10px";
scoreE.style.left = "10px";
scoreE.style.width = "600px";
scoreE.style.textAlign = "center";
scoreE.textContent = "Click canvas area to get focus";
 

canvas.width = 600;
canvas.height = 200;
var ctx  = this.canvas.getContext("2d");
document.body.appendChild(canvas);
document.body.appendChild(scoreE);
var lastKeyDown = 0;
window.addEventListener('keydown', function(e) {
     lastKeyDown = e.keyCode;
     e.preventDefault()
})

var snakePartSize = 8;
var playWidth = canvas.width /snakePartSize;
var playHeight = canvas.height /snakePartSize;
var snake = [];
var snakeLength = 10;
var snakePosX = 0;
var snakePosY = 0;
var snakeDirX = 0;
var snakeDirY = 0;
var snakeSpeed = 16; // number of frame between moves
var gameOver = true;
var instDrawn = false;
var food = [];
var foodFreq = 60; 
var yum = 0;
var yumCol = ["red","orange","yellow"];
 

function startSnake(){
    ctx.fillStyle = "black";
    ctx.fillRect(0,0,canvas.width,canvas.height);
    snakePosX = Math.floor(playWidth  / 2);
    snakePosY = Math.floor(playHeight / 2);
    snakeDirX = 0;
    snakeDirY = 0;
    snakeLength = 10;
    snake = [];
    snakeSpeed = 16;
    move(snakePosX,snakePosY); // set first pos
    food = [];
    score = 0;
}
function testHit(x,y){
    if(x < 0 || y < 0 || y >= playHeight   || x >= playWidth ){
        return true;
    }
    for(var i = 0; i < snake.length; i ++){
        if(snake[i].x === x && snake[i].y === y){
            return true;
        }
    }
}
function testFood(x,y){
    for(var i = 0; i < food.length; i ++){
        if(food[i].x === x && food[i].y === y){
            food.splice(i,1);
            i --;
            yum = 4;
            score += 100;
            snakeLength += 1;
            if(snakeLength % 4 === 0){
               snakeSpeed -= snakeSpeed > 1 ? 1:0;
            }
        }
    }
}
function addFood(){
    var x = Math.floor(Math.random() * playWidth );
    var y = Math.floor(Math.random() * playHeight );
    if(!testHit(x,y)){
       food.push({x:x,y:y});
       drawFood();
    }
} 

function move(x,y){
    if(testHit(x,y)){
        gameOver = true;
        return;
    }
    testFood(x,y);
    snake.push({x : x, y : y});
    drawSnakeHead();
    if(snake.length > snakeLength){
        drawSnakeTail();
        snake.shift();
    }
}
function drawYum(){
    for(var i = 0; i < snake.length; i ++){
        ctx.fillStyle = yumCol[yum];
        ctx.fillRect(snake[i].x*snakePartSize, snake[i].y*snakePartSize, snakePartSize, snakePartSize);
    }

}

function drawFood(){
    var f = food[food.length-1];
    ctx.fillStyle = "green";
    ctx.fillRect(f.x*snakePartSize, f.y*snakePartSize, snakePartSize, snakePartSize);
    
}
function drawSnakeHead(){
    var head = snake[snake.length-1];
    ctx.fillStyle = "red";
    ctx.fillRect(head.x*snakePartSize, head.y*snakePartSize, snakePartSize, snakePartSize);
    
}
function drawSnakeTail(){
    var head = snake[0];
    ctx.fillStyle = "black";
    ctx.fillRect(head.x*snakePartSize, head.y*snakePartSize, snakePartSize, snakePartSize);
    
}



var counter = 0;
function update(){
    counter += 1;
    if(!gameOver){
        
        if(snakeDirX === 0){ 
            if(lastKeyDown === 37){   // left
                snakeDirX = -1;
                snakeDirY = 0;
            }
            if(lastKeyDown === 39){ // right
                snakeDirX = 1;
                snakeDirY = 0;
            }
        }
        if(snakeDirY === 0){ 
            if(lastKeyDown === 38){   // up
                snakeDirY = -1;
                snakeDirX = 0;
           }
           if(lastKeyDown === 40){ // down
                snakeDirY = 1;
                snakeDirX = 0;
           }
        }
        lastKeyDown = 0;
      
        if(counter % foodFreq ===0){
            addFood();
        }
        if(counter % snakeSpeed === 0){
            snakePosX += snakeDirX;
            snakePosY += snakeDirY;      
            score += 1;  
            move(snakePosX ,snakePosY);        
        }
        if((counter % 2 === 0) && yum > 0){
            yum -= 1;
            drawYum();

        }
        scoreE.textContent = "Score : "+ score;


    }
    if(gameOver){
        if(!instDrawn){
            instDrawn = true;
            ctx.fillStyle = "white";
            ctx.font = "32px arial";
            ctx.textAlign = "center";
            ctx.fillText("GAME OVER",canvas.width /2, canvas.height /2);
            ctx.font = "16px arial";
            ctx.fillText("Press a direction key to start.",canvas.width /2, canvas.height /2+32);
        }
        if(lastKeyDown >= 37 && lastKeyDown <= 40){
            gameOver = false;
            instDrawn = false;
            counter = -1;
            startSnake();

        }
    }
    
    
    
    requestAnimationFrame(update);
}
requestAnimationFrame(update);
startSnake();
&#13;
&#13;
&#13;