After decimating the enemy forces that have attacked your ship, you are charged with taking out as many of the remaining enemy fighters as possible. 3d space fighter game was initially written while I was testing some 3d routines I was implementing for a flight simulator, but my daughter started playing it and seemed to enjoy it so I added a few sound effects, explosions etc. and so this little game was born.

Dependencies:   mbed

Committer:
taylorza
Date:
Sun Feb 08 01:38:18 2015 +0000
Revision:
4:b857db213f10
Parent:
2:db53af3d2e0f
Removed duty lookup table

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taylorza 0:01829868570e 1 #include "mbed.h"
taylorza 0:01829868570e 2 #include <cstdarg>
taylorza 0:01829868570e 3 #include "LCD_ST7735.h"
taylorza 0:01829868570e 4 #include "GameInput.h"
taylorza 0:01829868570e 5 #include "font_IBM.h"
taylorza 0:01829868570e 6 #include "Canvas.h"
taylorza 0:01829868570e 7 #include "Color565.h"
taylorza 0:01829868570e 8 #include "Math.h"
taylorza 1:9ff7384171ec 9 #include "SpriteSheet.h"
taylorza 1:9ff7384171ec 10
taylorza 1:9ff7384171ec 11 #include "SoundBlock.h"
taylorza 1:9ff7384171ec 12 #include "SoundChannel.h"
taylorza 1:9ff7384171ec 13 #include "OneBitSound.h"
taylorza 0:01829868570e 14
taylorza 0:01829868570e 15 #define VIEW_WIDTH 160
taylorza 0:01829868570e 16 #define VIEW_HEIGHT 104
taylorza 0:01829868570e 17
taylorza 0:01829868570e 18 #define NUM_STARS 10
taylorza 0:01829868570e 19 #define NUM_TIES 5
taylorza 0:01829868570e 20 #define NUM_TIE_VERTS 10
taylorza 0:01829868570e 21 #define NUM_TIE_EDGES 10
taylorza 0:01829868570e 22 #define NUM_EXPLOSIONS (NUM_TIES)
taylorza 0:01829868570e 23
taylorza 0:01829868570e 24 #define TARGET_X (VIEW_WIDTH >> 1)
taylorza 0:01829868570e 25 #define TARGET_Y (VIEW_HEIGHT >> 1)
taylorza 0:01829868570e 26
taylorza 1:9ff7384171ec 27 const float NearZ = 10;
taylorza 1:9ff7384171ec 28 const float FarZ = 2000;
taylorza 1:9ff7384171ec 29 const float ViewDistance = 80;
taylorza 1:9ff7384171ec 30 const float HalfViewWidth = VIEW_WIDTH/ 2;
taylorza 1:9ff7384171ec 31 const float HalfViewHeight = VIEW_HEIGHT/ 2;
taylorza 0:01829868570e 32
taylorza 1:9ff7384171ec 33 const float TenPercent = 0.1f;
taylorza 1:9ff7384171ec 34 const float NintyFivePercent = 0.95f;
taylorza 0:01829868570e 35
taylorza 1:9ff7384171ec 36 const float StarVelocity = 10;
taylorza 0:01829868570e 37
taylorza 0:01829868570e 38 Vector3d stars[NUM_STARS];
taylorza 0:01829868570e 39
taylorza 0:01829868570e 40 struct Line3d
taylorza 0:01829868570e 41 {
taylorza 0:01829868570e 42 uint8_t V1;
taylorza 0:01829868570e 43 uint8_t V2;
taylorza 0:01829868570e 44
taylorza 0:01829868570e 45 Line3d(uint8_t v1, uint8_t v2) : V1(v1), V2(v2) {}
taylorza 0:01829868570e 46 };
taylorza 0:01829868570e 47
taylorza 0:01829868570e 48 struct TieFighter
taylorza 0:01829868570e 49 {
taylorza 0:01829868570e 50
taylorza 0:01829868570e 51 Vector3d Position;
taylorza 0:01829868570e 52 Vector3d Velocity;
taylorza 0:01829868570e 53
taylorza 0:01829868570e 54 int MinX;
taylorza 0:01829868570e 55 int MinY;
taylorza 0:01829868570e 56 int MaxX;
taylorza 0:01829868570e 57 int MaxY;
taylorza 0:01829868570e 58 };
taylorza 0:01829868570e 59
taylorza 0:01829868570e 60 struct Explosion
taylorza 0:01829868570e 61 {
taylorza 0:01829868570e 62 bool Active;
taylorza 0:01829868570e 63 int Counter;
taylorza 0:01829868570e 64 Vector3d P1[NUM_TIE_EDGES];
taylorza 0:01829868570e 65 Vector3d P2[NUM_TIE_EDGES];
taylorza 0:01829868570e 66 Vector3d Velocity[NUM_TIE_EDGES];
taylorza 0:01829868570e 67 };
taylorza 0:01829868570e 68
taylorza 0:01829868570e 69 Vector3d tieVerts[NUM_TIE_VERTS] =
taylorza 0:01829868570e 70 {
taylorza 0:01829868570e 71 Vector3d(-50, 40, 0),
taylorza 0:01829868570e 72 Vector3d(-40, 0, 0),
taylorza 0:01829868570e 73 Vector3d(-50, -40, 0),
taylorza 0:01829868570e 74 Vector3d(-10, 0, 0),
taylorza 0:01829868570e 75 Vector3d(0, 20, 0),
taylorza 0:01829868570e 76 Vector3d(10, 0, 0),
taylorza 0:01829868570e 77 Vector3d(0, -20, 0),
taylorza 0:01829868570e 78 Vector3d(50, 40, 0),
taylorza 0:01829868570e 79 Vector3d(40, 0, 0),
taylorza 0:01829868570e 80 Vector3d(50, -40, 0),
taylorza 0:01829868570e 81 };
taylorza 0:01829868570e 82
taylorza 0:01829868570e 83 Line3d tieShape[NUM_TIE_EDGES] =
taylorza 0:01829868570e 84 {
taylorza 0:01829868570e 85 Line3d(0, 1),
taylorza 0:01829868570e 86 Line3d(1, 2),
taylorza 0:01829868570e 87 Line3d(1, 3),
taylorza 0:01829868570e 88 Line3d(3, 4),
taylorza 0:01829868570e 89 Line3d(4, 5),
taylorza 0:01829868570e 90 Line3d(5, 6),
taylorza 0:01829868570e 91 Line3d(6, 3),
taylorza 0:01829868570e 92 Line3d(5, 8),
taylorza 0:01829868570e 93 Line3d(8, 7),
taylorza 0:01829868570e 94 Line3d(8, 9),
taylorza 0:01829868570e 95 };
taylorza 0:01829868570e 96
taylorza 0:01829868570e 97 TieFighter ties[NUM_TIES];
taylorza 0:01829868570e 98 Explosion explosions[NUM_EXPLOSIONS];
taylorza 0:01829868570e 99 Vector3d steeringForce;
taylorza 0:01829868570e 100
taylorza 0:01829868570e 101 bool updateHud = true;
taylorza 0:01829868570e 102 int hits = 0;
taylorza 0:01829868570e 103 int misses = 0;
taylorza 0:01829868570e 104 int score = 0;
taylorza 0:01829868570e 105
taylorza 0:01829868570e 106 Bitmap1bpp image(VIEW_WIDTH, VIEW_HEIGHT);
taylorza 0:01829868570e 107 Canvas<Bitmap1bpp> canvas(&image);
taylorza 0:01829868570e 108
taylorza 0:01829868570e 109 int cannonState = 0;
taylorza 0:01829868570e 110 int cannonCount = 0;
taylorza 0:01829868570e 111
taylorza 0:01829868570e 112 void initStar(int index, bool initial);
taylorza 0:01829868570e 113 void initTie(int index);
taylorza 0:01829868570e 114
taylorza 0:01829868570e 115 void startExplosion(int tieIndex);
taylorza 0:01829868570e 116
taylorza 1:9ff7384171ec 117 void showIntro();
taylorza 1:9ff7384171ec 118 void playGame();
taylorza 1:9ff7384171ec 119
taylorza 0:01829868570e 120 void update();
taylorza 0:01829868570e 121 void draw();
taylorza 0:01829868570e 122
taylorza 1:9ff7384171ec 123 char buffer[20];
taylorza 1:9ff7384171ec 124
taylorza 1:9ff7384171ec 125 OneBitSound soundEngine(P0_18);
taylorza 1:9ff7384171ec 126
taylorza 1:9ff7384171ec 127 CREATE_EFFECT(Sound_FireLaser)
taylorza 1:9ff7384171ec 128 TONE(20, 50, 2000, -50, 128, 0)
taylorza 1:9ff7384171ec 129 END_EFFECT
taylorza 1:9ff7384171ec 130
taylorza 1:9ff7384171ec 131 CREATE_EFFECT(Sound_Explosion)
taylorza 1:9ff7384171ec 132 NOISE(20, 1000, 10, 5)
taylorza 1:9ff7384171ec 133 END_EFFECT
taylorza 1:9ff7384171ec 134
taylorza 0:01829868570e 135 LCD_ST7735 Surface(
taylorza 0:01829868570e 136 P0_19,
taylorza 2:db53af3d2e0f 137 P0_20,
taylorza 2:db53af3d2e0f 138 P0_7,
taylorza 0:01829868570e 139 P0_21,
taylorza 0:01829868570e 140 P0_22,
taylorza 0:01829868570e 141 P1_15,
taylorza 0:01829868570e 142 P0_2,
taylorza 0:01829868570e 143 LCD_ST7735::RGB);
taylorza 0:01829868570e 144
taylorza 0:01829868570e 145 main()
taylorza 0:01829868570e 146 {
taylorza 0:01829868570e 147 Surface.setOrientation(LCD_ST7735::Rotate270, false);
taylorza 1:9ff7384171ec 148
taylorza 1:9ff7384171ec 149 showIntro();
taylorza 1:9ff7384171ec 150 playGame();
taylorza 1:9ff7384171ec 151 }
taylorza 1:9ff7384171ec 152
taylorza 1:9ff7384171ec 153 void showIntro()
taylorza 1:9ff7384171ec 154 {
taylorza 1:9ff7384171ec 155 // Title - Space Raiders
taylorza 1:9ff7384171ec 156 Surface.drawBitmap(13, 0, bmp, 0, 0, 133, 13, Color565::Aqua, Color565::Black);
taylorza 1:9ff7384171ec 157
taylorza 1:9ff7384171ec 158 // Image
taylorza 1:9ff7384171ec 159 Surface.drawBitmap(45, 16, bmp, 0, 16, 69, 83, Color565::Green, Color565::Black);
taylorza 1:9ff7384171ec 160
taylorza 1:9ff7384171ec 161 // Press [] to start
taylorza 1:9ff7384171ec 162 Surface.drawBitmap(43, 102, bmp, 72, 16, 73, 8, Color565::White, Color565::Black);
taylorza 1:9ff7384171ec 163
taylorza 1:9ff7384171ec 164 // (c)2015
taylorza 1:9ff7384171ec 165 Surface.drawBitmap(44, 120, bmp, 72, 32, 71, 8, Color565::White, Color565::Black);
taylorza 1:9ff7384171ec 166
taylorza 1:9ff7384171ec 167 while (!GameInput::isSquarePressed());
taylorza 1:9ff7384171ec 168 }
taylorza 1:9ff7384171ec 169
taylorza 1:9ff7384171ec 170 void playGame()
taylorza 1:9ff7384171ec 171 {
taylorza 1:9ff7384171ec 172 Surface.clearScreen();
taylorza 0:01829868570e 173
taylorza 0:01829868570e 174 // Init stars
taylorza 0:01829868570e 175 for (int i = 0; i < NUM_STARS; ++i)
taylorza 0:01829868570e 176 {
taylorza 0:01829868570e 177 initStar(i, true);
taylorza 0:01829868570e 178 }
taylorza 0:01829868570e 179
taylorza 0:01829868570e 180 // Init tie fighters
taylorza 0:01829868570e 181 for (int i = 0; i < NUM_TIES; ++i)
taylorza 0:01829868570e 182 {
taylorza 1:9ff7384171ec 183 initTie(i);
taylorza 0:01829868570e 184 }
taylorza 0:01829868570e 185
taylorza 0:01829868570e 186 // Init explosions
taylorza 0:01829868570e 187 for (int i = 0; i < NUM_EXPLOSIONS; ++i)
taylorza 0:01829868570e 188 {
taylorza 0:01829868570e 189 explosions[i].Active = false;
taylorza 0:01829868570e 190 }
taylorza 0:01829868570e 191
taylorza 0:01829868570e 192 while (true)
taylorza 0:01829868570e 193 {
taylorza 0:01829868570e 194 canvas.clear();
taylorza 0:01829868570e 195
taylorza 0:01829868570e 196 update();
taylorza 0:01829868570e 197 draw();
taylorza 0:01829868570e 198
taylorza 0:01829868570e 199 Surface.drawBitmap(0, 16, image, 0, 0, VIEW_WIDTH, VIEW_HEIGHT, Color565::White, Color565::Black);
taylorza 0:01829868570e 200
taylorza 0:01829868570e 201 if (updateHud)
taylorza 0:01829868570e 202 {
taylorza 0:01829868570e 203 updateHud = false;
taylorza 0:01829868570e 204 Surface.setForegroundColor(Color565::White);
taylorza 0:01829868570e 205 Surface.drawString(font_ibm, 0, 0, "Hits Score Misses");
taylorza 0:01829868570e 206
taylorza 0:01829868570e 207 Surface.setForegroundColor(Color565::Yellow);
taylorza 0:01829868570e 208 sprintf(buffer, "%d", hits);
taylorza 0:01829868570e 209 Surface.drawString(font_ibm, 8, 8, buffer);
taylorza 0:01829868570e 210
taylorza 0:01829868570e 211 Surface.setForegroundColor(Color565::Lime);
taylorza 0:01829868570e 212 sprintf(buffer, "%d", score);
taylorza 0:01829868570e 213 Surface.drawString(font_ibm, 56, 8, buffer);
taylorza 0:01829868570e 214
taylorza 0:01829868570e 215 Surface.setForegroundColor(Color565::Red);
taylorza 0:01829868570e 216 sprintf(buffer, "%d", misses);
taylorza 0:01829868570e 217 Surface.drawString(font_ibm, 128, 8, buffer);
taylorza 0:01829868570e 218 }
taylorza 0:01829868570e 219
taylorza 1:9ff7384171ec 220 if (misses == 50) break;
taylorza 1:9ff7384171ec 221 }
taylorza 1:9ff7384171ec 222
taylorza 1:9ff7384171ec 223 Surface.setForegroundColor(Color565::Red);
taylorza 1:9ff7384171ec 224 Surface.drawString(font_ibm, 44, 60, "GAME OVER");
taylorza 0:01829868570e 225 }
taylorza 0:01829868570e 226
taylorza 0:01829868570e 227 void initStar(int index, bool initial)
taylorza 0:01829868570e 228 {
taylorza 1:9ff7384171ec 229 stars[index].X = -VIEW_WIDTH + rand() % (2 * VIEW_WIDTH);
taylorza 1:9ff7384171ec 230 stars[index].Y = -VIEW_HEIGHT + rand() % (2 * VIEW_HEIGHT);
taylorza 0:01829868570e 231 if (initial)
taylorza 1:9ff7384171ec 232 stars[index].Z = NearZ + rand() % (int)(FarZ - NearZ);
taylorza 0:01829868570e 233 else
taylorza 0:01829868570e 234 stars[index].Z = 500;
taylorza 0:01829868570e 235 }
taylorza 0:01829868570e 236
taylorza 0:01829868570e 237 void initTie(int index)
taylorza 0:01829868570e 238 {
taylorza 0:01829868570e 239 ties[index].Position.X = -VIEW_WIDTH + rand() % (2 * VIEW_WIDTH);
taylorza 0:01829868570e 240 ties[index].Position.Y = -VIEW_HEIGHT + rand() % (2 * VIEW_HEIGHT);
taylorza 0:01829868570e 241 ties[index].Position.Z = FarZ * (rand() % 3 + 1);
taylorza 0:01829868570e 242
taylorza 0:01829868570e 243 ties[index].Velocity.X = -0.5f + rand() % 2;
taylorza 0:01829868570e 244 ties[index].Velocity.Y = -0.5f + rand() % 2;
taylorza 1:9ff7384171ec 245 int difficulty = hits > 48 ? 48 : hits;
taylorza 1:9ff7384171ec 246 ties[index].Velocity.Z = -4 - rand() % (8 + difficulty);
taylorza 0:01829868570e 247 }
taylorza 0:01829868570e 248
taylorza 0:01829868570e 249 void startExplosion(int tieIndex)
taylorza 0:01829868570e 250 {
taylorza 0:01829868570e 251 TieFighter &tie = ties[tieIndex];
taylorza 0:01829868570e 252 for (int i = 0; i < NUM_EXPLOSIONS; ++i)
taylorza 0:01829868570e 253 {
taylorza 0:01829868570e 254 Explosion &explosion = explosions[i];
taylorza 0:01829868570e 255 if (explosion.Active == false)
taylorza 0:01829868570e 256 {
taylorza 0:01829868570e 257 explosion.Active = true;
taylorza 0:01829868570e 258 explosion.Counter = 0;
taylorza 0:01829868570e 259
taylorza 0:01829868570e 260 for (int edge = 0; edge < NUM_TIE_EDGES; ++edge)
taylorza 0:01829868570e 261 {
taylorza 0:01829868570e 262 Line3d &shape = tieShape[edge];
taylorza 0:01829868570e 263
taylorza 0:01829868570e 264 // Start
taylorza 0:01829868570e 265 Vector3d &p1 = explosion.P1[edge];
taylorza 0:01829868570e 266 Vector3d &v1 = tieVerts[shape.V1];
taylorza 0:01829868570e 267 p1.X = tie.Position.X + v1.X;
taylorza 0:01829868570e 268 p1.Y = tie.Position.Y + v1.Y;
taylorza 0:01829868570e 269 p1.Z = tie.Position.Z + v1.Z;
taylorza 0:01829868570e 270
taylorza 0:01829868570e 271 // End
taylorza 0:01829868570e 272 Vector3d &p2 = explosion.P2[edge];
taylorza 0:01829868570e 273 Vector3d &v2 = tieVerts[shape.V2];
taylorza 0:01829868570e 274 p2.X = tie.Position.X + v2.X;
taylorza 0:01829868570e 275 p2.Y = tie.Position.Y + v2.Y;
taylorza 0:01829868570e 276 p2.Z = tie.Position.Z + v2.Z;
taylorza 0:01829868570e 277
taylorza 0:01829868570e 278 // Trajectory
taylorza 0:01829868570e 279 Vector3d &velocity = explosion.Velocity[edge];
taylorza 0:01829868570e 280 Vector3d &tieVelocity = tie.Velocity;
taylorza 0:01829868570e 281 velocity.X = tieVelocity.X - 8 + rand() % 16;
taylorza 0:01829868570e 282 velocity.Y = tieVelocity.Y - 8 + rand() % 16;
taylorza 0:01829868570e 283 velocity.Z = tieVelocity.Z - 8 + rand() % 16;
taylorza 0:01829868570e 284 }
taylorza 1:9ff7384171ec 285 soundEngine.play(2, EFFECT(Sound_Explosion));
taylorza 0:01829868570e 286 break;
taylorza 0:01829868570e 287 }
taylorza 0:01829868570e 288 }
taylorza 0:01829868570e 289 }
taylorza 0:01829868570e 290
taylorza 0:01829868570e 291 void update()
taylorza 0:01829868570e 292 {
taylorza 0:01829868570e 293 // Move ties
taylorza 0:01829868570e 294 for (int i = 0; i < NUM_TIES; ++i)
taylorza 0:01829868570e 295 {
taylorza 0:01829868570e 296 TieFighter &tie = ties[i];
taylorza 0:01829868570e 297
taylorza 0:01829868570e 298 if (cannonState == 1)
taylorza 0:01829868570e 299 {
taylorza 0:01829868570e 300 if (tie.MinX < TARGET_X && tie.MaxX > TARGET_X
taylorza 0:01829868570e 301 && tie.MinY < TARGET_Y && tie.MaxY > TARGET_Y)
taylorza 0:01829868570e 302 {
taylorza 0:01829868570e 303 startExplosion(i);
taylorza 0:01829868570e 304 ++hits;
taylorza 0:01829868570e 305 score += ((int)tie.Position.Z) / 10;
taylorza 1:9ff7384171ec 306 updateHud = true;
taylorza 0:01829868570e 307 initTie(i);
taylorza 0:01829868570e 308 continue;
taylorza 0:01829868570e 309 }
taylorza 0:01829868570e 310 }
taylorza 0:01829868570e 311
taylorza 0:01829868570e 312 tie.Position.X += (tie.Velocity.X + steeringForce.X);
taylorza 0:01829868570e 313 tie.Position.Y += (tie.Velocity.Y + steeringForce.Y);
taylorza 0:01829868570e 314 tie.Position.Z += (tie.Velocity.Z + steeringForce.Z);
taylorza 0:01829868570e 315
taylorza 0:01829868570e 316 if (tie.Position.Z <= NearZ)
taylorza 0:01829868570e 317 {
taylorza 0:01829868570e 318 initTie(i);
taylorza 0:01829868570e 319 ++misses;
taylorza 0:01829868570e 320 updateHud = true;
taylorza 0:01829868570e 321 }
taylorza 0:01829868570e 322 }
taylorza 0:01829868570e 323
taylorza 0:01829868570e 324 // Move stars
taylorza 0:01829868570e 325 for (int i = 0; i < NUM_STARS; ++i)
taylorza 0:01829868570e 326 {
taylorza 0:01829868570e 327 Vector3d &star = stars[i];
taylorza 0:01829868570e 328 star.X += (steeringForce.X * TenPercent);
taylorza 0:01829868570e 329 star.Y += (steeringForce.Y * TenPercent);
taylorza 0:01829868570e 330 star.Z -= StarVelocity;
taylorza 0:01829868570e 331
taylorza 0:01829868570e 332 if (star.Z <= NearZ)
taylorza 0:01829868570e 333 {
taylorza 0:01829868570e 334 initStar(i, false);
taylorza 0:01829868570e 335 }
taylorza 0:01829868570e 336 }
taylorza 0:01829868570e 337
taylorza 0:01829868570e 338 // Update explosions
taylorza 0:01829868570e 339 for (int i = 0; i < NUM_EXPLOSIONS; ++i)
taylorza 0:01829868570e 340 {
taylorza 0:01829868570e 341 Explosion &explosion = explosions[i];
taylorza 0:01829868570e 342 if (explosion.Active == false) continue;
taylorza 0:01829868570e 343
taylorza 0:01829868570e 344 for (int edge = 0; edge < NUM_TIE_EDGES; ++edge)
taylorza 0:01829868570e 345 {
taylorza 0:01829868570e 346 Vector3d &v = explosions[i].Velocity[edge];
taylorza 0:01829868570e 347
taylorza 0:01829868570e 348 Vector3d &p1 = explosions[i].P1[edge];
taylorza 0:01829868570e 349 p1.X += v.X;
taylorza 0:01829868570e 350 p1.Y += v.Y;
taylorza 0:01829868570e 351 p1.Z += v.Z;
taylorza 0:01829868570e 352
taylorza 0:01829868570e 353 Vector3d &p2 = explosions[i].P2[edge];
taylorza 0:01829868570e 354 p2.X += v.X;
taylorza 0:01829868570e 355 p2.Y += v.Y;
taylorza 0:01829868570e 356 p2.Z += v.Z;
taylorza 0:01829868570e 357 }
taylorza 0:01829868570e 358
taylorza 0:01829868570e 359 if (++explosions[i].Counter > 100)
taylorza 0:01829868570e 360 {
taylorza 0:01829868570e 361 explosions[i].Active = false;
taylorza 0:01829868570e 362 }
taylorza 0:01829868570e 363 }
taylorza 0:01829868570e 364
taylorza 1:9ff7384171ec 365 if (GameInput::isLeftPressed()) steeringForce.X += 1.5;
taylorza 1:9ff7384171ec 366 if (GameInput::isRightPressed()) steeringForce.X -= 1.5;
taylorza 1:9ff7384171ec 367 if (GameInput::isUpPressed()) steeringForce.Y -= 1.5;
taylorza 1:9ff7384171ec 368 if (GameInput::isDownPressed()) steeringForce.Y += 1.5;
taylorza 0:01829868570e 369
taylorza 0:01829868570e 370 if (GameInput::isCirclePressed() && cannonState == 0)
taylorza 0:01829868570e 371 {
taylorza 0:01829868570e 372 cannonState = 1;
taylorza 1:9ff7384171ec 373 cannonCount = 0;
taylorza 0:01829868570e 374 }
taylorza 0:01829868570e 375
taylorza 0:01829868570e 376 if (cannonState == 1)
taylorza 1:9ff7384171ec 377 if (++cannonCount > 10)
taylorza 0:01829868570e 378 cannonState = 2;
taylorza 0:01829868570e 379
taylorza 0:01829868570e 380 if (cannonState == 2)
taylorza 0:01829868570e 381 if (++cannonCount > 20)
taylorza 0:01829868570e 382 cannonState = 0;
taylorza 0:01829868570e 383
taylorza 0:01829868570e 384 // Dampen thrusters
taylorza 0:01829868570e 385 steeringForce.X *= NintyFivePercent;
taylorza 0:01829868570e 386 steeringForce.Y *= NintyFivePercent;
taylorza 0:01829868570e 387 steeringForce.Z *= NintyFivePercent;
taylorza 0:01829868570e 388 }
taylorza 0:01829868570e 389
taylorza 0:01829868570e 390 void draw()
taylorza 0:01829868570e 391 {
taylorza 0:01829868570e 392 // Draw stars
taylorza 0:01829868570e 393 for (int i = 0; i < NUM_STARS; ++i)
taylorza 0:01829868570e 394 {
taylorza 0:01829868570e 395 Vector3d &star = stars[i];
taylorza 0:01829868570e 396
taylorza 0:01829868570e 397 // Perspective transform
taylorza 1:9ff7384171ec 398 float x_per = ViewDistance * (star.X / star.Z);
taylorza 1:9ff7384171ec 399 float y_per = ViewDistance * (star.Y / star.Z);
taylorza 0:01829868570e 400
taylorza 0:01829868570e 401 // Screen coordiante transform
taylorza 0:01829868570e 402 int x_screen = (int)(HalfViewWidth + x_per);
taylorza 0:01829868570e 403 int y_screen = (int)(HalfViewHeight + y_per);
taylorza 0:01829868570e 404
taylorza 0:01829868570e 405 // Clip to screen
taylorza 0:01829868570e 406 if (x_screen >= VIEW_WIDTH || x_screen < 0 ||
taylorza 0:01829868570e 407 y_screen >= VIEW_HEIGHT || y_screen < 0)
taylorza 0:01829868570e 408 {
taylorza 0:01829868570e 409 initStar(i, false);
taylorza 0:01829868570e 410 continue;
taylorza 0:01829868570e 411 }
taylorza 0:01829868570e 412
taylorza 0:01829868570e 413 canvas.setPixel(x_screen, y_screen, 1);
taylorza 0:01829868570e 414 }
taylorza 0:01829868570e 415
taylorza 0:01829868570e 416 // Draw ties
taylorza 0:01829868570e 417 for(int i = 0; i < NUM_TIES; ++i)
taylorza 0:01829868570e 418 {
taylorza 0:01829868570e 419 TieFighter &tie = ties[i];
taylorza 0:01829868570e 420
taylorza 0:01829868570e 421 tie.MinX = 1000000;
taylorza 0:01829868570e 422 tie.MinY = 1000000;
taylorza 0:01829868570e 423 tie.MaxX = -1000000;
taylorza 0:01829868570e 424 tie.MaxY = -1000000;
taylorza 0:01829868570e 425
taylorza 0:01829868570e 426 for (int edge = 0; edge < NUM_TIE_EDGES; ++edge)
taylorza 0:01829868570e 427 {
taylorza 0:01829868570e 428 Vector3d p1_per, p2_per;
taylorza 0:01829868570e 429
taylorza 0:01829868570e 430 Line3d &shape = tieShape[edge];
taylorza 0:01829868570e 431 Vector3d &v1 = tieVerts[shape.V1];
taylorza 0:01829868570e 432 Vector3d &v2 = tieVerts[shape.V2];
taylorza 0:01829868570e 433
taylorza 0:01829868570e 434 p1_per.X = ViewDistance * ((tie.Position.X + v1.X) / (tie.Position.Z + v1.Z));
taylorza 0:01829868570e 435 p1_per.Y = ViewDistance * ((tie.Position.Y + v1.Y) / (tie.Position.Z + v1.Z));
taylorza 0:01829868570e 436
taylorza 0:01829868570e 437 p2_per.X = ViewDistance * ((tie.Position.X + v2.X) / (ties[i].Position.Z + v2.Z));
taylorza 0:01829868570e 438 p2_per.Y = ViewDistance * ((tie.Position.Y + v2.Y) / (ties[i].Position.Z + v2.Z));
taylorza 0:01829868570e 439
taylorza 0:01829868570e 440 int p1_screen_x = (int)(HalfViewWidth + p1_per.X);
taylorza 0:01829868570e 441 int p1_screen_y = (int)(HalfViewHeight + p1_per.Y);
taylorza 0:01829868570e 442 int p2_screen_x = (int)(HalfViewWidth + p2_per.X);
taylorza 0:01829868570e 443 int p2_screen_y = (int)(HalfViewHeight + p2_per.Y);
taylorza 0:01829868570e 444
taylorza 0:01829868570e 445 if (p1_screen_x < tie.MinX) tie.MinX = p1_screen_x;
taylorza 0:01829868570e 446 if (p2_screen_x < tie.MinX) tie.MinX = p2_screen_x;
taylorza 0:01829868570e 447 if (p1_screen_x > tie.MaxX) tie.MaxX = p1_screen_x;
taylorza 0:01829868570e 448 if (p2_screen_x > tie.MaxX) tie.MaxX = p2_screen_x;
taylorza 0:01829868570e 449
taylorza 0:01829868570e 450 if (p1_screen_y < tie.MinY) tie.MinY = p1_screen_y;
taylorza 0:01829868570e 451 if (p2_screen_y < tie.MinY) tie.MinY = p2_screen_y;
taylorza 0:01829868570e 452 if (p1_screen_y > tie.MaxY) tie.MaxY = p1_screen_y;
taylorza 0:01829868570e 453 if (p2_screen_y > tie.MaxY) tie.MaxY = p2_screen_y;
taylorza 0:01829868570e 454
taylorza 0:01829868570e 455 canvas.drawLine(p1_screen_x, p1_screen_y, p2_screen_x, p2_screen_y, 1);
taylorza 0:01829868570e 456 }
taylorza 0:01829868570e 457 }
taylorza 0:01829868570e 458
taylorza 0:01829868570e 459 // Draw explosions
taylorza 0:01829868570e 460 for (int i = 0; i < NUM_EXPLOSIONS; ++i)
taylorza 0:01829868570e 461 {
taylorza 0:01829868570e 462 Explosion &explosion = explosions[i];
taylorza 0:01829868570e 463 if (explosion.Active == false) continue;
taylorza 0:01829868570e 464
taylorza 0:01829868570e 465 for (int edge = 0; edge < NUM_TIE_EDGES; ++edge)
taylorza 0:01829868570e 466 {
taylorza 0:01829868570e 467 Vector3d &p1 = explosion.P1[edge];
taylorza 0:01829868570e 468 Vector3d &p2 = explosion.P2[edge];
taylorza 0:01829868570e 469
taylorza 0:01829868570e 470 if (p1.Z < NearZ && p2.Z < NearZ) continue;
taylorza 0:01829868570e 471
taylorza 0:01829868570e 472 Vector3d p1_per, p2_per;
taylorza 0:01829868570e 473
taylorza 0:01829868570e 474 p1_per.X = ViewDistance * (p1.X / p1.Z);
taylorza 0:01829868570e 475 p1_per.Y = ViewDistance * (p1.Y / p1.Z);
taylorza 0:01829868570e 476
taylorza 0:01829868570e 477 p2_per.X = ViewDistance * (p2.X / p2.Z);
taylorza 0:01829868570e 478 p2_per.Y = ViewDistance * (p2.Y / p2.Z);
taylorza 0:01829868570e 479
taylorza 0:01829868570e 480 int p1_screen_x = (int)(HalfViewWidth + p1_per.X);
taylorza 0:01829868570e 481 int p1_screen_y = (int)(HalfViewHeight + p1_per.Y);
taylorza 0:01829868570e 482 int p2_screen_x = (int)(HalfViewWidth + p2_per.X);
taylorza 0:01829868570e 483 int p2_screen_y = (int)(HalfViewHeight + p2_per.Y);
taylorza 0:01829868570e 484
taylorza 0:01829868570e 485 canvas.drawLine(p1_screen_x, p1_screen_y, p2_screen_x, p2_screen_y, 1);
taylorza 0:01829868570e 486 }
taylorza 0:01829868570e 487 }
taylorza 0:01829868570e 488
taylorza 0:01829868570e 489 // Draw laser fire
taylorza 0:01829868570e 490 if (cannonState == 1)
taylorza 0:01829868570e 491 {
taylorza 0:01829868570e 492 if (rand() % 2 == 1)
taylorza 0:01829868570e 493 {
taylorza 0:01829868570e 494 canvas.drawLine(VIEW_WIDTH - 21, VIEW_HEIGHT - 1, -4 + rand() % 8 + TARGET_X, -4 + rand() % 8 + TARGET_Y, 1);
taylorza 1:9ff7384171ec 495 soundEngine.play(0, EFFECT(Sound_FireLaser));
taylorza 0:01829868570e 496 }
taylorza 0:01829868570e 497 else
taylorza 0:01829868570e 498 {
taylorza 0:01829868570e 499 canvas.drawLine(20, VIEW_HEIGHT - 1, -4 + rand() % 8 + TARGET_X, -4 + rand() % 8 + TARGET_Y, 1);
taylorza 1:9ff7384171ec 500 soundEngine.play(1, EFFECT(Sound_FireLaser));
taylorza 0:01829868570e 501 }
taylorza 0:01829868570e 502 }
taylorza 0:01829868570e 503
taylorza 0:01829868570e 504 // Draw cross-hair
taylorza 0:01829868570e 505 canvas.drawLine(VIEW_WIDTH / 2, VIEW_HEIGHT / 2 - 10, VIEW_WIDTH / 2, VIEW_HEIGHT / 2 - 5, 1);
taylorza 0:01829868570e 506 canvas.drawLine(VIEW_WIDTH / 2, VIEW_HEIGHT / 2 + 10, VIEW_WIDTH / 2, VIEW_HEIGHT / 2 + 5, 1);
taylorza 0:01829868570e 507
taylorza 0:01829868570e 508 canvas.drawLine(VIEW_WIDTH / 2 - 10, VIEW_HEIGHT / 2, VIEW_WIDTH / 2 - 5, VIEW_HEIGHT / 2, 1);
taylorza 0:01829868570e 509 canvas.drawLine(VIEW_WIDTH / 2 + 10, VIEW_HEIGHT / 2, VIEW_WIDTH / 2 + 5, VIEW_HEIGHT / 2, 1);
taylorza 0:01829868570e 510 }