我在ActionScript3中制作了一种太空入侵者类型的游戏,我创建了一种从舞台上移除子弹的方法:
private function removeBullet(bb:Bullet = null):void {
var leng:uint = bulletVector.length;
if (bb)
{
for (var i:uint = 0; i < leng; i++)
{
if (bulletVector[i] == bb)
{
bulletVector.splice(i, 1);
break;
}
}
// Remove bullet from the Display List
removeChild(bb);
// Return the bullet to its object pool
bulletPool.returnObject(bb);
} else {
// Remove all existing bullets currently on screen
for (var j:uint = 0; j < leng; j++)
{
var bullet:Bullet = bulletVector[j];
removeChild(bullet);
bulletPool.returnObject(bullet);
}
bulletVector.splice(0, leng);
}
}
bulletVector 是一个Vector,其中包含当前显示的所有项目符号, bulletPool 是一个对象池类,用于在项目未在舞台上使用时返回项目符号池了。如果没有参数传递给方法,该方法将删除屏幕上的所有项目符号。
现在,我有一个相同的方法从屏幕上删除敌人:
private function removeEnemy(ee:Enemy = null):void {
var leng:uint = enemyVector.length;
if (ee)
{
for (var i:uint = 0; i < leng; i++)
{
if (enemyVector[i] == ee)
{
enemyVector.splice(i, 1);
break;
}
}
// Remove enemy from the Display List
removeChild(ee);
// Return the enemy to its object pool
enemyPool.returnObject(ee);
} else {
// Remove all existing enemies currently on screen
for (var j:uint = 0; j < leng; j++)
{
var enemy:Enemy = enemyVector[j];
removeChild(enemy);
enemyPool.returnObject(enemy);
}
enemyVector.splice(0, leng);
}
}
“子弹”和“敌人”都是扩展Sprite类的类。我的问题是:是否有可能将这两种方法合并为一个处理子弹和敌人的方法,具体取决于哪一个作为参数传递?
[编辑] 我的想法是这样的:(伪代码)
if (ee is Bullet)
{
var s:String = "bullet"
} else if (ee is Enemy)
{
var s:String = "enemy"
}
eval[s+"Vector"].splice(i, 1);
eval[s+"Pool"].returnObject(ee);
[/编辑]
换句话说,是否有一种语法允许访问Vector和/或Classes(对象池)而不必将其名称硬编码到方法中?
提前感谢您的帮助。
答案 0 :(得分:3)
这样的事可能对你有用......
private function removeItem(ee:* = null):void {
if (ee) {
//ee has a value
if (ee is Bullet) {
//remove bullet
} else if (ee is Enemy) {
//remove Enemy
}
} else {
//ee is null so remove all bullets and emenies
}
}
答案 1 :(得分:1)
简答:使用Array代替Vector来获取敌人和子弹列表。
创建一个带有3个参数的方法:list:Array和item:Sprite和pool:Array然后从指定的Array中删除该项,而不是“硬编码”实例,最后用两个相同的方法。
/**
* Removes item from specified list
* @param list
* @param item
*/
public function removeItem( list:Array, item:Sprite, pool:Array ):void
{
// implement here
}
长答案:
这很棘手,因为你正在使用向量。
我的第一个冲动是创建一个带有2个参数,列表和项目的泛型函数:(暂时让我们忽略池)
/**
* Removes item from specified list
* @param list
* @param item
*/
public function removeItem( list:Vector.<Sprite>, item:Sprite ):void
{
// implement here
}
但我猜你的子弹列表是Vector类型。你的列表敌人属于Vector。,对吧?
所以即使Bullet和Enemy都扩展了Sprite,如果你使用Vector的实例调用这个方法,例如:
var list:Vector.<Bullet>;
var item:Bullet; // extends Sprite
removeItem( list, item );
这不会编译。你会得到:
Error: Implicit coercion of a value of type __AS3__.vec:Vector.<Bullet> to an unrelated type __AS3__.vec:Vector.<flash.display:Sprite>.
单独注意
你的removeItem方法似乎做了两件事。删除指定的项目和/或删除所有项目。为了安全和清晰,我会将这些分开。每种方法只应执行一项操作。
此外,使用此设置,如果在运行时您对项目的引用意外为空,则最终将从列表中删除所有项目。可能不是你想要的。
我会声明两个函数:
function removeItem(...)
function removeAllItems(...)
答案 2 :(得分:0)
第二个想法,我现在更喜欢使用Arrays进行软打字,因为它不会强迫你更改应用程序的其余部分(例如,你可以保留你的向量)
public function removeItem(list:*, pool:ObjectPool, item:Sprite):void
{
// remove item from specified list
var indx:int = list.indexOf(item);
if (indx >= 0)
{
list.splice(indx, 1);
}
// remove display object from display list
if (this.contains(item))
{
this.removeChild(item);
}
// return itemitem to specified pool
pool.returnObject(item);
}
请注意,您不需要迭代Vector以找出要删除的索引(拼接)。您可以改用indexOf方法。