贪吃蛇

JS版的贪吃蛇

演示地址:http://47.92.142.7:8080/snake(点击可以玩)

贪吃蛇

源码地址:https://gitee.com/rbqnb/snake.git

Html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<link rel="stylesheet" type="text/css" href="./CSS/index.css"/>
	</head>
	<body>
		<div class="content" id="">
			<div class="btn pause" id="">
				<button type="button"></button>
			</div>
			<div class="btn start" id="">
				<button type="button"></button>
			</div>
			<div id="score">
					分数:<input type="text"  name="" id="" value="" />
			</div>
			<div class="snakeWrap" id="snakeWrap">
				
			</div>
			<div class="button" id="">
				<button type="button" style="background-color: gray;">简单</button>
				<button type="button">难</button>
				<button type="button">较难</button>
				<button type="button">特别难</button>
			</div>
		</div>
		<script src="./JS/index.js" type="text/javascript" charset="utf-8"></script>
	</body>
</html>

CSS

.content{
	width: 640px;
	height: 640px;
	margin: 40px auto;
	position: relative;
}
.btn{
	width: 100%;
	height: 100%;
	position: absolute;
	left: 0;
	top: 0;
	z-index: 2;
}
.btn button{
	background: none;
	border: none;
	background-size: 100% 100%;
	
	cursor: pointer;
	outline: none;
	
	position: absolute;
	left: 50%;
	top: 50%;
}
.start button{
	width: 200px;
	height: 80px;
	background-image: url(../images/startGame.png);
	margin-top: -40px;
	margin-left: -100px;
}
.pause{
	display: none;
}
.pause button{
	width: 70px;
	height: 70px;
	background-image: url(../images/pause.png);
	margin-top: -35px;
	margin-left: -35px;
}
.snakeHead{
	background-image:url(../images/snake.png) ;
	background-size: cover;//背景大小和图片大小一样
}
.snakeWrap{
	width: 600px;
	height: 600px;
	background-color:gainsboro;
	border: 20px solid gray;
	position: relative;
}
.snakeBody{
	background-color: #9ddbb1;
	border-radius: 50%;
}
.food{
	background-image: url(../images/food.png);
	background-size: cover;//背景大小和图片大小一样
}
#score{
	z-index: 3;
	position: absolute;
	display: none;
	margin-top: 30px;
	margin-left: 30px;
	color: red;
	font-size: 15px;
}
#score input{
	margin-left: 0;
	border: none;
	background-color: transparent;
	width:  30px;
	height: 30px;
	color: #FF0000;
	text-align: center;
	font-size: 15px;
}

JS

var sw = 20, //一个方块的宽
	sh = 20, //一个方块的高
	tr = 30, //行数
	td = 30; //列数
var snake = null, //蛇实例
	food = null, //食物实例
	game = null; //游戏实例

var v = 200;
//方块构造函数 (链表节点Node)
function Square(x, y, classname) {
	this.next = null; //下一个节点
	this.pre = null; //上一个节点
	// x,y指的是小方块的位置,className是小方块的class
	this.x = x * sw;
	this.y = y * sh;
	this.name = classname; //该元素的class

	this.viewContent = document.createElement('div'); //方块对应的dom元素
	this.viewContent.className = this.name;

	//snakeWrap
	this.parent = document.getElementById('snakeWrap');
}

//在dom中创建一个方块
Square.prototype.create = function() {
	this.viewContent.style.position = 'absolute';
	this.viewContent.style.width = sw + 'px';
	this.viewContent.style.height = sh + 'px';
	this.viewContent.style.left = this.x + 'px';
	this.viewContent.style.top = this.y + 'px';
	//添加到snakeWrap中
	this.parent.appendChild(this.viewContent);
}

//在dom中删除方块
Square.prototype.remove = function() {
	this.parent.removeChild(this.viewContent);
}


//蛇(链表)
function Snake() {
	this.head = null; //存蛇头信息
	this.tail = null; //蛇尾
	this.pos = []; //每一个方块位置
	this.directionNum = { //存蛇走的方向
		left: {
			x: -1,
			y: 0,
			rotate: 90
		},
		up: {
			x: 0,
			y: -1,
			rotate: 0
		},
		down: {
			x: 0,
			y: 1,
			rotate: -90
		},
		right: {
			x: 1,
			y: 0,
			rotate: 180
		}
	}
	this.direction = this.directionNum.right;
}

//初始化蛇
Snake.prototype.init = function() {
	//初始化蛇头
	var snakeHead = new Square(2, 0, 'snakeHead');
	snakeHead.create();
	this.head = snakeHead;
	this.pos.push([2, 0]);
	//初始化蛇身体
	var snakebody1 = new Square(1, 0, 'snakeBody');
	snakebody1.create();
	this.pos.push([1, 0]);

	var snakebody2 = new Square(0, 0, 'snakeBody');
	this.tail = snakebody2;
	snakebody2.create();
	this.pos.push([0, 0]);
	
	//链表
	snakeHead.next = snakebody1;
	snakebody1.pre = snakeHead;
	snakebody1.next = snakebody2;
	snakebody2.pre = snakebody1;
}

//获取下一个点
Snake.prototype.getNextPos = function() {
	var nextPos = [
		this.head.x / sw + this.direction.x,
		this.head.y / sh + this.direction.y
	]

	//撞到自己游戏结束(下一个点的坐标在pos中可以找到)
	var selfCollied = false;

	this.pos.forEach(function(value) {
		if (value[0] == nextPos[0] && value[1] == nextPos[1]) {
			selfCollied = true;
		}
	})
	if (selfCollied) {
		this.strategies.over.call(this);
		return;
	}


	//撞到围墙游戏结束
	if (nextPos[0] < 0 || nextPos[1] < 0 || nextPos[0] > tr - 1 || nextPos[1] > td - 1) {
		this.strategies.over.call(this);
		return;
	}
	//撞到食物,吃
	if (food && food.pos[0] == nextPos[0] && food.pos[1] == nextPos[1]) {
		this.strategies.eat.call(this);
		return;
	}
	//什么都不是,走
	this.strategies.move.call(this);
}

//处理碰撞后要做的事
Snake.prototype.strategies = {
	over: function() {
		game.over();
		// 要在这个函数里面操作snake就得使用call
	},
	eat: function() {
		//直接调用move
		this.strategies.move.call(this, true);
		createFood();
		game.addScore();
	},
	move: function(format) {
		//创建一个新身体(在旧蛇头的位置)
		var newBody = new Square(this.head.x / sw, this.head.y / sh, 'snakeBody');
		newBody.create();

		//节点插入链表中
		newBody.next = this.head.next;
		newBody.next.pre = newBody;

		//创建一个新蛇头
		var newHead = new Square(this.head.x / sw + this.direction.x, this.head.y / sh + this.direction.y,
			'snakeHead');
		newHead.viewContent.style.transform = 'rotate(' + this.direction.rotate + ')';
		newHead.create();


		//节点插入链表
		newBody.pre = newHead;
		newHead.next = newBody;

		//将新蛇头加入pos头
		this.pos.unshift([this.head.x / sw + this.direction.x, this.head.y / sh + this.direction.y]);

		if (!format) { // 如果format为fasle时,需要删除,不是吃时
			//移除尾

			this.tail.remove();
			//将就旧蛇尾从pos(尾)中删掉
			this.pos.pop([this.tail.x / sw, this.tail.y / sh]);

			//新蛇头替换就蛇头
			this.tail = this.tail.pre;
			this.tail.next = null;
		}

		//移除旧头
		this.head.next = null
		this.head.remove();
		this.head = newHead;
	}
}
// 创造食物函数
function createFood() {
	var x = null;
	var y = null;

	var include = true;

	while (include) {
		//随机数 math.round四折五入   math.random()*x 随机产生的数在0--x
		x = Math.round(Math.random() * (td - 1));
		y = Math.round(Math.random() * (td - 1));

		snake.pos.forEach(function(value) {
			if (x != value[0] && y != value[1]) {
				include = false;
			}
		});
	}
	food = new Square(x, y, 'food');
	food.pos = [x, y];
	console.log(food);
	//判断是否还有食物(一直是一个foodDom)
	var foodDom = document.getElementsByClassName('food')[0];
	if (foodDom) {
		foodDom.style.left = x * sw + 'px';
		foodDom.style.top = y * sh + 'px';
	} else {
		food.create();
	}
}


//游戏构造函数
function Game() {
	this.timer = null;
	this.socre = 0;
}
//增加分数
Game.prototype.addScore = function() {
	game.socre++;
	var score1 = document.querySelector('#score input');
	score1.value = this.socre;
}
//游戏初始化
Game.prototype.init = function() {
	snake.init();
	createFood();
	var score2 = document.getElementById('score');
	score2.style.display = 'block';
	document.querySelector('#score input').value = this.socre;
	document.onkeydown = function(e) {
		// e.which 37-40 左 上 右 下
		if (e.which == 37 && snake.direction != snake.directionNum.right) { // 按下左键并且这个蛇不往右走
			snake.direction = snake.directionNum.left;
		} else if (e.which == 38 && snake.direction != snake.directionNum.down) { //按下上键
			snake.direction = snake.directionNum.up;
		} else if (e.which == 39 && snake.direction != snake.directionNum.left) { //按下右键
			snake.direction = snake.directionNum.right;
		} else if (e.which == 40 && snake.direction != snake.directionNum.up) { //按下下键
			snake.direction = snake.directionNum.down;
		}
	}
	var snakeWrop = document.getElementById('snakeWrap');
	snakeWrop.onclick = function() {
		var pauseBtn = document.querySelector('.pause')
		pauseBtn.style.display = 'block';
		game.pause();
	}
	this.start();
}
//开始游戏
Game.prototype.start = function() {
	this.timer = setInterval(function() {
		snake.getNextPos();
	}, v);
}
//暂停游戏
Game.prototype.pause = function() {
	clearInterval(this.timer);
	//暂停游戏
	var pauseBtn = document.querySelector('.pause')
		pauseBtn.onclick = function() {
			game.start();
			pauseBtn.style.display = 'none';
	}
}
//结束游戏
Game.prototype.over = function() {
	clearInterval(this.timer);
	alert('得分' + this.socre);

	//清屏
	var snakeWrop = document.getElementById('snakeWrap');
	snakeWrop.innerHTML = '';
	
	document.getElementById('score').style.display = 'none';

	//显示出开始游戏
	var startBtn = document.querySelector('.start');
	startBtn.style.display = 'block';
	
	// 清分
	
	//game为空
	snake = new Snake();
	game = new Game;
}

game = new Game();
//重置游戏
function reset(){
	clearInterval(game.timer);
	var snakeWrop = document.getElementById('snakeWrap');
	snakeWrop.innerHTML = '';
	document.getElementById('score').style.display = 'none';
	//显示出开始游戏
	var startBtn = document.querySelector('.start');
	startBtn.style.display = 'block';
	
}
//游戏初始化
function init(){
	snake = new Snake();
	game = new Game();
	startBtn.parentNode.style.display = 'none';
	game.init();
}
//开启游戏
var startBtn = document.querySelector('.start button');
startBtn.onclick = function() {
	console.log(v);
	init();
}
var button = document.getElementsByClassName('button')[0].children;
button[0].onclick = function(){
	for(var i=0;i<button.length;i++){
		button[i].style = 'none';
	}
	this.style.backgroundColor ='gray';
	v = 200;
	reset();
}
button[1].onclick = function(){
	document.getElementById('score').style.display = 'none';
	for(var i=0;i<button.length;i++){
		button[i].style = 'none';
	}
	this.style.backgroundColor ='gray';
	v=150;
	reset();
}
button[2].onclick = function(){
	for(var i=0;i<button.length;i++){
		button[i].style = 'none';
	}
	this.style.backgroundColor ='gray';
	v=75;
	reset();
}
button[3].onclick = function(){
	for(var i=0;i<button.length;i++){
		button[i].style = 'none';
	}
	this.style.backgroundColor ='gray';
	v=30;
	reset();
}

 

上一篇:python – 用2个点查找向量


下一篇:剑指 Offer 29. 顺时针打印矩阵 + 蛇形矩阵 + 模拟 + 思维题