H5游戏开发之Stick Hero

  自从上次发布一个小恐龙游戏以后,到现在10天了,前后又写了3个游戏,挑了一个感觉比较有挑战的游戏和大家分享一下。

效果演示

 

 这是我模拟一个苹果游戏《stick hero》游戏写的一个小游戏,在这里记录一下,希望大家会喜欢。

一直按下鼠标,会出一根棍子,棍子会变长,小人会根据棍子长度来移动。判断小人是否停留在柱子上,因为放在网上以后,鼠标判断有点卡,请大家见谅。

 那我们还是从头开始介绍一下这游戏的开发过程吧。

图片加载

这次的图片加载器是用的《H5手把手教你玛丽游戏》的图片加载器,个人感觉非常好用,可能是我没接触更好的图片加载器,大神都是用自己框架写的,感觉研究起来我很吃力,基础跟不上,最近一个大哥叫我去研究OOP思想来编写框架开发游戏,这也是我以后的方向,很感谢这位大哥给我的指导。

function loadImg(imgCount,callback){
    var img = {},
        total = imgCount.length,
        loaded = 0;
    for(var i = 0;i < total;i++){
        var imgs = img[imgCount[i].id] = new Image();
        imgs.src = imgCount[i].src;
        imgs.onload = function(){
            loaded++;
        };
    }

    if(typeof callback == "function"){
        function check(){
            if(loaded >= total)
                callback();
            else
                setTimeout(check,300);
        }
        check();
    }
    return img;
}

调用的方式和我上次那个差不多,也是传id和src,和回调函数,确保图片加载完以后执行。

        var imgs = null,
            game = null;

        function init(){
            imgs = loadImg([
                {id:"bg",src:"img/bg2.png"},
                {id:"player",src:"img/player.png"}
            ],start);
        }
        init();

        function start(){
            game = new Game({
                width:500,
                height:600,
                FPS:30,

            });
            game.init();
            game.move();
        }

精灵类

这次比较复杂的是存在着精灵,精灵存在动画,所以加了2个类,Sprite和Animation,在这个游戏中,我把柱子也当做精灵处理,因为每次的柱子他的宽度和初始位置是随机的,而且在检测人物是否站在柱子上的时候比较好检测。

function Sprite(option){
    for(var attr in option){
        this[attr] = option[attr];
    }
}
Sprite.prototype = {
    constructor:Sprite,
    x:0,
    y:340,
    w:0,
    h:0,
    maxX:999,
    maxY:999,
    animation:null,
    accX:0,
    accY:0,
    init:function(){
        if(this.animation){
            this.animation.init();
            this.animation.setNow(0);
        }
    },
    //每次更变人物的移动动画,让人物动起来。
    update:function(sleep,long){
        this.x += this.accX;
        this.animation.update(sleep);
        if(this.x >= long+40){
            this.x = long+40;
            this.animation.setNow(0);
            this.checkCollide();
        }
    },
    //人物的绘制
    draw:function(ct){
        this.animation.draw(ct,this.x,this.y);
    },
    //矩形的绘制
    drawRect:function(ct){
        ct.fillRect(this.x,this.y,this.w,this.h);
    },
    //检测人物是否在柱子上
    checkCollide:function(){
        var Px1 = this.x;
        var Px2 = this.x + 40;

        var Rx1 = game.colRect.x;
        var Rx2 = game.colRect.x + game.colRect.w ;
        if(Px1 > Rx2 || Px2 < Rx1){
            this.y += this.accY;
            if(this.y >= this.maxY){
                clearInterval(game.mainLoop);
                alert("挑战失败!    ");
            }
        }else{
            game.initStart();
        }
    }
};

下面是生成人物和柱子的代码,通过参数可以区分他们。

function createPlayer(){
    var config = {
        //人物走路速度
        accX:4,
        //人物掉落速度
        accY:7,
        //人物初始位置
        x:0,
        y:340,
        maxY:600,
        //人物移动过程
        animation:new Animation({
            frame:[
               {x:20,y:0,w:80,h:80,action:100},
               {x:120,y:0,w:80,h:80,action:100},
               {x:220,y:0,w:80,h:80,action:100},
               {x:320,y:0,w:80,h:80,action:100},
            ]
        })
    };
    return new Sprite(config);
}
function createRect(){
    var config = {
        //每次随机获取宽度和x位置,这样让游戏更有挑战
        w:(Math.random()*40 + 20)|0,
        x:(Math.random()*300+150)|0,
        y:400,
        h:200,
    };
    return new Sprite(config);
}

下面介绍的是人物的移动,通过组图的不断更换,让人物动起来。

function Animation(option){
    for(var attr in option){
        this[attr] = option[attr];
    }
}
Animation.prototype = {
    constructor:Animation,
    img:null,
    //移动过程
    frame:null,
    //动作的索引值
    index:null,
    //一个动作的进行时间
    time:null,
    //当前为多少帧
    frameNow:null,
    len:-1,

    init:function(){
        this.img = imgs["player"]||null;
        this.frame = this.frame||[];
        this.len = this.frame.length - 1;
        this.index = 0;
        this.setNow(this.index);
    },
    setNow:function(index){
        this.index = index;
        this.frameNow = this.frame[this.index];
    },
    //action为每个动作进行多长时间(前面传过来)
    update:function(sleep){
        if(this.time >= this.frameNow.action){
            this.time = 0;
            if(this.index >= this.len){
                this.index = 0;
            }else{
                this.index++;
            }

            this.setNow(this.index);
        }else{
            this.time += sleep;
        }
    },
    //人物的绘制
    draw:function(ct,x,y){
        var f = this.frameNow;
        ct.drawImage(this.img,f.x,f.y,f.w,f.h,x,y,60,60);
    }

};

游戏类

这个类里面一个主循环控制着我们所有移动的进行,这里我分步来说一下我遇到的问题。

1.如何实现一个柱子倒下的过程,开始我的想法是画一个矩形,然后通过rotate来实现倾斜,因为以前没有用过rotate方法,进入尝试了一次,才知道他的倾斜是将整个画布倾斜,这样连背景一起倾斜,根本无法达到效果,然后通过在纸上画了一下,用数学知识解决了这个问题,我把矩形换成换线,改变他的lineWidth让他看起来像一个矩形。

stick:function(){
        //当鼠标按下以后执行,并且在棍子移动时不会再次触发。
        if(this.moused && !this.clicked){
            this.time += this.sleep;
            //让棍子垂直向上伸展,通过循环让他的长度累加
            this.drawStick(this.time);   

        }else if(!this.moused && this.long > 0){
            //当鼠标松开(mouseup)以后,让棍子倒下去
            this.clicked = true;
            this.length = this.stickY - this.long;
            this.fallRect(this.length);
        }
    },
    //棍子向上伸展
    drawStick:function(time){
        this.time = time;
        this.long += (time/200)|0;
        this.ct.beginPath();
        this.ct.lineWidth = 5;
        this.ct.moveTo(this.stickX,this.stickY);
        this.ct.lineTo(this.stickX,this.stickY - this.long);
        this.ct.stroke();
    },
    //棍子向下掉落,记录下棍子的长度,就是人物行走的距离
    fallRect:function(length){
        this.length = length;
        if(this.angle < 30){
            this.angle += this.sleep/50;

            this.ct.beginPath();
            this.lineWidth = 5;
            this.ct.moveTo(this.stickX,this.stickY);

            var hudu = (2*Math.PI / 360) * 3 * this.angle;
            this.fallX = this.stickX + this.long*Math.sin(hudu);
            this.fallY = this.stickY - this.long*Math.cos(hudu);

            if(this.fallY >= this.stickY){
                this.fallY = this.stickY;
            }
            this.ct.lineTo(this.fallX,this.fallY);
            this.ct.stroke();
        }else{
            this.ct.beginPath();
            this.lineWidth = 5;
            this.ct.moveTo(this.stickX,this.stickY);
            this.ct.lineTo(this.fallX,this.fallY);
            this.ct.stroke();
            this.success = true;
        }
    },

2.当我以为这个游戏已经结束的时候出现了一个bug,就是每次棍子的绘制路径都被保留下来了,这是我canvas控制能力不足,每次绘制之前加一个beginPath就好了。

结束语

在这里,感谢帮助我的每一个人,以后我也会成为大牛,写更多更好的博文,尽自己的力量去帮助更多人。

最近在实验室学习,突然很想回家了,毕竟好久没看见家人了,还有10天就能回家了,心里还是很高兴。

只有半年的时间就要去找工作了,有时间都去研究JS,感觉JS真是非常强大,我现在的水平想开发框架还是太难了,不过慢慢来吧,欲速则不达,一步一步积累终有一天我能自己开发框架。

谢谢大家,如有什么疑问或者建议请留言。

时间: 2024-10-30 23:04:37

H5游戏开发之Stick Hero的相关文章

Cocos2d-x 3.x游戏开发之旅

Cocos2d-x 3.x游戏开发之旅 钟迪龙 著   ISBN 978-7-121-24276-2 2014年10月出版 定价:79.00元 516页 16开 内容提要 <Cocos2d-x 3.x游戏开发之旅>是<Cocos2d-x游戏开发之旅>的升级版,修改了Cocos2d-x 2.0版进阶到3.0版后的一些内容,新增了对CocoStudio.UI编辑器.Cocos2d-x 3.x新特性以及网络方面的知识点.主要介绍常用的API使用方式:如何通过官方Demo获取更多关于Coc

iOS游戏开发之UIDynamic

iOS游戏开发之UIDynamic 简介 什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象重力.弹性碰撞等现象 物理引擎的价值 广泛用于游戏开发,经典成功案例是“愤怒的小鸟” 让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果 提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏 知名的2D物理引擎 Box2d Chipmunk 使用步骤 要想使用UIDynamic来实现物理仿

[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(下)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei. 转载请注明出处,本文作者:

Cocos2d-x游戏开发之lua编辑器 subime 搭建,集成cocos2dLuaApi和自有类

Sublime Text http://baike.baidu.com/view/10701920.htm?from_id=8130415&type=syn&fromtitle=Sublime&fr=aladdin 简介 Sublime Text 是一个代码编辑器(Sublime Text 2是收费软件,但可以无限期试用),也是HTML和散文先进的文本编辑器.Sublime Text是由程序员Jon Skinner于2008年1月份所开发出来,它最初被设计为一个具有丰富扩展功能的V

Cocos2d-x游戏开发之lua工程创建

操作系统:OS X 10.85 Cocos2d-x 版本: 2.2.1 使用Cocos2d-x 可以创建lua工程,已经使用cpp创建的工程也可以继承lua进行开发,但是lua并不支持mac工程(因为一些框架的问题). 支持的工程文件如下: 所有使用创建工程create.py language 为cpp的工程,后集成lua及其工具的时候,要注意这一点. 撒 现在进入cocos2d-x 目录之下,通过cd 进入文件目录 进入之后,如果忘记了命令,可以直接运行 create_project.py 如

Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新完全解读

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei. 转载请注明出处,本文作者:

[Unity3D]Unity3D游戏开发之从Unity3D到Eclipse

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei. 转载请注明出处,本

[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述

各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei.在研究了Unity3D Mecanim动画系统的重定向特性后,今天我们继续来探索Mecanim动画系统更多的特性吧.今天博主想和大家分享的是ACT游戏中的三连击效果的实现,由于Unity3D目前存在Animation和Animator两种类型的动画组件,因此本文将分别讲这两种类型的动画组件的三连击效果的实现,其中Animation组件是Unity3.5以下版本所使用的动画组件,An

Unity3D游戏开发之Unity3D动画与Mecanim动画系统

Unity3D游戏开发之Unity3D动画与Mecanim动画系统 欢迎来到unity学习.unity培训.unity企业培训教育专区,这里有很多U3D资源.U3D培训视频.U3D教程.U3D常见问题.U3D项目源码,[狗刨学习网]unity极致学院,致力于打造业内unity3d培训.学习第一品牌. Mecanim是Unity新增的动画系统,其功能强大而灵活,让人类和非人类角色栩栩如生.Mecanim的重定向极大的提供了工作效率,而且占用极少CPU周期.使用从Unity资源商店找到的动画资源,或