用 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 ...
随机推荐
- CENTOS6.2系统日志rsyslog替换默认的日志服务syslog 转载自http://www.phpboy.net/linux/648.html
最近遇到配置centos 6.2的sshd及sftp日志,发现/etc/syslog.conf文件不存在, 然后: #rpm -qa | grep syslog 出来的是 rsyslog-5.8.10 ...
- JavaScript 垃圾回收机制分析
同C# .Java一样可以手工调用垃圾回收程序,但是由于其消耗大量资源,而且手工调用的不会比浏览器判断的准确,所以不推荐手工调用垃圾回收. 最近精力主要用在了Web 开发上,读了一下<Jav ...
- 修改Win7远程桌面端口
Win7与XP不同,在开启远程桌面修改端口后是无法直接访问的,原因是还未修改远程桌面在防火墙入站规则中的端口号. 修改远程桌面端口: [HKEY_LOCAL_MACHINE/SYSTEM/Curren ...
- iblog语法高亮示例
-------------------------------------------------------------------------------------- iblog 是一款 Sub ...
- cadence原理图绘制方法
仅记录了绘制好原理图后的一些处理: 1 重写编写元件编号 1)Tool -> Annotate 在Packing选项卡中 的Action 选中 Reset part references ...
- android studio安装插件
1.File-Settings菜单
- JNI-入门之一
下面我们开始编写HelloWorld程序,由于涉及到要编写c/c++代码因此我们会在开发中使用Microsoft VC++工具. 编写java代码我们在硬盘上建立一个hello目录作为我们的工作目录, ...
- iOS - 指定视图的圆角个数-b
平常设置视图的圆角最普遍的就是设置四个角的,方法也就是一句代码解决: view.layer.cornerRadius = 10; 四个圆角 但有时需求会是指定某个,或者特定哪几个角设置圆角,所以我们需 ...
- 如何解决Mac与iPhone之间handoff连接问题
首先账户以及设备handoff开关问题不再赘述.主要是昨天发现的一个小技巧 当确认所有设备的iCloud账号统一.蓝牙打开.处在同一WiFi下的前提下,我的iPhone和Mac仍然handoff连接有 ...
- jQuery+AJAX实现网页无刷新上传
新年礼,提供简单.易套用的 jQuery AJAX上传示例及代码下载.后台对文件的上传及检查,以 C#/.NET Handler 处理 (可视需要改写成 Java 或 PHP). 有时做一个网站项目 ...