arrays - 谁能帮我解决这个项目中的错误参数 hitTestObject 必须为非空?
问题描述
我对 as3 有点陌生,我正在尝试为我的教育制作简单的射击游戏。首先,我知道还有其他类似的问题,但我不知道我的问题是什么!因此,如果有人可以提供帮助,我会很高兴:)) 提前谢谢
当我点击大按钮时,我的船左右移动并发射子弹。敌舰(dusman/dusmanlar)也下降了。所以问题是我无法弄清楚一些子弹(mermi / mermiler)击中并用那颗子弹本身摧毁了一些敌舰,但大多数时候子弹只是穿过敌舰而没有任何反应。当然 animate 给出了错误 Parameter hitTestObject must be non-null on this project!
我在这里做错了什么?
var mermiler: Array = new Array(); //mermiler means bullets
var dusmanlar: Array = new Array(); // dusmanlar means enemy ships
var game_speed: int = 20;
var game_timer: int = 0;
var oyunHiz: int = 8; //bullet speed
var skor: Number = 0;
btn.addEventListener(MouseEvent.CLICK, ates);
function ates(event: MouseEvent): void {
//whenever the mouse is pressed add the Bullet from the library to the screen
var mermi: Mermi = new Mermi();
mermi.x = gemi.x;
mermi.y = gemi.y - (gemi.height / 2);
addChild(mermi);
//add it to the bullet array so we can loop through to move and hit test
mermiler.push(mermi);
}
addEventListener(Event.ENTER_FRAME, basla);
function basla(event: Event): void {
game_timer++;
if (game_timer >= game_speed) {
var dusman: Dusman = new Dusman();
dusman.x = Math.random() * 640 + 10;
dusman.y = Math.random() * 100 - 120;
dusman.xspeed = (Math.random() * 15) - 10;
dusman.yspeed = (Math.random() * 5) + 10;
addChild(dusman);
dusmanlar.push(dusman);
game_timer = 0;
}
yaz.text = String(skor);
gemi.x = mouseX;
gemi.y = 750;
//move all enemy ships down the screen
for (i = 0; i < dusmanlar.length; i++) {
//move enemy ships
dusmanlar[i].y += dusmanlar[i].yspeed;
dusmanlar[i].x += dusmanlar[i].xspeed;
//bounce off sides
if (dusmanlar[i].x >= 640 || dusmanlar[i].x <= 0) {
dusmanlar[i].xspeed = -dusmanlar[i].xspeed;
}
//if reach bottom remove ship
if (dusmanlar[i].y >= 860) {
removeChild(dusmanlar[i]);
dusmanlar[i] = null;
dusmanlar.splice(i, 1);
break;
}
}
//move all the bullets on the screen up
for (var i: int = 0; i < mermiler.length; i++) {
//move bullets
mermiler[i].y -= 20;
//if bullets got of screen
if (mermiler[i].y <= 0) {
removeChild(mermiler[i]);
mermiler[i] = null;
mermiler.splice(i, 1);
break;
}
}
//test if any bullets have hit any ships
for (var j: int = 0; j < dusmanlar.length; j++) {
if (mermiler != null && dusmanlar[j].hitTestObject(mermiler[i])) {
if (mermiler.length != 0 && dusmanlar[j] != null && mermiler[i].hitTestObject(dusmanlar[j])) {
removeChild(dusmanlar[j]);
dusmanlar[j] = null;
dusmanlar.splice(j, 1);
removeChild(mermiler[i]);
mermiler[i] = null;
mermiler.splice(i, 1);
skor++
break;
}
}
}
}
解决方案
你做的很多事情都是错误的。
首先,当您打算浏览一个数组以从中删除一个或多个元素时,请使用后向循环而不是前向循环,因为当您使用 Array.splice(...)时,数组的其余部分会向左移动一个位置而您会错过一个对象。我在这个答案中解释了原理。你也不需要打破循环。
// Move all enemy ships down the screen.
for (i = dusmanlar.length - 1; i >= 0; i--)
{
// Get a ship to work with.
var aShip:Dusman = dusmanlar[i];
// Move the ship.
aShip.y += aShip.yspeed;
aShip.x += aShip.xspeed;
if (aShip.y > 860)
{
// Remove the ship if it reached the bottom.
removeChild(aShip);
dusmanlar.splice(i, 1);
}
else if (aShip.x > 640)
{
// Bounce the ship off right.
aShip.xspeed = -Math.abs(aShip.xspeed);
}
else if (aShip.x < 0)
{
// Bounce the ship off left.
aShip.xspeed = Math.abs(aShip.xspeed);
}
}
其次,您需要对许多对象与许多对象进行适当的检查。最直接的方法是检查每一个可能的碰撞。
var aShip:Dusman;
var aBullet:Mermi;
// Prepare lists for objects to remove.
var deadShips:Array = new Array;
var deadBullets:Array = new Array;
// Iterate over all enemy ships, presently alive.
for each (aShip in dusmanlar)
{
// Iterate over all flying bullets in an inner loop.
for each (aBullet in mermiler)
{
// As both ship and bullet are listed in the respective Arrays,
// you don't need to check if they are not "null" or whatever.
if (aShip.hitTestObject(aBullet))
{
// Add them for deletion. But only once.
if (deadShips.indexOf(aShip) < 0)
{
deadShips.push(aShip);
}
// The bullets are iterated over in an inner loop,
// you can kill many ships with the single bullet,
// if it hits these ships at the same time.
// Also, a single ship can take several bullets at once,
// again, if they all hit simultaneously.
if (deadBullets.indexOf(aBullet) < 0)
{
deadBullets.push(aBullet);
}
}
}
}
// Now you have a list of killed ships and dead bullets.
// It's time to remove them.
var anIndex:int;
for each (aShip in deadShips)
{
anIndex = dusmanlar.indexOf(aShip);
// Sanity check.
if (anIndex > 0)
{
dusmanlar.splice(anIndex, 1);
}
// Another sanity check.
if (aShip.parent == this)
{
removeChild(aShip);
}
}
for each (aBullet in deadBullets)
{
anIndex = mermiler.indexOf(aBullet);
// Sanity check.
if (anIndex > 0)
{
mermiler.splice(anIndex, 1);
}
// Another sanity check.
if (aBullet.parent == this)
{
removeChild(aBullet);
}
}
推荐阅读
- maven - 使用自定义根文件夹名称生成 Maven 原型
- amazon-dynamodb - Dynamo DB - 仅从表列中获取唯一值
- gitlab-ci - 在管道期间删除的文件
- postgresql - 如何在 postgresql 中的 JSONB 列上添加 SQLAlchemy BTREE 索引
- python - 使用 Python OpenCV 测量已知圆的精确位置
- docker - 通过 TLS 连接到 OPENLDAP:找不到证书
- java - 在方法内更改应该在方法外的字符串
- linux - pci 驱动程序函数是否表示为 PCI 的 driver_data 对象中的函数号
- automation - 使用 QuerySerge 在 ALM 测试用例步骤级别附加屏幕截图
- reactjs - 我想在 React Native 中将 My Screen 修改为 Drawer