我正在尝试在Actionscript 3中制作我的第一个游戏。它是一个简单的炮兵游戏,你在左下角有一把枪,AI飞过屏幕,你必须击落。现在,在一个分类射击游戏中,如何实现这一目标要么是通过从枪发射子弹并使用AI movieClip执行该子弹的命中测试,或者通过简单地移除(或播放死亡动画)AI动画片段。但这是问题所在。我不想做其中任何一个。我想展示一种射速很快的枪,因此没有子弹。而且我也不希望玩家完全点击AI动画片段来摧毁它们(只需指向正确方向的枪/炮塔就足够了)。所以这就是我的尝试。
这张图片可以帮助描绘整个事物。
尝试将“线”连接到炮塔并检查与AI夹子的碰撞。当线倾斜时,由于边界框问题,这显然失败了。
我尝试在线上放置多个微小的movieClip并在循环中迭代它们并检查与AI的任何碰撞。这种方法部分起作用,但它太慢了,似乎不是“正确的”方法。
我绘制了2条假设线。一个在p1和p2之间,另一个连接p3和p4(请参见上图)。 p3 ---- p4的lenght = AI.width是一条横穿AI MovieClip中心的水平线。在mouseClick上我检查这两行之间的任何交集。现在,如果我在屏幕上有多个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);
}
}
答案 0 :(得分:3)
您当前所有的方法基本上都依赖Flash的渲染器来了解船只和子弹线的位置。但在您的情况下,由于移动部件之间的几何关系相对简单,因此分析处理问题要快得多。
考虑船舶正好坐在枪的火线上的情况。在这种情况下,枪,船和屏幕底部形成一个直角三角形。如果我们将theta
定义为枪与屏幕底部之间的角度,则以下内容将成立:
tangent(theta) = ship.y / ship.x
其中x
和y
从枪中向右和向上测量。现在您可以对此进行概括并将其用于命中测试。当枪被射击时,首先找到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
}
}
这只是伪代码,但希望你能得到这个想法。无论如何,这就是我将如何做到这一点 - 这将比你使用实际命中测试所做的任何事情都要快得多,对于所描述的情况,它应该也能正常工作。