This code contains the game Starship designed for the STM32F429i-DISC1 board. It requires a keyboard to play.
Dependencies: Starship LCD_DISCO_F429ZI USBHost mbed
Game.c@1:527a11035e0b, 2017-11-17 (annotated)
- Committer:
- Oshyrath
- Date:
- Fri Nov 17 02:23:33 2017 +0000
- Revision:
- 1:527a11035e0b
First Publish of the code.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Oshyrath | 1:527a11035e0b | 1 | #include "Game.h" |
Oshyrath | 1:527a11035e0b | 2 | |
Oshyrath | 1:527a11035e0b | 3 | |
Oshyrath | 1:527a11035e0b | 4 | int16_t level; |
Oshyrath | 1:527a11035e0b | 5 | int16_t levelScore; |
Oshyrath | 1:527a11035e0b | 6 | int16_t totalScore; |
Oshyrath | 1:527a11035e0b | 7 | int16_t lives; |
Oshyrath | 1:527a11035e0b | 8 | int8_t X_DIR; |
Oshyrath | 1:527a11035e0b | 9 | int8_t Y_DIR; |
Oshyrath | 1:527a11035e0b | 10 | int8_t didUserRequestFire; |
Oshyrath | 1:527a11035e0b | 11 | |
Oshyrath | 1:527a11035e0b | 12 | void newGame() |
Oshyrath | 1:527a11035e0b | 13 | { |
Oshyrath | 1:527a11035e0b | 14 | lives = STARTING_LIFE_TOTAL; |
Oshyrath | 1:527a11035e0b | 15 | level = 1; |
Oshyrath | 1:527a11035e0b | 16 | levelScore = 0; |
Oshyrath | 1:527a11035e0b | 17 | totalScore = 0; |
Oshyrath | 1:527a11035e0b | 18 | } |
Oshyrath | 1:527a11035e0b | 19 | void newLevel() |
Oshyrath | 1:527a11035e0b | 20 | { |
Oshyrath | 1:527a11035e0b | 21 | X_DIR = NO_DIR; |
Oshyrath | 1:527a11035e0b | 22 | Y_DIR = NO_DIR; |
Oshyrath | 1:527a11035e0b | 23 | clearEnemies(); |
Oshyrath | 1:527a11035e0b | 24 | clearBullets(); |
Oshyrath | 1:527a11035e0b | 25 | resetPlayer(); |
Oshyrath | 1:527a11035e0b | 26 | clearPowerUps(); |
Oshyrath | 1:527a11035e0b | 27 | levelScore = 0; |
Oshyrath | 1:527a11035e0b | 28 | } |
Oshyrath | 1:527a11035e0b | 29 | char didLoseLife() |
Oshyrath | 1:527a11035e0b | 30 | { |
Oshyrath | 1:527a11035e0b | 31 | return player.health ? 0 : 1; |
Oshyrath | 1:527a11035e0b | 32 | } |
Oshyrath | 1:527a11035e0b | 33 | char isGameOver() |
Oshyrath | 1:527a11035e0b | 34 | { |
Oshyrath | 1:527a11035e0b | 35 | return lives ? 0 : 1; |
Oshyrath | 1:527a11035e0b | 36 | } |
Oshyrath | 1:527a11035e0b | 37 | int8_t shouldAddEnemy() |
Oshyrath | 1:527a11035e0b | 38 | { |
Oshyrath | 1:527a11035e0b | 39 | return enemyCount<(level+2) ? 1 : 0; |
Oshyrath | 1:527a11035e0b | 40 | } |
Oshyrath | 1:527a11035e0b | 41 | void addRandomEnemy() |
Oshyrath | 1:527a11035e0b | 42 | { |
Oshyrath | 1:527a11035e0b | 43 | int16_t x_pos = randomInt(0,LCD_WIDTH-ENEMY_WIDTH); |
Oshyrath | 1:527a11035e0b | 44 | int8_t x_vel_var = level>=3 ? 3 : level; |
Oshyrath | 1:527a11035e0b | 45 | int16_t x_vel = randomInt(-x_vel_var,x_vel_var)*SLOWEST_ENEMY_X_VELOCITY; |
Oshyrath | 1:527a11035e0b | 46 | int8_t y_vel_var = level>=3 ? 3 : level; |
Oshyrath | 1:527a11035e0b | 47 | int16_t y_vel = randomInt(1,y_vel_var)*SLOWEST_ENEMY_Y_VELOCITY; |
Oshyrath | 1:527a11035e0b | 48 | int16_t health = randomInt(1,level); |
Oshyrath | 1:527a11035e0b | 49 | addEnemy(x_pos,x_vel,y_vel,health); |
Oshyrath | 1:527a11035e0b | 50 | } |
Oshyrath | 1:527a11035e0b | 51 | char didLevelUp() |
Oshyrath | 1:527a11035e0b | 52 | { |
Oshyrath | 1:527a11035e0b | 53 | if(levelScore>= level*4+6) |
Oshyrath | 1:527a11035e0b | 54 | return 1; |
Oshyrath | 1:527a11035e0b | 55 | return 0; |
Oshyrath | 1:527a11035e0b | 56 | } |
Oshyrath | 1:527a11035e0b | 57 | void callMultiFunc() |
Oshyrath | 1:527a11035e0b | 58 | { |
Oshyrath | 1:527a11035e0b | 59 | callMultiFuncEnemy(); |
Oshyrath | 1:527a11035e0b | 60 | callMultiFuncBullet(); |
Oshyrath | 1:527a11035e0b | 61 | callMultiFuncPowerUp();//DEBUG!!! |
Oshyrath | 1:527a11035e0b | 62 | callMultiFuncPlayer();//DEBUG!!! |
Oshyrath | 1:527a11035e0b | 63 | } |
Oshyrath | 1:527a11035e0b | 64 | void addWideShotBullets() |
Oshyrath | 1:527a11035e0b | 65 | { |
Oshyrath | 1:527a11035e0b | 66 | int16_t xP = getPlayerBulletPos(X_ID); |
Oshyrath | 1:527a11035e0b | 67 | int16_t yP = getPlayerBulletPos(Y_ID); |
Oshyrath | 1:527a11035e0b | 68 | int16_t yV = -DEFAULT_BULLET_SPEED; |
Oshyrath | 1:527a11035e0b | 69 | int16_t xV_Right = (int16_t)(yV * WIDE_SHOT_X_VELOCITY_FACTOR); |
Oshyrath | 1:527a11035e0b | 70 | int16_t xV_Left = -xV_Right; |
Oshyrath | 1:527a11035e0b | 71 | int8_t powr = player.powerShotTimer ? POWER_BULLET_ID : DEFAULT_BULLET_ID; |
Oshyrath | 1:527a11035e0b | 72 | addPlayerBullet(xP, yP, xV_Right, yV, powr, NOT_BOMB_ID); |
Oshyrath | 1:527a11035e0b | 73 | addPlayerBullet(xP, yP, xV_Left, yV, powr, NOT_BOMB_ID); |
Oshyrath | 1:527a11035e0b | 74 | } |
Oshyrath | 1:527a11035e0b | 75 | |
Oshyrath | 1:527a11035e0b | 76 | void firePlayerBullet() |
Oshyrath | 1:527a11035e0b | 77 | { |
Oshyrath | 1:527a11035e0b | 78 | player.gunTimer = PLAYER_FIRE_PERIOD; |
Oshyrath | 1:527a11035e0b | 79 | int16_t xP = getPlayerBulletPos(X_ID); |
Oshyrath | 1:527a11035e0b | 80 | int16_t yP = getPlayerBulletPos(Y_ID); |
Oshyrath | 1:527a11035e0b | 81 | int16_t xV = 0; |
Oshyrath | 1:527a11035e0b | 82 | int16_t yV = -DEFAULT_BULLET_SPEED; |
Oshyrath | 1:527a11035e0b | 83 | int8_t powr = player.powerShotTimer ? POWER_BULLET_ID : DEFAULT_BULLET_ID; |
Oshyrath | 1:527a11035e0b | 84 | addPlayerBullet(xP, yP, xV, yV, powr, NOT_BOMB_ID); |
Oshyrath | 1:527a11035e0b | 85 | if(player.wideShotTimer) |
Oshyrath | 1:527a11035e0b | 86 | addWideShotBullets(); |
Oshyrath | 1:527a11035e0b | 87 | } |
Oshyrath | 1:527a11035e0b | 88 | int8_t didBulletHitEnemy(struct Enemy * enemy, struct Bullet * bullet) |
Oshyrath | 1:527a11035e0b | 89 | { |
Oshyrath | 1:527a11035e0b | 90 | return !((bullet->y_pos>enemy->y_pos+ENEMY_HEIGHT)|| |
Oshyrath | 1:527a11035e0b | 91 | (bullet->y_pos+BULLET_SIZE<enemy->y_pos)|| |
Oshyrath | 1:527a11035e0b | 92 | (bullet->x_pos>enemy->x_pos+ENEMY_WIDTH)|| |
Oshyrath | 1:527a11035e0b | 93 | (bullet->x_pos+BULLET_SIZE<enemy->x_pos)); |
Oshyrath | 1:527a11035e0b | 94 | |
Oshyrath | 1:527a11035e0b | 95 | } |
Oshyrath | 1:527a11035e0b | 96 | int8_t didBulletHitPlayer(struct Bullet * bullet) |
Oshyrath | 1:527a11035e0b | 97 | { |
Oshyrath | 1:527a11035e0b | 98 | return !((bullet->y_pos>player.y_pos+PLAYER_HEIGHT)|| |
Oshyrath | 1:527a11035e0b | 99 | (bullet->y_pos+BULLET_SIZE<player.y_pos)|| |
Oshyrath | 1:527a11035e0b | 100 | (bullet->x_pos>player.x_pos+PLAYER_WIDTH)|| |
Oshyrath | 1:527a11035e0b | 101 | (bullet->x_pos+BULLET_SIZE<player.x_pos)); |
Oshyrath | 1:527a11035e0b | 102 | } |
Oshyrath | 1:527a11035e0b | 103 | int8_t didPlayerCollideWithEnemy(struct Enemy * enemy) |
Oshyrath | 1:527a11035e0b | 104 | { |
Oshyrath | 1:527a11035e0b | 105 | return !((enemy->y_pos>player.y_pos+PLAYER_HEIGHT)|| |
Oshyrath | 1:527a11035e0b | 106 | (enemy->y_pos+ENEMY_HEIGHT<player.y_pos)|| |
Oshyrath | 1:527a11035e0b | 107 | (enemy->x_pos>player.x_pos+PLAYER_WIDTH)|| |
Oshyrath | 1:527a11035e0b | 108 | (enemy->x_pos+ENEMY_WIDTH<player.x_pos)) && |
Oshyrath | 1:527a11035e0b | 109 | !player.shieldTimer; |
Oshyrath | 1:527a11035e0b | 110 | } |
Oshyrath | 1:527a11035e0b | 111 | void collideBulletsWithPlayer() |
Oshyrath | 1:527a11035e0b | 112 | { |
Oshyrath | 1:527a11035e0b | 113 | int j; |
Oshyrath | 1:527a11035e0b | 114 | for(j = enemyBulletCount; j;j--) |
Oshyrath | 1:527a11035e0b | 115 | { |
Oshyrath | 1:527a11035e0b | 116 | enemyBulletPTR=enemyBulletPTR->next; |
Oshyrath | 1:527a11035e0b | 117 | if(didBulletHitPlayer(enemyBulletPTR)) |
Oshyrath | 1:527a11035e0b | 118 | { |
Oshyrath | 1:527a11035e0b | 119 | dealDamageToPlayer(); |
Oshyrath | 1:527a11035e0b | 120 | removeBullet(enemyBulletPTR); |
Oshyrath | 1:527a11035e0b | 121 | } |
Oshyrath | 1:527a11035e0b | 122 | } |
Oshyrath | 1:527a11035e0b | 123 | } |
Oshyrath | 1:527a11035e0b | 124 | void checkIfBulletsHitEnemies() |
Oshyrath | 1:527a11035e0b | 125 | { |
Oshyrath | 1:527a11035e0b | 126 | int i; |
Oshyrath | 1:527a11035e0b | 127 | for(i = enemyCount; i; i--) |
Oshyrath | 1:527a11035e0b | 128 | { |
Oshyrath | 1:527a11035e0b | 129 | enemyPTR = enemyPTR->next; |
Oshyrath | 1:527a11035e0b | 130 | int j; |
Oshyrath | 1:527a11035e0b | 131 | for(j = playerBulletCount; j;j--) |
Oshyrath | 1:527a11035e0b | 132 | { |
Oshyrath | 1:527a11035e0b | 133 | playerBulletPTR=playerBulletPTR->next; |
Oshyrath | 1:527a11035e0b | 134 | if(didBulletHitEnemy(enemyPTR,playerBulletPTR)) |
Oshyrath | 1:527a11035e0b | 135 | { |
Oshyrath | 1:527a11035e0b | 136 | int16_t PowUpPosX = enemyPTR->x_pos + ENEMY_WIDTH/2 - POWER_UP_SIZE/2; |
Oshyrath | 1:527a11035e0b | 137 | int16_t PowUpPosY = enemyPTR->y_pos + ENEMY_HEIGHT/2 - POWER_UP_SIZE/2; |
Oshyrath | 1:527a11035e0b | 138 | int8_t points = dealDamageToEnemy(enemyPTR,playerBulletPTR->powerShot ? POWER_BULLET_DAMAGE : NORMAL_BULLET_DAMAGE); |
Oshyrath | 1:527a11035e0b | 139 | if(points && probabilityOfSuccess(PROPABILITY_DROP_POWERUP)) |
Oshyrath | 1:527a11035e0b | 140 | addPowerUp(PowUpPosX,PowUpPosY); |
Oshyrath | 1:527a11035e0b | 141 | levelScore+=points; |
Oshyrath | 1:527a11035e0b | 142 | totalScore+=points; |
Oshyrath | 1:527a11035e0b | 143 | removeBullet(playerBulletPTR); |
Oshyrath | 1:527a11035e0b | 144 | if(points) |
Oshyrath | 1:527a11035e0b | 145 | break; |
Oshyrath | 1:527a11035e0b | 146 | } |
Oshyrath | 1:527a11035e0b | 147 | } |
Oshyrath | 1:527a11035e0b | 148 | } |
Oshyrath | 1:527a11035e0b | 149 | } |
Oshyrath | 1:527a11035e0b | 150 | void enemiesFireBullet() |
Oshyrath | 1:527a11035e0b | 151 | { |
Oshyrath | 1:527a11035e0b | 152 | int i; |
Oshyrath | 1:527a11035e0b | 153 | for(i = enemyCount; i; i--) |
Oshyrath | 1:527a11035e0b | 154 | { |
Oshyrath | 1:527a11035e0b | 155 | if(!(enemyPTR->gunTimer)) |
Oshyrath | 1:527a11035e0b | 156 | addEnemyBullet(getEnemyBulletPos(enemyPTR,X_ID),getEnemyBulletPos(enemyPTR,Y_ID)); |
Oshyrath | 1:527a11035e0b | 157 | enemyPTR = enemyPTR->next; |
Oshyrath | 1:527a11035e0b | 158 | } |
Oshyrath | 1:527a11035e0b | 159 | } |
Oshyrath | 1:527a11035e0b | 160 | void generateExplosion() |
Oshyrath | 1:527a11035e0b | 161 | { |
Oshyrath | 1:527a11035e0b | 162 | int16_t xP = getPlayerBulletPos(X_ID); |
Oshyrath | 1:527a11035e0b | 163 | int16_t yP = getPlayerBulletPos(Y_ID); |
Oshyrath | 1:527a11035e0b | 164 | int16_t i; |
Oshyrath | 1:527a11035e0b | 165 | for(i = 0; i<NUMBER_OF_BULLETS_PER_EXPLOSION; i++) |
Oshyrath | 1:527a11035e0b | 166 | { |
Oshyrath | 1:527a11035e0b | 167 | double angle = PI * 2.0 / NUMBER_OF_BULLETS_PER_EXPLOSION * i; |
Oshyrath | 1:527a11035e0b | 168 | int16_t xV = (int16_t)(sin(angle)*DEFAULT_BULLET_SPEED); |
Oshyrath | 1:527a11035e0b | 169 | int16_t yV = (int16_t)(cos(angle)*DEFAULT_BULLET_SPEED); |
Oshyrath | 1:527a11035e0b | 170 | addPlayerBullet(xP, yP, xV, yV, POWER_BULLET_ID, BOMB_BULLET_ID); |
Oshyrath | 1:527a11035e0b | 171 | } |
Oshyrath | 1:527a11035e0b | 172 | } |
Oshyrath | 1:527a11035e0b | 173 | void usePowerUpAbility(enum PowerUpType type) |
Oshyrath | 1:527a11035e0b | 174 | { |
Oshyrath | 1:527a11035e0b | 175 | switch(type) |
Oshyrath | 1:527a11035e0b | 176 | { |
Oshyrath | 1:527a11035e0b | 177 | case PU_RapidFire: |
Oshyrath | 1:527a11035e0b | 178 | player.rapidFireTimer = RAPID_FIRE_TIME; |
Oshyrath | 1:527a11035e0b | 179 | return; |
Oshyrath | 1:527a11035e0b | 180 | case PU_PowerShot: |
Oshyrath | 1:527a11035e0b | 181 | player.powerShotTimer = POWER_SHOT_TIME; |
Oshyrath | 1:527a11035e0b | 182 | return; |
Oshyrath | 1:527a11035e0b | 183 | case PU_FreezeEnemies: |
Oshyrath | 1:527a11035e0b | 184 | freezeEnemies(); |
Oshyrath | 1:527a11035e0b | 185 | return; |
Oshyrath | 1:527a11035e0b | 186 | case PU_WideShot: |
Oshyrath | 1:527a11035e0b | 187 | player.wideShotTimer = WIDE_SHOT_TIME; |
Oshyrath | 1:527a11035e0b | 188 | return; |
Oshyrath | 1:527a11035e0b | 189 | case PU_Explosion: |
Oshyrath | 1:527a11035e0b | 190 | generateExplosion(); |
Oshyrath | 1:527a11035e0b | 191 | return; |
Oshyrath | 1:527a11035e0b | 192 | case PU_BonusHealth: |
Oshyrath | 1:527a11035e0b | 193 | player.health = PLAYER_STARTING_HEALTH; |
Oshyrath | 1:527a11035e0b | 194 | return; |
Oshyrath | 1:527a11035e0b | 195 | case PU_Shield: |
Oshyrath | 1:527a11035e0b | 196 | player.shieldTimer = SHIELD_TIME; |
Oshyrath | 1:527a11035e0b | 197 | return; |
Oshyrath | 1:527a11035e0b | 198 | } |
Oshyrath | 1:527a11035e0b | 199 | } |
Oshyrath | 1:527a11035e0b | 200 | int8_t didPlayerHitPowerUp(struct PowerUp * powerUp) |
Oshyrath | 1:527a11035e0b | 201 | { |
Oshyrath | 1:527a11035e0b | 202 | return !((powerUp->y_pos>player.y_pos+PLAYER_HEIGHT)|| |
Oshyrath | 1:527a11035e0b | 203 | (powerUp->y_pos+POWER_UP_SIZE<player.y_pos)|| |
Oshyrath | 1:527a11035e0b | 204 | (powerUp->x_pos>player.x_pos+PLAYER_WIDTH)|| |
Oshyrath | 1:527a11035e0b | 205 | (powerUp->x_pos+POWER_UP_SIZE<player.x_pos)); |
Oshyrath | 1:527a11035e0b | 206 | } |
Oshyrath | 1:527a11035e0b | 207 | void pickUpPowerUps() |
Oshyrath | 1:527a11035e0b | 208 | { |
Oshyrath | 1:527a11035e0b | 209 | int i; |
Oshyrath | 1:527a11035e0b | 210 | for(i = powerUpCount; i; i--) |
Oshyrath | 1:527a11035e0b | 211 | { |
Oshyrath | 1:527a11035e0b | 212 | powerUpPTR = powerUpPTR->next; |
Oshyrath | 1:527a11035e0b | 213 | if(didPlayerHitPowerUp(powerUpPTR)) |
Oshyrath | 1:527a11035e0b | 214 | { |
Oshyrath | 1:527a11035e0b | 215 | usePowerUpAbility(powerUpPTR->type); |
Oshyrath | 1:527a11035e0b | 216 | removePowerUp(powerUpPTR); |
Oshyrath | 1:527a11035e0b | 217 | } |
Oshyrath | 1:527a11035e0b | 218 | } |
Oshyrath | 1:527a11035e0b | 219 | } |
Oshyrath | 1:527a11035e0b | 220 | void collideWithEnemies() |
Oshyrath | 1:527a11035e0b | 221 | { |
Oshyrath | 1:527a11035e0b | 222 | int i; |
Oshyrath | 1:527a11035e0b | 223 | for(i = enemyCount; i; i--) |
Oshyrath | 1:527a11035e0b | 224 | { |
Oshyrath | 1:527a11035e0b | 225 | enemyPTR = enemyPTR->next; |
Oshyrath | 1:527a11035e0b | 226 | if(didPlayerCollideWithEnemy(enemyPTR)) |
Oshyrath | 1:527a11035e0b | 227 | { |
Oshyrath | 1:527a11035e0b | 228 | player.health = 0; |
Oshyrath | 1:527a11035e0b | 229 | break; |
Oshyrath | 1:527a11035e0b | 230 | } |
Oshyrath | 1:527a11035e0b | 231 | } |
Oshyrath | 1:527a11035e0b | 232 | } |
Oshyrath | 1:527a11035e0b | 233 | void loopIteration() |
Oshyrath | 1:527a11035e0b | 234 | { |
Oshyrath | 1:527a11035e0b | 235 | if(shouldFire(didUserRequestFire)) |
Oshyrath | 1:527a11035e0b | 236 | firePlayerBullet(); |
Oshyrath | 1:527a11035e0b | 237 | didUserRequestFire = 0; |
Oshyrath | 1:527a11035e0b | 238 | if(shouldAddEnemy()) |
Oshyrath | 1:527a11035e0b | 239 | addRandomEnemy(); |
Oshyrath | 1:527a11035e0b | 240 | checkIfBulletsHitEnemies(); |
Oshyrath | 1:527a11035e0b | 241 | movePlayer(X_DIR,Y_DIR); |
Oshyrath | 1:527a11035e0b | 242 | enemiesFireBullet(); |
Oshyrath | 1:527a11035e0b | 243 | pickUpPowerUps(); |
Oshyrath | 1:527a11035e0b | 244 | collideBulletsWithPlayer(); |
Oshyrath | 1:527a11035e0b | 245 | collideWithEnemies(); |
Oshyrath | 1:527a11035e0b | 246 | callMultiFunc(); |
Oshyrath | 1:527a11035e0b | 247 | } |