int main() { SetupAll(); SetupBalls(); DoTimers(); LoadBitmaps(); DoBlock(); while (!key[KEY_ESC] && GoGame == 1) { CheckDead(); CheckBlock(); MoveBall(); if (BallsToDrop > 0) DropBalls(); if (Lives <= 0) GoGame = 0; DrawBack(); CheckExplode(); DrawBalls(); MoveMouse(); MoveStoneBlock(); WaitTimer(); flip(); } EndOfGame(); allegro_exit(); //Clean up allegro return 0; }
void BreakOut::Update(game_info* gi, float deltatime) { bool move = false; if (gi->state == STATE_BREAKOUT_TRANS) { gi->rot2 -= TRANSITION_SPEED * deltatime; if (gi->rot2 <= 0) { gi->rot2 = 0; engine.ChangeState(gi, STATE_TETRIS); } engine.PassMessage(MSG_ROT_BOARD2, (gi->rot2 / 180.0f) * 255.0f, 0,0); return; } if (engine.keys[SDLK_LEFT]) { gi->fine -= BREAKOUT_PADDLE_SPEED * deltatime; float amt = GetLeftBounds(gi); if (gi->fine < amt) { gi->fine = amt; } move = true; } if (engine.keys[SDLK_RIGHT]) { gi->fine += BREAKOUT_PADDLE_SPEED * deltatime; float amt = GetRightBounds(gi); if (gi->fine > amt) { gi->fine = amt; } move = true; } gi->break_out_time -= deltatime; if (gi->break_out_time <= 0) { gi->break_out_time = 0; engine.DisplayMessage(STR_YOUSURVIVED); engine.audio.PlaySound(SND_CHANGEVIEW); engine.ChangeState(gi, STATE_BREAKOUT_TRANS); gi->pos = (int)(gi->fine / 0.5f); gi->fine = 0; return; } if (gi->ball_fast > 0) { gi->ball_fast -= deltatime; if (gi->ball_fast < 0) { gi->ball_fast = 0; if (gi->ball_dx < 0) { gi->ball_dx = -BREAKOUT_BALL_SPEED_X; } else { gi->ball_dx = BREAKOUT_BALL_SPEED_X; } if (gi->ball_dy < 0) { gi->ball_dy = -BREAKOUT_BALL_SPEED_Y; } else { gi->ball_dy = BREAKOUT_BALL_SPEED_Y; } } } if (move) { engine.PassMessage(MSG_UPDATEPADDLE, (unsigned char)((gi->fine / 11.0f) * 255.0f), 0, 0); } // move ball // solve for all collisions! // wall collisions! if (!engine.network_thread) { if (gi->ball_dx < 0) { gi->ball_dx = -(BREAKOUT_BALL_SPEED_X + (LEVEL * 0.2)); } else { gi->ball_dx = (BREAKOUT_BALL_SPEED_X + (LEVEL * 0.2)); } if (gi->ball_dy < 0) { gi->ball_dy = -(BREAKOUT_BALL_SPEED_Y + (LEVEL * 0.2)); } else { gi->ball_dy = (BREAKOUT_BALL_SPEED_Y + (LEVEL * 0.2)); } } MoveBall(gi,deltatime,-1); engine.PassMessage(MSG_UPDATEBALL, ((float)(gi->ball_x) / 20.0f) * 255.0f, ((float)(gi->ball_y) / 20.0f) * 255.0f, 0); if (gi->ball_y < -1.5) { engine.GameOver(); } }
void BreakOut::MoveBall(game_info* gi, float t, int last_type) { float cur_t = 1000.0; int type_t = 0; int board_i = -1; int board_j = -1; float up_t = CheckBallAgainst(gi, t, -5, 11.75, 10, 11.75); float left_t = CheckBallAgainst(gi, t, 0, 13, 0, 0); float right_t = CheckBallAgainst(gi, t, 4.5, 13, 4.5, 0); // check against borders if (gi->ball_dy > 0 && up_t < cur_t && !(1 != last_type)) { cur_t = up_t; type_t |= 1; } if (gi->ball_dx > 0 && right_t < cur_t && !(2 & last_type)) { cur_t = right_t; type_t |= 2; } if (gi->ball_dx < 0 && left_t < cur_t && !(4 & last_type)) { cur_t = left_t; type_t |= 4; } int i,j; // check against the blocks for (i=0; i<10; i++) { for (j=0; j<24; j++) { if (gi->board[i][j] != -1) { if (CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, (float)(i * 0.5f), (float)(j+1) * 0.5f, 0)) { board_i = i; board_j = j; j = 24; i = 10; } } } } // collision against paddle // for all of the blocks that make up the paddle... check against their edges float x,y; x = gi->fine; y = 0; switch (gi->curpiece) { case 0: if (gi->curdir % 2) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-1.0, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); } else { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+1.0, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); } break; case 1: if (gi->curdir % 2) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y-0.5, 1); } else { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y-0.5, 1); } break; case 2: if (gi->curdir % 2) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y-0.5, 1); } else { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y-0.5, 1); } break; case 3: CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y+0.5, 1); break; case 4: if (gi->curdir == 0) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y+0.5, 1); } else if (gi->curdir == 1) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y+0.5, 1); } else if (gi->curdir == 2) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y-0.5, 1); } else { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y-0.5, 1); } break; case 5: if (gi->curdir == 0) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y+0.5, 1); } else if (gi->curdir == 1) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y-0.5, 1); } else if (gi->curdir == 2) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y-0.5, 1); } else { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y+0.5, 1); } break; case 6: if (gi->curdir == 0) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); } else if (gi->curdir == 1) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); } else if (gi->curdir == 2) { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x+0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); } else { CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x-0.5, y, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y+0.5, 1); CheckBallAgainstBlock(gi, t, cur_t, type_t, last_type, x, y-0.5, 1); } break; } // adjust ball, call again if required // no collisions? if (type_t == 0) { // use up all t! gi->ball_x += t * gi->ball_dx; gi->ball_y += t * gi->ball_dy; return; } // we have a collision, move as far as we can gi->ball_x += cur_t * gi->ball_dx; gi->ball_y += cur_t * gi->ball_dy; engine.audio.PlaySound(SND_BOUNCE); // then, change direction, and move the rest of the way t -= cur_t; if (type_t & ~0x7) { gi->break_out_consecutives++; } if (type_t & 1) { // top gi->ball_dy = -gi->ball_dy; } else if (type_t & 2) { // right gi->ball_dx = -gi->ball_dx; } else if (type_t & 4) { // left gi->ball_dx = -gi->ball_dx; } else if (type_t & 8) { // left side block gi->ball_dx = -gi->ball_dx; // get rid of block??? gi->board[board_i][board_j] = -1; engine.PassMessage(MSG_REMOVEBLOCK, board_i, board_j, 0); gi->score += (2 * 100); engine.PassMessage(MSG_APPENDSCORE, 100, 2, 0); } else if (type_t & 16) { // top side block gi->ball_dy = -gi->ball_dy; // get rid of block??? gi->board[board_i][board_j] = -1; engine.PassMessage(MSG_REMOVEBLOCK, board_i, board_j, 0); gi->score += (2 * 100); engine.PassMessage(MSG_APPENDSCORE, 100, 2, 0); } else if (type_t & 32) { // right side block gi->ball_dx = -gi->ball_dx; // get rid of block??? gi->board[board_i][board_j] = -1; engine.PassMessage(MSG_REMOVEBLOCK, board_i, board_j, 0); gi->score += (2 * 100); engine.PassMessage(MSG_APPENDSCORE, 100, 2, 0); } else if (type_t & 64) { // bottom side block gi->ball_dy = -gi->ball_dy; // get rid of block??? gi->board[board_i][board_j] = -1; engine.PassMessage(MSG_REMOVEBLOCK, board_i, board_j, 0); gi->score += (2 * 100); engine.PassMessage(MSG_APPENDSCORE, 100, 2, 0); } // paddle else if (type_t & 128) { if (gi->break_out_consecutives >= 7) { engine.SendAttack(3); } else if (gi->break_out_consecutives >= 5) { engine.SendAttack(2); } else if (gi->break_out_consecutives >= 4) { engine.SendAttack(1); } gi->break_out_consecutives = 0; gi->ball_dx = -gi->ball_dx; } else if (type_t & 256) { if (gi->break_out_consecutives >= 7) { engine.SendAttack(3); } else if (gi->break_out_consecutives >= 5) { engine.SendAttack(2); } else if (gi->break_out_consecutives >= 4) { engine.SendAttack(1); } gi->break_out_consecutives = 0; gi->ball_dy = -gi->ball_dy; } else if (type_t & 512) { if (gi->break_out_consecutives >= 7) { engine.SendAttack(3); } else if (gi->break_out_consecutives >= 5) { engine.SendAttack(2); } else if (gi->break_out_consecutives >= 4) { engine.SendAttack(1); } gi->break_out_consecutives = 0; gi->ball_dx = -gi->ball_dx; } else if (type_t & 1024) { if (gi->break_out_consecutives >= 7) { engine.SendAttack(3); } else if (gi->break_out_consecutives >= 5) { engine.SendAttack(2); } else if (gi->break_out_consecutives >= 4) { engine.SendAttack(1); } gi->break_out_consecutives = 0; gi->ball_dy = -gi->ball_dy; } // call this again MoveBall(gi, t, type_t); }
/** Game event loop. */ void EventLoop() { struct timeval last, current; unsigned long elapsedTime; int repeat; XEvent event; SetFirstLevel(); XSelectInput(display, mainWindow, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); shouldExit = 0; DoStartDelay(); gettimeofday(&last, NULL); while(!shouldExit) { if(didWin) { WinLoop(); NextLevel(); moveRight = 0; moveLeft = 0; gettimeofday(&last, NULL); } if(didLose) { Redraw(); DoStartDelay(); break; } while(XPending(display) > 0) { XNextEvent(display, &event); switch(event.type) { case Expose: HandleExposeEvent(&event.xexpose); break; case KeyPress: HandleKeyPressEvent(&event.xkey); break; case KeyRelease: HandleKeyReleaseEvent(&event.xkey); break; case ButtonPress: HandleButtonPressEvent(); break; default: break; } } if(isPaused) { gettimeofday(&last, NULL); continue; } gettimeofday(¤t, NULL); elapsedTime = (current.tv_sec - last.tv_sec) * 1000000; elapsedTime += current.tv_usec - last.tv_usec; if(elapsedTime >= SPEED) { last = current; EraseBall(); repeat = (int)(((float)elapsedTime / SPEED) + 0.5); do { if(moveRight && !moveLeft) { MoveBallRight(); } else if(moveLeft && !moveRight) { MoveBallLeft(); } MoveBall(); --repeat; } while(repeat); DrawBall(); Redraw(); if(didDie) { didDie = 0; DoStartDelay(); gettimeofday(&last, NULL); } } } }
void BallScene::Update(float dt) { MoveBall(dt,0,25); m_world.Update(dt); }
static void GameLoop(struct BALL *const Ball, struct PADDLE *const Paddle) { /*Primary loop where most events get processed.*/ struct BRICKSTRIKE Strike; int Key = 0; int SecTick = 0; Bool PaddleMovedLastTick; DirectionX PaddleMoveDir; int Inc = 0; Bool Flip = false; int SlowBallTicks = 0, BallNukeTicks = 0; while ((Key = getch()) != 27) /*27 is ESC*/ { if (SecTick == 10) { /*We get score every second for just surviving.*/ Score += 2; DrawStats(); SecTick = 0; } ++SecTick; if (Ball->Y == 1) { /*We hit the ceiling.*/ BounceBallY(Ball, DOWN); } else if (Ball->Y >= BRICKTICK_MAX_Y - 2) { /*More happens when we hit the floor.*/ if (!CheckBallHitPaddle(Ball, Paddle)) { DeleteBall(Ball); Ball->Y = BRICKTICK_MAX_Y - 1; DrawBall(Ball); if (Lives == 1) { /*We ran out of lives.*/ ProcessGameOver(Ball, Paddle); } else { --Lives; DrawStats(); WaitForUserLaunch(); DeleteBall(Ball); DeletePaddle(Paddle); ResetBall(Ball); ResetPaddle(Paddle); DrawPaddle(Paddle); DrawBall(Ball); /*Redraw but don't reset.*/ DrawAllBricks(); } } else { BounceBallY(Ball, UP); if (PaddleMovedLastTick) { /*We can "whack" the ball with our Paddle->*/ Ball->DirX = PaddleMoveDir; } else { /*We cut the paddle into thirds for the X direction after bounce.*/ #define PADDLE_THIRD (Paddle->Length / 3) if (Ball->X <= Paddle->X + PADDLE_THIRD) { Ball->DirX = LEFT; } else if (Ball->X > Paddle->X + PADDLE_THIRD && Ball->X <= Paddle->X + (PADDLE_THIRD * 2)) { /*Make whether we hit up or not as a chance.*/ Bool StraightUp = rand() & 1; if (StraightUp) Ball->DirX = X_NEUTRAL; } else { Ball->DirX = RIGHT; } } } } PaddleMovedLastTick = false; /*Bounce off left and right walls.*/ if (Ball->X >= BRICKTICK_MAX_X - 1) { Ball->X = BRICKTICK_MAX_X - 1; BounceBallX(Ball, LEFT); } else if (Ball->X <= 0) { Ball->X = 0; BounceBallX(Ball, RIGHT); } /*Check if a charm hit the paddle.*/ for (Inc = 0; Inc < BRICK_MAX_NUMLINES * BRICK_MAX_PERLINE; ++Inc) { if (Charms[Inc].Type == CHARM_NONE || !Charms[Inc].Dropped || Charms[Inc].Y != BRICKTICK_MAX_Y - 2) continue; if (CheckCharmHitPaddle(Paddle, Charms + Inc)) { void *Ptr = NULL; const char *const Strings[] = { "+1,000 Score", "+1 Lives", "10 Second Slow Ball", "3 second nuke mode" }; switch (Charms[Inc].Type) { case CHARM_SCORE: Ptr = &Score; break; case CHARM_LIFE: Ptr = &Lives; break; case CHARM_SLOW: Ptr = &SlowBallTicks; break; case CHARM_NUKE: Ptr = &BallNukeTicks; break; default: break; } if (Charms[Inc].Type != CHARM_NONE) { /*Show a message on what type of charm we have here.*/ DrawMessage(Strings[Charms[Inc].Type - 1]); fflush(NULL); usleep(500000); DeleteMessage(); DrawAllBricks(); DrawStats(); } /*Do the thing the charm does.*/ ProcessCharmAction(Charms + Inc, Ptr); } /*In any case, we're done with it.*/ DeleteCharm(Charms + Inc); Charms[Inc].Type = CHARM_NONE; } /*We hit a brick.*/ if (BallStruckBrick(Ball, &Strike)) { if (BallNukeTicks == 0) /*Nuclear ball passes through.*/ { switch (Strike.StrikeV) { case STRIKE_TOP: Ball->DirY = UP; break; case STRIKE_BOTTOM: Ball->DirY = DOWN; break; default: break; } switch (Strike.StrikeH) { case STRIKE_LEFT: Ball->DirX = LEFT; break; case STRIKE_RIGHT: Ball->DirX = RIGHT; break; default: { if (Ball->DirX != X_NEUTRAL) break; else { Bool Dir = rand() & 1; Ball->DirX = (DirectionX)Dir; } break; } } } DeleteBrick(Strike.Brick); Score += 100; DrawStats(); if (!BricksLeft()) { /*Move to next level.*/ if (SetLevel(Level + 1)) { /*We have more levels to go before we win.*/ DeleteAllBricks(); DeleteAllCharms(); DeleteBall(Ball); DeletePaddle(Paddle); DrawStats(); Score += 1000; /*Reward for making it this far.*/ Lives = BRICKTICK_NUMLIVES; ResetBall(Ball); ResetPaddle(Paddle); ResetBricks(); DrawAllBricks(); DrawPaddle(Paddle); WaitForUserLaunch(); DrawBall(Ball); DrawAllBricks(); /*Redraw to fix WaitForUserLaunch() goofing.*/ } else { /*WE WON!!!!*/ char WonBuf[256]; snprintf(WonBuf, sizeof WonBuf, "You Won! Score is %d! Hit ESC to exit or space to play again.", Score); DrawMessage(WonBuf); WinRegetch: switch (getch()) { case 27: /*27 is ESC*/ endwin(); exit(0); break; case ' ': { DeleteMessage(); SetLevel(1); Lives = BRICKTICK_NUMLIVES; Score = 0; DeleteAllBricks(); DeleteAllCharms(); DeleteBall(Ball); DeletePaddle(Paddle); DrawStats(); ResetBall(Ball); ResetPaddle(Paddle); ResetBricks(); DrawAllBricks(); DrawPaddle(Paddle); WaitForUserLaunch(); DrawBall(Ball); DrawAllBricks(); /*Redraw to fix WaitForUserLaunch() goofing.*/ continue; /*For the loop we are in.*/ } default: goto WinRegetch; } } continue; } else { /*Charm drops.*/ struct CHARM *Charm = GetCharmByBrick(Strike.Brick); if (Charm) { /*We DO have a charm for this brick.*/ PerformCharmDrop(Charm); /*Mark it dropped.*/ /*Now draw the charm.*/ DrawCharm(Charm); } } } switch (Key) { /*Paddle movement.*/ case KEY_LEFT: MovePaddle(Paddle, LEFT); PaddleMovedLastTick = true; PaddleMoveDir = LEFT; break; case KEY_RIGHT: MovePaddle(Paddle, RIGHT); PaddleMovedLastTick = true; PaddleMoveDir = RIGHT; break; case 's': /*They want to save the game.*/ if (SaveGame(Ball, Paddle)) { DrawMessage("Game saved."); } else { DrawMessage("Failed to save game."); } fflush(NULL); usleep(500000); DeleteMessage(); DrawAllBricks(); /*Redraw bricks if damaged.*/ break; case 'o': /*They want us to load a game.*/ { const Bool LoadedOk = LoadGame(Ball, Paddle); if (LoadedOk) { /*Restore the state.*/ clear(); DrawBorders(); /*Need to redraw these after clearing the screen.*/ DrawBall(Ball); DrawPaddle(Paddle); DrawStats(); DrawAllBricks(); DrawMessage("Game loaded."); } else { DrawMessage("Failed to load game."); } fflush(NULL); usleep(500000); DeleteMessage(); DrawAllBricks(); break; } case ' ': { DrawMessage("PAUSED"); cbreak(); PauseRegetch: switch (getch()) { case ' ': DeleteMessage(); DrawAllBricks(); /*Redraw to fix what deleting the message messed up.*/ halfdelay(1); break; case 27: /*27 is ESC*/ endwin(); exit(0); break; default: goto PauseRegetch; } } default: break; } Flip = !Flip; /*Ball movement, obviously. Flip is used to keep it at half speed if we got a 'slow' charm.*/ if (Flip || SlowBallTicks == 0) MoveBall(Ball); /*Decrement slow ball ticks until zero, then the ball goes fast again.*/ if (SlowBallTicks > 0) --SlowBallTicks; /*Decrement nuclear ball until ticks hit zero.*/ if (BallNukeTicks > 0) --BallNukeTicks; /*Charm movement.*/ for (Inc = 0; Inc < BRICK_MAX_NUMLINES * BRICK_MAX_PERLINE; ++Inc) { if (Charms[Inc].Type == CHARM_NONE || !Charms[Inc].Dropped) continue; if (Flip) MoveCharm(Charms + Inc); } /*Redraw borders in case of terminal resize.*/ DrawBorders(); } }