示例:

全部代码如下:

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 写一个贪吃蛇的更多相关文章

  1. 使用Python写一个贪吃蛇

    参考代码http://blog.csdn.net/leepwang/article/details/7640880 我在程序中加入了分数显示,三种特殊食物,将贪吃蛇的游戏逻辑写到了SnakeGame的 ...

  2. 一步一步用Canvas写一个贪吃蛇

    之前在慕课网看了几集Canvas的视频,一直想着写点东西练练手.感觉贪吃蛇算是比较简单的了,当年大学的时候还写过C语言字符版的,没想到还是遇到了很多问题. 最终效果如下(图太大的话 时间太长 录制gi ...

  3. 如何用Python写一个贪吃蛇AI

    前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD, ...

  4. 【C/C++】10分钟教你用C++写一个贪吃蛇附带AI功能(附源代码详解和下载)

    C++编写贪吃蛇小游戏快速入门 刚学完C++.一时兴起,就花几天时间手动做了个贪吃蛇,后来觉得不过瘾,于是又加入了AI功能.希望大家Enjoy It. 效果图示 AI模式演示 imageimage 整 ...

  5. pygame试水,写一个贪吃蛇

    最近学完python基础知识,就想着做一个游戏玩玩,于是就在https://www.pygame.org/docs/学着做了个贪吃蛇游戏. 首先要导入模块. import pygame import ...

  6. 用Python写一个贪吃蛇

    最近在学Python,想做点什么来练练手,命令行的贪吃蛇一般是C的练手项目,但是一时之间找不到别的,就先做个贪吃蛇来练练简单的语法. 由于Python监听键盘很麻烦,没有C语言的kbhit(),所以这 ...

  7. 用js写一个贪吃蛇小游戏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Java 用java GUI写一个贪吃蛇小游戏

    目录 主要用到 swing 包下的一些类 上代码 游戏启动类 游戏数据类 游戏面板类 代码地址 主要用到 swing 包下的一些类 JFrame 窗口类 JPanel 面板类 KeyListener ...

  9. python 写一个贪吃蛇游戏

    #!usr/bin/python #-*- coding:utf-8 -*- import random import curses s = curses.initscr() curses.curs_ ...

随机推荐

  1. node.js 简单的获取命令参数

    class Argvs { constructor() { this.argvsAll = this.argvsAll(); } argvsAll() { return process.argv.sl ...

  2. STL 标准模板库

    <vector> 可变长的数组 Vector<int>v int是一个模板参数,这样传进来的都会是int V.push_back(a)将a传进v,且放在最后一个 V.clear ...

  3. TOP100summit2017:网易云通信与视频CTO赵加雨:外力推动下系统架构的4个变化趋势

      壹佰案例:很荣幸邀请到您成为第六届壹佰案例峰会架构专场的联席主席,您曾深度参与Cisco Jabber,Webex Meeting, Cisco Spark等多项分布式实时通信类产品的架构与研发, ...

  4. 自动化运维工具-pdsh工具安装配置及简单使用讲解

    1.先决条件: 安装pssh工具的主机针对远程主机需要配置免秘钥认证: ssh-keygen -t rsa ssh-copy-id [remotehost] 2.下载pssh工具安装介质: https ...

  5. iOS知识点持续更新。。。

    1.自动布局拉伸和压缩优先级 Autolayout中每个约束都有一个优先级,优先级的范围是1~1000.创建一个约束,默认的优先级最高是1000. Content Hugging Priority:该 ...

  6. nginx rate limit

    nginx rate limithttps://www.topjishu.com/12139.htmlhttps://blog.csdn.net/hellow__world/article/detai ...

  7. 转:Java 异常结构体系

    原文地址:Java 异常结构体系 保存一份资料 前几天在参加网易和360公司的在线考试的时候,都出了一道关于java中异常类的多项选择题.这几天翻看了相关书籍和网上一些资料,结合自己的理解与思考,将自 ...

  8. Struts2验证框架_xml验证失败

    测试Struts2验证框架-->XML验证   启动tomcat后网页登录失败 Employee-validation.xml文件头如下: <!DOCTYPE validators PUB ...

  9. 关于安装SVN Service 出错 Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details

    关于安装SVN Service 出错 Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in ...

  10. 【数据库】SQL语句解析

    学习网站: http://www.runoob.com/sql/sql-having.html 1. 1.现在我们想要查找总访问量大于 200 的网站. 回取出多条重复的网址的SQL语句: selec ...