zoukankan      html  css  js  c++  java
  • createjs 小游戏开发实战

    【转载请注明出处】

    紧接着上一篇文章createjs入门http://www.cnblogs.com/beidan/p/7055422.html

    这里来一篇小游戏实战篇。

    效果图:(录屏的时候有点卡)

     demo地址https://github.com/beidan/canvas/tree/master/demo/car。如果对你有用,请点star

    游戏整体思路实现

    1. 实现一个无缝连接的背景图,模拟出汽车在加速的状态

    this.backdrop = new createjs.Bitmap(bg);
    this.backdrop.x = 0;
    this.backdrop.y = 0;
    this.stage.addChild(that.backdrop);
    this.w = bg.width;
    this.h = bg.height;
    
    //创建一个背景副本,无缝连接
    var copyy = -bg.height;
    this.copy = new createjs.Bitmap(bg);
    this.copy.x = 0;
    this.copy.y = copyy;  //在画布上y轴的坐标为负的背景图长
    //使用createjs的tick函数,逐帧刷新舞台
    createjs.Ticker.addEventListener("tick", tick);
    function tick(e) {
       if (e.paused !== 1) {
            //舞台逐帧逻辑处理函数
            that.backdrop.y = that.speed + that.backdrop.y;
            that.copy.y = that.speed + that.copy.y;
    
            if (that.copy.y > -40) {
                  that.backdrop.y = that.copy.y + copyy;
            }
            if (that.copy.y > -copyy - 100) {
                  that.copy.y = copyy + that.backdrop.y;
            }
            that.stage.update(e);
        }          
    }

    2. 随机绘制障碍物

    由于一条跑道肯定会有很多障碍物,对于超出屏幕的障碍物我们要进行‘资源回收’,否则游戏到后面会越来越卡顿。

    // 删除越界的元素
    for (var i = 0, flag = true, len = that.props.length; i < len; flag ? i++ : i) {
        if (that.props[i]) {
            if (that.props[i].y > height + 300) {
                that.stage.removeChild(that.props[i]);
                that.props.splice(i, 1);
                flag = false;
            } else {
                flag = true;
            }
        }
    }

    一共有3条赛道,我们不能出现3个道具同时出现在水平线上,因此我们会随机取1~2个值绘制障碍物。所有游戏我们都应该有参数去控制它的难易程度,免得临上线的时候,老板体验之后觉得游戏太难了……那就非常地尴尬了。 因此,我们会设置加速物体,减速物体,炸弹出现的比例,后期可以调整这个比例来设置游戏的难易程度。

    var num = parseInt(2 * Math.random()) + 1, i;
        for (i = 0; i < num; i++) {
            var type = parseInt(10 * Math.random()) + 1;
    
            // 设置道具出现比例
            if (type == 1) {
                /绘制炸弹
            } else if ((type >= 2) && (type <= 5)) {
                //绘制加速道具
            } else if ((type >= 6) && (type <= 10)) {
                //绘制减速道具
            }
        }

    第一次绘制完障碍物之后,会随机时间绘制下一次的障碍物。

    var time = (parseInt(3 * Math.random()) + 1);  //随机取1~3整数
    // 随机时间绘制障碍物
    setTimeout(function () {
        that.propsTmp = [];  //清空
        that.drawObstacle(obj);
    }, time * 400);  //400ms ~ 1200ms

    3.碰撞检测

    我们用一个数组来存放汽车占的矩形区域,障碍物占的矩形区域,在每一次tick的时候循环遍历数组,看是否有重叠的,若有重叠,则发生了碰撞。

    createjs的一些小知识:

    1. 暂停和恢复舞台渲染 

    createjs.Ticker.addEventListener(“tick”, tick); 
    function tick(e) { 
        if (e.paused === 1) { 
        //处理 
        }
    }     
    createjs.Ticker.paused = 1; //在函数任何地方调用这个,则会暂停tick里面的处理 createjs.Ticker.paused = 0; //恢复游戏

    2. 由于汽车会有加速,减速,弹气泡的效果。因此我们把这几个效果绘制在同一个container中,方便统一管理,对这些效果设置name属性,之后可以直接使用getChildByName获取到该对象。

    container.name = ‘role’; //设置name值
    car = this.stage.getChildByName(“role”);  //使用name值方便获取到该对象

    3. 预加载 preload (createjs 的 preload 非常的实用)

    一开始是自己写的预加载,后来发现createjs里面对图片是有跨域处理的,自己处理跨域的img就比较麻烦,所以直接使用createjs的预加载。

    //放置静态资源的数组
    var manifest = [
        {src: __uri('./images/car_prop2_tyre@2x.png'), id: 'tyre'}
    ];
    var queue = new createjs.LoadQueue();
    queue.on('complete', handleComplete, this);
    queue.loadManifest(manifest);
    //资源加载成功后,进行处理
    function handleComplete() {
       var tyre = queue.getResult('tyre');  //拿到加载成功后的img
    }

    一般做一个游戏,我们正常都会构建一个游戏类来承载。 下面是一个游戏正常有的接口:

    ;(function () {
        function CarGame(){}
        CarGame.prototype = {
            init:function(manifest) {
                this.preLoad(manifest);  //资源预加载
                //时间倒计时
                this.prepare(3, 3);  //倒计时3秒
                this.bindEvent(); 
            },
            render:function() {
               this.drawBg(bg1);
               this.drawRole(car, effbomb, effquick);
               this.drawObstacle(obj);
            },
            //在游戏结束的时候批量销毁
            destroy:function(){
                //移除tick事件
                createjs.Ticker.removeEventListener("tick", this.tick);
                //暂停里程,倒计时
                clearInterval(this.changem);
                clearTimeout(this.gametime);
            },
            //由于期间用户可能切出程序进行其他操作,因此都需要一个暂停的接口
            pause:function() {
                //暂停里程,倒计时
                clearInterval(this.changem);
                clearTimeout(this.gametime);
    
                //暂停页面滚动
                createjs.Ticker.paused = 1;
            },
            //重新开始游戏
            reStart:function(){
               this.destroy();
               this.init(manifest);
            },
            gameOver:function(){
               //显示爆炸效果
               var car = this.stage.getChildByName("role");
               car.getChildByName('bomb').visible = true;
               car.getChildByName('quick').visible = false;
               this.destroy();
            }
        }
    })()
  • 相关阅读:
    【PHP学习】PHP 变量
    【PHP学习】PHP 语法
    枚举进程使用的DLL
    多线程学习----CreateThread
    C++接口定义及实现举例
    注册表操作(VC_Win32)
    Windows 动态链接库编程
    [代码]JAVA触发器,Spring的quartz配置
    [实例]JAVA调用微信接口发送图文消息,不用跳到详情页
    [实例]JAVA生成字母+随机数字并生成文件
  • 原文地址:https://www.cnblogs.com/beidan/p/7122731.html
Copyright © 2011-2022 走看看