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

介绍一下几个主要的类

  • 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;
}
}

 1 //定义贞管理类,兼容
2 var requestAnimationFrame = window.requestAnimationFrame
3 || window.mozRequestAnimationFrame
4 || window.webkitRequestAnimationFrame
5 || function(cb){setTimeout(cb,1000/60)};
6
7 var TimeProcess = function(){
8
9 this.list = [];
10 this.isStart = false;
11 }
12 TimeProcess.prototype = {
13
14 add : function(cb,param,context){
15
16 this.list.push({cb:cb,param:param,context:context});
17 },
18 start : function(){
19
20 this.isStart = true;
21
22 var self = this;
23
24 requestAnimationFrame(function(){
25
26 var item = null,
27 p = [];
28
29 for(var i=0;i<self.list.length;i++){
30
31 item = self.list[i];
32
33 item.cb.apply(item.context,item.param);
34 }
35
36 if(self.isStart)requestAnimationFrame(arguments.callee);
37 });
38 },
39 stop : function(){
40
41 this.isStart = false;
42 }
43 }

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;
}

 1 //帧的定义
2 /**
3 @param x int 帧在雪碧图中的起始x坐标
4 @param y int 帧在雪碧图中的起始y坐标
5 @param w int 帧在雪碧图中的宽
6 @param y int 帧在雪碧图中的高
7 @param dw int 帧实际的宽
8 @param dh int 帧实际的高
9 */
10 var Frame = function(x,y,w,h,dw,dh){
11
12 this.x = x;
13 this.y = y;
14 this.w = w;
15 this.h = h;
16 this.dw = dw;
17 this.dh = dh;
18 }

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};
}
}

 1 //一个动画得定义
2 var Animation = function(param) {
3
4 this.startX = param.startX || 0;
5 this.startY = param.startY || 0;
6 this.fs = param.fs || 1;
7 this.sw = param.sw || 0;
8 this.sh = param.sh || 0;
9 this.width = param.width || param.sw;
10 this.height = param.height || param.sh;
11 this.dir = param.dir || "right";
12 this.loop = !!param.loop;
13 //this.fps = param.fps || 30;
14
15 //this.lazy = 1000 / this.fps;
16 //this.last = 0;
17
18 this.ls = [];
19 //当前帧
20 this.current = null;
21 //当前帧得索引
22 this.index = -1;
23
24 this.init();
25 }
26 Animation.prototype = {
27 init : function(){
28
29 for(var i=0;i<this.fs;i++){
30
31 var x = this.startX + (this.dir=="right"?i*this.sw:0);
32 var y = this.startY + (this.dir=="down"?i*this.sh:0);
33
34 var frame = new Frame(x,y,this.sw,this.sh,this.width,this.height);
35
36 this.ls.push(frame);
37 }
38
39 this.index = 0;
40 this.current = this.ls[0];
41 },
42 //下一帧
43 next : function() {
44
45 if(this.index + 1 >= this.ls.length){
46
47 if(this.loop){
48
49 this.current = this.ls[0];
50 this.index = 0;
51 }
52 }
53 else{
54
55 this.index += 1;
56
57 this.current = this.ls[this.index];
58 }
59 },
60 //重置为第一帧
61 reset : function(){
62
63 this.current = this.ls[0];
64 this.index = 0;
65 },
66 size : function(){
67
68 return {w:this.width,h:this.height};
69 }
70 }

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};
}
}

  1 //一个精灵的定义
2 /**
3 @param objParam object 动画的json对象 {"left":[frame1,frame2],"right":[frame1,frame2]}
4 @param def string 默认动画索引
5 @param img object 精灵得雪碧图
6 @param cxt object canvas对象
7 @param x int 精灵的起始位置x
8 @param y int 精灵的起始位置y
9 */
10 var Sprite = function(img,cxt,fps,param){
11
12 this.animations = {};
13 this.img = img;
14 this.cxt = cxt;
15 this.x = param.x || 0;
16 this.y = param.y || 0;
17 this.fps = fps;
18
19 this.xspeed = param.xspeed || 0;
20 this.yspeed = param.yspeed || 0;
21
22 this.yaspeed = param.yaspeed || 0;
23
24 this.lazy = 1000 / this.fps;
25 this.last = 0;
26
27 this.moveLazy = 33;
28 this.moveLast = 0;
29
30 //当前动画
31 this.index = null;
32
33 this.key = "";
34 }
35 Sprite.prototype = {
36 add : function(key,animation){
37
38 this.animations[key] = animation;
39
40 if(!this.index){
41 this.index = animation;
42 this.key = key;
43 }
44 },
45 //修改当前动画
46 change : function(key){
47
48 if(key == this.key)return false;
49
50 var index = this.animations[key];
51
52 if(!index)return false;
53
54 this.index = index;
55 this.okey = this.key;
56 this.key = key;
57 this.index.reset();
58 },
59 //绘画出当前帧
60 draw : function(){
61
62 if(!this.index || !this.img)return false;
63
64 var frame = this.index.current;
65
66 this.cxt.drawImage(this.img,frame.x,frame.y,frame.w,frame.h,this.x,this.y,frame.dw,frame.dh);
67 },
68 //更新精灵
69 update : function(){
70
71 var t = new Date().getTime();
72
73 var diff = t - this.last;
74
75 var moveDiff = t - this.moveLast;
76
77 if(this.last == 0){
78 diff = this.lazy;
79 moveDiff = this.moveLazy;
80 }
81
82 if(diff >= this.lazy){
83
84 this.index.next();
85
86 this.last = t;
87 }
88
89 if(moveDiff >= this.moveLazy){
90
91 if(this.yaspeed)this.yspeed += this.yaspeed;
92
93 if(this.xspeed)this.x += this.xspeed;
94 if(this.yspeed)this.y += this.yspeed;
95
96 this.moveLast = t;
97 }
98 },
99 //移动
100 move : function(x,y){
101
102 this.x = x;
103 this.y = y;
104 },
105 setXSpeed : function(xs){
106
107 this.xspeed = xs;
108 },
109 setYSpeed : function(ys,yas){
110
111 this.yspeed = ys;
112 this.yaspeed = yas || 0;
113 },
114 //获取当前精灵得大小
115 size : function(){
116
117 var frame = this.index.current;
118
119 return {w:frame.dw,h:frame.dh,x:this.x,y:this.y,r:this.x+frame.dw,b:this.y+frame.dh};
120 }
121 }

下面是游戏试玩:

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

 
第0层

<>

加载中...

完整源码猛击:下载

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

 
 
 
标签: JavaScriptHtml5

HTML5小游戏UI美化版的更多相关文章

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

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

  2. js消除小游戏(极简版)

    js小游戏极简版 (1) 基础布局 <div class = "box"> <p></p> <div class="div&qu ...

  3. HTML5小游戏【是男人就下一百层】UI美化版

    之前写的小游戏,要么就比较简单,要么就是比较难看,或者人物本身是不会动的. 结合了其它人的经验,研究了一下精灵运动,就写一个简单的小游戏来试一下. 介绍一下几个主要的类: Frame:帧的定义,主要描 ...

  4. HTML5小游戏源码收藏

    html5魅族创意的贪食蛇游戏源码下载 html5网页版打砖块小游戏源码下载 html5 3D立体魔方小游戏源码下载 html5网页版飞机躲避游戏源码下载 html5三国人物连连看游戏源码下载 js ...

  5. 用面向对象的编程方式实现飞机大战小游戏,java版

    概述 本文将使用java语言以面向对象的编程方式一步一步实现飞机大战这个小游戏 本篇文章仅供参考,如有写的不好的地方或者各位读者哪里没看懂可以在评论区给我留言 或者邮件8274551712@qq.co ...

  6. Html5 小游戏 俄罗斯方块

    导言 在一个风和日丽的一天,看完了疯狂HTML 5+CSS 3+JavaScript讲义,跟着做了书里最后一章的俄罗斯方块小游戏,并做了一些改进,作为自己前端学习的第一站. 游戏效果: 制作思路 因为 ...

  7. 通通制作Html5小游戏——第二弹(仿flappy bird像素鸟)

    亲爱的博友们,我又回来啦~因为我们技术宅的思想只有技术宅懂得,好不容易写了点好玩的东西发QQ空间,结果只有11的UV,0回复....10分钟ps一个女神的素描效果发QQ空间朋友圈,一大堆回复加赞,作为 ...

  8. 菜鸟做HTML5小游戏 - 翻翻乐

    记录下开放过程.做小游戏开发,又要跨平台,flash又不支持iPhone,html5是最好的选择. 先看看最后效果: 好了,开始demo. 1.准备工作: 图片素材(省略...最后代码一起打包) 了解 ...

  9. HTML5小游戏之见缝插针

    今天给大家带来的就是一款叫做<见缝插针>的游戏.有空你就往里插,直到你无处可插!看你能过多少关! 简洁大气 黑白搭配游戏画面非常的简洁,米白色的背景中央,放置着一个不断旋转的太阳状的球体, ...

随机推荐

  1. Tomcat剖析(一):一个简单的Web服务器

    Tomcat剖析(一):一个简单的Web服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三):连接器 ...

  2. Swift语言指南(二)--语言基础之注释和分号

    原文:Swift语言指南(二)--语言基础之注释和分号 注释 通过注释向自己的代码中注入不可执行的文本,作为你自己的笔记或提示.Swift编译器运行时会忽略注释. Swift的注释与C语言极其相似,单 ...

  3. WebBrowser一点心得,如果在Javascript和Winform代码之间实现双向通信

    原文:WebBrowser一点心得,如果在Javascript和Winform代码之间实现双向通信 最近工作需要,学习了一下winform内嵌webbrowser控件,然后与htm页面中的javasc ...

  4. 合并多段zip文件并解压缩

    cat xxx.zip.*** >xxx.zip unzip xxx.zip

  5. android 控制手机的体积的大小 切换音效模式

    (1)项目介绍 于android API的AudioManager于,它提供了一种方法来调整电话音量. audioMa.adjustVolume(AudioManager.ADJUST_LOWER, ...

  6. 空连接ipc$入侵

    使用命令 net use url=file://\\IP\ipc$\\IP\ipc$ "" /user:"" 就可以简单地和目标建立一个空连接(需要目标开放ip ...

  7. x240 uefi ubuntu 12.04.4

    http://askubuntu.com/questions/355034/ubuntu-12-04-3-lts-installation-failed-says-grub-installation- ...

  8. Java 多并发之原子访问(Atomic Access)

    在编程中,一个原子操作是只会出现一次的.一个原子操作在中间不会停止:要么全部发生要么一点也不发生.我们只有在原子操作完成之后才会看到原子操作的具体影响. 甚至是非常简单的表达式能够构造分解为简单操作的 ...

  9. VS2015 Apache Cordova

    VS2015 Apache Cordova第一个Android和IOS应用   前言 本人个人博客原文链接地址为http://aehyok.com/Blog/Detail/75.html. http: ...

  10. 小贴士——提高PHP程序在NGINX代理服务器的性能

    NGINX本身就是面向最大性能的代理服务器,因此在使用NGINX,并没有性能调整的配置工作.但是却有很多选项可用于定制NGINX的行为,利用底层硬件和操作系统. 下面将介绍用于提供PHP在NGINX的 ...