Egret – 2D跑酷背景循环讨论

跑酷场景参考如下:
让我们一步步来实现并对这个进行优化

跑酷地图分层原理

首先我们需要确认跑酷游戏元素的组成部分,主要包括:

  • 游戏场景 (Scene)
  • 游戏控制角色 (Role)
  • 游戏道具 (Tool)
  • 道路障碍 (Obstacles)
  • 称为SRTO。

    游戏场景

    游戏场景我们可以理解为跑酷地图。首先我们需要知道跑酷地图分为多少层?每一层都是什么?
    不同的2D跑酷游戏,地图包含的层级也有所不同,一般分为以下几层:
    1 背景底衬
    2 天空层
    3 远景层
    4 近景层
    5 道路层
    6 前景层
    而对于2D没有摄像机的,一般通过控制道路移动来实现,这里为了实现景深感,需要对于不同的层级做不同的速度处理,1层作为底衬不动,2层作为天空层,移动很缓慢处于基本不动的情况,而3层移动缓慢,但是移动可以感受到,4、5、6三层移动速度一致,一般称之为跑酷的移动速度。除了景深效果,还有就是地图的无限循环,这里就涉及到一些方法,我们一起讨论下,如果不加循环效果,就会出现如下效果:


    除去绘制的物理体效果,背景层、天空层还在,但是远景、近景前景基本都已经不复存在。
    我们一层一层的来进行处理,首先来添加近景层。

    一般需要背景循环,我们的步骤如下

  • 初始化
  • public InitNear():void {
    	// 
    	this.nearContent = new egret.DisplayObjectContainer();
    	this.addChildAt(this.nearContent, this.numChildren);
    
    	// 添加草皮
    	var grass_content:egret.DisplayObjectContainer = this.AddGrass();
    	// 添加该草皮的元素
    	this.AddGrassElement(grass_content);
    }
    

  • 检查更新后位置,如果位置超过左边界, 则进行Append
  • public update(_targetVelocity:number[]) {
    	// 近景
    	this.nearContent.x += _targetVelocity[0] * 0.84;
    	this.nearContent.y += _targetVelocity[1] * 0.84;
    	this.farHillContent.x += _targetVelocity[0] * 0.84 * 0.33;
    	this.farHillContent.y += _targetVelocity[1] * 0.84 * 0.33;
    	this.cloudContent.x += _targetVelocity[0] * 0.84 * 0.1;
    	this.cloudContent.y += _targetVelocity[1] * 0.84 * 0.1;
    	this.CheckNear();
    	this.CheckFar();
    	this.CheckCloud();
    }
    public CheckNear() {
        var cNum = this.nearContent.numChildren;
        var all_numbers = 0;
        var over_numbers = 0;
        var remove_objs = [];
        for (var i = 0; i < cNum; i++) {
            var child = this.nearContent.getChildAt(i);
            if (child.name.substr(0, 1) == "G") {
                all_numbers = all_numbers + 1;
                var offx = child.x + this.nearContent.x;
                if (offx < -100) {
                    over_numbers = over_numbers + 1;
                } else if (offx < -1000) {
                    remove_objs.push(child);
                }
            }
        }
    
        for (var i = 0; i < remove_objs.length; i++) {
            var grass:egret.Bitmap = remove_objs[i];
            grass.parent.removeChild(grass);
        }
    
        if (over_numbers == all_numbers) {
            // Create New
            this.AppendNear();
        }
    }
    public AppendNear() {
        // 附加近景
        // 添加草皮
        var grass_content:egret.DisplayObjectContainer = this.AddGrass();
        // 添加该草皮的元素
        this.AddGrassElement(grass_content);
        var offx = this.GetNearRight(3);
        grass_content.x = offx;
    }
    // GetRight
    public GetNearRight(type:number) {
        var ret = 0;
        var cNum = 0;
        if (type == 1) {
            // 云
            cNum = this.cloudContent.numChildren;
            for (var i = 0; i < cNum; i++) {
                var child = this.cloudContent.getChildAt(i);
                if (child.name.substr(0, 1) == "C") {
                    if (child.x + child.width > ret) {
                        ret = child.x + child.width;
                    }
                }
            }
        } else if (type == 2) {
            // 远山
            cNum = this.farHillContent.numChildren;
            for (var i = 0; i < cNum; i++) {
                var child = this.farHillContent.getChildAt(i);
                if (child.name.substr(0, 1) == "H") {
                    if (child.x + child.width > ret) {
                        ret = child.x + child.width;
                    }
                }
            }
        } else if (type == 3) {
            // 草地
            cNum = this.nearContent.numChildren;
            for (var i = 0; i < cNum; i++) {
                var child = this.nearContent.getChildAt(i);
                if (child.name.substr(0, 1) == "G") {
                    if (child.x + child.width > ret) {
                        ret = child.x + child.width;
                    }
                }
            }
        }
        return ret;
    }
    



    从上面视频我们知道,需要修正部分装饰物的位置,我们设置一个偏移数组来完成。
    经过位置和随机优化,我们效果如下

    现在只剩下道路的和场景的匹配,我们调整一下道路即可。下一章我们将开始制作吃金币和吸金币的功能。

    欢迎留言

    avatar
      Subscribe  
    Notify of