2017-07-26 53 views
0

我已經寫了這個簡單的蛇遊戲 - 你使用箭頭導航蛇吃蘋果(紅色圓圈)。現在在我的代碼中,當蛇吃(相交)時,它的(蛇)大小增加1個塊(10px)。 我想要做的是:每次蛇吃蘋果 - >增加蛇的大小 - >將蘋果移動到畫布內的不同位置。javascript蛇遊戲 - 如何移動蘋果?

我已標記,我覺得代碼移動蘋果應該去的部分裏面的代碼,但我不知道如何實現,什麼將是實際代碼:

if (!this.objectCollide(myApple)){ 
     this.segments.pop(); 
    } else { 
     alert("COLLISION!!")) 
    }; 

下面是完整的Javascript代碼:

var gameField = document.getElementById('gameField'); 
var ctx = gameField.getContext("2d"); 
var blockSize = 10; 
columnCt = gameField.width/blockSize; 
rowsCt = gameField.height/blockSize; 

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

block.prototype.drawBlock = function() { 
    ctx.fillStyle = "blue"; 
    ctx.fillRect(this.x * blockSize, this.y * blockSize, blockSize, 
    blockSize); 
}; 

block.prototype.drawApple = function() { 
    ctx.fillStyle = "red"; 
    ctx.textBaseline = "bottom"; 
    ctx.arc(this.x, this.y, 6, 2 * Math.PI, false); 
    ctx.fill(); 
} 

var Snake = function() { 
    this.segments = [new block(20, 20), new block(19, 20), new block(18, 20), new block(17, 20), 
    new block(16, 20), new block(15, 20), new block(14, 20), new block(13, 20), new block(12, 20), 
    new block(11, 20), new block(10, 20) 
    ]; 
    this.direction = "right"; 
} 

Snake.prototype.drawSnake = function() { 
    for (i = 0; i < this.segments.length; i++) { 
    this.segments[i].drawBlock(); 
    } 
} 

Snake.prototype.setDirection = function(dir) { 
    if (this.direction == "left" && dir == "right" || this.direction == "right" && dir == "left" || this.direction == "up" && dir == "down" || 
    this.direction == "down" && dir == "up") { 
    return 
    } else { 
    this.direction = dir; 
    }; 
}; 

Snake.prototype.objectCollide = function(obj) { 
    if (this.segments[0].x == Math.round(obj.x/blockSize) && this.segments[0].y == Math.round(obj.y/blockSize)) { 
    return true 
    } else { 
    return false 
    } 
}; 

Snake.prototype.move = function() { 
    var head = this.segments[0]; 
    var newHead; 

    switch (this.direction) { 
    case "right": 
     newHead = new block(head.x + 1, head.y); 
     break; 
    case "left": 
     newHead = new block(head.x - 1, head.y) 
     break; 
    case "down": 
     newHead = new block(head.x, head.y + 1) 
     break; 
    case "up": 
     newHead = new block(head.x, head.y - 1) 
     break; 
    } 

    this.segments.unshift(newHead); 

    if (!this.objectCollide(myApple)) { 
    this.segments.pop(); 
    } else { 
    alert("COLLISION!!!") 
    }; 
    var collision = newHead.x >= columnCt || newHead.x <= -1 || 
    newHead.y >= rowsCt || newHead.y <= -1; 

    for (i = 1; i < this.segments.length; i++) { 
    if (this.segments[i].x == newHead.x && this.segments[i].y == newHead.y) { 
     collision = true; 
     break; 
    }; 
    }; 

    if (collision) { 
    clearInterval(myFun); 
    }; 

}; 

var mySnake = new Snake() 
mySnake.drawSnake(); 
var myApple = new block(Math.floor(Math.random() * gameField.width), 
    Math.floor(Math.random() * gameField.height)); 
var myFun = setInterval(function() { 
    ctx.clearRect(0, 0, gameField.width, gameField.height); 
    mySnake.move(); 
    mySnake.drawSnake(); 
    myApple.drawApple(); 
}, 100) 

var directions = { 
    37: "left", 
    38: "up", 
    39: "right", 
    40: "down" 
}; 

document.onkeydown = function(event) { 
    var newDirection = directions[event.keyCode] 
    if (newDirection != undefined) { 
    mySnake.setDirection(newDirection); 
    }; 
}; 

而且例如在的jsfiddle:https://jsfiddle.net/x9ztn3vs/

+0

myApple = new block(Math.random()* gameField.width,Math.random()* gameField.height) –

+0

只需選擇一個沒有被蛇佔據的隨機塊(只是隨機地嘗試,直到你得到這樣的一個塊),然後將該塊設置爲蘋果內部數據。爲了讓蛇變大,只需要在其內部分段字段的末尾添加一個新分段。 – Zabuza

+0

@Jonasw你的代碼工作!問題是蛇吃了蘋果後,新的蘋果出現在不同的位置(這是好的),但「老」的一個並沒有消失。任何想法如何使老蘋果disapper? – Pawel

回答

2

而不是使用alert("COLLISION!!!");只是做這兩事情:

增加蛇的大小

就在年底另一個元素添加到陣列中:

this.segments.push(this.segments[this.segments.length-1]); 

圍繞蘋果移動

do { 
    myApple.x = Math.floor(Math.random() * gameField.width); 
    myApple.y = Math.floor(Math.random() * gameField.height); 
    var colliding = this.segments.find((v) => v.x == Math.round(myApple.x/blockSize) && v.y == Math.round(myApple.y/blockSize));  
} while (colliding); 

免責聲明:這是不是高效。它會滯後,因爲蛇的長度會增加,因爲碰撞的可能性。

+0

Afaik Snake中的蘋果不允許在被蛇佔領的地方產卵。你的代碼很簡單,肯定可以幫助OP,但它不能解決這種情況。 – Zabuza

+0

@Zabuza這是應該做的。 – lilezek

+0

OP的函數'this.objectCollide(myApple)'只會檢測與蛇'段[0]'的頭部的碰撞,而不會與其他段碰撞。另外,我認爲OP的問題還包括「*在發現碰撞後如何增加蛇的大小?」,所以你只給出部分答案,但是它是有幫助的。 – Zabuza