Exemple #1
0
ES_Event RunGameplay(ES_Event ThisEvent) {
	ES_Event returnVal;
	returnVal.EventType = ES_NO_EVENT;

	// Initialize nextState as current state
	GameplayState_t nextState = currentState;

	switch (currentState) {

		case INIT:
			if (ThisEvent.EventType == ES_INIT) {
				resetGameplay();
				nextState = ARMED;
				startArmedUX();
			}
			break;

		case ARMED:
			if (ThisEvent.EventType == START_BUTTON_UP) {
				printf("Game Started\r\n");
				// start timers
				ES_Timer_InitTimer(GAME_TIMER, GAME_TIME);
				ES_Timer_InitTimer(INACTION_TIMER, INACTION_TIME);

				// send GAME_STARTED event to TimeOfDaySM
				ES_Event Event2Post;
				Event2Post.EventType = GAME_STARTED;
				// ES_PostAll(Event2Post); // post to TimeOfDay 
				PostTimeOfDay(Event2Post);
				PostEventPrinter(Event2Post);

				stopArmedUX();
				startMixingUX();
				nextChemUX();
				nextState = MIXING;
			}  
			break;
	
		case MIXING:
			switch (ThisEvent.EventType) {
				case CHEM_BUTTON_DOWN:
					if (QueryStir() == STIRRING  && numChems < TOTAL_AMMO * CHEMS_PER_AMMO) {
						if (thisChem == ThisEvent.EventParam) {
							numChems++;
							printf("Correct button press. numChems: %u\r\n", numChems);
							addChemUX();
							if (numChems % CHEMS_PER_AMMO == 0) {
								numAmmo++;
								addChemLightUX();
							}
							if (numChems == TOTAL_AMMO * CHEMS_PER_AMMO) {
								stopMixingUX();
								startSprayingUX();
								nextState = SHOOTING;
								printf("Mixing complete");
							} else {
								nextChemUX();
								printf("Next chem UX");
							}
						} else {
							// if pressed the wrong chemical button
							if (numChems > CHEMS_PER_AMMO)
								numChems -= CHEMS_PER_AMMO;
							else
								numChems = 0;
							
							if (numAmmo > 0)
								numAmmo--;
							// play the sound for wrong chemical added and decrement a light if necessary
							wrongChemAddedUX();
						}
					}
					break;
				case CHEM_BUTTON_UP:
					ES_Timer_InitTimer(INACTION_TIMER, INACTION_TIME);
					break;
				case ES_TIMEOUT:
					if (ThisEvent.EventParam == INACTION_TIMER || ThisEvent.EventParam == GAME_TIMER) {
						
						// send GAME_ENDED event to TimeOfDaySM
						ES_Event Event2Post;
						Event2Post.EventType = GAME_ENDED;
						// ES_PostAll(Event2Post); // only post to TimeOfDay 
						PostTimeOfDay(Event2Post);
						PostEventPrinter(Event2Post);
						
						stopMixingUX();
						startFailUX();
						nextState = FAIL;
						ES_Timer_InitTimer(GAME_STATE_TIMER,FAIL_DISPLAY_TIME);
					}
					break;
			}
			break;
		case SHOOTING:
			switch (ThisEvent.EventType) {
				ES_Event Event2Post;
				case FIRE_READY:
					ES_Timer_InitTimer(INACTION_TIMER, INACTION_TIME);
					fireReadyUX();
					break;
				case FIRE_ON:
					ES_Timer_InitTimer(INACTION_TIMER, INACTION_TIME);
					// UX: Flash indicator light & turn on IR emitter
					fireOnUX();
					break;
				case FIRE_OFF:
					ES_Timer_InitTimer(INACTION_TIMER, INACTION_TIME);
					// UX: Turn off IR emitter & indicator light
					fireOffUX();
					break;
				case CITY_SAVED:
					// UX: Turn that city’s LED blue
					citySavedUX(ThisEvent.EventParam);
					break;
				case ALL_CITIES_SAVED:
					ES_Timer_InitTimer(GAME_STATE_TIMER,WIN_DISPLAY_TIME);
						
					// send GAME_ENDED event to TimeOfDaySM
					Event2Post.EventType = GAME_ENDED;
					// ES_PostAll(Event2Post); // only post to TimeOfDay 
					PostTimeOfDay(Event2Post);
					PostEventPrinter(Event2Post);

					startWinUX();
					nextState = WIN;
					break;
				case USED_ONE_AMMO:
					numAmmo--;
					usedOneAmmoUX();	
					if (numAmmo>0) {
							printf("numAmmo: %u\r\n", numAmmo); // FOR DEBUGGING
							
						} else {

							// send GAME_ENDED event to TimeOfDaySM
							ES_Event Event2Post;
							Event2Post.EventType = GAME_ENDED;
							// ES_PostAll(Event2Post); //  only post to TimeOfDay 
							PostTimeOfDay(Event2Post);
							PostEventPrinter(Event2Post);

							stopSprayingUX();
							startFailUX();
							nextState = FAIL;
							ES_Timer_InitTimer(GAME_STATE_TIMER, FAIL_DISPLAY_TIME);
						}
						break;

				case ES_TIMEOUT:
					if (ThisEvent.EventParam == INACTION_TIMER || ThisEvent.EventParam == GAME_TIMER) {
						// send GAME_ENDED event to TimeOfDaySM
						ES_Event Event2Post;
						Event2Post.EventType = GAME_ENDED;
						// ES_PostAll(Event2Post); //  only post to TimeOfDay 
						PostTimeOfDay(Event2Post);
						PostEventPrinter(Event2Post);
						stopSprayingUX();
						startFailUX();
						nextState = FAIL;
						ES_Timer_InitTimer(GAME_STATE_TIMER, FAIL_DISPLAY_TIME);
					}
					break;
			}
			break;

		case FAIL:
			if ((ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam == GAME_STATE_TIMER) || ThisEvent.EventType == START_BUTTON_UP) {
					// send GAME_ENDED event to TimeOfDaySM
					ES_Event Event2Post;
					Event2Post.EventType = GAME_ENDED;
					// ES_PostAll(Event2Post); // only post to TimeOfDay 
					PostTimeOfDay(Event2Post);
					PostEventPrinter(Event2Post);

					// reset software & hardware
					resetGameplay();
					nextState = ARMED;
					startArmedUX();
			}
			break;
		case WIN:
			if ((ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam == GAME_STATE_TIMER) || ThisEvent.EventType == START_BUTTON_UP) {

					// send GAME_ENDED event to TimeOfDaySM
					ES_Event Event2Post;
					Event2Post.EventType = GAME_ENDED;
					// ES_PostAll(Event2Post); // only post to TimeOfDay 
					PostTimeOfDay(Event2Post);
					PostEventPrinter(Event2Post);

					// reset software & hardware & next state is ARMED
					resetGameplay();
					nextState = ARMED;
					startArmedUX();
			}
			break;
	}
	// set currentState to nextState
	currentState = nextState;

	return returnVal;
}
Exemple #2
0
int main(void)
{
    // seed pseudorandom number generator
    srand48(time(NULL));

    // instantiate window
    GWindow window = newGWindow(WIDTH, HEIGHT);

    // instantiate bricks
    initBricks(window);

    // instantiate ball, centered in middle of window
    GOval ball = initBall(window);

    // instantiate paddle, centered at bottom of window
    GRect paddle = initPaddle(window);

    // instantiate scoreboard, centered in middle of window, just above ball
    GLabel label = initScoreboard(window);

    // number of lives initially
    int lives = LIVES;

    // number of bricks initially
    int bricks = ROWS * COLS;

    // number of points initially
    int points = 0;

    // default ball direction is down
    Velocity *velocity = (Velocity *) malloc(sizeof(Velocity));
    velocity->horizontalVelocity = 0.0;
    velocity->verticalVelocity = 2.0;

    char *paddleDirection = malloc(sizeof(char) * 10);
  
    Paddle *bat = (Paddle *) malloc(sizeof(Paddle));
    bat->paddle = paddle;
    bat->direction = paddleDirection;
    bat->x = getX(paddle);
    bat->y = getY(paddle);

    // show the scoreboard
    updateScoreboard(window, label, points);

    // keep playing until game over
    while (lives > 0 && bricks > 0)
    {
        checkForEvent(bat); 

        GObject object = detectCollision(window, ball);
        if (object != NULL)
        {
            if (object == bat->paddle)
            {
                ballHitsPaddle(bat, velocity, ball);
            }
            else if (strcmp(getType(object), "GRect") == 0)
            {
                ballHitsBrick(velocity, &window, &object, &label, &points, &bricks);
            }
        }
        else
        {
            if (hasBallHitTheSides(&ball, &window))
            {
                invertHorizontalDirection(velocity);
            }
            else if (hasBallHitTheTop(&ball, &window))
            {
                invertVerticalDirection(velocity);
            }
            else if (hasBallHitTheBottom(&ball, &window))
            {
                resetGameplay(velocity, &ball, bat, &lives);
            }
        }

        move(ball, velocity->horizontalVelocity, velocity->verticalVelocity);
        pause(10);
    }

    showGameOverMessage(window, label);

    // wait for click before exiting
    waitForClick();

    // game over
    closeGWindow(window);
    return 0;
}