zoukankan      html  css  js  c++  java
  • 纯JS写的2048游戏,分享之

    这几天玩儿着2048这个游戏,突然心血来潮想练习下敲代码的思路。于是乎就模仿做了一个,到眼下位置还没有实现动态移动,不是非常好看,只是玩儿着自己模仿的小游戏还是蛮爽的,哈哈


    假设没有玩儿过这个游戏,最好先试玩儿下,这样看起下边的代码来easy些

    用的是event。临时不支持firefox下玩儿。。。

    试玩儿>>


    里边好多步骤写得不够简单介绍明了。欢迎指正

    两个小时构思,主要构思用什么形式存表格,以及当中用到的几个比較关键的方法,比方:是否须要移动,是否须要合并,移动方法。合并方法等,然后開始编程的时候会遇到非常多问题,慢慢解决之


    <html>
    	<head>
    		<title>2048</title>
    		<meta http-equiv='content-type' content='text/html;charset=gb2312' />
    		<style type="text/css">
    			body,div,ul,li,p{padding:0;margin:0;border-radius:10px;}
    			body{
    				font-family:"Microsoft YaHei",微软雅黑,Arial,Simsun,sans-serif;
    				background:#FFFCEC;
    			}
    			.game_box{
    				margin:20px auto;
    				400px;
    			}
    			.info{
    				height:60px;
    				color:#333;
    				font-size:32px;
    			}
    			.main_box{
    				border:2px solid #8E8E8E;
    				background-color:#8E8E8E;
    				height:396px;
    				color:#333;
    				font-size:36px;
    				font-weight:700;
    				text-align:center;
    				line-height:100px;
    			}
    			.main_box li{
    				float:left;
    				background:#d0d0d0;
    				border:4px solid #8E8E8E;
    				height:91px;
    				91px;
    			}
    			.rule{
    				color:#333;
    				font-size:16px;
    			}
    		</style>
    	</head>
    	<body onload="init();" onkeyup="run();">
    		<div class="game_box">
    			<div class="info">
    				<p style="float:right;">得分:<span id="score">0</span></p>
    				最大值:<span id="max_value">0</span>
    			</div>
    			<ul class="main_box">
    				<li id="11"></li>
    				<li id="12"></li>
    				<li id="13"></li>
    				<li id="14"></li>
    				<li id="21"></li>
    				<li id="22"></li>
    				<li id="23"></li>
    				<li id="24"></li>
    				<li id="31"></li>
    				<li id="32"></li>
    				<li id="33"></li>
    				<li id="34"></li>
    				<li id="41"></li>
    				<li id="42"></li>
    				<li id="43"></li>
    				<li id="44"></li>
    			</ul>
    			<div style="clear:both;"></div>
    			<p class="rule">玩法:</p>
    			<p class="rule">1.用键盘上下左右键控制数字走向</p>
    			<p class="rule">2.当点击了一个方向时,格子中的数字会所有往那个方向移动。直到不能再移动,假设有同样的数字则会合并</p>
    			<p class="rule">3.当格子中不再有可移动和可合并的数字时,游戏结束</p>
    		</div>
    	</body>
    	<script type="text/javascript">
    		var table = {
    			11:0,12:0,13:0,14:0,
    			21:0,22:0,23:0,24:0,
    			31:0,32:0,33:0,34:0,
    			41:0,42:0,43:0,44:0
    		};//整个表格
    		var cur_queue = null;//因为移动时是一行或一列移动的,此变量代表须要处理的当前行和列
    		var direction = 0;//当前操作移动的方向
    		var max_value = 0;//最大值
    		var score = 0;//最高分数
    		
    		function is_num_exist() {//推断当前处理行(列)是否有数字。有则进行处理。无则不用处理
    			return table[cur_queue[1]]||table[cur_queue[2]]||table[cur_queue[3]]||table[cur_queue[4]];
    		}
    
    		function need_move() {//当前行(列)是否须要移动(不包含合并)
    			if(Boolean(table[cur_queue[4]])>=Boolean(table[cur_queue[3]])&&Boolean(table[cur_queue[3]])>=Boolean(table[cur_queue[2]])&&Boolean(table[cur_queue[2]])>=Boolean(table[cur_queue[1]])) {
    				return false;
    			}else {
    				return true;
    			}
    		}
    		
    		function need_merge() {//当前行(列)是否须要合并
    			if((table[cur_queue[4]]==table[cur_queue[3]])&&table[cur_queue[4]]&&table[cur_queue[3]]||(table[cur_queue[3]]==table[cur_queue[2]])&&table[cur_queue[3]]&&table[cur_queue[2]]||(table[cur_queue[2]]==table[cur_queue[1]])&&table[cur_queue[2]]&&table[cur_queue[1]]) {
    				return true;
    			}else {
    				return false;
    			}
    		}
    		
    		function move() {//对当前行(列)的数字进行移动
    			for(var i=4;i>=2;i--) {
    				if(Boolean(table[cur_queue[i]]<Boolean(table[cur_queue[i-1]]))) {
    					table[cur_queue[i]] = table[cur_queue[i-1]];
    					table[cur_queue[i-1]] = 0;
    					break;
    				}
    			}
    		}
    
    		function merge() {//对当前行(列)的数字进行合并
    			for(var i=4;i>=2;i--) {
    				if(table[cur_queue[i]]==table[cur_queue[i-1]]) {
    					score=score+table[cur_queue[i]];
    					table[cur_queue[i]] = table[cur_queue[i]]+table[cur_queue[i-1]];
    					table[cur_queue[i-1]] = 0;
    					document.getElementById("score").innerHTML=score;//更新最高分
    					break;
    				}
    			}
    		}
    
    		function run() {//点击上下左右键时開始运行
    			var done = false;
    			if(event.keyCode>=37&&event.keyCode<=40) {//仅仅有
    				set_direction();//设置移动方向參数
    				for(var i=1;i<=4;i++) {//因为一个方向上移动时有4行(列)所以须要逐行处理
    					set_cur_queue(i);//设置当前行(列)
    					if(is_num_exist()) {
    						if(need_move()||need_merge()) {
    							done = true;//此变量用来限制每次仅仅合并一次
    						}
    						while(need_move()) {//假设能够移动则一直移动
    							move();
    						}
    						if(need_merge()) {//假设须要合并
    							if(table[cur_queue[1]]==table[cur_queue[2]]&&table[cur_queue[3]]==table[cur_queue[4]]) {//特例,当一行(列)上四个数字所有同样时候,进行两次合并
    								merge();
    								while(need_move()) {
    									move();
    								}
    								merge();
    							}else {
    								merge();
    								while(need_move()) {
    									move();
    								}
    							}
    						}
    					}
    				}
    				//var empty_box = find_empty_box();//获取当前空格子集合
    				//if(empty_box.length==0&&!need_merge()) {//假设没有没有空位且不能合并
    				//	alert('Game over');
    				//	return;
    				//}
    				if(done) {//假设此次有移动或合并,即有效操作,则生成新的数字
    					create_and_set_num();
    				}
    				update_max_value();//更新最大值
    				draw();//又一次绘制表格用于显示
    			}
    		}
    
    		function update_max_value() {
    			max_value = Math.max(table[11],table[12],table[13],table[14],table[21],table[22],table[23],table[24],table[31],table[32],table[33],table[34],table[41],table[42],table[43],table[44]);
    			document.getElementById("max_value").innerHTML=max_value;
    		}
    
    		function set_cur_queue(queue_num) {
    			if(direction == 37) {
    				cur_queue = {1:queue_num*10+4,2:queue_num*10+3,3:queue_num*10+2,4:queue_num*10+1};
    			}else if(direction == 38) {
    				cur_queue = {1:40+queue_num,2:30+queue_num,3:20+queue_num,4:10+queue_num};
    			}else if(direction == 39) {
    				cur_queue = {1:queue_num*10+1,2:queue_num*10+2,3:queue_num*10+3,4:queue_num*10+4};
    			}else if(direction == 40) {
    				cur_queue = {1:10+queue_num,2:20+queue_num,3:30+queue_num,4:40+queue_num};
    			}else {
    				cur_queue = {1:queue_num*10+1,2:queue_num*10+2,3:queue_num*10+3,4:queue_num*10+4};
    			}
    		}
    
    		function draw() {//总体刷新16个格子
    			for(var i=10;i<=40;i+=10) {
    				for(var j=1;j<=4;j++) {
    					if(table[i+j]!=0) {
    						document.getElementById(i+j).innerHTML=table[i+j];
    					}else {
    						document.getElementById(i+j).innerHTML='';
    					}
    				}
    			}
    		}
    
    		function set_direction() {//设置此次移动的方向
    			direction = event.keyCode;
    		}
    
    		function set_new_num(empty_box) {//生成新的数字
    			var num = 0;
    			var ranNum = Math.random()*100;
    			if(ranNum>80) {
    				num = 4;
    			}else {
    				num = 2;
    			}
    			var box_num = Math.floor(Math.random()*(empty_box.length));
    			table[empty_box[box_num]] = num;
    		}
    
    		function find_empty_box() {//获得所有的空格子。即值为0的格子集合
    			var empty_box = [];
    			for(var num in table) {
    				if(table[num]==0) {
    					empty_box.push(num);
    				}
    			}
    			return empty_box;
    		}
    
    		function init() {
    			create_and_set_num();
    			for(var i=1;i<=4;i++) {
    				set_cur_queue(i);
    				draw();
    			}
    			update_max_value();
    		}
    
    		function create_and_set_num() {
    			var empty_box;
    			empty_box = find_empty_box();
    			set_new_num(empty_box);
    		}
    	</script>
    </html>



    如需转载,请注明作者及出处。
  • 相关阅读:
    php 3des加密 兼容JAVA 多么痛的领悟呀
    主机序和网络序
    不用递归实现无限分类数据的树形格式化
    python学习笔记之open函数的用法
    据说是百度面试题(1)
    YII+DWZ三级城市联动挂件
    wpf 报错: 在 AddNew 或 EditItem 事务过程中不允许“DeferRefresh”。
    MVVM了解
    纪念2015年上半年
    c# 委托与事件
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7289697.html
Copyright © 2011-2022 走看看