PlayCanvas__三消解析

发布于 2020-04-20  36 次阅读


前言

之前用PlayCanvas抄了个三消,虽然有C#的源码,但是转起来还是有一些要注意的地方,而且逻辑都捋了一遍。
项目做完整理一下问题并做记录,总会收获一些“沉淀”。

正文

根据自己的习惯整理开发思路和问题,项目地址贴出来,有兴趣的可以看看。

项目地址

开始场景

  • 乒乓动画
  • Element的Texture不支持Tween。
SwingHeart.prototype.update = function(dt) {
    if(this.isPlay)
    {
        this.currentOffest += dt *  this.comp;
        if(this.currentOffest >this.MaxOffest || this.currentOffest < this.MinOffest)
        {
           this.comp = -this.comp ;
        } 
        this.entity.setEulerAngles(0,0,this.currentOffest); 
        this.star.setLocalEulerAngles(0,0,this.currentOffest *10);  
    }
};

切换场景

切换场景在之前讲过,这里就不说了。

游戏场景

惯例

  • Globals 依然是集成Audio,Model,UI。
  • AudioMgr 控制音频的方法。
  • ModelMgr 集成模型模块。
  • UIMgr 集成UI模块。

GameAudioMgr.js,挂在Sound物体上,并设置好声音。

var GameAudioMgr = pc.createScript('gameAudioMgr'); 
GameAudioMgr.prototype.StopEffect = function(effect)
{
    if(effect !== null)
    {
        this.entity.sound.stop(effect);
    }
};  
GameAudioMgr.prototype.PlayEffect = function(effect)
{
    if(effect !== null)
    { 
        this.entity.sound.play(effect); 
    }
};

游戏逻辑

  • GameManager 控制甜品逻辑。
    • 初始化一些数据
    • 生成甜品和背景
    • 开启时间倒计时
    • 填充
    • 判断是否相邻,交换
    • 清除匹配
      • 清除行
      • 清除列
      • 清除颜色
  • GameSweet 包含每一个甜品的Component属性。
    • ColorSweet 控制甜品颜色的脚本
    • MovedSweet 控制甜品移动给的脚本
    • ClearedSweet 清楚甜品的脚本

TouchHandle

代码在GameSweet里,思路是touchstart(鼠标也可以)的时候记录当前的甜品,然后判断X和Y轴的偏移量,再根据坐标索引得到临近的甜品。

//Down
this.entity.element.on('touchstart', this.OnMouseDown, this);          
//Enter
this.entity.element.on('touchmove',this.OnMouseEnter,this);
//up的时候
this.entity.element.on('touchend',this.OnMouseUp,this);
GameSweet.prototype.OnMouseDown = function(e)
{
    console.log("OnMouseDown");
    this.isOpenTouch = true;
    this.oldTouchX = e.touches[0].pageX;
    this.oldTouchY = e.touches[0].pageY;
    this.gameManager.PressSweet(this);

};
GameSweet.prototype.OnMouseEnter = function(e)
{
    console.log("OnMouseEnter");
    if(this.isOpenTouch)
    {
        this.newTouchX = e.touches[0].pageX;
        this.newTouchY = e.touches[0].pageY;
    }
    this.gameManager.EnterSweet(this); 
}; 

GameSweet.prototype.OnMouseUp = function()
{
    console.log("OnMouseUp"); 
    var ofx = 0;
    var ofy = 0;
    //先比较绝对值 看x或者y哪个偏移值大
    if(Math.abs(this.newTouchX - this.oldTouchX ) > Math.abs(this.newTouchY - this.oldTouchY ))
    { //X    
        if(this.newTouchX - this.oldTouchX >0)
        {
            ofx = 1; 
        }   
        else
        {
            ofx = -1;
        }

    }
    else
    { //Y
        if(this.newTouchY - this.oldTouchY >0)
        {
            ofy = 1; 
        }   
        else
        {
            ofy = -1;
        }

    }
    var a = this.gameManager.GetSweetByXY(this.x + ofx,this.y + ofy); 
    this.gameManager.PressSweet(a); 
    this.gameManager.ReleaseSweet(); 
}; 

ColorSweet.js

更换颜色行为

ColorSweet.prototype.SetColor = function(newColor)
{ 
    this._color = newColor; 
    if (ColorSweet.colorSpriteDict.get(newColor))//Map
    {   
        this.entity.element.sprite = ColorSweet.colorSpriteDict.get(newColor).resource; 
    }
};

MovedSweet.js

主要是通过setInterval控制一帧一帧的移动

MovedSweet.prototype.Move = function(newX,newY,time)
{ 
    var self = this;   
    this.sweet.X = newX;
    this.sweet.Y = newY; 
    //每一帧移动一点点
    this.startPos = this.entity.getPosition(); 

    this.endPos = this.sweet.gameManager.CorrectPositon(newX, newY); 
    //用setInterval代替携程,Lerp坐标
    this.currentTime = 0; 
    var a = setInterval(function() {
        self.currentTime +=  20; 
        self.startPos.lerp(self.startPos,self.endPos,self.currentTime/time);
        self.entity.setPosition(self.startPos); 

        if(self.currentTime>= time)
        {
            self.entity.setPosition(self.endPos); 
            clearInterval(a);
        }
    },20); 
};

ClearedSweet.js

在C#里是继承的,我在这里是判断完直接删除


不积跬步,无以至千里;不积小流,无以成江海。