纯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;
				width: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;
				width: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>

如需转载,请注明作者及出处。

时间: 2024-08-26 01:12:31

纯JS写的2048游戏,分享之的相关文章

原生js写一个2048游戏

本例逻辑1,一个二维数组,记录数字方块的数值与对应dom对象 2, 一个一维数组,记录空白方块的坐标(行与列)3,左移,最左边一列不做移动测试,从左边倒数第二列开始依次向左边做移动测试,若可合并,则向左移,数字不变或乘2.其他方向同逻辑 4, 判断输赢,若某个方块的值达到2048,即赢,游戏可以继续.当空白坐标数组的长度为0是,依次检测每个方块在四个方向可否移动,若都不能,即游戏结束. → → → → 预览 ← ← ← ← js代码: /*game 2048*/ //事件处理对象 var Eve

280行代码:Javascript 写的2048游戏

2048 原作者就是用Js写的,一直想尝试,但久久未动手. 昨天教学生学习JS代码.不妨就做个有趣的游戏好了.2048这么火,是一个不错的选择. 思路: 1. 数组 ,2维数组4x4 2. 移动算法,移动后有数字的对齐,无数字(我用的0,但不显示)补齐. 移动前 移动后(注意程序合并了第一行2个2,并产生了新的2) 移动算法分2步: 第一步骤:移动 第二步骤:合并 移动代码参考: [html] view plaincopy function left(t,i) { var j; var len 

js写的2048

闲着无聊,用js写个简单的2048玩儿...引用了jquery,需要改下地址 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html><head><title>2048</title> <script src="jquery-1.8

分享一下自己写的2048游戏(3*3,4*4,5*5,6*6多种玩法,可反悔)

2048是一款非常常见的小游戏,所以我也想自己尝试着写一款,给自己练练手.说道练手,这里需要交代一下:我从事Android的工作刚刚一年,平时的工作主要是客制化UI和修改Bug,也就是这里改改,那里改改,因此,完整的开发项目的机会比较少,所以,对我而言,想要提高自己的编程水平,抽出时间自己做一些小项目是有意义的.虽然平时的工作主要是客制化UI和修改bug,但并不意味这我的工作是简单枯燥的,我时常会遇到系统中的一些bug,这样我有机会阅读android系统的源码,并从中分析问题出现的原因,这份工作

纯js制作的弹球游戏

纯js的弹球游戏,撞壁自动返回,按钮放置暂停移动,移开开始移动 1 <!-- 2 author:zhangjie 3 date :2016-7-23 4 --> 5 <!DOCTYPE html> 6 <html> 7 <head> 8 <title></title> 9 <meta charset="UTF-8"> 10 <script type='text/javascript'> 11

使用纯js写的一个分页

上图晒效果: 网上确实有很多分页的插件以及开源代码,单本是一个后台开发猿,前台css等样式还驾驭不住,所以就开始自己去写了.其实这个分页原理很简单,就是用ajax往后台传值(当前页码),后台使用limit进行分页. 因为这是我自己第一次动手用js写分页,写的应该也不是很完美,有些公共的没有抽取出来,但是用起来还是可以的,这块代码是可以把它当做公共的分页去处理的,我就是用 这块代码写了两个稍微不同一些的分页!公共的代码抽取的也差不多,主要就是ajax后台以及返回的值不同而已,只要把总页码的值获取到

13行js写贪吃蛇游戏

先上源码,版本是ES6 13行常规(700bytes) shortest snake game.html 压缩后的500bytes(当然两处document还是可以用eval压缩的) index.500bytes.html 之前很火的20行代码地址(有BUG)(900bytes) hj7jay/article/details/51011269 一维数组700char (0,0)位置的蛇身用0表示,(0,1)用1,(1,0)用10表示,以此类推 因为就13行js, 第4行 是声明 第5行 比较难理

JS 写的俄罗斯方块游戏

http://www.htmleaf.com/html5/html5youxi/201501201236.html https://github.com/Aerolab/blockrain.js/blob/gh-pages/src/blockrain.jquery.src.js <!doctype html> <html lang="zh"> <meta charset="UTF-8"> <link rel="st

纯js写的分页表格数据为json串

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getSchem