react 写一个贪吃蛇
示例:

全部代码如下:

snake.jsx
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { is, fromJS } from 'immutable';
import "./snake.less";
const TYP = {
normal:1,
head:2,
body:3,
food:4
};
const DIRCTION = {
top:1,
bottom:2,
left:3,
right:4
}
export default class Snake extends Component{
constructor(props){
super(props);
this.state = {
count:0
}
}
componentWillMount(){
var n = 20;
var arr = [];
for(var i = 0; i < n; i++ ){
var temp = [];
for(var j = 0; j < n; j++){
temp[j] = TYP.normal;
}
arr.push(temp);
}
var body = [
{r:6,c:10},
{r:7,c:10},
{r:8,c:10},
{r:9,c:10}
];
var food = {r:14,c:14};
this.conf = {
run:true,
n:n,
dirction:DIRCTION.top,
arr:arr,
body:body,
food:food
};
this.renderSake();
window.addEventListener("keydown",this.keydown.bind(this));
}
componentWillUnmount(){
window.removeEventListener("keydown",this.keydown);
}
keydown=(event)=>{
var key = event.key;
if(!this.conf.run && this.conf.timer){
return ;
}
if(key === "w" && this.conf.dirction !== DIRCTION.top){
//上
this.conf.dirction = DIRCTION.top;
}else if(key === "s" && this.conf.dirction !== DIRCTION.bottom){
//下
this.conf.dirction = DIRCTION.bottom;
}else if(key === "a" && this.conf.dirction !== DIRCTION.left){
//左
this.conf.dirction = DIRCTION.left;
}else if(key === "d" && this.conf.dirction !== DIRCTION.right){
//右
this.conf.dirction = DIRCTION.right;
}
}
mainTimer =()=>{
var me = this;
if(me.conf.timer){
return ;
}
me.conf.timer = setInterval(function(){
if(me.conf.dirction === DIRCTION.top){
//上
me.move(-1,0);
}else if(me.conf.dirction === DIRCTION.bottom){
//下
me.move(1,0);
}else if(me.conf.dirction === DIRCTION.left ){
//左
me.move(0,-1);
}else if(me.conf.dirction === DIRCTION.right ){
//右
me.move(0,1);
}
},360);
}
moveCheck(r,c){
//校验
var body = this.conf.body;
var head = body[0];
var food = this.conf.food;
var n = this.conf.n;
var nextHead = {
r:head.r + r,
c:head.c + c
}
//检查出界
if((nextHead.r >= n) || (nextHead.r < 0 ) || (nextHead.c >= n) || (nextHead.c < 0) ){
return false;
}
//检查咬自己,没有咬到就运动
for(var i = body.length-1; i >= 1; i--){
var item = body[i];
if(item.r === nextHead.r && item.c === nextHead.c ){
return false;
}
item.r = body[i-1].r;
item.c = body[i-1].c;
}
//检查吃食物
if(food.r === nextHead.r && food.c === nextHead.c){
//吃东西
body.push({
r:food.r,
c:food.c
});
//记录分数
this.setState({
count:this.state.count + 1
});
//重新创建食物
this.conf.food = this.createFood();
}
body[0] = nextHead;
return true;
}
move(r,c){
//上下
if(this.moveCheck(r,c)){
//可以下一步
this.renderSake();
}else{
//游戏结束
this.conf.run = false;
clearInterval(this.conf.timer);
this.conf.timer = null;
alert("游戏结束");
}
}
renderSake(){
//渲染蛇的身体
var config = JSON.parse(JSON.stringify(this.conf.arr));
var body = this.conf.body;
var food = this.conf.food;
this.setFood(config,food);
this.setBody(config,body);
this.setState({
config:config
});
}
createFood(){
//创建食物
var food = this.validFood();
var max = 30;
while(!food && max > 0){ //防止死循环和获取的食物坐标在蛇的身体上
food = this.validFood();
max--;
}
return food;
}
validFood(){
//校验食物坐标是否可用
var body = this.conf.body;
var n = this.conf.n;
var r = Math.floor(Math.random()* n);
var c = Math.floor(Math.random()* n);
for(var i = 0,len = body.length; i < len; i++){
var item = body[i];
if(item.r === r && item.c === c){
return false;
}
}
return {r,c};
}
setBody(config,body){
//设置蛇身体
for(var i = 1,len = body.length; i < len; i++){
var item = body[i];
config[item.r][item.c] = TYP.body;
}
config[body[0].r][body[0].c] = TYP.head;
}
setFood(config,food){
//设置食物
config[food.r][food.c] = TYP.food;
}
getClass=(item)=>{
if(item === TYP.head){
return "head";
}else if(item === TYP.body){
return "body";
}else if(item === TYP.food){
return "food";
}
}
render(){
return (
<div className="Snake">
<button className="start" onClick={this.mainTimer}> 点击开始</button>
<p>分数:{this.state.count}</p>
<div className="box">
{
this.state.config.map((item,index)=>{
return <div className="cols" key={index} >
{
item.map((itm,idx)=>{
return <div className={ this.getClass(itm) } key={index + '-'+ idx} ></div>
})
}</div>
})
}
</div>
</div>
);
}
}
snake.less
#root{
height: 100%;
}
.Snake{
width: 100%;
height: 100%;
text-align: center;
background: #fff;
overflow: hidden;
button{
width: 100px;
height: 30px;
}
.box{
width: 400px;
margin: 10px auto;
div.cols{
overflow: hidden;
>div{
float: left;
width: 20px;
height: 20px;
box-sizing: border-box;
border: 1px solid #dedede;
border-inline-start-style: unset;
}
div.body{
background: blueviolet;
}
div.head{
background: red;
}
div.food{
background: gold;
}
}
}
}
react 写一个贪吃蛇的更多相关文章
- 使用Python写一个贪吃蛇
参考代码http://blog.csdn.net/leepwang/article/details/7640880 我在程序中加入了分数显示,三种特殊食物,将贪吃蛇的游戏逻辑写到了SnakeGame的 ...
- 一步一步用Canvas写一个贪吃蛇
之前在慕课网看了几集Canvas的视频,一直想着写点东西练练手.感觉贪吃蛇算是比较简单的了,当年大学的时候还写过C语言字符版的,没想到还是遇到了很多问题. 最终效果如下(图太大的话 时间太长 录制gi ...
- 如何用Python写一个贪吃蛇AI
前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD, ...
- 【C/C++】10分钟教你用C++写一个贪吃蛇附带AI功能(附源代码详解和下载)
C++编写贪吃蛇小游戏快速入门 刚学完C++.一时兴起,就花几天时间手动做了个贪吃蛇,后来觉得不过瘾,于是又加入了AI功能.希望大家Enjoy It. 效果图示 AI模式演示 imageimage 整 ...
- pygame试水,写一个贪吃蛇
最近学完python基础知识,就想着做一个游戏玩玩,于是就在https://www.pygame.org/docs/学着做了个贪吃蛇游戏. 首先要导入模块. import pygame import ...
- 用Python写一个贪吃蛇
最近在学Python,想做点什么来练练手,命令行的贪吃蛇一般是C的练手项目,但是一时之间找不到别的,就先做个贪吃蛇来练练简单的语法. 由于Python监听键盘很麻烦,没有C语言的kbhit(),所以这 ...
- 用js写一个贪吃蛇小游戏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Java 用java GUI写一个贪吃蛇小游戏
目录 主要用到 swing 包下的一些类 上代码 游戏启动类 游戏数据类 游戏面板类 代码地址 主要用到 swing 包下的一些类 JFrame 窗口类 JPanel 面板类 KeyListener ...
- python 写一个贪吃蛇游戏
#!usr/bin/python #-*- coding:utf-8 -*- import random import curses s = curses.initscr() curses.curs_ ...
随机推荐
- freemarker 中可以直接使用的内置对象
freemarker 中可以直接使用的内置对象 需要配置一下:springboot中配置 ## Freemarker \u914D\u7F6E ## \u6587\u4EF6\u914D\u7F6E\ ...
- JQ-总结
-----------------------------------------------------------------------------jQuery----------------- ...
- Ubuntu系统中各种文件颜色的含义
蓝 色:文件夹 ,ls -l或ll时可以看到权限部分的第1个字母是d红色:压缩文件 绿色:可执行文件,包括jar白色:文本文件红色闪烁:错误的符号链接淡蓝色:符号链接黄色:设备文件灰色:其它文件 ...
- 12.4 hdfs总结
启动hdfs 需要在namenode 节点 上 s11 启动yarn 需要在resourceManager 节点上 namenode, resourceManager 都需要在整个集群中都是可以无密登 ...
- BZOJ 3224 - 普通平衡树 - [Treap][Splay]
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中 ...
- [No0000131]WCF压缩传输方案整理
1.WCF进阶:将编码后的字节流压缩传输 2.通过WCF扩展实现消息压缩 3.WCF 消息压缩性能问题及解决方法
- 深入理解无穷级数和的定义(the sum of the series)
Given an infinite sequence (a1, a2, a3, ...), a series is informally the form of adding all those te ...
- [network] netfilter
netfilter 是什么? netfilter.org is home to the software of the packet filtering framework inside the Li ...
- python fabric实现远程操作和部署示例
https://www.jb51.net/article/48434.htm 近期接手越来越多的东西,发布和运维的工作相当机械,加上频率还蛮高,导致时间浪费还是优点多.修复bug什么的,测试,提交版本 ...
- DbGridEh 一个单元格的值改变时另一单元格的值随之改变
你可以为每个字段设置OnSetText事件,这样在输入完后回车会移动时就会触发,或者在adoquery的beforepost中或afterpost中都可以grid也提供了一些事件,也可以在某些条件下做 ...