贪吃蛇是我们都玩过的游戏,也是一代人的回忆。今天就带大家用原生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好改多了,不管怎样多写才能更加熟练。