0% found this document useful (0 votes)
68 views12 pages

Enemyship 2

The document is a header file for a module that manages enemy ship locations in a Galaga-style game. It includes header files, defines constants, and function prototypes related to initializing the module, running its state machine, and updating the ship locations and display. Key functions include initializing the module, running its state machine to handle timeouts and collisions, and posting updates to other modules.

Uploaded by

api-532411015
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views12 pages

Enemyship 2

The document is a header file for a module that manages enemy ship locations in a Galaga-style game. It includes header files, defines constants, and function prototypes related to initializing the module, running its state machine, and updating the ship locations and display. Key functions include initializing the module, running its state machine to handle timeouts and collisions, and posting updates to other modules.

Uploaded by

api-532411015
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

/****************************************************************************

Module
EnemyShip.c

Revision
1.0.1

Description
This is a Service to update enemy ship locations in galaga

Notes

History
When Who What/Why
-------------- --- --------
10/30/20 EM Created File
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "EnemyShip.h"
#include "UpdateOLED.h"
#include "Gameplay.h"
#include "Spaceship.h"
#include "Projectile.h"
#include "DotStarService.h"
/*----------------------------- Module Defines ----------------------------*/
#define OLED_TEST
#define NUM_INIT_ROWS 14
#define TIME_STEP 1000
#define NUM_SHIFTS 0
#define LOSE 2
// how hard game is
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this machine.They should be functions
relevant to the behavior of this state machine
*/
void moveShipsOddREvenL(void);
void moveShipsOddLEvenR(void);
void addRowOddREvenL(void);
void addRowOddLEvenR(void);
bool checkLastRow(void);
void setEnemysToZero(void);
void clearShip(uint8_t index);
/*---------------------------- Module Variables ---------------------------*/
// everybody needs a state variable, you may need others as well.
// type of state variable should match htat of enum in header file
static EnemyShipState_t CurrentState;

// with the introduction of Gen2, we need a module level Priority var as well
static uint8_t MyPriority;
static enemyArray_t XWingPosition;
static uint16_t counter;
static bool enemyRow1[X_WING_COLS];
static bool enemyRow2[X_WING_COLS];
static bool enemyRow3[X_WING_COLS];
static bool enemyRow4[X_WING_COLS];

static uint8_t countMoves;


static uint16_t timeStep;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitTemplateFSM

Parameters
uint8_t : the priorty of this service

Returns
bool, false if error in initialization, true otherwise

Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes

Author
J. Edward Carryer, 10/23/11, 18:55
****************************************************************************/
bool InitEnemyShip(uint8_t Priority)
{
ES_Event_t ThisEvent;

MyPriority = Priority;
// put us into the Initial PseudoState
CurrentState = InitEnemyShipState;

// uint8_t row;
// uint8_t col;
// for(row=0;row<X_WING_ROWS; row++){
// for(col=0;col<X_WING_COLS;col++){
// DEFAULT_ENEMY_POS[row][col] = false;
// }
// }

// post the initial transition event


ThisEvent.EventType = ES_INIT;
if (ES_PostToService(MyPriority, ThisEvent) == true)
{
return true;
}
else
{
return false;
}
}

/****************************************************************************
Function
PostEnemyShip

Parameters
EF_Event_t ThisEvent , the event to post to the queue

Returns
boolean False if the Enqueue operation failed, True otherwise

Description
Posts an event to this state machine's queue
Notes

Author
J. Edward Carryer, 10/23/11, 19:25
****************************************************************************/
bool PostEnemyShip(ES_Event_t ThisEvent)
{
return ES_PostToService(MyPriority, ThisEvent);
}

/****************************************************************************
Function
RunEnemyShip

Parameters
ES_Event_t : the event to process

Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise

Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
J. Edward Carryer, 01/15/12, 15:23
****************************************************************************/
ES_Event_t RunEnemyShip(ES_Event_t ThisEvent)
{
ES_Event_t ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors

//SAMPLE FSM
switch (CurrentState)
{

case InitEnemyShipState: // If current state is initial Psedudo State


{
if(ThisEvent.EventType == ES_INIT){
CurrentState = Idle;
//XWingPosition = DEFAULT_ENEMY_POS;
setEnemysToZero();
counter = 0;
}
}
break;
case Idle: // If current state is state one
{
if(ThisEvent.EventType == ES_START_GAME){
// Updates time step depending on difficulty level selected.
// Smaller time step = more difficult
timeStep = 6000;
timeStep = timeStep - 2000 * ThisEvent.EventParam;
ES_Timer_InitTimer(ENEMY_SHIP_TIMER, 10);
CurrentState = InitOddLEvenR;
//XWingPosition = DEFAULT_ENEMY_POS;
setEnemysToZero();
//addRowOddREvenL();
counter = 0;

ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;
newEvent.EventParam = enemyshipID;
PostUpdateOLED(newEvent);
countMoves=0;
}
}break;
case InitOddLEvenR:
switch (ThisEvent.EventType)
{
case ES_TIMEOUT: //If event is event timeout
{ // Execute action function for state one : event one

//first check if there are any true values in the last row, if so game
is over (a ship has made it to the bottom)
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;

if(checkLastRow()){ //A ship is still in the last row


ES_Event_t gameOverEvent;
gameOverEvent.EventType = ES_GAME_OVER;
gameOverEvent.EventParam = LOSE;
PostGameplay(gameOverEvent);
PostEnemyShip(gameOverEvent);
PostSpaceship(gameOverEvent);
PostProjectile(gameOverEvent);
PostDotStarService(gameOverEvent);
newEvent.EventType = gameoverID;
}else{
newEvent.EventParam = enemyshipID;
ES_Timer_InitTimer(ENEMY_SHIP_TIMER, timeStep);
}

moveShipsOddREvenL(); //Decide what the next state will be


addRowOddREvenL();
counter++;

PostUpdateOLED(newEvent);
// if(countMoves < NUM_SHIFTS){
// countMoves++;
// if(counter > NUM_INIT_ROWS){
// CurrentState = OddLEvenR;
// }else{
// CurrentState = InitOddLEvenR;
// }
// }else{
// countMoves=0;
if(counter > NUM_INIT_ROWS){
CurrentState = OddLEvenR;
}else{
CurrentState = InitOddLEvenR;
}
// }

}
break;
case ES_COLLISION:
{
puts("\rCollision Received in Enemy Ships");
clearShip(ThisEvent.EventParam);
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;
newEvent.EventParam = enemyshipID;
PostUpdateOLED(newEvent);
}break;
case ES_GAME_OVER:
{
CurrentState = Idle;
//XWingPosition = DEFAULT_ENEMY_POS;
setEnemysToZero();
counter = 0;
}break;
default:
{}
}break;

//NOTE: This state was created so that we could make more complex ship
movements
// however, after testing, we liked the basic zig zag movement best.
// Therefore, this state and OddREvenL are not used.
case InitOddREvenL:
switch (ThisEvent.EventType)
{
case ES_TIMEOUT: //If event is event timeout
{ // Execute action function for state one : event one
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;

if(checkLastRow()){ //A ship is still in the last row


ES_Event_t gameOverEvent;
gameOverEvent.EventType = ES_GAME_OVER;
PostGameplay(gameOverEvent);
PostEnemyShip(gameOverEvent);
PostSpaceship(gameOverEvent);
PostProjectile(gameOverEvent);
PostDotStarService(gameOverEvent);
newEvent.EventType = gameoverID;
}else{
newEvent.EventParam = enemyshipID;
ES_Timer_InitTimer(ENEMY_SHIP_TIMER, timeStep);
}

moveShipsOddLEvenR(); //Decide what the next state will be


addRowOddLEvenR();
counter++;
PostUpdateOLED(newEvent);
// if(countMoves < NUM_SHIFTS){
// countMoves++;
// if(counter > NUM_INIT_ROWS){
// CurrentState = OddREvenL;
// }else{
// CurrentState = InitOddREvenL;
// }
// }else{
// countMoves=0;
if(counter > NUM_INIT_ROWS){
CurrentState = OddLEvenR;
}else{
CurrentState = InitOddLEvenR;
}
// }
}
break;
case ES_COLLISION:
{
puts("\rCollision Received in Enemy Ships");
clearShip(ThisEvent.EventParam);
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;
newEvent.EventParam = enemyshipID;
PostUpdateOLED(newEvent);
}break;
case ES_GAME_OVER:
{
CurrentState = Idle;
//XWingPosition = DEFAULT_ENEMY_POS;
setEnemysToZero();
counter = 0;
}break;
default:
{}
}break;

case OddLEvenR:
switch (ThisEvent.EventType)
{
case ES_TIMEOUT: //If event is event timeout
{ // Execute action function for state one : event one
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;

if(checkLastRow()){ //A ship is still in the last row


ES_Event_t gameOverEvent;
gameOverEvent.EventType = ES_GAME_OVER;
PostGameplay(gameOverEvent);
PostEnemyShip(gameOverEvent);
PostSpaceship(gameOverEvent);
PostProjectile(gameOverEvent);
PostDotStarService(gameOverEvent);
newEvent.EventType = gameoverID;
}else{
newEvent.EventParam = enemyshipID;
ES_Timer_InitTimer(ENEMY_SHIP_TIMER, timeStep);
}

moveShipsOddREvenL(); //Decide what the next state will be


// if(countMoves < NUM_SHIFTS){
// countMoves++;
// CurrentState = OddLEvenR;
// }else{
// countMoves=0;
CurrentState = OddLEvenR;
// }
PostUpdateOLED(newEvent);
}
break;
case ES_COLLISION:
{
puts("\rCollision Received in Enemy Ships");
clearShip(ThisEvent.EventParam);
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;
newEvent.EventParam = enemyshipID;
PostUpdateOLED(newEvent);
}break;
case ES_GAME_OVER:
{
CurrentState = Idle;
//XWingPosition = DEFAULT_ENEMY_POS;
setEnemysToZero();
counter = 0;
}break;
default:
{}
}break;

case OddREvenL:
switch (ThisEvent.EventType)
{
case ES_TIMEOUT: //If event is event timeout
{ // Execute action function for state one : event one
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;

if(checkLastRow()){ //A ship is still in the last row


ES_Event_t gameOverEvent;
gameOverEvent.EventType = ES_GAME_OVER;
PostGameplay(gameOverEvent);
PostEnemyShip(gameOverEvent);
PostSpaceship(gameOverEvent);
PostProjectile(gameOverEvent);
PostDotStarService(gameOverEvent);
newEvent.EventType = gameoverID;
}else{
newEvent.EventParam = enemyshipID;
ES_Timer_InitTimer(ENEMY_SHIP_TIMER, timeStep);
}

moveShipsOddLEvenR(); //Decide what the next state will be


// if(countMoves < NUM_SHIFTS){
// countMoves++;
// CurrentState = OddREvenL;
// }else{
// countMoves=0;
CurrentState = OddLEvenR;
// }
PostUpdateOLED(newEvent);
}
break;
case ES_COLLISION:
{
clearShip(ThisEvent.EventParam);
ES_Event_t newEvent;
newEvent.EventType = ES_UPDATE_OLED;
newEvent.EventParam = enemyshipID;
PostUpdateOLED(newEvent);
}break;
case ES_GAME_OVER:
{
CurrentState = Idle;
//XWingPosition = DEFAULT_ENEMY_POS;
setEnemysToZero();
counter = 0;
}break;
default:
{}
}break;
// repeat state pattern as required for other states
default:
{}
} // end switch on Current State
return ReturnEvent;
}

/****************************************************************************
Function
QueryEnemyShip

Parameters
None

Returns
EnemyShipState_t The current state of the enemy ships state machine

Description
returns the current state of the Template state machine
Notes
Author
J. Edward Carryer, 10/23/11, 19:21
****************************************************************************/
EnemyShipState_t QueryEnemyShip(void)
{
return CurrentState;
}

//recieves a pointer to an array as a parameter and it populates that array with


the current ship locations
void QueryEnemyShipPosition(enemyArray_t* posArray){

uint8_t j;
for(j=0; j<X_WING_COLS; j++){
(*posArray)[0][j] = enemyRow1[j];
}
for(j=0; j<X_WING_COLS; j++){
(*posArray)[1][j] = enemyRow2[j];
}
for(j=0; j<X_WING_COLS; j++){
(*posArray)[2][j] = enemyRow3[j];
}
for(j=0; j<X_WING_COLS; j++){
(*posArray)[3][j] = enemyRow4[j];
}
}

//returns the status (true/false) of a given ship location


bool QueryLocationStatus(uint8_t location){
uint8_t rowNum = location/10;
uint8_t colNum = location%10;
bool returnVal = false;
switch (rowNum){
case 0:
{
returnVal = enemyRow1[colNum];
}break;
case 1:
{
returnVal = enemyRow2[colNum];
}break;
case 2:
{
returnVal = enemyRow3[colNum];
}break;
case 3:
{
returnVal = enemyRow4[colNum];
}break;
default:
;
}
return returnVal;
}
/***************************************************************************
private functions
***************************************************************************/
void moveShipsOddREvenL(void){

bool newRow1 [X_WING_COLS];


bool newRow2 [X_WING_COLS];
bool newRow3 [X_WING_COLS];
bool newRow4 [X_WING_COLS];
uint8_t i;
for(i=0; i<X_WING_COLS; i++){
newRow1[i] = false;
newRow2[i] = false;
newRow3[i] = false;
newRow4[i] = false;
}
for(i=0; i<X_WING_COLS-1; i++){
newRow2[i+1] = enemyRow1[i];
newRow3[i] = enemyRow2[i+1];
newRow4[i+1] = enemyRow3[i];
}
for(i=0; i<X_WING_COLS; i++){
enemyRow1[i] = newRow1[i];
enemyRow2[i] = newRow2[i];
enemyRow3[i] = newRow3[i];
enemyRow4[i] = newRow4[i];
}

void moveShipsOddLEvenR(void){
bool newRow1 [X_WING_COLS];
bool newRow2 [X_WING_COLS];
bool newRow3 [X_WING_COLS];
bool newRow4 [X_WING_COLS];
uint8_t i;
for(i=0; i<X_WING_COLS; i++){
newRow1[i] = false;
newRow2[i] = false;
newRow3[i] = false;
newRow4[i] = false;
}
for(i=0; i<X_WING_COLS-1; i++){
newRow2[i] = enemyRow1[i+1];
newRow3[i+1] = enemyRow2[i];
newRow4[i] = enemyRow3[i+1];
}
for(i=0; i<X_WING_COLS; i++){
enemyRow1[i] = newRow1[i];
enemyRow2[i] = newRow2[i];
enemyRow3[i] = newRow3[i];
enemyRow4[i] = newRow4[i];
}

void addRowOddREvenL(void){
uint8_t i;
for(i=0; i<X_WING_COLS-1; i+=2){ //stop at 1 col from right because for row 0
(even) it is offset to the left
enemyRow1[i] = true;
//XWingPosition[0][i] = true; //add in first row of ships
}

void addRowOddLEvenR(void){
uint8_t i;
for(i=1; i<X_WING_COLS; i+=2){ //starting with i=1 because for row 0 (even) it
is offset to the right
enemyRow1[i] = true;
//XWingPosition[0][i] = true; //add in first row of ships
}
}

bool checkLastRow(void){
uint8_t i;
bool returnVal = false;
for(i=0; i<X_WING_COLS; i++){
if(enemyRow4[i]){
returnVal = true;
}
// if(XWingPosition[X_WING_ROWS-1][i]){ //look at every value in the last
row
// returnVal = true;
// }
}
return returnVal;
}

void setEnemysToZero(void){
//XWingPosition = DEFAULT_ENEMY_POS;
uint8_t i;
for(i=0; i<X_WING_COLS; i++){
enemyRow1[i] = false;
enemyRow2[i] = false;
enemyRow3[i] = false;
enemyRow4[i] = false;
}
}

void clearShip(uint8_t index){


uint8_t rowNum = index/10;
uint8_t colNum = index%10;
switch (rowNum){
case 0:
{
enemyRow1[colNum] = false;
}break;
case 1:
{
enemyRow2[colNum] = false;
}break;
case 2:
{
enemyRow3[colNum] = false;
}break;
case 3:
{
enemyRow4[colNum] = false;
}break;
}

You might also like