我正在为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的坐标转换为相对于世界/屏幕坐标的坐标,传统上这些坐标在垂直方向上缓慢移动。