之前写的小游戏,要么就比较简单,要么就是比较难看,或者人物本身是不会动的。
结合了其它人的经验,研究了一下精灵运动,就写一个简单的小游戏来试一下。

介绍一下几个主要的类

  • Frame:帧的定义,主要描述动画的一帧
  • Animation:动画的定义,主要描述一个连贯的动画,由多个帧组成
  • Sprite:精灵的定义,主要描述一个完整的实体,由多个动画组成
  • TimeProcess:时间管理,由requestAnimationFrame完成
  • Person:一个完整人定义,就是主人公--男人
  • BlockBase:块的基类,下降中的障碍物基类,包含一些基本的参数与方法
  • NormalBlock:普通块,继承于BlockBase,最基础的块
  • MissBlock,LeftBlock...等:其它特殊功能的块
  • BlockFactory:块工厂,生产块的类
  • Main:游戏主入口

游戏的文件结构

  1. wfn.js:基础文件,包含动画定义,公共方法(都是比较简单的)
  2. person.js:人物的定义
  3. block.js:各种障碍物块的定义
  4. main.js:游戏主逻辑入口文件,处理主要逻辑

游戏的文件结构

TimeProcess:主要用于统一处理定时器的事件,确保全局只有一个计时器

 //定义贞管理类,兼容
var requestAnimationFrame = window.requestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame
|| function(cb){setTimeout(cb,1000/60)}; var TimeProcess = function(){ this.list = [];
this.isStart = false;
}
TimeProcess.prototype = { add : function(cb,param,context){ this.list.push({cb:cb,param:param,context:context});
},
start : function(){ this.isStart = true; var self = this; requestAnimationFrame(function(){ var item = null,
p = []; for(var i=0;i<self.list.length;i++){ item = self.list[i]; item.cb.apply(item.context,item.param);
} if(self.isStart)requestAnimationFrame(arguments.callee);
});
},
stop : function(){ this.isStart = false;
}
}

Frame:帧的定义,就类似flash中的帧

 //帧的定义
/**
@param x int 帧在雪碧图中的起始x坐标
@param y int 帧在雪碧图中的起始y坐标
@param w int 帧在雪碧图中的宽
@param y int 帧在雪碧图中的高
@param dw int 帧实际的宽
@param dh int 帧实际的高
*/
var Frame = function(x,y,w,h,dw,dh){ this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.dw = dw;
this.dh = dh;
}

Animation:动画的定义,一个动作需要多个连贯的帧才能完成

 //一个动画得定义
var Animation = function(param) { this.startX = param.startX || 0;
this.startY = param.startY || 0;
this.fs = param.fs || 1;
this.sw = param.sw || 0;
this.sh = param.sh || 0;
this.width = param.width || param.sw;
this.height = param.height || param.sh;
this.dir = param.dir || "right";
this.loop = !!param.loop;
//this.fps = param.fps || 30; //this.lazy = 1000 / this.fps;
//this.last = 0; this.ls = [];
//当前帧
this.current = null;
//当前帧得索引
this.index = -1; this.init();
}
Animation.prototype = {
init : function(){ for(var i=0;i<this.fs;i++){ var x = this.startX + (this.dir=="right"?i*this.sw:0);
var y = this.startY + (this.dir=="down"?i*this.sh:0); var frame = new Frame(x,y,this.sw,this.sh,this.width,this.height); this.ls.push(frame);
} this.index = 0;
this.current = this.ls[0];
},
//下一帧
next : function() { if(this.index + 1 >= this.ls.length){ if(this.loop){ this.current = this.ls[0];
this.index = 0;
}
}
else{ this.index += 1; this.current = this.ls[this.index];
}
},
//重置为第一帧
reset : function(){ this.current = this.ls[0];
this.index = 0;
},
size : function(){ return {w:this.width,h:this.height};
}
}

Sprite:精灵的定义,一个完整的个体,是需要多个动画,例如向左,向右等

 //一个精灵的定义
/**
@param objParam object 动画的json对象 {"left":[frame1,frame2],"right":[frame1,frame2]}
@param def string 默认动画索引
@param img object 精灵得雪碧图
@param cxt object canvas对象
@param x int 精灵的起始位置x
@param y int 精灵的起始位置y
*/
var Sprite = function(img,cxt,fps,param){ this.animations = {};
this.img = img;
this.cxt = cxt;
this.x = param.x || 0;
this.y = param.y || 0;
this.fps = fps; this.xspeed = param.xspeed || 0;
this.yspeed = param.yspeed || 0; this.yaspeed = param.yaspeed || 0; this.lazy = 1000 / this.fps;
this.last = 0; this.moveLazy = 33;
this.moveLast = 0; //当前动画
this.index = null; this.key = "";
}
Sprite.prototype = {
add : function(key,animation){ this.animations[key] = animation; if(!this.index){
this.index = animation;
this.key = key;
}
},
//修改当前动画
change : function(key){ if(key == this.key)return false; var index = this.animations[key]; if(!index)return false; this.index = index;
this.okey = this.key;
this.key = key;
this.index.reset();
},
//绘画出当前帧
draw : function(){ if(!this.index || !this.img)return false; var frame = this.index.current; this.cxt.drawImage(this.img,frame.x,frame.y,frame.w,frame.h,this.x,this.y,frame.dw,frame.dh);
},
//更新精灵
update : function(){ var t = new Date().getTime(); var diff = t - this.last; var moveDiff = t - this.moveLast; if(this.last == 0){
diff = this.lazy;
moveDiff = this.moveLazy;
} if(diff >= this.lazy){ this.index.next(); this.last = t;
} if(moveDiff >= this.moveLazy){ if(this.yaspeed)this.yspeed += this.yaspeed; if(this.xspeed)this.x += this.xspeed;
if(this.yspeed)this.y += this.yspeed; this.moveLast = t;
}
},
//移动
move : function(x,y){ this.x = x;
this.y = y;
},
setXSpeed : function(xs){ this.xspeed = xs;
},
setYSpeed : function(ys,yas){ this.yspeed = ys;
this.yaspeed = yas || 0;
},
//获取当前精灵得大小
size : function(){ var frame = this.index.current; return {w:frame.dw,h:frame.dh,x:this.x,y:this.y,r:this.x+frame.dw,b:this.y+frame.dh};
}
}

下面是游戏试玩:

键盘左右控制移动,界面上的按钮是给iphone触屏用,图片全面兼容iphone4的retina,可以直接放在phonegap中使用!

 
第0层

< >

加载中...
 

完整源码猛击:下载

PS:bug这种玩意,是肯定会有的了。。。大家就见谅吧。。

HTML5小游戏【是男人就下一百层】UI美化版的更多相关文章

  1. HTML5小游戏UI美化版

    HTML5小游戏[是男人就下一百层]UI美化版 之前写的小游戏,要么就比较简单,要么就是比较难看,或者人物本身是不会动的. 结合了其它人的经验,研究了一下精灵运动,就写一个简单的小游戏来试一下. 介绍 ...

  2. Unity经典游戏教程之:是男人就下100层

    版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...

  3. 推荐10款超级有趣的HTML5小游戏

    HTML5的发展速度比任何人的都想像都要更快.更加强大有效的和专业的解决方案已经被开发......甚至在游戏世界中!这里跟大家分享有10款超级趣味的HTML5游戏,希望大家能够喜欢! Kern Typ ...

  4. 超多经典 canvas 实例,动态离子背景、移动炫彩小球、贪吃蛇、坦克大战、是男人就下100层、心形文字等等等

    超多经典 canvas 实例 普及:<canvas> 元素用于在网页上绘制图形.这是一个图形容器,您可以控制其每一像素,必须使用脚本来绘制图形. 注意:IE 8 以及更早的版本不支持 &l ...

  5. 【CQgame】[下一百层] [Down]

    简单的下一百层的c++实现,代码一晚上就码完了 注意:游戏前请在 默认值 或 属性 中调整缓冲区大小,否则会输出爆屏,方法写在代码里了 觉得速度 快/慢 的可以在第 23 行手动改一下,相信大神们能看 ...

  6. 是男人就下100层【第四层】——Crazy贪吃蛇(2)

    在上一篇<是男人就下100层[第四层]--Crazy贪吃蛇(1)>中我们让贪吃蛇移动了起来,接下来我们来实现让贪吃蛇能够绕着手机屏幕边线移动而且能够改变方向 一.加入状态并改动代码 首先我 ...

  7. 使用AndEngine重制《是男人就上一百层》

    1.为什么还要做<是男人就上一百层> 一是在用Android原生API开发完<是男人就上一百层>以后,一直想体验一下用引擎开发游戏是个什么感觉,顺便也让游戏听上去高大上一些(使 ...

  8. 是男人就下100层【第四层】——Crazy贪吃蛇(3)

    上一篇<是男人就下100层[第四层]--Crazy贪吃蛇(2)>实现了贪吃蛇绕着屏幕四周移动,这一篇我们来完成贪吃蛇的所有功能. 一.随机产生苹果 private void addAppl ...

  9. Cocos2d-x 版本小游戏 《是男人就下100层》 项目开源

    这个是很久就开始动手写的一个小游戏了,直到最近才把它收尾了,拖拖拉拉的毛病总是很难改啊. 项目是基于 cocos2d-x v2.2 版本 ,目前只编译到了 Win8 平台上,并且已经上传到了商店,支持 ...

随机推荐

  1. [转载]sed 简明教程

    文章转载自酷壳 – CoolShell.cn,作者:陈皓,地址http://coolshell.cn/articles/9104.html awk于1977年出生,今年36岁本命年,sed比awk大2 ...

  2. Android Studio-设置switch/case代码块自动补齐

    相信很多和我一样的小伙伴刚从Eclipse转到Android Studio的时候,一定被快捷键给搞得头晕了,像Eclipse中代码补齐的快捷键是Alt+/ ,但是在AS中却要自己设置,这还不是问题的关 ...

  3. absolute布局和css布局释疑

    jqueryui也不是万能的, 有时候, 也需要自己写一些, 由 css 和jquery结合的一些东西, 如: banner中, 依次播放的div等 ## 关于jquery设计的一些思想和理念?but ...

  4. 优化MySQL,还是使用缓存?读一篇文章有感

    今天我想对一个Greenfield项目上可以采用的各种性能优化策略作个对比.换言之,该项目没有之前决策强加给它的各种约束限制,也还没有被优化过. 具体来说,我想比较的两种优化策略是优化MySQL和缓存 ...

  5. 繁华模拟赛 ljw搭积木

    #include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...

  6. 淘宝(阿里百川)手机客户端开发日记第六篇 Service详解(五)

    我们现在对上一节中的DEMO进行改进,在服务中开启线程来执行. package com.example.service; import android.app.Service; import andr ...

  7. 淘宝(阿里百川)手机客户端开发日记第四篇 自定义ListView详解

    我们知道,如果采用官方的ListView,实现的功能在很多时候,并不能满足自己的业务需求,比如在设计到复杂的列表的时候,这一节,我们就开始动手自己实现自定义的ListView. 在上一节中,我们采用了 ...

  8. unity缓存和浏览器缓存

    原地址:http://www.cnblogs.com/hisiqi/p/3203553.html <蒸汽之城>游戏中,为什么会黑屏?或者无法正常进入游戏? 我们在进行多项测试中发现少数用户 ...

  9. 查看daemon使用技巧

    una ~ # ps -ef|egrep "*d$"或"[a-z]d"               //查看现有的服务器上都有哪些服务器进程.root 3509 ...

  10. ubuntu14.04安装OpenVirteX

    官网链接: http://ovx.onlab.us/getting-started/installation/ step1: System requirements: Recommended 4 Co ...