代码地址如下:
http://www.demodashi.com/demo/11818.html

贪吃蛇小游戏(第二版)

一年半前层用react写过贪吃蛇小游戏https://github.com/caohuilin/Snake_React

那时刚刚学习React的我兴奋的尝试了很久

近些日子比较清闲,想着用学到的东西重新写个版本,于是V2就来了https://github.com/caohuilin/Snake_React_v2

游戏规则

贪吃蛇大家都不陌生了,吃掉一个食物,蛇的身体会变长,食物随机出现在屏幕的另一个位置。碰到自己或者碰到墙壁游戏结束。

注意一点就是设置目前只支持游戏模式的设置。

点击设置按钮后,点击左键或者右键进行模式切换。

项目安装部署

Install

yarn install

Start Serve

It's served in http://localhost:3000 .

yarn run serve

Build

yarn run build

游戏思路介绍

基础项目搭建

采用webpack、gulp构建工具,搭建React开发脚手架

游戏界面划分

  • 设计游戏界面(游戏界面分为标题,主界面,按键三部分组成)
  • 根据划分的界面构建组件

基础组件界面实现

  • Header采用蛇身体部分元素展示
  • 主界面分为游戏屏幕界面和游戏过程中信息展示界面
  • 按键界面主要为游戏方向控制键,游戏开始键和游戏设置相关键

让蛇动起来

  • 定义snake初始值和初始方向

    snake初始值为游戏界面随机相邻的两个点
const index = modal === 1 ? 3 : 1;// modal为游戏模式
const x = Math.floor(Math.random() * (column - index)) + 1;// column为根据屏幕大小计算出的游戏界面的高度
const y = Math.floor(Math.random() * (Row - index)) + 1;// Row为游戏界面的宽度
const ISnakeRecord = Immutable.Record({
snake: Immutable.fromJS([
{
x: x,
y: y
}, {
x: x,
y: y - 1
}
])
});
const IDirectionRecord = Immutable.Record({
snake: 3
});
  • 定义设置snake的action
export const setSnack = createAction('set snake');export const setSnack = createAction('set snake');
  • 开始游戏后,每500ms计算蛇下一个的位置
//goNext函数为计算snake下一个的位置,并触发设置snake的action,组件重新加载,从而模拟蛇前进的动画。
startGame = () => {
if (this.timer ) { clearInterval(this.timer); }
this.timer = setInterval(this.goNext, 500);
}

监听按键,改变蛇的运动方向

  • 定义设置snake方向的action
export const setSnackDirection = createAction('set snake direction');
  • DOM监听KeyDown事件
<div className='app' onKeyDown={this.keyDown} tabIndex={0}>
...
</div>
  • keyDown事件的实现

    除了改变蛇的方向的按键之外,还实现了游戏开始,游戏结束,游戏暂停,重新开始游戏,设置游戏模式等按键的监听,实现方式基本差不多,只是触发不同的action,改变不同的reducer
  handleKeyDown = (code) => {
// init 为游戏当前所处状态,只有当初始化动画显示完毕开始游戏之后,方向键才起相应作用
const init = this.props.game.get('init');
if (code === 1) {
this.props.actions.setVolume();
} else if (init === 0) {// 初始化完毕
if (code === 2 || code === 0 ) {// 开始游戏
this.props.actions.setGameInit(1);
this.props.actions.clearCode();
this.props.actions.startGame();
} else if (code === 3) {// 设置游戏模式
this.props.actions.setGameInit(-2);
}
} else if (init === 1) {// 游戏中
let direction = this.props.direction.get('snake');
if (code === 38 && direction !== 1) {
direction = 0;
} else if (code === 40 && direction !== 0) {
direction = 1;
} else if (code === 37 && direction !== 3) {
direction = 2;
} else if (code === 39 && direction !== 2) {
direction = 3;
} else if (code === 32) {
this.props.actions.pauseGame();
} else if (code === 4) {
this.props.actions.pauseGame({pause: true});
} else if (code === 2) {
this.props.actions.pauseGame({pause: false});
this.props.actions.startGame();
} else if (code === 0) {
this.props.actions.endGame();
this.props.actions.setGameInit(-1);
this.props.actions.initSnack();
setTimeout(this.handleKeyDown.bind(null, 2), 0);
}
this.props.actions.setSnackDirection(direction);
} else if (init === -2) {// 设置游戏模式
if (code === 37 || code === 39) {
this.props.actions.setModal();
} else if (code === 2) {
this.props.actions.setGameInit(1);
this.props.actions.startGame();
}
} else if (init === -1 && code === 2) {// 初始化中
setTimeout(this.handleKeyDown.bind(null, 2), 0);
}
}
keyDown = (event: any) => {
const code = event.nativeEvent.keyCode;
this.handleKeyDown(code);
}

食物的产生

  • 初始化食物的位置
const index = modal === 1 ? 3 : 1;
const x = Math.floor(Math.random() * (column - index)) + 1;
const y = Math.floor(Math.random() * (Row - index)) + 1;
const IFoodRecord = Immutable.Record({
food: Immutable.fromJS(
{
x: x,
y: y
}
)
});
  • 定义重新设置食物位置的action
export const setFood = createAction('set food');
  • 让食物闪动起来

    每隔200ms改变食物是否显示的样式,制造食物闪动的效果
this.foodTimer = setInterval(this.setFoodShowOrHide, 200);
setFoodShowOrHide = () => {
this.setState({ showFood: !this.state.showFood});
}
<div className={`cell ${showFood ? 'food-o-cell' : 'food-cell'}`}></div>
  • 判断snake头部下一个位置是否为食物的位置,若为食物的位置,蛇的长度+1,出发重新设置食物位置的action
    if (next.x !== currentFood.x || next.y !== currentFood.y) {
currentSnake.pop();
} else {
this.props.actions.getCode();
this.props.actions.setFood();
}

分数展示

初始设置分数为0,每一次判断到snake头部下一个位置是否为食物时,分数+1

模式选择

在设置模式下,左右按键实现模式切换

试玩

https://caohuilin.github.io/Snake_React_v2/

补充

基本功能已经实现,难免有处理不当或者没有考虑到的界限问题,欢迎提Issue,https://github.com/caohuilin/Snake_React_v2

祝大家玩的愉快!

附项目文件截图



基于React的贪吃蛇游戏的设计与实现

代码地址如下:
http://www.demodashi.com/demo/11818.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

最新文章

  1. Nginx的配置文件
  2. Codeforces Round #381 (Div. 1) A. Alyona and mex 构造
  3. CEF 相关资料
  4. cache写策略
  5. Objective-C 【动态类型检测&amp;响应方法】
  6. java IO复习(二)
  7. javascript:DOM自定义属性的妙用
  8. epoll的原理和使用方法
  9. [Cycle.js] Introducing run() and driver functions
  10. webpack+gulp实现自动构建部署
  11. easyUI创建人员树
  12. Python函数篇(7)-正则表达式
  13. studio多渠道打包
  14. MonolithFirst
  15. SpringMVC FistMVC详解
  16. db2系统表相应功能
  17. 《spring boot 实战》读书笔记
  18. python flask实现小项目方法
  19. REDIS 缓存的穿透,雪崩和热点key
  20. Win7局域网打印机共享设置(详细图文流程)

热门文章

  1. Visual Studio Code 好用的 source code editor
  2. python--enum
  3. Fiddler抓包9-保存会话(save)【转载】
  4. vim的最最基本配置
  5. poj 1329(已知三点求外接圆方程.)
  6. CentOS下yum安装
  7. 洛谷——2639[USACO09OCT]Bessie的体重问题Bessie&#39;s We…——01
  8. response.getWriter().write()与out.print()的区别(转)
  9. Bean 生命周期&amp;&amp;模块化配置
  10. xcode里面使用Memory Leaks和Instruments检测内存泄漏