Android 射击游戏。强大的敌人模式以实现复杂的群体行为

我正在为Android开发一款类似于《伊卡洛斯》的街机射击游戏。我面临的问题是,创建敌人移动和射击模式的过程相当困难。目前,我已经创建了两个抽象类EnemyShip和FlightPath,分别是每个不同的敌人和移动模式的基类。当World被创建时,它会实例化一个LevelManager,该管理器以以下形式存储关卡信息:

waveInfos.add(new WaveInfo(3, 3f)); // new WaveInfo(NumberOfGroups, spawn interval)enemyGroups.add(new EnemyGroup(8, EnemyGroup.TYPE_SCOUT_SHIP, EnemyGroup.F_PATH_INVADERS));enemyGroups.add(new EnemyGroup(1, EnemyGroup.TYPE_QUAD_SPHERE, EnemyGroup.F_PATH_QUAD_SPHERE_L, World.BLACK));enemyGroups.add(new EnemyGroup(8, EnemyGroup.TYPE_SCOUT_SHIP, EnemyGroup.F_PATH_INVADERS));// new EnemyGroup(NumberOfEnemies, EnemyType, FlightPathType)// new EnemyGroup(NumberOfEnemies, EnemyType, FlightPathType, ShipColour)waveInfos.add(new WaveInfo(2, 0.33f));enemyGroups.add(new EnemyGroup(1, EnemyGroup.TYPE_QUAD_SPHERE, EnemyGroup.F_PATH_QUAD_SPHERE_L, World.WHITE));enemyGroups.add(new EnemyGroup(1, EnemyGroup.TYPE_QUAD_SPHERE, EnemyGroup.F_PATH_QUAD_SPHERE_R, World.WHITE));totalWaves = waveInfos.size();

关卡被分成一波波的敌人群,目前EnemyGroup类负责实例化,添加指定的FlightPath到新创建的敌人,并将该敌人传递到LevelManager的ArrayList中暂存,直到在需要的时间生成到世界中。

一旦生成,FlightPath组件就会接管并开始根据它自己的状态时间(stateTime)发布指令,由于每个FlightPath都有一个指向其EnemyShip所有者的引用字段,它可以访问它所控制的飞船的功能和成员变量。

EnemyShip类有一些简便的指令函数,如moveTo(float x, float y, float duration)和shoot(),但即使有这些函数,FlightPath的派生类仍然难以创建,尤其是当我希望同一组中的不同敌人有略微不同的路径和略微不同的到达时间时。

我在FlightPath中创建了一些字段来跟踪关键帧(keyFrames):

public int currentKeyFrame = 0;public int totalKeyFrames;public KeyFrame[] keyFrames; // Stores duration of instruction to be done, the spreadTime, totalFrameTime and enemyIntervalTimepublic int shipNumber; // Stores which ship out of group this FlightPath is attached topublic int totalShips; // Stores total number of ships in this EnemyShip's grouppublic float stateTime = 0;

KeyFrame.spreadTime是我尝试控制组中第一个敌人开始移动/射击与最后一个敌人之间的时间间隔的方法。

KeyFrame.totalFrameTime = KeyFrame.duration + KeyFrame.spreadTime

KeyFrame.enemyIntervalTime = KeyFrame.spreadTime / 该组中的敌人数量

虽然这种设置对于非常简单的线性移动效果很好,但感觉相当繁琐。

感谢您阅读到这里。我的问题是,如何实现一个更流畅的模式控制,使复杂的移动无需大量的if()语句来检查组中其他敌人的行为等。

我希望我已经提供了足够的信息,让您了解敌人是如何处理的。我将向任何感兴趣的人提供任何源代码。提前感谢您对这个主题的任何见解。

@Marios Kalogerou

编辑:我找到了一篇非常适合我想要的系统描述的页面,但我不知道如何正确地实现它,特别是关于整体组关键帧的部分

http://www.yaldex.com/games-programming/0672323699_ch12lev1sec3.html


回答:

FlightPath不应该控制任何对象。它是一条路径,不是管理器。然而,它应该能够在给定任何关键帧或时间时提供坐标。例如:flightPath.getX(1200) -> 在1200毫秒时我应该在X坐标的哪里?

每个EnemyShip应该保持对FlightPath实例的拥有。EnemyShip每帧检查它在路径中的位置。

然后,EnemyGroup控制每个EnemyShip的生成。如果一个EnemyGroup中有8个EnemyShip,并且都拥有相同的FlightPath类型,那么您可以想象EnemyGroup会以大约500毫秒的间隔生成每艘飞船,以形成波浪。

最后,您将所有EnemyShip的坐标转换为相对于世界/屏幕坐标的坐标,传统上这些坐标在垂直方向上缓慢移动。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注