用 React 编写2048游戏
1.代码
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>万能的React</title>
<style>
.app{
margin:10px;
font-family: arial;
}
.board{
display:block;
position:relative;
margin:10px 0px 10px 0px;
border:1px solid #ccc;
width:215px;
height:215px;
padding:5px;
}
.board span{
font-family: arial;
letter-spacing: -1px;
display:block;
width:50px;
height:36px;
position:absolute;
text-align:center;
color:white;
font-weight:bold;
font-size:20px;
padding-top:14px;
background-color:#ebe76f;
border-radius: 5px;
transition: all 100ms linear;
}
.a1, .b1, .c1, .d1{ left:5px; }
.a2, .b2, .c2, .d2{ left:60px; }
.a3, .b3, .c3, .d3{ left:115px; }
.a4, .b4, .c4, .d4{ left:170px; }
.a1, .a2, .a3, .a4{ top:5px; }
.b1, .b2, .b3, .b4{ top:60px; }
.c1, .c2, .c3, .c4{ top:115px; }
.d1, .d2, .d3, .d4{ top:170px; }
span.value2{ background-color:#ebb26f; }
span.value4{ background-color:#ea6feb; }
span.value8{ background-color:#eb6fa3; }
span.value16{ background-color:#7a6feb; }
span.value32{ background-color:#af6feb; }
span.value64{ background-color:#6febcf; }
span.value128{ background-color:#6fbeeb; }
span.value256{ background-color:#afeb6f; }
span.value512{ background-color:#7aeb6f; }
span.value1024{ background-color:#e4eb6f; }
</style>
</head>
<body>
<script src="./react-0.13.2/react-0.13.2/build/react.js"></script>
<script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script>
<script type="text/jsx">
var initial_board = {
a1:null,a2:null,a3:null,a4:null,
b1:null,b2:null,b3:null,b4:null,
c1:null,c2:null,c3:null,c4:null,
d1:null,d2:null,d3:null,d4:null
}; function available_spaces(board){
return Object.keys(board).filter(function(key){
return board[key] == null
});
} function used_spaces(board){
return Object.keys(board).filter(function(key){
return board[key] !== null
});
} function score_board(board){
return used_spaces(board).map(function(key){
return (board[key].values.reduce(function(a, b) {
return a + b; //sum tile values
})) - board[key].values[0]; //don't count initial value
}).reduce(function(a,b){return a+b}, 0);
} function tile_value(tile){
return tile ? tile.values[tile.values.length-1] : null;
} function can_move(board){
var new_board = [up,down,left,right].reduce(function(b, direction){
return fold_board(b, direction);
}, board);
return available_spaces(new_board).length > 0
} function same_board(board1, board2){
return Object.keys(board1).reduce(function(ret, key){
return ret && board1[key] == board2[key];
}, true);
} function fold_line(board, line){
var tiles = line.map(function(key){
return board[key];
}).filter(function(tile){
return tile !== null
});
var new_tiles = [];
if(tiles){
//must loop so we can skip next if matched
for(var i=0; i < tiles.length; i++){
var tile = tiles[i];
if(tile){
var val = tile_value(tile);
var next_tile = tiles[i+1];
if(next_tile && val == tile_value(next_tile)){
//skip next tile;
i++;
new_tiles.push({
id: next_tile.id, //keep id
values: tile.values.concat([val * 2])
});
}
else{
new_tiles.push(tile);
}
}
}
}
var new_line = {};
line.forEach(function(key, i){
new_line[key] = new_tiles[i] || null;
});
return new_line;
} function fold_order(xs, ys, reverse_keys){
return xs.map(function(x){
return ys.map(function(y){
var key = [x,y];
if(reverse_keys){
return key.reverse().join("");
}
return key.join("");
});
});
} function fold_board(board, lines){
//copy reference
var new_board = board;
lines.forEach(function(line){
var new_line = fold_line(board, line);
Object.keys(new_line).forEach(function(key){
//mutate reference while building up board
new_board = set_tile(new_board, key, new_line[key]);
});
});
return new_board;
} var tile_counter = 0;
function new_tile(initial){
return {
id: tile_counter++,
values: [initial]
};
} function set_tile(board, where, tile){
//do not destory the old board
var new_board = {};
Object.keys(board).forEach(function(key, i){
//copy by reference for structual sharing
new_board[key] = (key == where) ? tile : board[key];
});
return new_board;
} var left = fold_order(["a","b","c","d"], ["1","2","3","4"], false);
var right = fold_order(["a","b","c","d"], ["4","3","2","1"], false);
var up = fold_order(["1","2","3","4"], ["a","b","c","d"], true);
var down = fold_order( ["1","2","3","4"], ["d","c","b","a"], true); var GameBoard = React.createClass({
getInitialState: function(){
return this.addTile(this.addTile(initial_board));
},
keyHandler:function(e){
var directions = {
37: left,
38: up,
39: right,
40: down
};
if(directions[e.keyCode]
&& this.setBoard(fold_board(this.state, directions[e.keyCode]))
&& Math.floor(Math.random() * 30, 0) > 0){
setTimeout(function(){
this.setBoard(this.addTile(this.state));
}.bind(this), 100);
}
},
setBoard:function(new_board){
if(!same_board(this.state, new_board)){
this.setState(new_board);
return true;
}
return false;
},
addTile:function(board){
var location = available_spaces(board).sort(function() {
return .5 - Math.random();
}).pop();
if(location){
var two_or_four = Math.floor(Math.random() * 2, 0) ? 2 : 4;
return set_tile(board, location, new_tile(two_or_four));
}
return board;
},
newGame:function(){
this.setState(this.getInitialState());
},
componentDidMount:function(){
window.addEventListener("keydown", this.keyHandler, false);
},
render:function(){
var status = !can_move(this.state)?" - Game Over!":"";
return <div className="app">
<span className="score">
Score: {score_board(this.state)}{status}
</span>
<Tiles board={this.state}/>
<button onClick={this.newGame}>New Game</button>
</div>
}
}); var Tiles = React.createClass({
render: function(){
var board = this.props.board;
//sort board keys first to stop re-ordering of DOM elements
var tiles = used_spaces(board).sort(function(a, b) {
return board[a].id - board[b].id;
});
return <div className="board">{
tiles.map(function(key){
var tile = board[key];
var val = tile_value(tile);
return <span key={tile.id} className={key + " value" + val}>
{val}
</span>;
})}</div>
}
}); React.render(<GameBoard />, document.body);
</script>
</body>
</html>
2.结果
用 React 编写2048游戏的更多相关文章
- powershell字符界面的,powershell加WPF界面的,2048游戏
------[序言]------ 1 2048游戏,有段时间很火,我在地铁上看有人玩过.没错,坐地铁很无聊,人家玩我就一直盯着看. 2 我在电脑上找了一个,试玩了以下,没几次格子就满了.我就气呼呼的放 ...
- Android项目开发实战-2048游戏
<2048>是一款比较流行的数字游戏,最早于2014年3月20日发行.原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台.这款游戏是基于&l ...
- 对弈类游戏的人工智能(5)--2048游戏AI的解读
前言: 闲得没事, 网上搜"游戏AI", 看到一篇<<2048游戏的最佳算法是?来看看AI版作者的回答>>的文章. 而这篇文章刚好和之前讲的对弈类游戏AI对 ...
- cocos2d-x游戏开发实战原创视频讲座系列1之2048游戏开发
cocos2d-x游戏开发实战原创视频讲座系列1之2048游戏开发 的产生 视持续更新中.... 视频存放地址例如以下:http://ipd.pps.tv/user/1058663622 ...
- C++学习(三十九)(C语言部分)之 游戏项目(2048游戏)
/***************************项目 2048**********************c语言编写 图形库制作时间:2019.04.03 准备工具: vs2013 图形库 i ...
- 用javascript制作2048游戏的思路(原创若 转载请附上本链接)
一.项目已上传至github,地址:https://github.com/forjuan/2048game 二.学习了javascript基础后,想要捣鼓点东西做,做了一个自己以前很爱玩的2048游戏 ...
- [swift实战入门]手把手教你编写2048(一)
苹果设备越来越普及,拿着个手机就想捣鼓点啥,于是乎就有了这个系列,会一步一步教大家学习swift编程,学会自己做一个自己的app,github地址:https://github.com/scarlet ...
- Cocos2d-html5入门之2048游戏
一.介绍 Cocos2d-JS是Cocos2d-x的Javascript版本,它的前身是Cocos2d-html5.在3.0版本以前叫做Cocos2d-html5,从3.0版本开始叫做Cocos2d- ...
- 用javascript实现一个2048游戏
早就想自己写一个2048游戏了,昨晚闲着没事,终于写了一个 如下图,按方向键开始玩吧. 如果觉得操作不方便,请直接打开链接玩吧: http://gujianbo.1kapp.com/2048/2048 ...
随机推荐
- HTML5的页面资源预加载技术(Link prefetch)加速页面加载
不管是浏览器的开发者还是普通web应用的开发者,他们都在做一个共同的努力:让Web浏览有更快的速度感觉.有很多已知的技术都可以让你的网站速度变得更快:使用CSS sprites,使用图片优化工具,使用 ...
- SQL中char,varchar,nvarchar等的异同
比较这几个数据类型,总是忘记,可能比较细节的原因.先做个记号,回头完善.
- #include< > 和 #include” ” 的区别
一.#include< > #include< > 引用的是编译器的类库路径里面的头文件. 假如你编译器定义的自带头文件引用在 C:\Keil\c51\INC\ 下面,则 #i ...
- C#——中文转化成拼音
在KS系统中用到了中文转化成拼音的功能.通过查阅资料为下面是代码. /// <summary> /// MyConvert 的摘要说明 /// </summary> publi ...
- Oracle中的日期
--1.日期字符转换函数的用法 /****************************TO_CHAR********************************/ -------------- ...
- 关于使用视图进行分页时出现当前记录集不支持书签的错误解决方法及原因(asp)
一般在使用视图进行查询时,视图中意般都关联了两个或者更多个表,一般在这种情况下才会使用视图,但是但我在使用视图来查询数据时没有问题,但是一旦在分页中使用到视图进行查询就会出现错误提示如下: ADODB ...
- kendo ui template的用法
kendo ui template的用法: Kendo UI 框架提供了一个易用,高性能的JavaScript模板引擎.通过模板可以创建一个HTML片段然后可以和JavaScript数据合并成最终的H ...
- Java并发编程:Lock(上)
在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方 ...
- Java中List和ArrayList的区别
List:是一个有序的集合,可以包含重复的元素.提供了按索引访问的方式.它继承 Collection.List有两个重要的实现类:ArrayList 和 LinkedListArrayList:我们可 ...
- SpringMVC+redis整合
在网络上有一个很多人转载的springmvc+redis整合的案例,不过一直不完整,也是被各种人装来转去,现在基本将该框架搭建起来. package com.pudp.bae.base; import ...