JavaScript 游戏系列目录
文章目录
一、实例截图
默认界面
游戏界面
二、游戏分析
首先,从截图里我们能够看到,游戏存在着 地图,蛇,食物 。
由此我们可以划分三个类 蛇类,食物类 与 游戏类。
每个类包含如下功能:
Snake 类 :
- 移动
- 死亡(是否撞到自己的身体)
- 长大(吃到食物)
- 改变其移动方向(无法回头)
Food 类 :
- 定义食物位置(默认为左上角)
Game 类 :
- 游戏初始化
- 游戏渲染
- 验证蛇是否吃到食物
- 验证蛇是否撞到障碍物
- 验证蛇是否撞到墙
- 弹出提示信息
- 游戏结束
- 重置食物位置
- 绑定键盘事件
其次我们再来理一理游戏的规则。
- 食物随机刷新位置(包括被 “吃” 了,但不能刷新在 地图外 / 障碍物上 / 蛇头部位置)
- 蛇不能撞到墙
- 蛇不能撞到障碍物
- 蛇吃了食物后会长大
- 玩家获取了一定分数获胜
了解了游戏规则与每个类的功能后,我们准备着手编写代码,首先是 入口文件 与 样式文件。
三、HTML 与 CSS 文件
1、入口文件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>贪吃蛇小游戏</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app"></div>
<script src="app.js"></script>
</body>
</html>
2、样式文件
* {
padding: 0;
margin: 0;
}
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #333;
}
.game {
position: relative;
border: 1px solid #ccc;
}
.game button {
position: absolute;
left: calc(50% - 60px);
bottom: -40px;
width: 120px;
height: 32px;
outline: none;
}
/* 网格 */
.row {
overflow: hidden;
display: flex;
}
.col {
width: 18px;
height: 18px;
border: 1px solid #ddd;
background: #FFF;
}
/* 网格 */
/* 计分dom */
.score {
position: absolute;
top: 10px;
left: 10px;
text-align: center;
font-size: 30px;
}
/* 计分dom */
/* 消息面板 */
.messages-content {
position: fixed;
top: 20px;
left: 20px;
}
.messages-content .alert {
min-width: 150px;
text-align: center;
padding: 5px 8px;
color : #333;
border-radius: 5px;
margin-bottom: 20px;
animation: alertShowHide 0.5s ease;
}
.messages-content .alert.alert-success {
background: #dff0d8;
}
.messages-content .alert.alert-danger {
background: #f2dede;
}
/* 消息面板 */
/* 动画 */
@keyframes alertShowHide {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
/* 动画 */
四、游戏逻辑的实现
在我们的 入口文件 与 样式文件 全部准备好后,我们便可以开始动手写代码了~。
1、创建类及其构造函数
class Game {
constructor(id) {
this.snake = new Snake();// 实例化蛇类
this.food = new Food();// 实例化食物类
this.mapDom = document.getElementById(id);// 获取容器元素
this.mapArr = [];// 地图数组
this.timer = null;// 定时器
this.row = 40;// 游戏行数
this.col = 40;// 游戏列数
this.cell = 20;// 方格大小
this.score = 0;// 得分
this.stones = [
{
row : 15 , col : 15 },
{
row : 15 , col : 16 },
{
row : 15 , col : 17 },
{
row : 15 , col : 18 },
{
row : 15 , col : 19 },
{
row : 15 , col : 20 },
{
row : 15 , col : 21 },
{
row : 15 , col : 22 },
{
row : 15 , col : 23 },
{
row : 15 , col : 24 },
{
row : 15 , col : 25 },
{
col : 15 , row : 15 },
{
col : 15 , row : 16 },
{
col : 15 , row : 17 },
{
col : 15 , row : 18 },
{
col : 15 , row : 19 },
{
col : 15 , row : 20 },
{
col : 15 , row : 21 },
{
col : 15 , row : 22 },
{
col : 15 , row : 23 },
{
col : 15 , row : 24 },
{
col : 15 , row : 25 },
];// 障碍物
this.levelScore = 40;// 达成通过分数
this.init();// 游戏类初始化
}
}
class Snake {
constructor() {
this[0] = {
row : 10 , col : 9 };// 蛇头
this[1] = {
row : 10 , col : 8 };// 蛇身
this[2] = {
row : 10 , col : 7 };// 蛇尾
this.length = 3;// 蛇的长度
this.tail = null;// 尾部
this.direction = 39;// 移动方向,对应键盘事件里“上下左右键”的 code 码
}
}
// 食物类
class Food {
constructor(row = 0,col = 0) {
this.row = row;
this.col = col;
}
}
建造好三个类及其构造函数后,我们来接着为 Game类 来实现如 初始化,渲染等方法。
2、Game 类 初始化系列方法
我们曾在上面的 Game类 里的构造函数里,调用了 init 方法,那么接下来就让我们来实现他。
init() {
this.initButton();// 初始化开始游戏按钮
this.iniMapStyle();// 初始化地图容器元素样式
this.initScoreStyle();// 初始化得分容器元素样式
this.initMessageBoxStyle();// 初始化信息框容器元素样式
this.