项目需求
- 设计地图
- 设计高度和宽度
- 地图由一个个原子组成(原子就是小的div)
- 可以设计X轴有n个原子,Y轴n个原子
- 显示画布的功能
- 创造食物
- 食物的宽度和高度等于原子的大小
- 功能:在地图上显示食物
- 蛇本体
- 设置头、体、尾(至少三个原子)
- 高度和宽度为原子的大小
- 功能:
- 持续运动
- 键盘控制方向
- 遇到边界,游戏结束,重新开始
- 遇到事物,增加一个原子的大小
- 自己碰到自己,游戏结束,重新开始
- 规则
- 蛇可以升级,定义一个级别号
- 每升一级,速度加快
- 定义升级条件,随着等级提高,升级难度加大
业务流程:
创建每一个对象,相关使用对象
开始暂停功能
项目开发
阶段一: (制作背景)
1. 创建一个定时器,并绑定给开始游戏和暂停游戏z
1. 制作背景地图,选择是否显示格子
1. 代码见 -> [阶段一开发代码](https://www.yuque.com/u12581613/sr444s/euf28o?view=doc_embed)
阶段二:(基础内容)
1. 构造一个食物对象,并且会在地图中随机生成食物
1. 构造蛇对象,先初始化蛇的头、体、尾
1. 键盘控制方向,让蛇自由运动
1. 代码见 -> [阶段二开发代码](https://www.yuque.com/u12581613/sr444s/swqzg7?view=doc_embed)
阶段三:(控制规则)
1. 控制蛇吃掉食物会自己变长
1. 判断蛇撞墙和咬到自己,游戏结束
1. 增加游戏难度(如关数,速度...)
1. 美化网页(可自选)
1. 代码见下方,此项目完成
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇</title>
<style>
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
body{
background: url("img/bj.jpg") 0 no-repeat;
background-size: cover;
background-attachment: fixed;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
#main{
margin: 100px;
}
.btn{
width: 100px;
height: 40px;
/* margin: 10px; */
}
.canvas{
position: relative;
top: 40px;
border: 1px solid rgb(107, 221, 178);
background-color: rgb(218, 236, 245);
/* background-color: rgb(0, 0, 0); */
}
.gtitle{
font-size: 25px;
font-weight: bold;
margin: 10px;
padding:10px;
}
#gnum{
color: red;
}
</style>
</head>
<body>
<div id="main">
<h1>贪吃蛇</h1>
<input class="btn" type="button" value="开始游戏" id="begin"/>
<input class="btn" type="button" value="暂停游戏" id="pause"/>
<span class="gtitle">第<span id="gnum">1</span>关</span>
<script>
var timer; //变量可以提升
var showCanvas = false; //是否显示格子
/*设置地图的构造方法:
atom为原子初始化的宽高(应该一致)
xnum为地图x轴应该有多少个原子(横向)
ynum为地图y轴应该有多少个原子(纵向)
*/
function Map(atom,xnum,ynum){
this.atom = atom;
this.xnum = xnum;
this.ynum = ynum;
this.canvas = null; //初始化画布
this.create = function(){
this.canvas = document.createElement("div");
this.canvas.className = "canvas";
this.canvas.style.width = this.atom * this.xnum + "px"; //画布的宽
this.canvas.style.height = this.atom * this.ynum + "px"; //画布的高
main.appendChild(this.canvas);
//判断是否需要显示格子
if (showCanvas){
for (var i = 0;i<xnum;i++){
for (var j = 0;j<ynum;j++){
//定义格子的样式
var lattice = document.createElement("div");
lattice.style.border = "1px solid rgb(107, 221, 178)";
lattice.style.width = this.atom + "px";
lattice.style.height = this.atom + "px";
//添加格子到地图中
this.canvas.appendChild(lattice);
lattice.style.position = "absolute";
//利用绝对定位
lattice.style.left = i * this.atom + "px";
lattice.style.top = j * this.atom + "px";
}
}
}
}
}
//创建食物的构造方法
function Food(map){
this.width = map.atom;
this.height = map.atom;
this.bgcolor = "rgb(" + Math.floor(Math.random()*200) + "," + Math.floor(Math.random()*200) + ","+ Math.floor(Math.random()*200) + ")";
//基于x轴和y轴的位置
this.x = Math.floor(Math.random()*map.xnum);
this.y = Math.floor(Math.random()*map.ynum);
this.flag = document.createElement("div");
//设置食物的样式
this.flag.style.width = this.width + "px";
this.flag.style.borderRadius = "5px";
this.flag.style.height = this.height + "px";
this.flag.style.backgroundColor = this.bgcolor;
//定义食物的位置
this.flag.style.position = "absolute";
this.flag.style.left = this.x * this.width + "px";
this.flag.style.top = this.y * this.height + "px";
map.canvas.appendChild(this.flag);
}
//创建蛇的构造方法
function Snake(map){
//设置宽、高
this.width = map.atom;
this.height = map.atom;
//默认走的方向
this.direction = "right";
//设置蛇的主体
this.body = [
{ x:2, y:0 }, //蛇头
{ x:1, y:0 }, //蛇体
{ x:0, y:0 }, //蛇尾
];
//显示蛇 var i in this.body
this.display = function(){
for (var i = 0;i < this.body.length; i++){
if (this.body[i].x != null){
var create_s = document.createElement("div");
//将节点保存到一个状态变量当中,以便之后删除
this.body[i].flag = create_s;
//设置蛇的样式
create_s.style.width = this.width + "px";
create_s.style.height = this.height + "px";
/* create_s.style.border = "2px solid rgb(241, 159, 112)" */
create_s.style.backgroundColor = "rgb(107, 109, 221)";
create_s.style.borderRadius = "5px";
//设置蛇的位置
create_s.style.position = "absolute";
create_s.style.left = this.body[i].x * this.width + "px";
create_s.style.top = this.body[i].y * this.height + "px";
//添加到地图中
map.canvas.appendChild(create_s);
}
}
}
//控制蛇的运动
this.run = function(){
/*
{ x:2, y:0 }, //蛇头
{ x:1, y:0 }, //蛇体
{ x:0, y:0 }, //蛇尾
让x轴的每个位置+1
*/
for (var i = this.body.length-1; i>0; i--) {
this.body[i].x = this.body[i-1].x;
this.body[i].y = this.body[i-1].y;
}
//根据方向处理蛇头
switch (this.direction) {
case "left":this.body[0].x--; break;
case "right":this.body[0].x++; break;
case "up": this.body[0].y--; break;
case "down": this.body[0].y++; break;
}
//判断蛇头是否吃到食物,吃到食物坐标重叠
if (this.body[0].x == food.x && this.body[0].y == food.y){
//蛇加一节,由前面的否循环给这里的x和y赋值
this.body.push({ x:null,y:null,flag:null });
//判断是否下一关
if (this.body.length >= level.slength){
level.set();
}
//删除旧食物节点
map.canvas.removeChild(food.flag);
//创建新的食物
food = new Food(map);
}
//判断蛇是否出界
if (this.body[0].x < 0 || this.body[0].x > map.xnum - 1 || this.body[0].y < 0 || this.body[0].y > map.ynum-1) {
//出界游戏结束,关闭定时器
clearInterval(timer);
alert("真笨呢~居然撞墙死掉了!");
//重置关数
document.querySelector("#gnum").innerHTML = "1";
//重新开始游戏
restart(map,this);
return false;
}
// 判断蛇是否和咬到自己
for (var i = 4;i < this.body.length; i++) {
if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y){
clearInterval(timer);
alert("哎~怎么能咬到自己呢!");
//重置关数
document.querySelector("#gnum").innerHTML = "1";
//重新开始游戏
restart(map,this);
return false;
}
}
//删除旧的元素
for (var i in this.body){
if (this.body[i].flag != null){ //当吃到食物,flag等于null,且不能删除
map.canvas.removeChild(this.body[i].flag);
}
}
//显示新的元素
this.display();
}
}
function restart(map,snake){
//删除蛇的"尸体"
for (var i in snake.body){
map.canvas.removeChild(snake.body[i].flag);
}
//重新生成蛇
snake.body = [
{ x:2, y:0 }, //蛇头
{ x:1, y:0 }, //蛇体
{ x:0, y:0 }, //蛇尾
];
//初始化方向
snake.direction = "right";
//重新显示蛇
snake.display();
map.canvas.removeChild(food.flag);
food = new Food(map)
}
//设置规则类,控制级别
function Level(){
this.num = 1; //第几级别
this.speed = 300; //毫秒,每升一关,速度加快
this.slength = 7; //每一关的程度判断
this.set = function(){
this.num++;
if (this.speed <= 100){
this.speed = 100;
}else{
this.speed -= 40;
}
this.slength += 3; //通关的长度,自行设置
this.display();
start(); //重新开始,速度加快
}
//定义关数的显示
this.display = function(){
document.querySelector("#gnum").innerHTML = this.num;
}
}
//实例化规则类
var level = new Level();
level.display();
//实例化地图类
var map = new Map(20,40,20);
map.create(); //创建画布
//实例化食物类,并创建食物
var food = new Food(map);
//实例化蛇类,创建蛇
var snake = new Snake(map);
//显示蛇
snake.display();
//加入键盘事件,控制蛇的方向
document.onkeydown = function(event){
event = event || window.event;
//上:38 右:39 下:40 左:37
switch (event.keyCode){
case 38:
if (snake.direction != "down"){
snake.direction = "up";
}
break;
case 39:
if (snake.direction != "left"){
snake.direction = "right";
}
break;
case 40:
if (snake.direction != "up"){
snake.direction = "down";
}
break;
case 37:
if (snake.direction != "right"){
snake.direction = "left";
}
break;
}
}
function start(){
clearInterval(timer);
timer = setInterval(function(){
snake.run();
},level.speed);
}
//给开始按钮绑定函数
document.querySelector("#begin").onclick = function(){
start();
}
document.querySelector("#pause").onclick = function(){
clearInterval(timer);
}
</script>
</div>
</body>
</html>