示例:

全部代码如下:

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. nodejs XML和json互相转换

    Docs: https://www.npmjs.com/package/fast-xml-parser const xml = ` <user> <name>ajanuw< ...

  2. Ubuntu下搭建高匿HTTP代理(亲测可用)

    功能用途 我们在生活中见过各种代理,比如我们距离火车站较远,我们可以选择通过距离最近的火车票代售点来购买火车票.又比如商品代理商,我们拿不到厂家的直接或者,可以通过厂家授权的代理经销商来获得产品.代理 ...

  3. [c#基础]使用抽象工厂实现三层 和反射

    引言 昨天加了一天班,今天闲来无事,就在想如何将之前的三层和最近一直在学的设计模式给联系在一起,然后就动手弄了个下面的小demo. 项目结构 项目各个层实现 Wolfy.Model层中有一个抽象类Ba ...

  4. ThinkPHP框架 【 AJAX方法返回 】 例子:简单添加一条数据 和 查询一个表里的数据

    注:thinkphp使用ajax和之前使用ajax的方法一样,不同点在于之前的ajax中的url指向了一个页面,而thinkphp里面的url需要指向一个操作方法. 在模块控制器Controller文 ...

  5. javascript与java正则表达式写法的区别

    Js验证写法:(转义符\) var str = "待验证文本"; var regular = new RegExp(/这里是正则表达式/); if (regular.test(st ...

  6. python 过滤掉字符串中的回车符与换行符(\t\n)

    我们在文本数据预处理前,要将数据统一整理成需要的格式,其中有回车(\t)或者(\n)符号,会对我们的数据保存有影响,那么就需要将其过滤掉. 比较简单的方法,用replace()将这些符号替换为空,一定 ...

  7. hive优化之并行执行任务

    1.与Oracle并行技术一样,hive在执行mapreduce作业时也可以执行并行查询.针对于不同业务场景SQL语句的执行情况,有些场景下SQL的执行是需要分割成几段去执行的,而且期间并不全是存在依 ...

  8. Python:导入自定义模块

    在C语言里为了工程文件的主程序main代码简洁的效果,我们经常用include“XXX”的来导入其.h文件 在Python里Import自己的自定义模块需要注意几个坑 以main主函数和需要导入的ha ...

  9. 创建ReactNative的iOS项目

    http://reactnative.cn/docs/integration-with-existing-apps/ 1.安装好ReactNative开发环境 2.安装好CocoaPods 3.创建项 ...

  10. Etcd+Confd实现Nginx配置文件自动管理

    一.需求 我们使用Nginx做七层负载均衡,后端是Tomcat.项目采用灰度发布方式,每次项目升级,都要手动先从Nginx下摘掉一组,然后再升级这组,当项目快速迭代时,手动做这些操作显然会增加部署时间 ...