基于egret的小游戏——拼图

前天接触了egret引擎,看了下里面的系列教程(黑白方块):http://edn.egret.com/cn/article/index/id/57 ,自己跟着做并改了一下逻辑,完善了一下,包括第一次点击后开始计时、计时结束后不能再点击等。

源码:https://github.com/1998y12/DontTouchWhite.git

下载地址:https://download.csdn.net/download/qq_41508508/10626762

然后今天做了下拼图游戏,有些地方还待完善,不过算是初步了解下egret。

开始界面:

基于egret的小游戏——拼图_第1张图片

游戏界面:

基于egret的小游戏——拼图_第2张图片

结束界面:

基于egret的小游戏——拼图_第3张图片

这里的拼图是那种右下角缺一块那种,逻辑部分比较简单,主要就是怎样打乱,移动,判断是否还原。

打乱的话,可以先将各个拼图块表示成数字存入数组currentorder中,然后在排序sort函数中加入随机数来随机排序方法进行打乱。

打乱后还要判断是否能够还原,以未打乱的拼图(3*3)为例,表示为0,1,2,3,4,5,6,7,8,以它做标准列,其逆序数为0。

判断是否能够还原的条件是:打乱后方块的逆序数 + 打乱后空白方块到右下角方块的曼哈顿距离 是否为偶数

曼哈顿距离: 两者之间x距离差+y距离差

逆序数:计算打乱后的拼图逆序数即看数列中每一个数的前面,有多少个比它大的数。如 2,5,3,1,4,8,7,0,6,其逆序数为:0+0+1+3+1+0+1+7+2 = 15

如果打乱后不能还原,则再打乱一次。

public upset(){  
        this.currentOrder.sort(
            function(){
                return 0.5 - Math.random();
            });
        
        var r:number = 0;
        var cur_index:number = 0;
        
        for(var i = 0;i this.currentOrder[i]){
                    r++;
                }
            }
        }

        var temp_j = cur_index % this.currentLevel;
        var temp_i = (cur_index - temp_j) / this.currentLevel;
      
        r += ((this.currentLevel - 1 - temp_i) + (this.currentLevel - 1 - temp_j));

        if(r%2){
            this.upset();
        }
       
    }

接下来是游戏主界面的搭建:

首先新建GameDate类,用这个类来存储游戏的一些静态配置,数据等。

class GameData
{
    public static LENGTH = 600;    //拼图原始图片像素设为600
    
    public static LEVEL_EASY = 3;
    public static LEVEL_NORMAL = 4;
    public static LEVEL_HARD = 5;

    public static step = 0;

    public static one:Array = [ "one_01_png" , "one_02_png" , "one_03_png" , "one_04_png"
     , "one_05_png" , "one_06_png" , "one_07_png" , "one_08_png" , "block_png"];

    public static onenor:Array = [ "onenor_01_png" , "onenor_02_png" , "onenor_03_png" , "onenor_04_png" , 
    "onenor_05_png" , "onenor_06_png" , "onenor_07_png" , "onenor_08_png" , "onenor_09_png" ,
    "onenor_10_png" , "onenor_11_png" , "onenor_12_png" , "onenor_13_png" , "onenor_14_png" ,
    "onenor_15_png" , "blocknor_png"];

    public static onehar:Array = [ "onehar_01_png" , "onehar_02_png" , "onehar_03_png" , "onehar_04_png" ,
     "onehar_05_png" , "onehar_06_png" , "onehar_07_png" , "onehar_08_png" , "onehar_09_png" , "onehar_10_png" ,
     "onehar_11_png" , "onehar_12_png" , "onehar_13_png" , "onehar_14_png" , "onehar_15_png" , "onehar_16_png" ,
     "onehar_17_png" , "onehar_18_png" , "onehar_19_png" , "onehar_20_png" , "onehar_21_png" , "onehar_22_png" ,
     "onehar_23_png" , "onehar_24_png" , "blockhar_png"];
    

接下来新建puzzlepart类,继承自egret.sprite,表示拼图的每一小块。包含图片的边框,以及一张图片。同时有添加图片createImg方法和展示show方法。

class Puzpart extends egret.Sprite
{
    public img:egret.Bitmap = null;
    public border:egret.Sprite = null;
    private imgNumber:number = 0;
    public Loc_x:number = 0;    //表示这个方块在拼图中的位置
    public Loc_y:number = 0;

    public constructor(){
        super();
        this.touchEnabled = true;
    }

    

    public createImg(name:string){
        this.img = new egret.Bitmap();
        let texture: egret.Texture = RES.getRes(name);
        this.img.texture = texture;
        this.img.x = 0;
        this.img.y = 0;
        // this.addChild(this.img);
    }

    public show(){
        if(!this.border)
        {
            this.border = new egret.Sprite();
        }
        this.border.graphics.lineStyle(1,0xcccccc);
        this.border.graphics.drawRect(0,0,this.img.width,this.img.width);
        this.addChild(this.img);
        this.addChild(this.border);
        
        
        
    }

    public setimgNumber(val:number){
        this.imgNumber = val;
    }

    public getimgNumber(){
        return this.imgNumber;
    }

    public static getWidth(){
        return this.getWidth;
    }
    
    
}

接着新建puzzle类,控制方块移动,判断游戏是否成功等。

私有属性:

private parts:Array;
    public currentOrder:Array;    //当前拼图的顺序
    public currentBlock_x:number;    //当前空白块位置x
    public currentBlock_y:number;    //当前空白块位置y
    public Block_v:number = 8;    //拼图复原后空白块的位置
    public currentLevel:number;    //当前游戏等级(3*3,4*4,5*5)
    public partsNum:number;    //拼图的块数
    public partLen:number;    //每一块拼图块的长度
    
    
    public gameStartPanel:GameStartPanel;    //开始界面
    public gameOverPanel:GameOverPanel;    //结束界面

游戏初始化及show方法:

public init(arrs:Array){
        this.parts = [];
        this.currentOrder = [];
        for(var i = 0;i

接下来就是拼图块移动的方法,其实也就是点击某个拼图块,判断它周边是否有空白块,有则交换

public onPuzzleClick(evt:egret.TouchEvent){
        //console.log(evt.target.Loc_x+","+evt.target.Loc_y);
        var tempX = evt.target.Loc_x;
        var tempY = evt.target.Loc_y;
        if(tempX==this.currentBlock_x && Math.abs(tempY - this.currentBlock_y)==1){
            var temp = tempY;
            tempY = this.currentBlock_y;
            this.currentBlock_y = temp;
            this.changeBlock(tempX,tempY);  
            GameData.step++;
            this.show();  
        }  
        else if(tempY==this.currentBlock_y && Math.abs(tempX - this.currentBlock_x)==1){
            var temp = tempX;
            tempX = this.currentBlock_x;
            this.currentBlock_x = temp;
            this.changeBlock(tempX,tempY);
            GameData.step++;
            this.show();
        }  
        this.judge(); 
    }

    public changeBlock(x:number , y:number){
        var index1 = x * this.currentLevel + y;
        var index2 = this.currentBlock_x * this.currentLevel + this.currentBlock_y;
        var v = this.currentOrder[index1];
        this.currentOrder[index1] = this.currentOrder[index2];
        this.currentOrder[index2] = v;
    }

判断方法judege也比较简单,直接看currentorder数组是否等于0,1,2,...,8。

public judge(){
        var t = 0;
        var i = 0;
        for(i = 0;i

剩下的也就是加入开始,结束界面,并添加监听器而已了。

开始界面是自定义的皮肤界面,egret中的皮肤机制,有点类似于上学期学的android studio,主要都是将ui界面同逻辑部分分离,减少耦合。

还有许多优化,比如图片可以不用利用ps先分割,可以在代码里利用drawtotexture方法来进行裁切等。

拼图游戏源码:https://github.com/1998y12/PuzzleGame

下载地址:https://download.csdn.net/download/qq_41508508/10626746

你可能感兴趣的:(egret,egret,拼图,小游戏)