javascript经典小游戏
JavaScript编写连连看小游戏
天天看到别人玩连连看, 表示没有认真玩过, 不就把两个一样的图片连接在一起么, 我自己写一个都可以呢。
使用Javascript写了一个, 托管到github, 在线DEMO地址查看:http://sqqihao.github.io/games/link/index.html
最终的效果图:
写连连看之前要先考虑哪些呢?
1:如何判断两个元素可以连接呢, 刚刚开始的时候我也纳闷, 可以参考这里:打开;
2:模板引擎怎么选择呢, 我用了底线库的template,因为语法简单。 本来想用Handlebars,但是这个有点大啊, 而且底线库也提供很多常用工具方法( •̀ ω •́ )y;
3:布局如何布局呢, 用table, td加上边框, 边框内部一个div,div就是连连看的棋子, 界面更清爽, 简单, 其实直接用canvas写也行, 没认真研究过canvas;
4:两个元素连接时连线的效果我们要怎么实现呢,如果用dom实现那么需要用到图片,元素连接时候把图片定位到连接的路径。 或者用canvas, 直接用canvas把连接的效果画出来, 我选择后者;
因为我不考虑低浏览器, 使用了zeptoJS库, 基于习惯,把bootstrap也引用了;
使用了三个主要构造函数, 包括Data, View, Score;
View的结构如下, 东西比较少 包括事件绑定, 界面生成, 以及当两个相同元素消失时的 绘图效果:
View
* @desc 根据数据生成map
* */
renderHTML : function
/**
* @desc 界面的主要事件绑定
* @return this;
* */
bindEvents : function
/**
* @desc 工具方法,在canvas上面进行绘图;
* @param [{x:0,y:0},{x:1,y:1},{x:2,y:2},{x:3,y:3}]一个数组, 会自动重绘;
* */
showSparkLine : function
<script type="text/template" id="tr-td-tpl">
<% for(var i=0; i<data.length; i++) {%>
<tr>
<% for(var j=0; j< data[i].length; j++ ) { %>
<td id="<%=i%><%=j%>" class="bg<%=data[i][j]%>" data-x="<%=j%>" data-y="<%=i%>" data-data="<%=data[i][j]%>" data-info='{"x":<%=[j]%>,"y":<%=[i]%>}'>
<div>
<%=getImg(data[i][j])%>
</div>
</td>
<% } %>
</tr>
<% } %>
</script>
window.getImg = function( num ) {
switch(num){
case 1:
return "<img src='imgs/ani (1).gif' />";
case 2:
return "<img src='imgs/ani (2).gif' />";
case 3:
return "<img src='imgs/ani (3).gif' />";
case 4:
return "<img src='imgs/ani (4).gif' />";
case 5:
return "<img src='imgs/ani (5).gif' />";
case 6:
return "<img src='imgs/ani (6).gif' />";
}
};
Score = function(el) {
this.el = $(el);
this.score = 0;
};
$.extend( Score.prototype , {
/**
* @desc 改变元素的HTML,递增分数;
* @param
* */
addScore : function() {
this.el.html(++this.score);
}
});
构造函数Data, 主要的结构如下 , 虽然方法比较少, 实际上Data这块代码占了300行.... 要判断元素是否可以连接用canConnect方法,canConnect方法又会调用dirConnect方法, 计算比较繁琐, 想了解的话最好自己写写:
//新建初始化
newData : function
//工具方法,随机混肴数组;
suffer : function
/**
* @desc set值,把地图中对应的数据清空或者设置,两用接口
* @param x, y
* @return chain
* */
set : function
/**
* @desc 判断两个元素之间是否可以连接
* @param [{x:1,y:1},{x:1,y:1}]
* @return false || []
* */
canConnect : function
/**
* @desc 判断元素是否可以直连
* @param [{x:1,y:1},{x:1,y:1}]
* @return false || true
* */
dirConnect
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.4/css/bootstrap.min.css">
<title>link</title>
<script src="js/zepto.js"></script>
<script src="js/underscore1.8.js"></script>
<style>
table{
border-collapse: collapse;
}
td{
border:1px solid #f5f5f5;
text-align: center;
line-height: 40px;
cursor: pointer;
}
td.active{
opacity: 0.7;
}
td div{
width:40px;
height:40px;
}
.bg1{
/*background: #2ECC71;*/
}
.bg2{
/*background: #E67E22;*/
}
.bg3{
/*background: #34495E;*/
}
.bg4{
/*background: #1ABC9C;*/
}
.relative{
position: relative;
}
.absolute{
position: absolute;
left:0;
top:0;
}
</style>
</head>
<body>
<div class="container ">
<div class="row" style="width:80%;margin:0 auto;">
<h3>得分<span class="label label-default" id="score">0</span></h3>
</div>
</div>
<div class="container">
<div class="row relative">
<table class="absolute">
<thead></thead>
<tbody id="tbody">
</tbody>
</table>
<canvas id="canvas">
<p>Your browserdoes not support the canvas element.</p>
</canvas>
</div>
</div>
<script type="text/template" id="tr-td-tpl">
<% for(var i=0; i<data.length; i++) {%>
<tr>
<% for(var j=0; j< data[i].length; j++ ) { %>
<td id="<%=i%><%=j%>" class="bg<%=data[i][j]%>" data-x="<%=j%>" data-y="<%=i%>" data-data="<%=data[i][j]%>" data-info='{"x":<%=[j]%>,"y":<%=[i]%>}'>
<div>
<%=getImg(data[i][j])%>
</div>
</td>
<% } %>
</tr>
<% } %>
</script>
<script>
var el = document.getElementById("tbody");
var elCan = document.getElementById("canvas");
var tpl = document.getElementById("tr-td-tpl");
var cfg = {
width : 8,
height : 8
};
window.getImg = function( num ) {
switch(num){
case 1:
return "<img src='imgs/ani (1).gif' />";
case 2:
return "<img src='imgs/ani (2).gif' />";
case 3:
return "<img src='imgs/ani (3).gif' />";
case 4:
return "<img src='imgs/ani (4).gif' />";
case 5:
return "<img src='imgs/ani (5).gif' />";
case 6:
return "<img src='imgs/ani (6).gif' />";
}
};
var View = function(data, score) {
this.data = data;
this.score = score;
},
Data = function(cfg) {
this.cfg = {
width : cfg.width+2,
height : cfg.height+2
};
this.getRandom = this.getRandom();
},
Score = function(el) {
this.el = $(el);
this.score = 0;
};
$.extend( Data.prototype, {
/**
* @desc 把两个
* @param HTMLELEMENT
* @return true || false
* */
clear : function(obj, target) {
},
/**
* @desc 根据this.cfg新建数据到this.map
* @param void
* @return void
* */
newData : function() {
var result = [];
for(var i=0; i<=this.cfg.height+1; i++ ) {
result[i] = result[i] || [];
for(var j = 0; j<= this.cfg.width+1; j++) {
if(i === 0 || j===0 || (i===this.cfg.height+1) || j === (this.cfg.width+1) ) {
result[i][j] = 0;
}else{
//1-4
result[i][j] = this.getRandom();
}
};
};
this.map = result;
return this;
},
//随机混肴数组;
suffer : function(obj) {
function random(min, max) {
if (max == null) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min + 1));
};
var set = obj;
var length = set.length;
var shuffled = Array(length);
for (var index = 0, rand; index < length; index++) {
rand = random(0, index);
if (rand !== index) shuffled[index] = shuffled[rand];
shuffled[rand] = set[index];
}
return shuffled;
},
/**
* @return 返回值必须是成双的, 消除到最后尼玛,发现有一堆不匹配的,玩个球;
* */
getRandom : function() {
//如果消消乐是3*3, 那么你告诉我....最后一个和谁消, 所以要做的就是把所有的元素生成变成一半,然后返回;
var arr = new Array( (this.cfg.height) * (this.cfg.width) / 2 );
var result = [];
for(var i=0; i<arr.length; i++ ) {
arr[i] = (Math.floor( Math.random()*6 ) + 1);
};
result = Array.prototype.concat.call( [] , arr, arr);
result = this.suffer( result );
return function( ) {
return result.pop();
};
},
/**
* @desc set值
* @param x, y
* @return chain
* */
set : function( x, y) {
this.map[y][x] = 0;
return this;
},
/**
* @desc 判断元素是否可以连接
* @param [{x:1,y:1},{x:1,y:1}]
* @return false || true
* */
canConnect : function(obj,target) {
var map = this.map;
//循环obj的y轴相等 , obj.x旁边所有数据为0的元素;;
var getX = function( obj ) {
var result = [];
//循环找出在X附近为0的元素;
for(var i=obj.x+1; i< map[0].length; i++) {
if( map[obj.y][i] == 0 ) {
result.push( {x:i, y:obj.y} );
}else{
break;
};
};
for(var i=obj.x-1; i>=0; i--) {
if( map[obj.y][i] == 0 ) {
result.push( {x:i,y:obj.y} );
}else{
break;
};
};
return result;
};
//循环obj的x轴相等, obj.y旁边所有数据为0的元素;
var getY = function(obj) {
var result = [];
for(var i=obj.y+1; i<map.length; i++) {
if( map[i][obj.x] == 0) {
result.push( { x : obj.x ,y : i} );
}else{
break;
};
};
for(var i=obj.y-1; i>=0; i--) {
if( map[i][obj.x] == 0 ) {
result.push( { x : obj.x ,y : i} );
}else{
break;
};
};
return result;
};
var arr0 = Array.prototype.concat.call( [], getX(obj), obj, getY(obj)).filter(function(obj) {
return !!obj;
});
var arr1 = Array.prototype.concat.call( [], getX(target), target, getY(target) ).filter(function(obj) {
return !!obj;
});
for(i = 0; i<arr0.length; i++) {
for(var j = 0; j<arr1.length; j++) {
//只要有一个连接就返回true;
if( this.dirConnect(arr0[i],arr1[j]) ) {
return [obj, arr0[i], arr1[j], target];
};
};
};
return false;
},
/**
* @desc 判断元素是否可以直接连接
* @param [{x:1,y:1},{x:1,y:1}]
* @return false || true
* */
dirConnect : function(obj, target) {
var map = this.map;
//row是x轴 列
//col是y轴 行
var min = 0, max = 0, sum = 0;
if(obj.y === target.y) {
if(obj.x < target.x) {
min = obj.x;
max = target.x;
}else{
min = target.x;
max = obj.x;
};
for(var i=min; i<=max; i++) {
sum += map[obj.y][i];
};
if(sum === (map[obj.y][obj.x] + map[target.y][target.x])) {
return true;
}else{
return false;
};
};
if(obj.x === target.x) {
if(obj.y < target.y) {
min = obj.y;
max = target.y;
}else{
min = target.x;
max = obj.y;
};
for( i=min; i<=max; i++) {
sum += map[i][obj.x];
};
if( sum === (map[obj.y][obj.x] + map[target.y][target.x])) {
return true;
}else{
return false;
};
};
}
});
$.extend( View.prototype, {
/**
* @desc 为view添加视图的主元素
* @return void
* */
setEL : function(el) {
this.el = el;
return this;
},
setTpl : function(tpl) {
this.tpl = _.template( tpl.innerHTML );
return this;
},
/**
* @desc 根据数据生成map
* */
renderHTML : function() {
$(this.el).html( this.tpl( {data : this.data.map} ) );
return this;
},
/**
* @desc 界面的主要事件绑定
* @return this;
* */
bindEvents : function() {
$(this.el).delegate("td", "click", this.click.bind(this));
return this;
},
/**
* @desc click事件, 单独抽出来的;
* */
click : function(ev) {
//修改样式;
$("td.active").removeClass("active");
var target = $(ev.target).closest("td");
target.addClass("active");
//第一次点击我们做的特殊处理;
var prev = this.prev;
if( !prev || target[0] === prev[0]){
this.prev = target;
return;
};
if( prev.attr("data-data") === target.attr("data-data")) {
var xy = JSON.parse( prev.attr("data-info") );
var xxyy = JSON.parse( target.attr("data-info") );
//保存了连接的数组信息
var connectionInfo = [] || false;
if( connectionInfo = this.data.canConnect( xy, xxyy) ) {
this.showSparkLine( connectionInfo );
this.prev = undefined;
this.data.set(xy.x, xy.y);
this.data.set(xxyy.x, xxyy.y);
this.score.addScore();
var _this = this;
setTimeout(function() {
_this.renderHTML();
},2000);
};
prev.attr("data-data", "");
target.attr("data-data","")
}else{
this.prev = target;
};
},
/**
* @desc 工具方法,在canvas上面进行绘图;
* @param [{x:0,y:0},{x:1,y:1},{x:2,y:2},{x:3,y:3}]一个数组, 会自动重绘;
* */
showSparkLine : function( arr ) {
arr = arr.map(function(xy) {
return {
x : (xy.x)*40 + 20,
y : (xy.y)*40 + 20
}
});
var elCan = document.getElementById("canvas");
function spark(ctx) {
function showAndClear(arr, lineWidth) {
ctx.clearRect(0,0,elCan.width,elCan.height);
ctx.beginPath();
ctx.lineJoin = "round";
ctx.lineWidth = lineWidth;
ctx.shadowColor = "rgba(241, 196, 15, 0.41)";
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
ctx.shadowBlur = 1;
for(var i=0; i<arr.length-1; i++) {
var xy = arr[i];
var nextXY = arr[i+1]
ctx.moveTo(xy.x, xy.y);
ctx.lineTo(nextXY.x, nextXY.y);
};
ctx.stroke();
};
var ctx = elCan.getContext("2d");
ctx.strokeStyle = "#F1C40F";
var lineWidthArr = [1,2,1,2,1,3,1,0];
var len = lineWidthArr.length;
var times = 400, addTimes = 200;
while(len--) {
(function(len){
setTimeout(function() {
showAndClear(arr, lineWidthArr[len]);
if(len==0) {
ctx.clearRect(0,0,elCan.width,elCan.height);
}
}, times);
times += addTimes;
})(len)
};
};
spark( elCan );
}
});
$.extend( Score.prototype , {
/**
* @desc 改变元素的HTML,递增分数;
* @param
* */
addScore : function() {
this.el.html(++this.score);
}
});
$(function() {
var score = new Score( document.getElementById("score") );
var data = new Data(cfg).newData();
var view = new View(data, score);
view.setEL( el ).setTpl( tpl).renderHTML().bindEvents();
(function init() {
//如果通过style属性添加width或者height,会根据原来的宽和高度自动伸缩的
elCan.width = el.offsetWidth;
elCan.height = el.offsetHeight;
})();
});
</script>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title> 连连看 </title>
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<style type="text/css">
#board{width:508px; height:500px; margin: 30px auto 0px; overflow: hidden; position: relative; background-color: #999999;}
#board span{display: block; position: absolute; width: 30px; height: 30px; }
</style>
</head>
<body>
<div id="board" >
</div>
</body>
<!-- js -->
<script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" >
$(function(){
var cont=$("#board");
var colors=["#ff0000","#00ff00","#0000ff","#ffcc33","#000000","#00ffcc","#ffffff"];
var pos=[];
var click=0;
var firstSpan;
var fx;
var fy;
var arr=[];
arr=[0,0,0,0,0,0,0,0];
pos.push(arr);
for(var i=0;i<8;i++){
new creSpan(i,cont,0,i*40,colors[6],0);
}
for(var i=1;i<=6;i++){
m=new creSpan(i,cont,i*40,0,"#ffffff");
arr=[0];
for(var j=0;j<6;j++){
var color=Math.floor(Math.random()*6);
new creSpan(i,cont,i*40,(j+1)*40,colors[color],(color+1));
arr.push(1);
}
m=new creSpan(i,cont,i*40,(j+1)*40,"#ffffff",0);
arr.push(0);
pos.push(arr);
}
for(var i=0;i<8;i++){
m=new creSpan(i,cont,7*40,i*40,"#ffffff",0);
}
arr=[0,0,0,0,0,0,0,0];
pos.push(arr);
function clear(c1,c2,x,y){
if(c1!=null)c1.style.background="#ffffff";
if(c2!=null){
c2.style.background="#ffffff";
pos[x-1][y-1]=0;
pos[fx-1][fy-1]=0;
}
fx=0;
fy=0;
click=0;
}
$.each($("#board span"),function(index,mSpan){
$(this).click(function(){
var x=Math.floor(index/8);
var y=Math.floor(index%8);
if(click==0){
click=1;
firstSpan=mSpan;
fx=x;
fy=y;
return;
}
if(firstSpan.id!=mSpan.id||(x==fx&&fy==y)){
clear(null,null,0,0);
return;
}
var col=6;
var row=6;
for(var i=0;i<row+2;i++){
var step=i-x>0?1:-1;
var count=0;
for(var j=x;j!=i;j+=step){
count+=pos[j][y];
}
step=y>fy?-1:1;
for(j=y;j!=fy;j+=step){
count+=pos[i][j];
}
step=i>fx?-1:1;
for(j=i;j!=fx;j+=step){
count+=pos[j][fy];
}
if(count==1){
clear(firstSpan,mSpan,x,y);
return;
}
}
for(i=0;i<col+2;i++){
step=i-y>0?1:-1;
count=0;
for(j=y;j!=i;j+=step){
count+=pos[x][j];
}
step=x>fx?-1:1;
for(j=x;j!=fx;j+=step){
count+=pos[i][j];
}
step=i<fy?1:-1;
for(j=i;j!=fy;j+=step){
count+=pos[fx][j];
}
if(count==1){
clear(firstSpan,mSpan,x,y);
return;
}
}
clear(null,null,0,0);
});
});
});
function creSpan(n,cont,mtop,mleft,mcolor,idstr){
var mSpan=document.createElement("span");
cont[0].appendChild(mSpan);
mSpan.id=idstr;
with(mSpan.style){
top=mtop+"px";
left=mleft+"px";
background=mcolor;
}
};
</script>
</html>
贪吃蛇游戏
1、JS函数的熟练掌握,
2、JS数组的应用,
3、JS小部分AJAX的学习
4、JS中的splice、shift等一些函数的应用,
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>贪吃蛇</title>
<link rel="stylesheet" type="text/css" href="./css.css">
<script type="text/javascript" src="./jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="./js.js"></script>
</head>
<body>
<div id="info">
<div id="score">0</div>
<form action="" id="form" name="form">
<input type="radio" name='time' value="500" checked='checked'/>简单
<input type="radio" name='time' value="300"/>中等
<input type="radio" name='time' value="150"/>高级
<input type="radio" name='time' value="50"/>神速
<input type="button" value="开始" class="button" id="start"/>
<input type="button" value="重玩" class="button" id="res"/>
</form>
</div>
<div id="main">
<div id="home">
<!--<div style="background:url(./images/snake0.png) no-repeat;"></div>
<div style="background:url(./images/snake1.png) no-repeat; left:20px;"></div>
<div style="background:url(./images/snake2.png) no-repeat; left:40px;"></div>
<div style="background:url(./images/snake3.png) no-repeat; left:60px;"></div>-->
</div>
<div class="wall left"></div>
<div class="wall right"></div>
<div class="wall top"></div>
<div class="wall bottom"></div>
</div>
</body>
</html>
这里是css代码:
*{padding: 0px; margin: 0px;font-size: 12px}
body{background: #ccc}
input.button{
width: 60px;
cursor: pointer;
}
#info{
width: 540px;
height: 30px;
margin: 30px auto 5px;
line-height: 30px;
}
#score{
width: 73px;
height: 28px;
padding-left: 64px;
background: url(./images/score.png) no-repeat;
float: left;
font-size: 14px;
font-weight: 700;
font-style:italic;
font-family: '微软雅黑';
}
#form{
float: right;
}
#form input{
vertical-align: middle;
margin-right: 5px;
}
#main{
width: 540px;
height: 500px;
margin: 0 auto;
position: relative;
/*background: #71a000*/
}
#main div{
width: 20px;
height: 20px;
position: absolute;
}
#main #home{
width: 500px;
height: 460px;
left: 20px;
top: 20px;
position: relative;
background: url(./images/background.jpg) no-repeat;
}
#main #home div{
position: absolute;
}
#main div.wall{
width: 540px;
height: 20px;
background: url("./images/div.jpg") repeat-x;
position: absolute;
}
#main div.top{
left:0px;
top:0px;
}
#main div.bottom{
left:0px;
top:480px;
}
#main div.left{
width: 20px;
height: 500px;
background: url(./images/div.jpg) repeat-y;
left:0px;
top:0px;
}
#main div.right{
width: 20px;
height: 500px;
background: url(./images/div.jpg) repeat-y;
left:520px;
top:0px;
}
.l{
-moz-transform:rotate(0deg);
-o-transform:rotate(0deg);
-webkit-transform:rotate(0deg);
transform:rotate(0deg);
/* IE8+ - must be on one line, unfortunately */
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=0, M21=0, M22=1, SizingMethod='auto expand')";
/* IE6 and 7 */
filter: progid:DXImageTransform.Microsoft.Matrix( M11=1, M12=0, M21=0, M22=1, SizingMethod='auto expand');
}
.t{
-moz-transform: rotate(90deg); -o-transform: rotate(90deg); -webkit-transform: rotate(90deg); transform: rotate(90deg);
/* IE8+ - must be on one line, unfortunately */ -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=-1.8369701987210297e-16, M12=-1, M21=1, M22=-1.8369701987210297e-16, SizingMethod='auto expand')"; /* IE6 and 7 */ filter: progid:DXImageTransform.Microsoft.Matrix( M11=-1.8369701987210297e-16, M12=-1, M21=1, M22=-1.8369701987210297e-16, SizingMethod='auto expand');
}
.r{
-moz-transform: rotate(180deg); -o-transform: rotate(180deg); -webkit-transform: rotate(180deg); transform: rotate(180deg);
/* IE8+ - must be on one line, unfortunately */ -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=-1, M12=1.2246467991473532e-16, M21=-1.2246467991473532e-16, M22=-1, SizingMethod='auto expand')"; /* IE6 and 7 */ filter: progid:DXImageTransform.Microsoft.Matrix( M11=-1, M12=1.2246467991473532e-16, M21=-1.2246467991473532e-16, M22=-1, SizingMethod='auto expand');
}
.b{
-moz-transform: rotate(270deg); -o-transform: rotate(270deg); -webkit-transform: rotate(270deg); transform: rotate(270deg);
/* IE8+ - must be on one line, unfortunately */ -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=6.123233995736766e-17, M12=1, M21=-1, M22=6.123233995736766e-17, SizingMethod='auto expand')"; /* IE6 and 7 */ filter: progid:DXImageTransform.Microsoft.Matrix( M11=6.123233995736766e-17, M12=1, M21=-1, M22=6.123233995736766e-17, SizingMethod='auto expand');
}
var home = $('#home');
var snakeArr = [];
var direcation = 'l';
var speed = 0;
var timer = '';
//460/20
var rows = 23;
var cols = 25;
var die = false; //用于判断是否game over
var food = [];
var sorce = 0; //得分的显示
for( var i=0; i<4; i++ ){
//var snakeDiv = document.createElement("div");
//snakeDiv.style = 'background:url(./images/snake' + i + '.png) no-repeat;';
var snakeDiv = $('<div style="background:url(./images/snake' + i + '.png) no-repeat;z-index:999"></div>');
home.append(snakeDiv);
snakeArr[i] = {r : 10, c : 10 + i, div : snakeDiv, d : direcation};
setPosition(snakeArr[i]);
}
有snake之后,自然就是移动了(move):
function move(){
var timer = setInterval(function(){
for( var i=snakeArr.length -1; i>0; i-- ){
snakeArr[i].c = snakeArr[i-1].c;
snakeArr[i].r = snakeArr[i-1].r;
snakeArr[i].d = snakeArr[i-1].d;
}
switch(direcation){
case 'l' :
snakeArr[0].c--;
snakeArr[0].d = 'l';
break;
case 'r' :
snakeArr[0].c++;
snakeArr[0].d = 'r';
break;
case 't' :
snakeArr[0].r--;
snakeArr[0].d = 't';
break;
case 'b' :
snakeArr[0].r++;
snakeArr[0].d = 'b';
break;
}
//snake的方向控制
$(window).keydown(function(event){
switch(event.keyCode){
case 37 :
direcation = 'l';
break;
case 38 :
direcation = 't';
break;
case 39 :
direcation = 'r';
break;
case 40 :
direcation = 'b';
break;
}
});
//snake事故
//1. snake撞墙
if( snakeArr[0].c < 0 || snakeArr[0].r < 0 || snakeArr[0].c >= cols || snakeArr[0].r >= rows ){
clearInterval(timer);
die = true;
alert('GAME OVER');
}
//2. snake撞到自己
for( var i=1; i<snakeArr.length; i++ ){
if( snakeArr[0].c == snakeArr[i].c && snakeArr[0].r == snakeArr[i].r ){
clearInterval(timer);
die = true;
alert('GAME OVER');
}
}
//snake吃水果
if( snakeArr[0].c == food[0].c && snakeArr[0].r == food[0].r ){
food[0].div.css({background : 'url(./images/snake2.png) no-repeat'});
snakeArr.splice(snakeArr.length - 1, 0, food[0]);
food.shift();
sorce += 10;
$('#score').html(sorce);
}
//snake产生水果
if( food.length == 0 ){
createFood();
}
for(var i = 0; i < snakeArr.length; i++){
setPosition(snakeArr[i]);
}
},speed);
}
食物的产生:
function createFood(){
var r = parseInt(rows * Math.random());
var c = parseInt(cols * Math.random());
var casrsh = false;
//2个水果出现的位置不能一样
while( food.length == 0 ){
//判断snake的位置,不能与snake相撞
for( var i = 0; i < snakeArr.length; i++ ){
if( r == snakeArr[i].r && c == snakeArr[i].c ){
casrsh = true;
}
}
//当位置不重叠的时候,产生水果
if( !casrsh ){
var i = parseInt(4 * Math.random());
var foodDiv = $('<div style="background:url(./images/fruit'+ i +'.png);"></div>');
home.append(foodDiv);
food.push({r : r, c : c, div : foodDiv});
setPosition(food[0]);
}
}
}
还有一个重要的功能就是重新设置定位:
function setPosition(obj){
obj.div.css({left : obj.c * 20, top : obj.r * 20});
obj.div.removeClass().addClass(obj.d);
}
createFood(); //那页面一被加载出来就显示出食物!
js+html5实现可在手机上玩的拼图游戏
var R=(function(){
/*右边菜单*/
function fa(){
if(mo.style.right!='0px'){
mo.style.right='0px';
mco.rcss('','cmck');
}else{
mo.style.right='-100px';
mco.rcss('cmck','');
}
}
on(mco,fa);
//设置全局常量
var to=doc.querySelector('.pzuo'),tmid,r_r;
function fb(el,i){
on(el,function(){
if(i==3){
location.reload();
}else if(i==0){
if(_gj.length > 0){
localStorage['ptgj']=_gj.join(',');
ui.success('保存成功!');
}else{
ui.error('没有轨迹可保存!');
}
}else if(i==2){
if(_zz){
to.style.top='-50px';
this.innerHTML='制作拼图';
_zz=false;
if(_zp > 0){
fc6(false);
}
}else if(_dl){
to.style.top='0px';
this.innerHTML='取消';
_zz=true;
if(_zp > 0){
fc6(true);
}
}else{
location.href='/login.php?cback='+location.href;
}
}else if(i==1){
sio.style.display='block';
fa();
clearTimeout(tmid);
tmid=setTimeout(function(){
sio.style.display='none';
},2500);
}else if(i==4){
if(_dl){
location.href='top.php?my=1';
}else{
location.href='/login.php?cback=http://m.yxsss.com/apps/pt.php';
}
}else if(i==5){
location.href='/';
}else if(i==6){
location.href='top.php';
}
});
}
var lis=doc.querySelectorAll('.menu li');
for(var i=0;i<lis.length;i++){
fb(lis[i],i);
}
var upico=A.$('upic'),imgo=new Image(),upe=0,rsrc='',rl=3,rh=3,rsx=[],rem=null;
function fc(el,i){
on(el,function(){
if(mo.style.right=='0px'){
fa();
}
if(_zp < i){
ui.error(['请选择图片!','','','请打乱板块的顺序'][_zp]);
return ;
}
if(el.className.indexOf('dp')==-1){
return ;
}
var farr=[
function(){
var tm=new Date().getTime();
if(tm - upe < 3000){
ui.error('若不能选择图片,请用浏览器打开本页面。',3000);
}
upe=tm;
},
function(){
fc3(true);
},
function(){
var i=rand(0,_l*_h -1);
fc5.call(po.children[i],i);
},
function(){
_zp=4;
fc1();
fc7();
},
function(){
fcv();
}
];
farr[i]();
});
}
function fcv(){
A.aj('../do.php','type=pts&hshu='+rh+'&lshu='+rl+'&sxu='+rsx,function(da){
if(da.ztai){
ui.success('拼图制作成功,马上邀请好友来挑战吧!',3600);
setTimeout(function(){
location.href='index.php?id='+da.id;
},5000);
}
},'json');
}
var rfc7=true;
function fc7(){
for(var i=0;i<50;i++){
yds(rand(37,40));
}
if(rfc7){
pts();
}
}
function fc1(){
for(var i=0;i<=_zp;i++){
zps[i].rcss('','dp');
}
if(_zp > 3){
for(var i=0;i<3;i++){
zps[i].rcss('dp','');
}
upico.style.display='none';
}
}
var zps=doc.querySelectorAll('.pzuo li');
for(var i=0;i<zps.length;i++){
fc(zps[i],i);
}
function fc2(da){
if(_zp==0){
rsrc=da;
_zp=1;
fc1();
fc3(true);
}else{
_img=rsrc=da;
pts();
fc5.call(po.children[_k]);
}
}
var f3o=doc.querySelector('.pwh'),f3o1=doc.querySelector('.pwh1 a');
on(f3o1,function(){
fc3(false);
})
function fc3(z){
if(z){
f3o.style.display='block';
setTimeout(function(){
f3o.style.opacity=1;
},30);
}else{
var h=doc.querySelector('.pwhh').value,l=doc.querySelector('.pwhl').value;
if(h < 3 || h > 10){
ui.error('行数只能在 3 - 10 之间');
return false;
}
if(l < 3 || l > 10){
ui.error('列数只能在 3 - 10 之间');
return false;
}
rl=parseInt(l);
rh=parseInt(h);
f3o.style.opacity=0;
setTimeout(function(){
f3o.style.display='none';
},300);
fc4();
}
}
function fc4(){
for(var i=0;i<rl*rh;i++){
rsx.push(i);
}
fc6(true);
_zp=3;
fc1();
fc5.call(po.children[0],0);
}
//交换数据
function fc6(w){
if(w){
r_r=[_l,_h,_img,_k,_sx1];
_sx1=rsx;
_img=rsrc;
_l=rl;
_h=rh;
_k=_rk;
}else{
_sx1=r_r[4];
_img=r_r[2];
_l=r_r[0];
_h=r_r[1];
_k=r_r[3];
}
pts();
}
function fc5(i){
if(rem){
rem.style.display='block';
}
_sx1[_rk]=_rk;
_rk=i;
_k=_rk;
_sx1[_k]=false;
this.style.display='none';
rem=this;
}
//上传图片
upico.onchange=function(){
var f=this.files[0];
if(!f){
return false;
}
var ext=f.name.match(/\.(png|jpg|gif)$/i);
if(f.type.match('image.*') || ext){
var r = new FileReader();
r.onload = function(){
var ida=this.result;
if(f.type==''){
ida=ida.replace('data:','data:image/'+ext[1].replace('jpg','jpeg')+';');
}
imgo.setAttribute('src',ida);
};
r.readAsDataURL(f);
}else{
ui.error('请选择正确的图片格式(png、jpg、gif)');
}
}
imgo.onload=function(){
var rc = A.$$('canvas');
var ct = rc.getContext('2d');
var w=300;
rc.width=w;
rc.height=w;
ct.drawImage(imgo,0,0,w,w);
A.aj('../do.php','type=ptpic&pda='+encodeURIComponent(rc.toDataURL('png')),function(da){
if(da.ztai){
fc2(da.src);
}else{
ui.error(da.msg);
}
},'json');
}
return {'fc5':fc5};
})();
(function(win,doc){
var ao = doc.querySelector('.pwap'),
po = doc.querySelector('.pbd'),
mo = doc.querySelector('.menu'),
mco = doc.querySelector('.menu .cm'),
sio = doc.querySelector('.pimg'),
sbdo = doc.querySelector('.sbd');
var _t='ontouchstart' in doc,_h=0,_l=0,_k=0,_sx1=[],_sx2=[],_img='',_wh=0,_gj=[],_zp=0,_rk=0,_zz=false,_dl=DL;
//屏幕大小或者旋转 改变拼图大小
function ini(){
var w=Math.min(win.innerWidth,h=win.innerHeight);
sbdo.style.width=win.innerWidth+'px';
sbdo.style.height=win.innerHeight+'px';
_wh=w*0.9;
ao.style.width=ao.style.height=_wh+'px';
ao.style.marginTop=(win.innerHeight - w*0.9)*0.5+'px';
if(_h && _l){
pts();
}
}
win.addEventListener('norientationchange' in win ? 'orientationchange' : 'resize' , ini, false);
ini();
function on(el,fun){
if(_t){
A.on(el,'touchstart',fun);
}else{
A.on(el,'click',fun);
}
}
function rand(n,m){
return Math.round(Math.random()*(m-n)+n);
}
//阻止默认动作
win.addEventListener('touchmove', function(e){
e.preventDefault();
},false);
function pts(){
po.innerHTML='';
_sx2=[];
var h=1/_h*100,w=1/_l*100;
_sx1.forEach(function(v,i){
if(_zz && _zp < 4){v=i};
if(v!==false){
var ls=i%_l,ts=Math.floor(i/_l);
ls=ls>0?ls*100/_l:0;
ts=ts>0?ts*100/_h:0;
var li=v%_l,ti=Math.floor(v/_l);
li=li>0?li*_wh/_l:0;
ti=ti>0?ti*_wh/_h:0;
var p=A.$$('<p style="width:' + w + '%; height:' + h + '%; left:' + ls + '%; top:' + ts + '%;"><img src="'+_img+'" width="'+_wh+'" style="left:-' + li + 'px; top:-' + ti + 'px;"></p>');
p.k=i;
yd(p);
_sx2.push(p);
po.appendChild(p);
}else{
_k=i;
_sx2.push(false);
}
});
if(_zz && _zp < 4){
R.fc5.call(po.children[_rk],_rk);
}
}
function yd(t){
if(_zz && _zp < 4){
on(t,yd2);
}else{
on(t,yd1);
}
}
function yd1(){
var k=this.k;
if(_k-k==1 && k%_l <_l -1){
yds(39);
}else if(_k-k==-1 && k%_l > 0){
yds(37);
}else if(_k-k==_l){
yds(40);
}else if(k-_k==_l){
yds(38);
}
if(!_zz){
ydd();
}
}
function ydd(){
var c=true;
_sx1.forEach(function(i,v){
if(v!==false && i!=v){
c=false;
}
});
if(c){
ui.confirm('您经过'+_gj.length+'步,挑战成功!<br>提交成绩到排行榜?',function(rt){
if(rt){
rtsu();
}
});
}
}
function rtsu(){
A.aj('../do.php','type=ptrt&ct='+_gj.join(',')+'&cts='+_gj.length+'&pid='+_pid,function(da){
if(da.ztai){
ui.success('保存成功!');
setTimeout(function(){
location.href='top.php?id='+_pid;
},3000);
}else{
location.href='/login.php?cback='+location.href+'#1';
}
},'json');
}
(function(){
var mp=location.href.match(/#1/);
if(mp){
A.aj('../do.php','type=ptrto',function(da){
if(da.ztai){
ui.success('保存成功!');
setTimeout(function(){
location.href='top.php?id='+_pid;
},3000);
}
},'json');
}
})();
function yd2(){
R.fc5.call(this,this.k);
}
function yds(n){
if(n==37){
if(_k%_l < _l - 1){
_sx2[_k + 1].style.left=_k%_l*100/_l+'%';
chge(_k + 1);
_gj.push(n);
}
}else if(n==38){
if(_k < (_h-1)*_l){
var nk=parseInt(_k) + parseInt(_l);
_sx2[nk].style.top=Math.floor(_k/_l)*100/_h+'%';
chge(nk);
_gj.push(n);
}
}else if(n==39){
if(_k%_l > 0){
_sx2[_k - 1].style.left=_k%_l*100/_l+'%';
chge(_k - 1);
_gj.push(n);
}
}else if(n==40){
if(_k >= _l){
_sx2[_k - _l].style.top=Math.floor(_k/_l)*100/_h+'%';
chge(_k - _l);
_gj.push(n);
}
}
}
function chge(k){
_sx1[_k]=_sx1[k];
_sx1[k]=false;
_sx2[_k]=_sx2[k];
_sx2[k]=false;
_sx2[_k].k=_k;
_k=k;
}
var _pid=1;
function lda(){
var g=location.href.match(/id=(\d+)/) || [1,1];
_pid=g[1];
A.aj('../do.php?id='+g[1],'type=getpt',function(da){
_sx1=eval('['+da.sxu+']');
_img=da.src;
_h=da.hshu;
_l=da.lshu;
_k=_h*_l-1;
sio.innerHTML='<img src="'+_img+'">';
pts();
},'json')
}
lda();
})(window,document);
javascript 打字游戏实现代码
GAME = {
//随机产生字母
randLetter: function() {
var arrLetter = new Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
"X",
"Y", "Z");
//随机产生字母
var index = Math.floor(Math.random() * 26);
return arrLetter[index];
},
//随机字母颜色
randLetterColor: function() {
var arrLetterColor = new Array("Red", "Green", "#555", "Blue", "Black");
var index = Math.floor(Math.random() * 4);
return arrLetterColor[index];
},
//随机字母大小
randLetterSize: function() {
var arrLetterSize = new Array("12px", "16px", "20px", "24px", "28px", "32px", "36px", "40px");
var index = Math.floor(Math.random() * 7);
return arrLetterSize[index];
},
//创建DIV
divCreate: function(width, height, left, top, value) {
this.width = width;
this.height = height;
this.div = document.createElement("div");
this.div.style.width = width;
this.div.style.height = height;
this.div.style.left = left;
this.div.style.top = top;
this.div.innerText = value;
this.div.style.color = this.randLetterColor();
this.div.style.fontSize = this.randLetterSize();
this.div.style.lineHeight = this.div.style.height;
this.div.style.textAlign = "center";
this.div.style.fontWeight = "bold";
//this.div.style.border = "solid red 1px";
this.div.style.position = "relative";
document.getElementById("map").appendChild(this.div);
return this.div;
},
//DIV下落
divDown: function() {
var divTop = parseInt(this.div.style.top.slice(0, -2)); //字母方块的Top
var mapHeight = parseInt(document.getElementById("map").style.height.slice(0, -2));
//就消失
if (divTop < mapHeight - parseInt(this.height) + 20) {
this.div.style.top = divTop + 30;
//获取按键的值
document.onkeydown = function() {
//按键的字母是不是 等于 div的值
if (String.fromCharCode(event.keyCode) == GAME.div.innerText) {
document.getElementById("TextRecord").value = "正确";
GAME.div.style.display = "none";
clearInterval(GAME.timeCreateID);
GAME.divCreate(100, 100, Math.floor(Math.random() * 300), -30, GAME.randLetter());
}
else {
document.getElementById("TextRecord").value = "错误";
}
}
}
//到达底线就消失,之后再创建DIV
else {
this.div.style.display = "none";
GAME.divCreate(100, 100, Math.floor(Math.random() * 300), -30, this.randLetter());
}
},
timeCreateID: null,
timeDownID: null,
START: function() {
this.divCreate(100, 100, 200, -40, this.randLetter());
this.timeDownID = setInterval("GAME.divDown();", 1000);
document.getElementById('ButtonStart').disabled = 'disabled';
document.getElementById('ButtonStop').disabled = '';
},
STOP: function() {
if (this.timeDownID != null) {
clearInterval(this.timeDownID);
this.div.style.display = "none";
}
document.getElementById('ButtonStart').disabled = '';
document.getElementById('ButtonStop').disabled = 'disabled';
}
}
Javascript编写俄罗斯方块
完整实例代码如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>俄罗斯方块</title>
<style type="text/css">
.c{margin:1px; width:19px; height:19px; background:red; position:absolute;}
.d{margin:1px; width:19px; height:19px; background:gray; position:absolute;}
.f{top:0px; left:0px; background:black; position:absolute;}
.e{top:0px; background:#151515; position:absolute;}
.g{width:100px; height:20px; color:white; position:absolute;}
</style>
<script type="text/javascript">
var row = 18;
var col = 10;
var announcement = 6;
var size = 20;
var isOver = false;
var shapes = ("0,1,1,1,2,1,3,1;1,0,1,1,1,2,2,2;2,0,2,1,2,2,1,2;0,1,1,1,1,2,2,2;1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";");
var tetris;
var container;
function createElm(tag,css)
{
var elm = document.createElement(tag);
elm.className = css;
document.body.appendChild(elm);
return elm;
}
function Tetris(css,x,y,shape)
{
// 创建4个div用来组合出各种方块
var myCss = css?css:"c";
this.divs = [createElm("div",myCss),createElm("div",myCss),createElm("div",myCss),createElm("div",myCss)];
if(!shape)
{
this.divs2 = [createElm("div",myCss),createElm("div",myCss),createElm("div",myCss),createElm("div",myCss)];
this.score = createElm("div","g");
this.score.style.top = 10*size+"px";
this.score.style.left = (col- -1)*size+"px";
this.score.innerHTML = "score:0";
}
this.container = null;
this.refresh = function()
{
this.x = (typeof(x)!='undefined')?x:3;
this.y = (typeof(y)!='undefined')?y:0;
// 如果有传参,优先使用参数的,如果有预告,优先使用预告,都没有就自己生成
if(shape)
this.shape = shape;
else if(this.shape2)
this.shape = this.shape2;
else
this.shape = shape?shape:shapes[Math.floor((Math.random()*shapes.length-0.000000001))].split(",");
this.shape2 = shapes[Math.floor((Math.random()*shapes.length-0.000000001))].split(",");
if(this.container && !this.container.check(this.x,this.y,this.shape))
{
isOver = true;
alert("游戏结束");
}
else
{
this.show();
this.showScore();
this.showAnnouncement();
}
}
// 显示方块
this.show = function()
{
for(var i in this.divs)
{
this.divs[i].style.top = (this.shape[i*2+1]- -this.y)*size+"px";
this.divs[i].style.left = (this.shape[i*2]- -this.x)*size+"px";
}
}
// 显示预告
this.showAnnouncement = function()
{
for(var i in this.divs2)
{
this.divs2[i].style.top = (this.shape2[i*2+1]- -1)*size+"px";
this.divs2[i].style.left = (this.shape2[i*2]- -1- -col)*size+"px";
}
}
// 显示分数
this.showScore = function()
{
if(this.container && this.score)
{
this.score.innerHTML = "score:" + this.container.score;
}
}
// 水平移动方块的位置
this.hMove = function(step)
{
if(this.container.check(this.x- -step,this.y,this.shape))
{
this.x += step;
this.show();
}
}
// 垂直移动方块位置
this.vMove = function(step)
{
if(this.container.check(this.x,this.y- -step,this.shape))
{
this.y += step;
this.show();
}
else
{
this.container.fixShape(this.x,this.y,this.shape);
this.container.findFull();
this.refresh();
}
}
// 旋转方块
this.rotate = function()
{
var newShape = [this.shape[1],3-this.shape[0],this.shape[3],3-this.shape[2],this.shape[5],3-this.shape[4],this.shape[7],3-this.shape[6]];
if(this.container.check(this.x,this.y,newShape))
{
this.shape = newShape;
this.show();
}
}
this.refresh();
}
function Container()
{
this.init = function()
{
// 绘制方块所在区域
var bgDiv = createElm("div","f");
bgDiv.style.width = size*col+"px";
bgDiv.style.height = size*row+"px";
// 绘制预告所在区域
var bgDiv = createElm("div","e");
bgDiv.style.left = size*col+"px";
bgDiv.style.width = size*announcement+"px";
bgDiv.style.height = size*row+"px";
// 清空积分
this.score = 0;
}
this.check = function(x,y,shape)
{
// 检查边界越界
var flag = false;
var leftmost=col;
var rightmost=0;
var undermost=0;
for(var i=0;i<8;i+=2)
{
// 记录最左边水平坐标
if(shape[i]<leftmost)
leftmost = shape[i];
// 记录最右边水平坐标
if(shape[i]>rightmost)
rightmost = shape[i];
// 记录最下边垂直坐标
if(shape[i+1]>undermost)
undermost = shape[i+1];
// 判断是否碰撞
if(this[(shape[i+1]- -y)*100- -(shape[i]- -x)])
flag = true;
}
// 判断是否到达极限高度
for(var m=0;m<3;m++)
for(var n=0;n<col;n++)
if(this[m*100+n])
flag = true;
if((rightmost- -x+1)>col || (leftmost- -x)<0 || (undermost- -y+1)>row || flag)
return false;
return true;
}
// 用灰色方块替换红色方块,并在容器中记录灰色方块的位置
this.fixShape = function(x,y,shape)
{
var t = new Tetris("d",x,y,shape);
for(var i=0;i<8;i+=2)
this[(shape[i+1]- -y)*100- -(shape[i]- -x)] = t.divs[i/2];
}
// 遍历整个容器,判断是否可以消除
this.findFull = function()
{
var s = 0;
for(var m=0;m<row;m++)
{
var count = 0;
for(var n=0;n<col;n++)
if(this[m*100+n])
count++;
if(count==col)
{
s++;
this.removeLine(m);
}
}
this.score -= -this.calScore(s);
}
this.calScore = function(s)
{
if(s!=0)
return s- -this.calScore(s-1)
else
return 0;
}
// 消除指定一行方块
this.removeLine = function(row)
{
// 移除一行方块
for(var n=0;n<col;n++)
document.body.removeChild(this[row*100+n]);
// 把所消除行上面所有的方块下移一行
for(var i=row;i>0;i--)
{
for(var j=0;j<col;j++)
{
this[i*100- -j] = this[(i-1)*100- -j]
if(this[i*100- -j])
this[i*100- -j].style.top = i*size + "px";
}
}
}
}
function init()
{
container = new Container();
container.init();
tetris = new Tetris();
tetris.container = container;
document.onkeydown = function(e)
{
if(isOver) return;
var e = window.event?window.event:e;
switch(e.keyCode)
{
case 38: //up
tetris.rotate();
break;
case 40: //down
tetris.vMove(1);
break;
case 37: //left
tetris.hMove(-1);
break;
case 39: //right
tetris.hMove(1);
break;
}
}
setInterval("if(!isOver) tetris.vMove(1)",500);
}
</script>
</head>
<body onload="init()">
</body>
</html>