我正在制作一个角色在不同的房间里走动的游戏,但我想让它不要穿过墙壁。我尝试制作一个障碍符号来阻止它,但由于四个墙围住了角色,hitTestObject每次都返回true,而不仅仅是当它碰到墙壁的坚固部分时。简单地使用hero.x< 0是角色可以装备的物品,使英雄的符号延伸到0以下。所有符号都已调整大小,所以我不能只在英雄的符号中获得符号的宽度。有什么想法可以更好地检测碰撞?可能是hitTestPoint,但不确定如果没有大量的测试点,它将如何工作。 。
答案 0 :(得分:0)
答案 1 :(得分:0)
这是一个快速演示,展示了我在评论中提到的想法:
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文件的文档类以运行代码,或尝试this 另请查看adobe网站上的maze tutorial