簡體   English   中英

牆體碰撞問題AS3

[英]Wall collision problems AS3

我正在制作一個游戲,其中一個角色在不同的房間里走來走去,但我想防止它穿過牆壁。 我嘗試制作一個障礙符號來阻止它,但是由於四堵牆圍住了角色,因此hitTestObject每次都會返回true,而不僅僅是擊中牆的實心部分。 我簡單地使用hero.x <0的問題是,角色可以裝備某些物品,這些物品會導致英雄的符號延伸到0以下。所有符號均已調整大小,因此我不能只獲得符號寬度英雄的象征。 有更好的檢測碰撞方法的想法嗎? 可能會命中TestTestPoint,但不是很確定如何在沒有大量測試點的情況下如何工作。

您可以使用迷宮游戲牆的邏輯。

它使用wall.hitTestPoint(character.x, character.y)

這是一個迷宮游戲的例子。

這是一個快速演示,展示了我在評論中提到的想法:

package {

    import flash.geom.Rectangle;

    import flash.geom.Point;

    import flash.utils.Proxy;

    import flash.external.ExternalInterface;

    import flash.text.TextField;

    import flash.ui.Keyboard;

    import flash.utils.Dictionary;

    import flash.events.KeyboardEvent;

    import flash.display.DisplayObject;

    import flash.events.Event;

    import flash.display.Sprite;

    public class HitTestShapeTest extends Sprite {



        private var player:Player;

        private var vx:Number = 0,vy:Number = 0;

        private var speed:Number = 2;

        private var previousValidPos:Point = new Point();

        private var maze:DisplayObject;

        private var keys:Dictionary = new Dictionary();

        private var t:TextField;

        public function HitTestShapeTest() {

            addEventListener(Event.ADDED_TO_STAGE,init);

        }

        private function init(e:Event):void{

            maze = addChild(new Maze());

            player = addChild(new Player()) as Player;

            player.x = stage.stageWidth * .5;

            player.y = stage.stageHeight * .5;

            previousValidPos.x = player.x;previousValidPos.y = player.y;

            stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);

            stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);

            this.addEventListener(Event.ENTER_FRAME,update);     

            t = addChild(new TextField()) as TextField;   t.text = "oi";

            ExternalInterface.call("alert('ready');");

        }

        private function onKeyDown(e:KeyboardEvent):void{

            keys[e.keyCode] = true;//this key is pressed, make that available for the update call

            t.text = ""+e.keyCode;

        }



        private function onKeyUp(e:KeyboardEvent):void{

            keys[e.keyCode] = null;//clear the hash map entry for the released key

            vx = vy = 0;

        }



        private function update(e:Event):void{

            //move player

            if(keys[Keyboard.LEFT] != undefined)  vx = -speed;

            if(keys[Keyboard.RIGHT] != undefined) vx =  speed;

            if(keys[Keyboard.UP] != undefined)    vy = -speed;

            if(keys[Keyboard.DOWN] != undefined)  vy =  speed;

            //update positions

            player.x += vx;

            player.y += vy;



            //get the boundary point in the direction of movement

            var bounds:Rectangle = player.getBounds(this);     //beg the character's bounds

            var testPoint:Point = new Point();
            //check which point is at the edge of the character in the direction of movement
            if(vx != 0 || vy != 0){

                if(vx < 0) testPoint.x = bounds.x;//left

                else       testPoint.x = bounds.x+bounds.width;//right

                if(vy < 0) testPoint.y = bounds.y;//top

                else       testPoint.y = bounds.y+bounds.height;//bottom

                if(vy == 0) testPoint.y = bounds.y + bounds.height * .5;//moving on x axis only, use the vertical centre on y 
                if(vx == 0) testPoint.x = bounds.x + bounds.width * .5;//moving on y axis only, use the vertical centre on x 
            }

            //check collisions

            var isHit:Boolean = maze.hitTestPoint(testPoint.x,testPoint.y,true);//check for collisions

            if(!isHit){//didn't hit anything, remember this valid position

                previousValidPos.x = player.x;

                previousValidPos.y = player.y;

            }else{//restore position because we just hit something

                player.x = previousValidPos.x;

                player.y = previousValidPos.y;

            }

            //debug graphics

            graphics.clear();

            graphics.lineStyle(1,0x990000);

            graphics.drawRect(bounds.x,bounds.y,bounds.width,bounds.height);

            graphics.drawCircle(testPoint.x,testPoint.y,5);

            player.alpha = isHit ? .5 : 1;

        }

    }

}
import flash.display.BlendMode;

import flash.events.Event;

import flash.display.Shape;

class Player extends Shape{

    public function Player(){

        init(); 

    }

    private function init():void{

        graphics.lineStyle(10);

        graphics.drawCircle(0,0,10);

        graphics.moveTo(0,10);

        graphics.lineTo(0,20);

        graphics.lineTo(-10,20);

        graphics.moveTo(0,20);

        graphics.lineTo(10,20);

        graphics.moveTo(0,20);

        graphics.lineTo(0,30);

        graphics.lineTo(-10,40);

        graphics.moveTo(0,30);

        graphics.lineTo(10,40);
        blendMode = BlendMode.LAYER;
    }

}

class Maze extends Shape{

    private var size:Number = 50;

    public function Maze(){

        addEventListener(Event.ADDED_TO_STAGE,init);

    }

    private function init(e:Event):void{

        graphics.beginFill(0);

        graphics.lineTo(stage.stageWidth,0);

        graphics.lineTo(stage.stageWidth,size);

        graphics.lineTo(size*4,size);

        graphics.lineTo(size*4,size*3);

        graphics.lineTo(size*3,size*3);

        graphics.lineTo(size*3,size);

        graphics.lineTo(size,size);

        graphics.lineTo(size,size*8);

        graphics.lineTo(stage.stageWidth,size*8);

        graphics.lineTo(stage.stageWidth,stage.stageHeight);

        graphics.lineTo(0,stage.stageHeight);

        graphics.lineTo(0,0);

        graphics.endFill();

    }

}

將其另存為HitTestShapeTest.as並將其設置為新的.fla文件的文檔類以運行代碼,或嘗試執行此操作。另請參閱Adobe網站上的迷宮教程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM