egret 碰撞检测

在游戏设计中,对鼠标与舞台的碰撞检测也是经常用到的,今天的碰撞检测主要用到hitTestPoint()函数。

一、碰撞的类型

(1)像素碰撞

什么是像素碰撞?通俗的讲就是在一张图中,它的不透明部分被点击时是可以被检测到的,

反之当透明部分被点击时,不能被检测到。

(2)矩形碰撞

什么是矩形碰撞?与像素碰撞相比矩形碰撞就没有那么的精确。就是在一张图中,当发生点击事件时,不区别图片的透明与非透明部分,只要图片被点击就会被检测到。

二、hitTestPoint(?,?,?)

①首先需要明白hitTestPoint(x?,y?,?)中的前两个参数代表鼠标点击的那一个点的x坐标和y坐标,检测该点是否与索要检测的物体重合,如果重合,则发生碰撞,否则就没有发生碰撞;
 ②第三个参数是对碰撞类型的选择,如果是true,则碰撞类型为像素碰撞;false为矩形碰撞。   

三、关键代码实现区别

(1)像素碰撞

this.Road.hitTestPoint(e.localX,e.localY,true)

(2)矩形碰撞

this.Road.hitTestPoint(e.localX,e.localY,false)

四、综合代码

(代码中用到的图片在文档最后,可自取使用,熟悉后更换图片试试)


class Main extends egret.DisplayObjectContainer {

    public constructor(){
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE,this.onAddToStage,this);
       
    }

    private onAddToStage(event:egret.Event){
        RES.loadConfig("resource/default.res.json","resource/");
        RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE,this.onGroupComplete,this);
    }

    private onGroupComplete(event:RES.ResourceEvent){
        RES.loadGroup("hit");
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE,this.onConfigComplete,this);

    }

    private Road:egret.Bitmap;

    private onConfigComplete(){
       //被检测图片
       this.Road = new egret.Bitmap();
       this.Road.texture = RES.getRes("Btn_Road_png");
       this.Road.y = 150;
       this.addChild(this.Road);
       this.stage.addEventListener(egret.TouchEvent.TOUCH_TAP,this.hitTest,this);
       this.changeState();

       //原图对比
       let Road2 = new egret.Bitmap();
       Road2.texture = RES.getRes("Btn_Road_png");
       Road2.y = 150;
       Road2.x = 300;
       this.addChild(Road2);

       let text1 = new egret.TextField();
       text1.text = "原图:";
       text1.textColor = 0x0000ff;
       text1.x = 300;
       text1.y = 120;
       this.addChild(text1);
    

    }
    
    private touchInfo:Array<string> = ["像素碰撞","矩形碰撞"];
    private count:number = 0;
   
    private text0:egret.TextField;
    
    // 切换碰撞状态。比如:由矩形碰撞到像素碰撞,或者反过来
    private changeState(){
        

        this.text0 = new egret.TextField();
        this.text0.text = "点击文字切换碰撞状态:" + this.touchInfo[this.count] + "\n"+ "点击蓝色方格中的图形和空白部分测试并观察现象";
        this.text0.background = true;
        this.text0.backgroundColor =  0xbcbcbc;
        this.addChild(this.text0); 
        this.drawText();
        this.DrawRect();
    }
    
    private DrawRect(){
        
        let rect =  new egret.Sprite;
        rect.graphics.lineStyle(2,0x0000ff);
        rect.graphics.beginFill(0xffffff,0);
        rect.graphics.drawRect(0,150,174,132);

        rect.graphics.endFill();
        this.addChild(rect);
    }

    private infoText: egret.TextField;

    private drawText() {
        this.infoText = new egret.TextField();
        this.infoText.y = 90;
        this.infoText.text = "isHit:";
        this.addChild(this.infoText);
    }
    
    private AmountHit:number = 0;//记录鼠标点击次数
    //关键代码
    private touch:Boolean;
    private hitTest(e:egret.TouchEvent){
        
        this.infoText.text = "isHit:";
     

        //文字被点击时状态的切换
        let text0Hit = this.text0.hitTestPoint(e.localX,e.localY,true);
        if(text0Hit == true){
             this.AmountHit++;
             console.log(this.AmountHit);
             let n = this.AmountHit % 2;
             if(n == 0){
                 this.count = 0;
                 this.text0.text = "点击文字切换碰撞状态:" + this.touchInfo[this.count] + "\n"+ "点击蓝色方格中的图形和空白部分测试并观察现象";
             }
             else{
                 this.count = 1;
                 this.text0.text = "点击文字切换碰撞状态:" + this.touchInfo[this.count] + "\n"+ "点击蓝色方格中的图形和空白部分测试并观察现象";
             }
        }

       //只需要理解下面这一部分即可,分清楚hitTestPoint中true和false的区别
       /**
        * ①首先需要明白hitTestPoint(x?,y?,?)中的前两个参数代表鼠标点击的坐标的x轴和y轴,
           也就是在舞台中的某一个点,检测该点是否与索要检测的物体重合,如何重合,则发生碰撞,否则则没有发生碰撞;
          ②第三个参数是对碰撞类型的选择,如果是true,则碰撞类型为像素碰撞;false为矩形碰撞。
               什么是像素碰撞?
                  像素碰撞检测,是判断显示对象的图案(非透明区域)是否与一点相交。也就是说像素碰撞只检测图中不为透明的区域,对于透明区域并不进行检测。
               什么矩形碰撞?
                  就是只要放出一张图,该图中的透明与非透明区域均被检测,不存在区别。   
        */
        if(e.localY >= 150){
            if(this.count == 0){
                //像素碰撞
                this.touch = this.Road.hitTestPoint(e.localX,e.localY,true);       
       
                this.infoText.text = "isHit:" + this.touch;
            }

            else{
                //矩形碰撞
                this.touch = this.Road.hitTestPoint(e.localX,e.localY,false);       
       
                this.infoText.text = "isHit:" + this.touch;
            }
        }

    }

    
}

代码中使用的图片:

《egret 碰撞检测》

注:下载完图片后,将图片名称改为Btn_Road,并将图片放到你自己设置的一个RES资源组中,如果使用的资源组的名字与代码中的资源组名字不一样,请将代码中资源组的名字改为你的资源组名。如果有不熟悉RES资源加载的请查看文章egret 如何解决RES加载了不存在或空的资源组_倥谷的博客-CSDN博客

基础部分更新完后,后续会推出一个制作一个完整的小游戏的专题文章。

《egret 碰撞检测》《egret 碰撞检测》  

 

 

    原文作者:倥谷
    原文地址: https://blog.csdn.net/qq_52702554/article/details/124476943
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞