貪吃蛇是我們都玩過的遊戲,也是一代人的回憶。今天就帶大家用原生js實現貪吃蛇遊戲功能。
基本思路:隨機創建地圖;利用top和left值,利用座標的傳遞使蛇動起來;隨機在地圖上顯示食物;利用蛇頭的座標進行判斷;
優化細節;
開發模式:單例模式;(開發模式有時間一併分享給大家)
實現效果如下:
代碼如下:
<!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">
<link rel="shortcut icon" href="./圖標.png" type="image/x-icon">
<title>貪吃蛇</title>
<style>
body {
margin: 0%;
padding: 0%;
}
.map {
width: 900px;
height: 600px;
background-color: rgb(0, 0, 0);
margin: 0% auto;
position: relative;
cursor: none;
}
.snake {
width: 30px;
height: 30px;
position: absolute;
border: 2px solid rgba(0, 0, 0, 0.226);
box-sizing: border-box;
}
.food {
position: absolute;
width: 30px;
height: 30px;
background-color: aquamarine;
border-radius: 50%;
}
.score {
color: white;
}
</style>
</head>
<body>
<script>
var Map; //地圖
var Snake; //蛇
var Food; //食物
var score = 0; //分數
var speed = 600; //蛇前進的速度
var game = (function () { //單例模式開發
function map() { //地圖方法,用於創建地圖和分數顯示
this._map = null;
this.creatmap = function () { //創建地圖
if (this._map == null) {
this._map = document.createElement('div');
this._map.className = 'map';
}
}
this.createSpan = function () { //創建分數顯示欄
this._span = null;
if (this._span == null) {
this._span = document.createElement("span");
this._span.className = "score";
this._span.innerHTML = "總分:0";
}
this._map.appendChild(this._span);//_span爲_map的子集
}
}
function snake() {//蛇的方法
this.direct = 'right';//默認移動方向爲向右
this._map = null;
this._span = null;
this._snake = [//初始蛇有三塊,頭,身,尾,利用數組儲存相對座標,顏色和判斷值
[3, 1, "red", null],
[2, 1, "orange", null],
[1, 1, "orange", null]
];
this.creatsnake = function () {//創建蛇
for (var i = 0; i < this._snake.length; i++) {
if (this._snake[i][3] == null) {
this._snake[i][3] = document.createElement('div');
this._snake[i][3].style.backgroundColor = this._snake[i][2];
this._snake[i][3].className = 'snake';
}
this._snake[i][3].style.left = this._snake[i][0] * 30 + 'px';//地圖大小是900*600,蛇一節爲30*30,推得結果
this._snake[i][3].style.top = this._snake[i][1] * 30 + 'px';
this._map.appendChild(this._snake[i][3]);//蛇的節是地圖的子集
}
}
this.snake_move = function () {//蛇移動,座標的遷移
var len = this._snake.length - 1;
for (var i = len; i > 0; i--) {
this._snake[i][1] = this._snake[i - 1][1];
this._snake[i][0] = this._snake[i - 1][0];
}
switch (this.direct) {//移動方向
case 'right':
this._snake[0][0] += 1;
break;
case 'left':
this._snake[0][0] -= 1;
break;
case 'top':
this._snake[0][1] += 1;
break;
case 'down':
this._snake[0][1] -= 1;
break;
}
// console.log(this._snake[0][3].style.left)
if (this._snake[0][0] == Food.x && this._snake[0][1] == Food.y) {//判斷利用蛇頭相對座標和食物相對座標是否吃到食物
score += 100;//吃到食物加分,滿500分加速一次
console.log(this._span);
this._span.innerHTML = "總分:" + score + "分";
if (score % 500 == 0 && speed > 100) {
speed -= 100;
console.log(speed);
clearInterval(timecount);
setInterval(function () {
Snake.snake_move();
}, speed);
}
this._snake.push([//增加蛇長
this._snake[this._snake.length - 1][0],
this._snake[this._snake.length - 1][1],
"yellow",
null
]);
Food.creatfood();//重新創建食物
}
if (this._snake[0][0] * 30 < 0 || this._snake[0][0] * 30 > 870 || this._snake[0][1] *
30 < 0 || this._snake[0][1] * 30 > 570) {//如果碰到牆壁,遊戲結束
clearInterval(timecount);
this._span.innerHTML = 'GAME OVER';
}
this.creatsnake();
}
}
function food() {//食物方法
this._food = null;
this.map = null;
this.x = 0;
this.y = 0;
this.creatfood = function () {//類似於創建蛇
this.x = Math.floor(Math.random() * 30);
this.y = Math.floor(Math.random() * 20);
if (this._food == null) {
this._food = document.createElement('div');
this._food.className = 'food';
}
this._food.style.left = this.x * 30 + "px";
this._food.style.top = this.y * 30 + "px";
this._map.appendChild(this._food);//食物也是地圖的子集
}
}
function getmaps() {
Map = new map;//實例化對象
Map.creatmap();
Map.createSpan();
CreatFood(Map._map);//由於要用到map,所以不能直接調用“創建”方法,要穿對應的參,實現對map,span的使用
CreatSnake(Map._map, Map._span);
return Map._map;
}
function CreatFood(map) {//在地圖上創建食物
Food = new food;
Food._map = map;
Food.creatfood();
}
function CreatSnake(map, span) {//在地圖上創建蛇,移動蛇
Snake = new snake();
Snake._map = map;
Snake._span = span;
Snake.creatsnake();
timecount = setInterval(function () {
Snake.snake_move();
}, speed);
document.onkeypress = function (e) {//wasd 來控制蛇的方向(不能直接轉換到相反方向)
switch (e.key) {
case 's':
if (Snake.direct == 'down') {
return;
}
Snake.direct = 'top';
break;
case 'a':
if (Snake.direct == 'right') {
return;
}
Snake.direct = 'left';
break;
case 'w':
if (Snake.direct == 'top') {
return;
}
Snake.direct = 'down';
break;
case 'd':
if (Snake.direct == 'left') {
return;
}
Snake.direct = 'right';
break;
}
}
}
return {
Snakemap: getmaps()
}
})();
document.body.appendChild(game.Snakemap);//創建的所有是body的子集
// console.log(Food.x);
</script>
</body>
</html>
說點什麼:感覺獨立的寫這種還是有點頭疼的,不過相對於canvas bug好改多了,不管怎樣多寫才能更加熟練。