PageRenderTime 67ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/Festaxian/src/fester/Festaxian/GalaxianGameEngine.java

https://github.com/bobstoned/Android
Java | 993 lines | 808 code | 107 blank | 78 comment | 147 complexity | 04e7fe8a81fc60053213d93ad6fd6fe3 MD5 | raw file
  1. package fester.Festaxian;
  2. import android.content.Context;
  3. import android.content.SharedPreferences;
  4. import android.graphics.*;
  5. import android.media.MediaPlayer;
  6. import android.preference.PreferenceManager;
  7. import android.view.KeyEvent;
  8. import android.view.MotionEvent;
  9. import com.example.R;
  10. import java.util.Random;
  11. /**
  12. * Created with IntelliJ IDEA.
  13. * User: RLester
  14. * Date: 23/05/12
  15. * Time: 12:13
  16. * To change this template use File | Settings | File Templates.
  17. */
  18. public class GalaxianGameEngine {
  19. public SpriteSheet sheet = new SpriteSheet();
  20. private SpriteSheet playerSpriteSheet = new SpriteSheet();
  21. private SpriteSheet missileSheet = new SpriteSheet();
  22. private SpriteSheet scoreSheet = new SpriteSheet();
  23. public Bitmap sheetBitmap ;
  24. private Bitmap playerSheetBitmap;
  25. private Bitmap missileSheetBitmap;
  26. private Bitmap scoreSheetBitmap;
  27. private Bitmap buttonBitmap;
  28. private Bitmap livesLeftBitmap;
  29. private int spriteCount = 150;
  30. private Galaxian[] galaxians = new Galaxian[spriteCount];
  31. private GalaxianAttackGroup galaxianAttackGroup1;
  32. private GalaxianAttackGroup galaxianAttackGroup2;
  33. private Sprite playerShip = new Sprite();
  34. private Sprite playerMissile = new Sprite();
  35. private int playerPosMissileFire = 0;
  36. public Rect gameArea = new Rect(0,100,450,800);
  37. private Rect galArea = new Rect(0,150,450,400);
  38. private int screenWidth = 1024;
  39. private int screenHeight = 600;
  40. public double pixelSize = 0.5;
  41. private StarField starField ;
  42. private int score = 0;
  43. private int maxPlayerShips = 3;
  44. private int curPlayerShip = 1;
  45. private int curFleetNo = 1;
  46. private SpriteFormation formation = new SpriteFormation(gameArea, 10, 20, 2);
  47. // Horizontal Direction of player movement
  48. private int dx = 0;
  49. private int buttonWidth = 100;
  50. private Context context;
  51. private MediaPlayer mediaPlayer[] = new MediaPlayer[6];
  52. private boolean isDebugMode = false;
  53. private String graphicsStyle = "1";
  54. private boolean showControls = false;
  55. private Typeface retroFont ;
  56. private Paint fontPaint;
  57. private Paint playerNoPaint;
  58. private SpriteTimer waveIntervalTimer = new SpriteTimer();
  59. private SpriteTimer playerDeathPauseTimer = new SpriteTimer();
  60. private SpriteTimer newPlayerReadyTimer = new SpriteTimer();
  61. private FlashingText playerReadyText = new FlashingText();
  62. // Set to true at the start of a game
  63. public boolean GamesStart = true;
  64. public boolean GameOver = false;
  65. public void InitSounds() {
  66. mediaPlayer[0] = MediaPlayer.create(context, R.raw.galaxian_insert_coin) ;
  67. mediaPlayer[1] = MediaPlayer.create(context, R.raw.galaxian_background_hum) ;
  68. mediaPlayer[1].setLooping(true);
  69. mediaPlayer[2] = MediaPlayer.create(context, R.raw.galaxian_player_fire) ;
  70. mediaPlayer[3] = MediaPlayer.create(context, R.raw.galaxian_alien_base_death) ;
  71. mediaPlayer[4] = MediaPlayer.create(context, R.raw.galaxian_alien_death) ;
  72. mediaPlayer[5] = MediaPlayer.create(context, R.raw.galaxian_player_death) ;
  73. }
  74. public void PlaySound(int soundID) {
  75. mediaPlayer[soundID-1].seekTo(0);
  76. mediaPlayer[soundID-1].start();
  77. }
  78. public void PauseSound(int soundID) {
  79. mediaPlayer[soundID-1].pause();
  80. }
  81. public void ResumeSound(int soundID) {
  82. mediaPlayer[soundID-1].start();
  83. }
  84. public void init(Context context)
  85. {
  86. SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
  87. graphicsStyle = sharedPref.getString("pref_graphics_style", "");
  88. showControls = sharedPref.getBoolean("pref_show_controls", true);
  89. isDebugMode = sharedPref.getBoolean("pref_debug_mode", false);
  90. this.context = context;
  91. retroFont = Typeface.createFromAsset(context.getAssets(), "Galaxian.ttf");
  92. fontPaint = new Paint();
  93. fontPaint.setColor(Color.RED);
  94. fontPaint.setStyle(Paint.Style.FILL);
  95. fontPaint.setTypeface(retroFont);
  96. fontPaint.setTextSize((int)(pixelSize * 10));
  97. playerNoPaint = new Paint();
  98. playerNoPaint.setColor(Color.WHITE);
  99. playerNoPaint.setStyle(Paint.Style.FILL);
  100. playerNoPaint.setTypeface(retroFont);
  101. playerNoPaint.setTextSize((int)(pixelSize * 10));
  102. // Speed settings for each type of object
  103. int starFieldDelay = 60;
  104. double starFieldMoveStep = 0.5;
  105. int playMissileDelay = 6;
  106. long galxAttackDelay = 30;
  107. double galxAttackStep = 1;
  108. double playMissileStep = pixelSize * 1.2;
  109. starField = new StarField(starFieldDelay, starFieldMoveStep, pixelSize);
  110. starField.setBounds(gameArea);
  111. starField.setPixelSize(pixelSize);
  112. starField.setCount(100);
  113. playerSpriteSheet.topLeft = new Point(0,0);
  114. playerSpriteSheet.gapX = 0;
  115. playerSpriteSheet.gapY = 0;
  116. formation.pixelSize = pixelSize;
  117. missileSheet.topLeft = new Point(0,0);
  118. missileSheet.gapX = 0;
  119. missileSheet.gapY = 0;
  120. missileSheet.spriteHeight = 2;
  121. missileSheet.spriteWidth = 1;
  122. scoreSheet.topLeft = new Point(0,0);
  123. scoreSheet.gapX =0;
  124. scoreSheet.gapY =0;
  125. scoreSheet.spriteHeight = 12;
  126. scoreSheet.spriteWidth = 12;
  127. BitmapFactory.Options options = new BitmapFactory.Options();
  128. options.inScaled = false;
  129. options.inDensity = 100;
  130. if (graphicsStyle.equals("1")) {
  131. // Define the sprite sheet for the classic galaxian graphics
  132. sheet.gapX = 8;
  133. sheet.gapY = 8;
  134. sheet.topLeft = new Point(111,0);
  135. sheet.spriteHeight = 12;
  136. sheet.spriteWidth = 12;
  137. sheetBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.galaxian_sheet, options) ;
  138. playerSpriteSheet.spriteHeight = 32;
  139. playerSpriteSheet.spriteWidth = 32;
  140. playerSheetBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.playership, options) ;
  141. }
  142. else {
  143. // Define the sprite sheet for the modern galaxian graphics
  144. sheet.gapX = 0;
  145. sheet.gapY = 0;
  146. sheet.topLeft = new Point(0,0);
  147. sheet.spriteHeight = 80;
  148. sheet.spriteWidth = 80;
  149. sheetBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.galaxian_sheet_modern, options) ;
  150. playerSpriteSheet.spriteHeight = 150;
  151. playerSpriteSheet.spriteWidth = 150;
  152. playerSheetBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.playership_modern, options) ;
  153. }
  154. missileSheetBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.missile_sheet, options);
  155. scoreSheetBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.score_sheet, options);
  156. buttonBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arcade_button, options);
  157. livesLeftBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.livesleft, options);
  158. // Define user ship sprite
  159. CreatePlayerShip();
  160. CreateGalaxians(galxAttackDelay, galxAttackStep);
  161. CreateMissile(playMissileDelay, playMissileStep);
  162. InitSounds();
  163. curFleetNo= 1;
  164. }
  165. public void StartNewGame() {
  166. GamesStart = true;
  167. GameOver = false;
  168. curPlayerShip = 1;
  169. newPlayerReadyTimer.delay = 3000;
  170. newPlayerReadyTimer.Enabled = true;
  171. newPlayerReadyTimer.Reset();
  172. }
  173. // Create the two sets of attack groups
  174. // Consisting of one base ship(yellow) and two wing men (red)
  175. private void CreateGalaxianAttackGroups() {
  176. galaxianAttackGroup1 = new GalaxianAttackGroup();
  177. galaxianAttackGroup2 = new GalaxianAttackGroup();
  178. }
  179. // The game area is dictated by the physical device screen
  180. // dimensions. Obviously there are a set of very common
  181. // screen resolutions. These are treated as special cases
  182. // with very specific settings.
  183. public void SetScreenDimensions(int width, int height) {
  184. boolean specificSize = false;
  185. screenWidth = width;
  186. screenHeight = height;
  187. galArea.right = width;
  188. galArea.bottom = height;
  189. gameArea = new Rect();
  190. gameArea.left = 0;
  191. gameArea.top = 0;
  192. gameArea.right = width;
  193. gameArea.bottom = height-10;
  194. if (height == 320) {
  195. specificSize = true;
  196. formation.gap = 2;
  197. pixelSize = 0.5;
  198. buttonWidth = 40;
  199. }
  200. // Nexus 10 - Pixel overload!
  201. if (height == 1504 && width == 2560) {
  202. specificSize = true;
  203. formation.gap = 3;
  204. pixelSize = 5;
  205. buttonWidth = 300;
  206. gameArea.left = 700;
  207. gameArea.top = 0;
  208. gameArea.right = 1960;
  209. gameArea.bottom = 1350;
  210. galArea.left = gameArea.left;
  211. galArea.top = 200;
  212. galArea.right = gameArea.right;
  213. galArea.bottom = gameArea.bottom;
  214. }
  215. // Nexus 10 - Pixel overload!
  216. if (height > 2400 && width > 1500) {
  217. specificSize = true;
  218. formation.gap = 4;
  219. //pixelSize = 2.3;
  220. pixelSize = 5;
  221. buttonWidth = 300;
  222. gameArea.left = 0;
  223. gameArea.top = 0;
  224. gameArea.right = width;
  225. gameArea.bottom = 1500;
  226. galArea.left = gameArea.left;
  227. galArea.top = 100;
  228. galArea.right = gameArea.right;
  229. galArea.bottom = gameArea.bottom;
  230. }
  231. // HTC DEsire etc (800 x 480)
  232. if ( (height >= 700 && height<= 800) && width == 480) {
  233. specificSize = true;
  234. formation.gap = 1;
  235. pixelSize = 2.2;
  236. //pixelSize = 4;
  237. buttonWidth = 100;
  238. galArea.left = 0;
  239. galArea.right = 480;
  240. galArea.bottom = 550;
  241. galArea.top = 50;
  242. gameArea.left = 0;
  243. gameArea.top = 0;
  244. gameArea.right = 480;
  245. gameArea.bottom = 550;
  246. }
  247. if (height == 480 && (width >= 700 && width<= 800)) {
  248. specificSize = true;
  249. formation.gap = 2;
  250. pixelSize = 1.8;
  251. buttonWidth = 80;
  252. galArea.left = 200;
  253. galArea.right = 600;
  254. galArea.bottom = 400;
  255. galArea.top = 0;
  256. gameArea.left = 200;
  257. gameArea.top = 0;
  258. gameArea.right = 600;
  259. gameArea.bottom = height;
  260. }
  261. //ZTE Grand X v970m ( 960 x 540)
  262. if ( (height >= 900 && height<= 960) && width == 540) {
  263. specificSize = true;
  264. formation.gap = 1;
  265. pixelSize = 2.6;
  266. buttonWidth = 100;
  267. galArea.left = 0;
  268. galArea.right = 540;
  269. galArea.bottom = 710;
  270. galArea.top = 50;
  271. gameArea.left = 0;
  272. gameArea.top = 0;
  273. gameArea.right = 540;
  274. gameArea.bottom = 710;
  275. }
  276. if (height == 540 && (width >= 900 && width<= 960)) {
  277. specificSize = true;
  278. formation.gap = 2;
  279. pixelSize = 2.2;
  280. buttonWidth = 80;
  281. galArea.left = 280;
  282. galArea.right = 680;
  283. galArea.bottom = 460;
  284. galArea.top = 0;
  285. gameArea.left = 280;
  286. gameArea.top = 0;
  287. gameArea.right = 680;
  288. gameArea.bottom = height;
  289. }
  290. if (!specificSize) {
  291. if (height > width) {
  292. if (width >= 700 && width < 1025) {
  293. formation.gap = 12;
  294. pixelSize = 3;
  295. buttonWidth = 100;
  296. }
  297. if (width > 320 && width < 700) {
  298. formation.gap = 8;
  299. pixelSize = 2;
  300. buttonWidth = 60;
  301. }
  302. }
  303. else {
  304. if (height >= 700 && height < 1025) {
  305. formation.gap = 12;
  306. pixelSize = 3;
  307. buttonWidth = 100;
  308. }
  309. if (height > 320 && height < 700) {
  310. formation.gap = 8;
  311. pixelSize = 2;
  312. buttonWidth = 60;
  313. }
  314. }
  315. }
  316. formation.Bounds = galArea;
  317. }
  318. private void CreatePlayerShip() {
  319. playerShip.setPixelSize(pixelSize);
  320. playerShip.logicalWidth = 32;
  321. playerShip.logicalHeight = 32;
  322. playerShip.Extent = new Rect(gameArea.left,gameArea.bottom-220,gameArea.right,gameArea.bottom);
  323. playerShip.SpriteRect = playerSpriteSheet.GetSpriteRectAt(0, 0);
  324. playerShip.MultipleSpriteRect = new Rect[4];
  325. playerShip.MultipleSpriteRect[0] = new Rect(10,17,20,22);
  326. playerShip.MultipleSpriteRect[1] = new Rect(14,14,16,16);
  327. playerShip.MultipleSpriteRect[2] = new Rect(12,10,18,13);
  328. playerShip.MultipleSpriteRect[3] = new Rect(15,5,15,8);
  329. playerShip.Movement.Direction = Movement.MovementDirection.Right;
  330. playerShip.Movement.Style = Movement.MovementStyle.Limit;
  331. playerShip.Movement.delay = 5;
  332. playerShip.Movement.setMovementStep(0.5 * pixelSize);
  333. playerShip.Animation.Frames = new Point[1] ;
  334. playerShip.Animation.Frames[0] = new Point(0,0);
  335. playerShip.Position = new Point(gameArea.left,gameArea.bottom-( (int)(playerShip.logicalHeight * pixelSize) ) );
  336. playerShip.DeathAnimation.FrameDelay = 200;
  337. playerShip.DeathAnimation.Loop = false;
  338. playerShip.DeathAnimation.Frames = new Point[4];
  339. playerShip.DeathAnimation.Frames[0] = new Point(1,0);
  340. playerShip.DeathAnimation.Frames[1] = new Point(2,0);
  341. playerShip.DeathAnimation.Frames[2] = new Point(1,1);
  342. playerShip.DeathAnimation.Frames[3] = new Point(2,1);
  343. }
  344. private void CreateGalaxians(long attackDelay, double attackStep) {
  345. Random ran = new Random();
  346. int row = -1;
  347. int col = 0;
  348. int i = 0;
  349. CreateGalaxianAttackGroups();
  350. // Define Galaxian sprites
  351. i =0;
  352. row = 0;
  353. col = 3;
  354. galaxians[i] = CreateGalaxian(3, attackDelay, attackStep);
  355. galaxians[i].Player = playerShip;
  356. formation.getMatrix()[col][row] = galaxians[i];
  357. i++;
  358. col = 6;
  359. galaxians[i] = CreateGalaxian(3, attackDelay, attackStep);
  360. formation.getMatrix()[col][row] = galaxians[i];
  361. i++;
  362. row = 1;
  363. for(int c=2; c<=7; c++) {
  364. galaxians[i] = CreateGalaxian(1, attackDelay, attackStep);
  365. formation.getMatrix()[c][row] = galaxians[i];
  366. i++;
  367. }
  368. row = 2;
  369. for(int c=1; c<=8; c++) {
  370. galaxians[i] = CreateGalaxian(2, attackDelay, attackStep);
  371. formation.getMatrix()[c][row] = galaxians[i];
  372. i++;
  373. }
  374. for (int r=3;r<=5;r++)
  375. for(int c=0; c<=9; c++) {
  376. galaxians[i] = CreateGalaxian(0, attackDelay, attackStep);
  377. formation.getMatrix()[c][r] = galaxians[i];
  378. i++;
  379. }
  380. spriteCount = i;
  381. SetupAttackGroups();
  382. formation.EnableAttack() ;
  383. // Create the initial positions of the galaxians in the formation
  384. // scale to a virtual dimension of 16x16 pixels (scaled to screen size)
  385. formation.PositionSprites(12, 12);
  386. formation.movement.delay = 70;
  387. }
  388. private void SetupAttackGroups() {
  389. galaxianAttackGroup1.AssignAttackShips(formation.getMatrix()[3][0], formation.getMatrix()[2][1], formation.getMatrix()[3][1]);
  390. galaxianAttackGroup2.AssignAttackShips(formation.getMatrix()[6][0], formation.getMatrix()[6][1], formation.getMatrix()[7][1]);
  391. galaxianAttackGroup1.coreShip.AttackTimer.Enabled = true;
  392. galaxianAttackGroup1.coreShip.AttackTimer.Expired();
  393. galaxianAttackGroup2.coreShip.AttackTimer.Enabled = true;
  394. galaxianAttackGroup2.coreShip.AttackTimer.Expired();
  395. }
  396. public Galaxian CreateGalaxian(int shipType, long attackDelay, double attackStep) {
  397. Random r = new Random();
  398. int uppershipType;
  399. int lowershipType;
  400. Galaxian galaxian = new Galaxian();
  401. galaxian.Player = playerShip;
  402. lowershipType = (shipType * 2);
  403. uppershipType = (shipType * 2)+1;
  404. switch(shipType) {
  405. case 0 : galaxian.setShipType(Galaxian.ShipType.Drone);
  406. break;
  407. case 1 : galaxian.setShipType(Galaxian.ShipType.BodyGuard);
  408. break;
  409. case 2 : galaxian.setShipType(Galaxian.ShipType.Raider);
  410. break;
  411. case 3 : galaxian.setShipType(Galaxian.ShipType.Base);
  412. break;
  413. }
  414. galaxian.setPixelSize(pixelSize);
  415. galaxian.Position = new Point(r.nextInt(340), r.nextInt(360));
  416. galaxian.SpriteRect = sheet.GetSpriteRectAt(r.nextInt(13),r.nextInt(5));
  417. // Set the logical width and height of the galaxian before scaling for resolution
  418. // this is based on the original bitmap dimensions
  419. galaxian.logicalHeight = 16;
  420. galaxian.logicalWidth = 16;
  421. galaxian.Extent = gameArea;
  422. galaxian.Movement.delay = 0;
  423. galaxian.Movement.setMovementStep(attackStep);
  424. galaxian.attackMovement.delay = attackDelay;
  425. galaxian.Movement.setMovementPixelSize((int)pixelSize);
  426. galaxian.attackMovement.setMovementPixelSize((int)(3*pixelSize));
  427. galaxian.dockingMovement.setMovementPixelSize((int)(3*pixelSize));
  428. galaxian.Movement.Style = Movement.MovementStyle.Cyclic;
  429. galaxian.Animation.FrameDelay = 200;
  430. galaxian.Animation.Frames = new Point[3];
  431. if (shipType <= 2) {
  432. galaxian.Animation.Frames[0] = new Point(8,lowershipType);
  433. galaxian.Animation.Frames[1] = new Point(0,uppershipType);
  434. galaxian.Animation.Frames[2] = new Point(1,uppershipType);
  435. }
  436. else {
  437. galaxian.Animation.Frames[0] = new Point(9,0);
  438. galaxian.Animation.Frames[1] = new Point(10,0);
  439. galaxian.Animation.Frames[2] = new Point(10,0);
  440. }
  441. galaxian.DeathAnimation.FrameDelay = 100;
  442. galaxian.DeathAnimation.Loop = false;
  443. galaxian.DeathAnimation.Frames = new Point[4];
  444. galaxian.DeathAnimation.Frames[0] = new Point(10,5);
  445. galaxian.DeathAnimation.Frames[1] = new Point(11,5);
  446. galaxian.DeathAnimation.Frames[2] = new Point(12,5);
  447. galaxian.DeathAnimation.Frames[3] = new Point(13,5);
  448. if (shipType <= 2)
  449. SetStandardGalaxianAnimations(galaxian, lowershipType) ;
  450. else
  451. SetBaseShipGalaxianAnimations(galaxian) ;
  452. galaxian.missileFrame = new Point(1,0) ;
  453. galaxian.missileRect = missileSheet.GetSpriteRectAt(1,0);
  454. return galaxian;
  455. }
  456. private void SetStandardGalaxianAnimations(Galaxian galaxian, int lowershipType){
  457. int uppershipType = lowershipType+1;
  458. galaxian.AttackAnimation.Frames = new Point[9];
  459. galaxian.AttackAnimation.Frames[0] = new Point(0, lowershipType); //90
  460. galaxian.AttackAnimation.Frames[1] = new Point(8, uppershipType); //120
  461. galaxian.AttackAnimation.Frames[2] = new Point(7, uppershipType); //140
  462. galaxian.AttackAnimation.Frames[3] = new Point(6, uppershipType); //160
  463. galaxian.AttackAnimation.Frames[4] = new Point(5, uppershipType); //180
  464. galaxian.AttackAnimation.Frames[5] = new Point(1, lowershipType); //60
  465. galaxian.AttackAnimation.Frames[6] = new Point(2, lowershipType); //40
  466. galaxian.AttackAnimation.Frames[7] = new Point(3, lowershipType); //30
  467. galaxian.AttackAnimation.Frames[8] = new Point(4, lowershipType); //0
  468. galaxian.getDiveAnimation().FrameDelay = 100;
  469. galaxian.getDiveAnimation().Loop = false;
  470. galaxian.getDiveAnimation().Frames = new Point[9];
  471. galaxian.getDiveAnimation().Frames[0] = new Point(1,uppershipType);
  472. galaxian.getDiveAnimation().Frames[1] = new Point(2,uppershipType);
  473. galaxian.getDiveAnimation().Frames[2] = new Point(3,uppershipType);
  474. galaxian.getDiveAnimation().Frames[3] = new Point(4,uppershipType);
  475. galaxian.getDiveAnimation().Frames[4] = new Point(5,uppershipType);
  476. galaxian.getDiveAnimation().Frames[5] = new Point(6,uppershipType);
  477. galaxian.getDiveAnimation().Frames[6] = new Point(7,uppershipType);
  478. galaxian.getDiveAnimation().Frames[7] = new Point(8,uppershipType);
  479. galaxian.getDiveAnimation().Frames[8] = new Point(0,lowershipType);
  480. galaxian.getDockingAnimation().FrameDelay = 200;
  481. galaxian.getDockingAnimation().Loop = false;
  482. galaxian.getDockingAnimation().Frames = new Point[9];
  483. galaxian.getDockingAnimation().Frames[0] = new Point(8,uppershipType);
  484. galaxian.getDockingAnimation().Frames[1] = new Point(7,uppershipType);
  485. galaxian.getDockingAnimation().Frames[2] = new Point(6,uppershipType);
  486. galaxian.getDockingAnimation().Frames[3] = new Point(5,uppershipType);
  487. galaxian.getDockingAnimation().Frames[4] = new Point(4,uppershipType);
  488. galaxian.getDockingAnimation().Frames[5] = new Point(3,uppershipType);
  489. galaxian.getDockingAnimation().Frames[6] = new Point(2,uppershipType);
  490. galaxian.getDockingAnimation().Frames[7] = new Point(1,uppershipType);
  491. galaxian.getDockingAnimation().Frames[8] = new Point(8,lowershipType);
  492. }
  493. private void SetBaseShipGalaxianAnimations(Galaxian galaxian){
  494. galaxian.AttackAnimation.Frames = new Point[9];
  495. galaxian.AttackAnimation.Frames[0] = new Point(12, 2); //90
  496. galaxian.AttackAnimation.Frames[1] = new Point(10, 2); //120
  497. galaxian.AttackAnimation.Frames[2] = new Point(13, 1); //140
  498. galaxian.AttackAnimation.Frames[3] = new Point(12, 1); //160
  499. galaxian.AttackAnimation.Frames[4] = new Point(11, 1); //180
  500. galaxian.AttackAnimation.Frames[5] = new Point(13, 2); //60
  501. galaxian.AttackAnimation.Frames[6] = new Point(9, 3); //40
  502. galaxian.AttackAnimation.Frames[7] = new Point(11, 3); //30
  503. galaxian.AttackAnimation.Frames[8] = new Point(13, 3); //0
  504. galaxian.getDiveAnimation().FrameDelay = 100;
  505. galaxian.getDiveAnimation().Loop = false;
  506. galaxian.getDiveAnimation().Frames = new Point[12];
  507. galaxian.getDiveAnimation().Frames[0] = new Point(11,0);
  508. galaxian.getDiveAnimation().Frames[1] = new Point(12,0);
  509. galaxian.getDiveAnimation().Frames[2] = new Point(13,0);
  510. galaxian.getDiveAnimation().Frames[3] = new Point(9,1);
  511. galaxian.getDiveAnimation().Frames[4] = new Point(10,1);
  512. galaxian.getDiveAnimation().Frames[5] = new Point(11,1);
  513. galaxian.getDiveAnimation().Frames[6] = new Point(12,1);
  514. galaxian.getDiveAnimation().Frames[7] = new Point(13,1);
  515. galaxian.getDiveAnimation().Frames[8] = new Point(9,2);
  516. galaxian.getDiveAnimation().Frames[9] = new Point(10,2);
  517. galaxian.getDiveAnimation().Frames[10] = new Point(11,2);
  518. galaxian.getDiveAnimation().Frames[11] = new Point(12,2);
  519. galaxian.getDockingAnimation().FrameDelay = 200;
  520. galaxian.getDockingAnimation().Loop = false;
  521. galaxian.getDockingAnimation().Frames = new Point[13];
  522. galaxian.getDockingAnimation().Frames[0] = new Point(12,2);
  523. galaxian.getDockingAnimation().Frames[1] = new Point(13,2);
  524. galaxian.getDockingAnimation().Frames[2] = new Point(9,3);
  525. galaxian.getDockingAnimation().Frames[3] = new Point(10,3);
  526. galaxian.getDockingAnimation().Frames[4] = new Point(11,3);
  527. galaxian.getDockingAnimation().Frames[5] = new Point(12,3);
  528. galaxian.getDockingAnimation().Frames[6] = new Point(13,3);
  529. galaxian.getDockingAnimation().Frames[7] = new Point(9,4);
  530. galaxian.getDockingAnimation().Frames[8] = new Point(10,4);
  531. galaxian.getDockingAnimation().Frames[9] = new Point(11,4);
  532. galaxian.getDockingAnimation().Frames[10] = new Point(12,4);
  533. galaxian.getDockingAnimation().Frames[11] = new Point(13,4);
  534. galaxian.getDockingAnimation().Frames[12] = new Point(10,0);
  535. }
  536. public void DrawGameFrame(Canvas canvas) {
  537. // Draw buttons if turned on
  538. if (showControls)
  539. DrawControlButtons(canvas);
  540. // Move the player ship in accordance with the any directional button press (dx)
  541. MovePlayer(canvas, dx);
  542. // Move the player ship missile if it hasn't collided or completed its movement
  543. if (!playerMissile.Dying && !playerMissile.Dead)
  544. MoveMissile(canvas);
  545. // Display the score at the top of the screen
  546. DisplayScore(canvas);
  547. Rect fRect = null;
  548. starField.DrawStars(canvas);
  549. starField.MoveStars();
  550. formation.SetFormationDirection(gameArea);
  551. if (!GamesStart) {
  552. UpdateGalaxians(canvas);
  553. // If the wave is ready draw the ships
  554. DrawGalaxians(canvas);
  555. }
  556. if (newPlayerReadyTimer.Enabled) {
  557. // Show a message "Ready player x"
  558. DisplayReadyMessage(canvas);
  559. }
  560. if (newPlayerReadyTimer.Expired() || !newPlayerReadyTimer.Enabled || GameOver) {
  561. GamesStart = false;
  562. newPlayerReadyTimer.Enabled = false;
  563. }
  564. boolean allDead = true;
  565. for(int i=0;i<spriteCount;i++) {
  566. if (!galaxians[i].Dead)
  567. allDead = false;
  568. }
  569. // Start again if all dead
  570. if (allDead) {
  571. if (!waveIntervalTimer.Enabled) {
  572. // wait 4 seconds until displaying the next wave
  573. waveIntervalTimer.delay = 4000;
  574. waveIntervalTimer.Reset();
  575. // start the interval timer
  576. waveIntervalTimer.Enabled = true;
  577. }
  578. // Reset formation position for new wave
  579. if (waveIntervalTimer.Expired()) {
  580. waveIntervalTimer.Enabled = false;
  581. ResetGame();
  582. }
  583. }
  584. if (curPlayerShip > maxPlayerShips) {
  585. GameOver = true;
  586. DisplayGameOverMessage(canvas);
  587. }
  588. try {
  589. // When the player dies, wait until all enemies have returned to
  590. // their formation positions before re-enabling the attack.
  591. // If this is shorter than the death pause, wait for that timer to expire
  592. // This prevents more bullets instantly killing the player again
  593. // If its the last player ship game over is displayed
  594. if (formation.AllDocked() && playerShip.Dead && playerDeathPauseTimer.Expired() && !GameOver) {
  595. playerDeathPauseTimer.Enabled = false;
  596. playerShip.Dying = false;
  597. playerShip.Dead = false;
  598. playerShip.DeathAnimation.Reset();
  599. // Re-start the formation attack
  600. formation.EnableAttack() ;
  601. }
  602. }
  603. catch(Exception ex) {
  604. System.out.println("Error in reset player");
  605. }
  606. }
  607. private void UpdateGalaxians(Canvas canvas) {
  608. // Update the Galaxian attack groups
  609. // Only one can attack at a time.
  610. if (galaxianAttackGroup2.IsAttacking() )
  611. galaxianAttackGroup1.Update(false);
  612. else
  613. galaxianAttackGroup1.Update(true);
  614. if (galaxianAttackGroup1.IsAttacking() )
  615. galaxianAttackGroup2.Update(false);
  616. else
  617. galaxianAttackGroup2.Update(true);
  618. // Display the score for the base ship if applicable
  619. DrawAttackGroupBaseShipScore(galaxianAttackGroup1, canvas) ;
  620. DrawAttackGroupBaseShipScore(galaxianAttackGroup2, canvas) ;
  621. // Move the whole formation as one
  622. formation.Move();
  623. }
  624. private void DrawGalaxians(Canvas canvas) {
  625. int boxColor;
  626. for(int i=0;i<spriteCount;i++) {
  627. boxColor = Color.WHITE;
  628. // Move all non formation Galaxians if not in an attack group
  629. // Update any logic independent state
  630. if (!IsAttackGroupShip(galaxians[i])) {
  631. galaxians[i].Move(false);
  632. galaxians[i].Update();
  633. }
  634. DrawSprite(galaxians[i], canvas);
  635. // Draw the Galaxian on the canvas
  636. if (!galaxians[i].Dead) {
  637. // Is the player missile colliding with the galaxian sprite
  638. if (!playerMissile.Dying && !playerMissile.Dead && !galaxians[i].Dying && !galaxians[i].Dead)
  639. if ( galaxians[i].IsCollision (playerMissile.GetBoundingBox() )) {
  640. // Increase the players score
  641. score = score + galaxians[i].getScore();
  642. galaxians[i].Dying = true;
  643. playerMissile.Dying = true;
  644. if (galaxians[i].getShipType() != Galaxian.ShipType.Base) {
  645. PlaySound(5);
  646. }
  647. else {
  648. // Need to find out which attack group this base ship is part of
  649. // then set the points based on the wingmen status
  650. if (galaxianAttackGroup1.IsAttackGroupShip(galaxians[i]))
  651. galaxianAttackGroup1.SetDeathAnimationPoints();
  652. if (galaxianAttackGroup2.IsAttackGroupShip(galaxians[i]))
  653. galaxianAttackGroup2.SetDeathAnimationPoints();
  654. if (galaxians[i].getScore() == 800)
  655. // Both wingmen killed first so max points (yay!), play "whirly" sound!
  656. PlaySound(4);
  657. else
  658. // normal kill sound effect
  659. PlaySound(5);
  660. }
  661. boxColor = Color.RED;
  662. }
  663. }
  664. // Check for collisions
  665. if (!playerShip.Dying && !playerShip.Dead) {
  666. // Check for collisions between the player ship and enemy missiles
  667. for(int m=0;m<=galaxians[i].missileCount-1;m++)
  668. if (!galaxians[i].missiles[m].Dead && playerShip.IsCollision(galaxians[i].missiles[m].GetBoundingBox())) {
  669. InitiatePlayerDeath(galaxians[i].missiles[m]);
  670. }
  671. // Check for collisions between the player ship and enemy ships
  672. if(!playerShip.Dying && !playerShip.Dead)
  673. if (!galaxians[i].Dead && playerShip.IsCollision(galaxians[i].GetBoundingBox())) {
  674. InitiatePlayerDeath(galaxians[i]);
  675. }
  676. }
  677. }
  678. }
  679. private void DisplayReadyMessage(Canvas canvas) {
  680. int x = galArea.left + (int)(galArea.width() / 2) - (int)(pixelSize * (8 * 7));
  681. int y = galArea.bottom - (int)(galArea.height() /2);
  682. playerReadyText.DrawText("Ready Player 1", canvas, x, y, pixelSize, retroFont, Color.BLUE);
  683. }
  684. private void DisplayGameOverMessage(Canvas canvas) {
  685. int x = galArea.left + (int)(galArea.width() / 2) - (int)(pixelSize * (8 * 7));
  686. int y = galArea.bottom - (int)(galArea.height() /2);
  687. playerReadyText.DrawText("Game Over", canvas, x, y, pixelSize, retroFont, Color.RED);
  688. }
  689. private void InitiatePlayerDeath(Sprite enemyObject) {
  690. playerShip.Dying = true;
  691. // Player death sound
  692. PlaySound(6);
  693. enemyObject.Dead = true;
  694. if (curPlayerShip <= maxPlayerShips)
  695. curPlayerShip++;
  696. playerDeathPauseTimer.delay = 4000;
  697. playerDeathPauseTimer.Reset();
  698. playerDeathPauseTimer.Enabled = true;
  699. newPlayerReadyTimer.Reset();
  700. newPlayerReadyTimer.Enabled = true;
  701. }
  702. // Draws the control buttons on the screen (left, right and fire)
  703. private void DrawControlButtons(Canvas canvas) {
  704. int margin = (int)(buttonWidth/2);
  705. Rect butRect = new Rect(0,0,64,64);
  706. Rect butDestRect = new Rect(0,screenHeight - buttonWidth - margin, buttonWidth,screenHeight - margin);
  707. Rect butDest2Rect = new Rect(buttonWidth + 20,screenHeight-buttonWidth - margin, (buttonWidth * 2) + 20,screenHeight - margin);
  708. Rect butDest3Rect = new Rect(screenWidth - buttonWidth,(screenHeight - buttonWidth) - margin, screenWidth,screenHeight - margin);
  709. canvas.drawBitmap(buttonBitmap, butRect, butDestRect, null);
  710. canvas.drawBitmap(buttonBitmap, butRect, butDest2Rect, null);
  711. canvas.drawBitmap(buttonBitmap, butRect, butDest3Rect, null);
  712. }
  713. public void ResetGame() {
  714. // Reset formation position for new wave
  715. formation.PositionSprites(16,16);
  716. SetupAttackGroups();
  717. for(int i=0;i<spriteCount;i++) {
  718. galaxians[i].Dying = false;
  719. galaxians[i].Dead = false;
  720. galaxians[i].DeathAnimation.Reset();
  721. }
  722. // Increment the current fleet count
  723. curFleetNo++;
  724. }
  725. private boolean IsAttackGroupShip(Galaxian ship) {
  726. if (galaxianAttackGroup1.IsAttackGroupShip(ship))
  727. return true;
  728. if (galaxianAttackGroup2.IsAttackGroupShip(ship))
  729. return true;
  730. return false;
  731. }
  732. private void DisplayScore(Canvas canvas) {
  733. canvas.drawText(Integer.toString(score), 10, (int)(pixelSize*12), fontPaint);
  734. canvas.drawText("1UP", (int)(pixelSize*80), (int)(pixelSize*12), playerNoPaint);
  735. if (curFleetNo < 10)
  736. for(int i=0;i<curFleetNo;i++) {
  737. scoreSheet.DrawSprite(scoreSheetBitmap, canvas, scoreSheet.GetSpriteRectAt(0,0), new Point( (int)(pixelSize*120) +(int)(i*8*pixelSize),(int)(pixelSize*2)), pixelSize, 12, 12);
  738. }
  739. else {
  740. int dec = curFleetNo / 10 ;
  741. int rem = curFleetNo % 10;
  742. for(int i=0;i<dec;i++) {
  743. scoreSheet.DrawSprite(scoreSheetBitmap, canvas, scoreSheet.GetSpriteRectAt(1,0), new Point((int)(pixelSize*120) +(int)(i*12*pixelSize),(int)(pixelSize*2)), pixelSize, 12, 12);
  744. }
  745. for(int i=0;i<rem;i++) {
  746. scoreSheet.DrawSprite(scoreSheetBitmap, canvas, scoreSheet.GetSpriteRectAt(0,0), new Point((int)(pixelSize*120) +(int)(i*8*pixelSize) + (int)(dec*12*pixelSize),(int)(pixelSize*2)), pixelSize, 12, 12);
  747. }
  748. }
  749. for (int i=0;i<maxPlayerShips-curPlayerShip;i++) {
  750. Rect sourceRect = new Rect(0, 0, 16, 16);
  751. int offsetStart = galArea.left + ((i+1) * ((int)(12 * pixelSize)));
  752. int offsetEnd = galArea.left + ((i+2) * ((int)(12 * pixelSize)));
  753. Rect destRect = new Rect(offsetStart, galArea.bottom+16, offsetEnd, galArea.bottom+16 + ((int)(12 * pixelSize))) ;
  754. canvas.drawBitmap(livesLeftBitmap, sourceRect, destRect, null);
  755. }
  756. }
  757. public boolean KeyDown(int key){
  758. if (key == KeyEvent.KEYCODE_DPAD_LEFT )
  759. dx = -1;
  760. if (key == KeyEvent.KEYCODE_DPAD_RIGHT)
  761. dx = +1;
  762. if (key == KeyEvent.KEYCODE_DPAD_CENTER)
  763. FirePlayerMissile();
  764. return true;
  765. }
  766. public boolean KeyUp(int key){
  767. // If released a directional key stop moving the player ship
  768. if (key == KeyEvent.KEYCODE_DPAD_LEFT || key == KeyEvent.KEYCODE_DPAD_RIGHT)
  769. dx = 0;
  770. return true;
  771. }
  772. public boolean ProcessTouchEvent(int event, float x, float y) {
  773. if (event == MotionEvent.ACTION_POINTER_2_DOWN) {
  774. dx = dx;
  775. }
  776. if (x > 0 && x <= 0 + buttonWidth)
  777. dx = -1;
  778. if ( (x > buttonWidth + 20) && (x <= (buttonWidth * 2) + 20) )
  779. dx = +1;
  780. if (x > screenWidth-buttonWidth && x <= screenWidth)
  781. FirePlayerMissile();
  782. if (event == MotionEvent.ACTION_UP)
  783. dx = 0;
  784. return true;
  785. }
  786. private void FirePlayerMissile() {
  787. if ( (playerMissile.Movement.Complete || playerMissile.Dead || playerMissile.Dying) && !playerShip.IsDyingOrDead()) {
  788. playerMissile.Dead =false;
  789. playerMissile.Dying = false;
  790. playerMissile.Movement.Complete = false;
  791. playerMissile.Position.x = playerShip.Position.x + (int)(pixelSize * 14) ;
  792. playerMissile.Position.y = playerShip.Position.y;
  793. PlaySound(3);
  794. }
  795. }
  796. private void DrawSprite(Galaxian sprite, Canvas canvas) {
  797. if (sprite.Position == null)
  798. sprite.Position = new Point(20,20);
  799. if (!sprite.Drawing && !sprite.Dead) {
  800. Point frame;
  801. frame = sprite.GetFrame();
  802. sprite.SpriteRect = sheet.GetSpriteRectAt(frame.x, frame.y);
  803. // Draw the sprite using a sprite(Rect) from the sprite sheet
  804. if (!isDebugMode)
  805. sheet.DrawSprite(sheetBitmap, canvas, sprite.SpriteRect, sprite.Position, pixelSize, 12, 12);
  806. else {
  807. // Draw a box representing the bounds of the sprite
  808. if (sprite.getStatus() != Galaxian.AttackStatus.Formation)
  809. sprite.DrawFormationBoundingBox(canvas, Color.WHITE);
  810. sprite.DrawBoundingBox(canvas, Color.RED);
  811. }
  812. if (!sprite.Dying) {
  813. //if (formation.movement.CanMove())
  814. //sprite.Move(true);
  815. }
  816. }
  817. // Draw missiles
  818. for(int m=0; m<sprite.missileCount; m++)
  819. if (!sprite.missiles[m].Dead)
  820. missileSheet.DrawSprite(missileSheetBitmap, canvas, sprite.missiles[m].SpriteRect, sprite.missiles[m].Position, pixelSize, 1, 3);
  821. }
  822. private void MovePlayer(Canvas canvas, int dx){
  823. if (!playerShip.Drawing && !playerShip.Dead) {
  824. playerShip.AdvanceFrame() ;
  825. if (dx < 0) {
  826. playerShip.Movement.Direction = Movement.MovementDirection.Left;
  827. playerShip.Move(false);
  828. }
  829. else if (dx >0) {
  830. playerShip.Movement.Direction = Movement.MovementDirection.Right;
  831. playerShip.Move(false);
  832. }
  833. Point frame;
  834. frame = playerShip.GetFrame();
  835. playerShip.SpriteRect = playerSpriteSheet.GetSpriteRectAt(frame.x, frame.y);
  836. // Draw the sprite using a sprite(Rect) from the sprite sheet
  837. if (!isDebugMode) {
  838. sheet.DrawSprite(playerSheetBitmap, canvas, playerShip.SpriteRect, playerShip.Position, pixelSize, 32, 32);
  839. }
  840. else {
  841. playerShip.DrawCollisionBoxes(canvas, Color.YELLOW);
  842. }
  843. //playerShip.DrawCollisionBoxes(canvas, Color.RED);
  844. }
  845. }
  846. private void MoveMissile(Canvas canvas) {
  847. if (!playerMissile.Drawing && !playerMissile.Dead && !playerMissile.Movement.Complete ) {
  848. Point frame;
  849. frame = playerMissile.GetFrame();
  850. playerMissile.SpriteRect = missileSheet.GetSpriteRectAt(frame.x, frame.y);
  851. // Draw the sprite using a sprite(Rect) from the sprite sheet
  852. missileSheet.DrawSprite(missileSheetBitmap, canvas, playerMissile.SpriteRect, playerMissile.Position, pixelSize, 1, 3);
  853. // Draw a box representing the bounds of the sprite
  854. //playerMissile.DrawBoundingBox(canvas, 2, Color.WHITE);
  855. if (!playerMissile.Dying && !playerMissile.Dead) {
  856. playerMissile.Move(false);
  857. }
  858. }
  859. }
  860. private void DrawAttackGroupBaseShipScore(GalaxianAttackGroup group, Canvas canvas) {
  861. if (group.BaseShip.Dead && group.BaseShipDeathScoreSprite.Dying) {
  862. Point frame;
  863. frame = group.BaseShipDeathScoreSprite.GetFrame();
  864. group.BaseShipDeathScoreSprite.SpriteRect = scoreSheet.GetSpriteRectAt(frame.x, frame.y);
  865. scoreSheet.DrawSprite(scoreSheetBitmap, canvas, group.BaseShipDeathScoreSprite.SpriteRect, group.BaseShipDeathScoreSprite.Position, pixelSize,2, 4);
  866. }
  867. }
  868. private void CreateMissile(int missileDelay, double missileStep) {
  869. // Define a missile sprite
  870. playerMissile.Extent = gameArea;
  871. playerMissile.SpriteRect = missileSheet.GetSpriteRectAt(0,0);
  872. playerMissile.setPixelSize(pixelSize);
  873. playerMissile.Movement.Direction = Movement.MovementDirection.Up;
  874. playerMissile.Movement.Style = Movement.MovementStyle.Limit;
  875. playerMissile.Movement.delay = missileDelay;
  876. playerMissile.Movement.setMovementStep((int)(missileStep));
  877. playerMissile.Animation.Frames = new Point[1] ;
  878. playerMissile.Animation.Frames[0] = new Point(0,0);
  879. playerMissile.Position = new Point(0,gameArea.bottom-( (int)(10 * pixelSize) ));
  880. playerMissile.DeathAnimation.FrameDelay = 5;
  881. playerMissile.DeathAnimation.Loop = false;
  882. playerMissile.DeathAnimation.Frames = new Point[1];
  883. playerMissile.DeathAnimation.Frames[0] = new Point(0,0);
  884. playerMissile.Movement.Complete = true;
  885. }
  886. }