HTML5小游戏UI美化版

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

介绍一下几个主要的类

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

HTML5小游戏UI美化版
 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 }
HTML5小游戏UI美化版

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

HTML5小游戏UI美化版
 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 }
HTML5小游戏UI美化版

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

HTML5小游戏UI美化版
 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 }
HTML5小游戏UI美化版

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

HTML5小游戏UI美化版
  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 }
HTML5小游戏UI美化版

下面是游戏试玩:

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

第0层

<>

加载中...

完整源码猛击:下载

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

标签: JavaScriptHtml5