我正在尝试用 Actionscript 3 制作我的第一个游戏。这是一个简单的火炮游戏,左下角有一把枪,AI 飞过屏幕,你必须将其击落。现在,在分类射击游戏中,实现这一点的方法是从枪中发射子弹并使用 AI 影片剪辑对该子弹进行 HitTest ,或者简单地删除(或播放死亡动画)AI 影片剪辑。但问题就在这里。我不想做其中任何一个。我想展示一把射速快、因此没有子弹的枪。而且我也不希望玩家准确点击 AI 动画片段来摧毁它们(只需将枪/炮塔指向正确的方向就足够了)。这就是我尝试过的。
这张图片应该有助于描绘整个事情。
尝试将一条“线”连接到炮塔上并检查与 AI 剪辑的碰撞情况。由于线倾斜时的边界框问题,这显然失败了。
我尝试将多个小型影片剪辑放在线上并循环遍历它们,并检查是否与 AI 发生任何冲突。这种方法部分有效,但速度太慢,而且看起来不是“正确”的方法。
我画了两条假设的线。一个位于 p1 和 p2 之间,另一个连接 p3 和 p4(请参见上图)。 p3----p4 的长度 = AI.width 是一条穿过 AI MovieClip 中心的水平线。单击鼠标后,我检查这两条线之间是否有交点。现在,如果我在屏幕上有多个 AI,我再次需要遍历每个 AI,绘制一个新的 p3-----p4 并检查与 p1-----p2 的交集。
我现在正在使用方法 3,我有一种感觉,一旦我开始向游戏中添加更多内容,帧率就会受到影响。我确信应该有一种更简单/优化的方法来执行此操作(也许是非常简单的方法)。附上一些相关代码。
shipGame.as
var baseAI:BaseAI;
var AIList:Array= new Array;
public function shipGame():void{
trace("still connected!!");
/*
irrelevant code..
*/
stage.addEventListener(Event.ENTER_FRAME, updateGame);
var a:MovieClip = new MovieClip;
aiTimer = setInterval(StartAI, 2000);
}
public function StartAI():void {
baseAI = new BaseAI(this);
AIList.push(baseAI);
}
public function updateGame(event:Event):void {
/*
code to rotate the turret here..
*/
for (var i:int = 0; i < AIList.length; i++)
{
if (AIList[i].myx < 100) {
AIList[i].basicAI.parent.removeChild(AIList[i].basicAI);
AIList.splice(i, 1);
}
}
if (mouseDn) {
basicTurret.gotoAndPlay(2);// Fire animation
for (var j:int = 0; j < AIList.length; j++)
{
if ( intersection(AIList[j])) // intersection(bai:BaseAI) returns boolean. Works fine.
{
AIList[j].shot = true;
}
}
}
}
BaseAI.as
var main:shipGame;
var myy:Number;
var myy:Number;
public function BaseAI(doc:shipGame):void{
main = doc;
basicAI = new BasicAI(); // BasicAI is a movieClip in the library
main.addChild(basicAI);
basicAI.x = 400;
basicAI.y = Math.abs(Math.random() * (280)) + 20;
myy = basicAI.y;
basicAI.addEventListener(Event.ENTER_FRAME, keepMoving);
}
public function keepMoving(evt:Event):void {
basicAI.x -= 5;
myx = basicAI.x;
if (shot && alive) {
alive = false;
basicAI.gotoAndPlay(2);
}
}
最佳答案
您当前的所有方法本质上都依赖于 Flash 的渲染器来了解船只和子弹线的位置。但就您的情况而言,由于运动部件之间的几何关系相对简单,因此通过分析方式处理问题会快得多。
考虑一下这样的情况:一艘船恰好位于你的火炮火线上。在这种情况下,枪、船和屏幕底部形成一个直角三角形。如果我们将 theta
定义为枪与屏幕底部之间的角度,则以下公式成立:
tangent(theta) = ship.y / ship.x
其中x
和y
是从枪向右和向上测量的。现在您可以概括这一点并将其用于您的 HitTest 。当枪响时,首先找到theta
。然后,对于每艘船,您可以通过执行以下操作轻松确定船在垂直或水平方向上距火线的距离:
var theta = /*determine theta based on where the mouse was clicked*/
var tanTheta = tangent(theta);
for each (ship) {
var gunX = ship.y / tanTheta;
if ( abs(gunX - ship.x) < ship.width/2 ) {
// a hit occurred
}
}
这只是伪代码,但希望您能理解。不管怎样,我就是这样做的——这将比你在真正的 HitTest 中所做的任何事情都要快得多,并且对于所描述的情况,它应该同样有效。
关于flash - 优化 Actionscript 3 中的碰撞检测。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7885705/