zoukankan      html  css  js  c++  java
  • HTML5小游戏UI美化版

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

    介绍一下几个主要的类

    • 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
  • 相关阅读:
    PHP 获取js中变量的方法
    Golang文件操作整理
    Golang的文件处理方式-常见的读写
    golang中文件以及文件夹路径相关操作
    服务器常用的状态码及其对应的含义
    left join on 和where条件的放置
    golang 文件导入数据追加sheet
    使用io/ioutil进行读写文件
    Go语言编程中字符串切割方法小结
    Golang学习
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3313612.html
Copyright © 2011-2022 走看看