Javascript Canvas游戏-如何知道对象何时穿过自己的路径? [英] Javascript Canvas Game - How to know when object crosses its own path?

查看:40
本文介绍了Javascript Canvas游戏-如何知道对象何时穿过自己的路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to Javascript. I am trying to make a canvas game similar to Snake, but without the fruits.

如果玩家越过自己的路,则游戏结束.以下是我的代码.您知道如何确定红色矩形何时穿过自己的路径并使用游戏结束功能吗?

The game is over if the player crosses his own path. The following is my code. Do you know how can I determine when the red rectangle crosses its own path and use the game over function?

谢谢!

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");
  }

}

canvas {
  padding-left: 0;
  padding-right: 0;
  margin-left: auto;
  margin-right: auto;
  display: block;
  background-color: #000;
}

<body onload="startGame()">
</body>

推荐答案

数组作为队列.

此游戏的传统制作方式是使用一种称为队列的特殊数组类型.就像真实的队列一样,您在一端添加了项目,而在另一端删除了这些项目,或者先进先出.

Array as a Queue.

The way this game is traditionally done is using a special array type called a queue. Like a real queue you have items added at one end and removed at the other, or first in first out.

JavaScript的队列没有特殊的数组类型,但是具有实现队列所需的所有功能.

Javascript does not have a special array type for a queue but it has all the functions needed to implement a queue.

推动并移动

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

因此对于蛇游戏,将头想象为队列的末端.每次向前移动时,您都会在队列中放置另一个项目.在另一端,如果数组的长度比蛇形的长度长,则删除一个项目;

So for the snake game imagine the head as the end of the queue. Every time it moves one forward you place another item on the queue. At the other end you remove an item if the length of the array is longer than the snake length;

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位置绘制它的每个部分

To draw the snake you just iterate each part drawing it at the X,y position

要使用以下功能来测试蛇是否已经运行完毕

To test if the snake has run its self over use the following function

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

当蛇吃东西时,它通常会长一些.只需增加length变量即可轻松完成. snakeLength + = 1 使队列更长.

When the snake eats something it traditionally grows in length. this is easily done by simply increasing the length variable. snakeLength += 1 makes the queue longer.

还有一个演示,因为我很久没玩游戏了.

And a demo as i have not played the game in so long why not.

 "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();

这篇关于Javascript Canvas游戏-如何知道对象何时穿过自己的路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆