![](/media/cache/profiles/fa1fc368935a59b748bec5e15aca97ea.jpg.50x50_q85.png)
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
- Committer:
- Oshyrath
- Date:
- 2017-11-17
- Revision:
- 1:527a11035e0b
File content as of revision 1:527a11035e0b:
#include "Game.h" int16_t level; int16_t levelScore; int16_t totalScore; int16_t lives; int8_t X_DIR; int8_t Y_DIR; int8_t didUserRequestFire; void newGame() { lives = STARTING_LIFE_TOTAL; level = 1; levelScore = 0; totalScore = 0; } void newLevel() { X_DIR = NO_DIR; Y_DIR = NO_DIR; clearEnemies(); clearBullets(); resetPlayer(); clearPowerUps(); levelScore = 0; } char didLoseLife() { return player.health ? 0 : 1; } char isGameOver() { return lives ? 0 : 1; } int8_t shouldAddEnemy() { return enemyCount<(level+2) ? 1 : 0; } void addRandomEnemy() { int16_t x_pos = randomInt(0,LCD_WIDTH-ENEMY_WIDTH); int8_t x_vel_var = level>=3 ? 3 : level; int16_t x_vel = randomInt(-x_vel_var,x_vel_var)*SLOWEST_ENEMY_X_VELOCITY; int8_t y_vel_var = level>=3 ? 3 : level; int16_t y_vel = randomInt(1,y_vel_var)*SLOWEST_ENEMY_Y_VELOCITY; int16_t health = randomInt(1,level); addEnemy(x_pos,x_vel,y_vel,health); } char didLevelUp() { if(levelScore>= level*4+6) return 1; return 0; } void callMultiFunc() { callMultiFuncEnemy(); callMultiFuncBullet(); callMultiFuncPowerUp();//DEBUG!!! callMultiFuncPlayer();//DEBUG!!! } void addWideShotBullets() { int16_t xP = getPlayerBulletPos(X_ID); int16_t yP = getPlayerBulletPos(Y_ID); int16_t yV = -DEFAULT_BULLET_SPEED; int16_t xV_Right = (int16_t)(yV * WIDE_SHOT_X_VELOCITY_FACTOR); int16_t xV_Left = -xV_Right; int8_t powr = player.powerShotTimer ? POWER_BULLET_ID : DEFAULT_BULLET_ID; addPlayerBullet(xP, yP, xV_Right, yV, powr, NOT_BOMB_ID); addPlayerBullet(xP, yP, xV_Left, yV, powr, NOT_BOMB_ID); } void firePlayerBullet() { player.gunTimer = PLAYER_FIRE_PERIOD; int16_t xP = getPlayerBulletPos(X_ID); int16_t yP = getPlayerBulletPos(Y_ID); int16_t xV = 0; int16_t yV = -DEFAULT_BULLET_SPEED; int8_t powr = player.powerShotTimer ? POWER_BULLET_ID : DEFAULT_BULLET_ID; addPlayerBullet(xP, yP, xV, yV, powr, NOT_BOMB_ID); if(player.wideShotTimer) addWideShotBullets(); } int8_t didBulletHitEnemy(struct Enemy * enemy, struct Bullet * bullet) { return !((bullet->y_pos>enemy->y_pos+ENEMY_HEIGHT)|| (bullet->y_pos+BULLET_SIZE<enemy->y_pos)|| (bullet->x_pos>enemy->x_pos+ENEMY_WIDTH)|| (bullet->x_pos+BULLET_SIZE<enemy->x_pos)); } int8_t didBulletHitPlayer(struct Bullet * bullet) { return !((bullet->y_pos>player.y_pos+PLAYER_HEIGHT)|| (bullet->y_pos+BULLET_SIZE<player.y_pos)|| (bullet->x_pos>player.x_pos+PLAYER_WIDTH)|| (bullet->x_pos+BULLET_SIZE<player.x_pos)); } int8_t didPlayerCollideWithEnemy(struct Enemy * enemy) { return !((enemy->y_pos>player.y_pos+PLAYER_HEIGHT)|| (enemy->y_pos+ENEMY_HEIGHT<player.y_pos)|| (enemy->x_pos>player.x_pos+PLAYER_WIDTH)|| (enemy->x_pos+ENEMY_WIDTH<player.x_pos)) && !player.shieldTimer; } void collideBulletsWithPlayer() { int j; for(j = enemyBulletCount; j;j--) { enemyBulletPTR=enemyBulletPTR->next; if(didBulletHitPlayer(enemyBulletPTR)) { dealDamageToPlayer(); removeBullet(enemyBulletPTR); } } } void checkIfBulletsHitEnemies() { int i; for(i = enemyCount; i; i--) { enemyPTR = enemyPTR->next; int j; for(j = playerBulletCount; j;j--) { playerBulletPTR=playerBulletPTR->next; if(didBulletHitEnemy(enemyPTR,playerBulletPTR)) { int16_t PowUpPosX = enemyPTR->x_pos + ENEMY_WIDTH/2 - POWER_UP_SIZE/2; int16_t PowUpPosY = enemyPTR->y_pos + ENEMY_HEIGHT/2 - POWER_UP_SIZE/2; int8_t points = dealDamageToEnemy(enemyPTR,playerBulletPTR->powerShot ? POWER_BULLET_DAMAGE : NORMAL_BULLET_DAMAGE); if(points && probabilityOfSuccess(PROPABILITY_DROP_POWERUP)) addPowerUp(PowUpPosX,PowUpPosY); levelScore+=points; totalScore+=points; removeBullet(playerBulletPTR); if(points) break; } } } } void enemiesFireBullet() { int i; for(i = enemyCount; i; i--) { if(!(enemyPTR->gunTimer)) addEnemyBullet(getEnemyBulletPos(enemyPTR,X_ID),getEnemyBulletPos(enemyPTR,Y_ID)); enemyPTR = enemyPTR->next; } } void generateExplosion() { int16_t xP = getPlayerBulletPos(X_ID); int16_t yP = getPlayerBulletPos(Y_ID); int16_t i; for(i = 0; i<NUMBER_OF_BULLETS_PER_EXPLOSION; i++) { double angle = PI * 2.0 / NUMBER_OF_BULLETS_PER_EXPLOSION * i; int16_t xV = (int16_t)(sin(angle)*DEFAULT_BULLET_SPEED); int16_t yV = (int16_t)(cos(angle)*DEFAULT_BULLET_SPEED); addPlayerBullet(xP, yP, xV, yV, POWER_BULLET_ID, BOMB_BULLET_ID); } } void usePowerUpAbility(enum PowerUpType type) { switch(type) { case PU_RapidFire: player.rapidFireTimer = RAPID_FIRE_TIME; return; case PU_PowerShot: player.powerShotTimer = POWER_SHOT_TIME; return; case PU_FreezeEnemies: freezeEnemies(); return; case PU_WideShot: player.wideShotTimer = WIDE_SHOT_TIME; return; case PU_Explosion: generateExplosion(); return; case PU_BonusHealth: player.health = PLAYER_STARTING_HEALTH; return; case PU_Shield: player.shieldTimer = SHIELD_TIME; return; } } int8_t didPlayerHitPowerUp(struct PowerUp * powerUp) { return !((powerUp->y_pos>player.y_pos+PLAYER_HEIGHT)|| (powerUp->y_pos+POWER_UP_SIZE<player.y_pos)|| (powerUp->x_pos>player.x_pos+PLAYER_WIDTH)|| (powerUp->x_pos+POWER_UP_SIZE<player.x_pos)); } void pickUpPowerUps() { int i; for(i = powerUpCount; i; i--) { powerUpPTR = powerUpPTR->next; if(didPlayerHitPowerUp(powerUpPTR)) { usePowerUpAbility(powerUpPTR->type); removePowerUp(powerUpPTR); } } } void collideWithEnemies() { int i; for(i = enemyCount; i; i--) { enemyPTR = enemyPTR->next; if(didPlayerCollideWithEnemy(enemyPTR)) { player.health = 0; break; } } } void loopIteration() { if(shouldFire(didUserRequestFire)) firePlayerBullet(); didUserRequestFire = 0; if(shouldAddEnemy()) addRandomEnemy(); checkIfBulletsHitEnemies(); movePlayer(X_DIR,Y_DIR); enemiesFireBullet(); pickUpPowerUps(); collideBulletsWithPlayer(); collideWithEnemies(); callMultiFunc(); }