/* run : worker thread for ball control along with AI generation */ void run(void *vsocket){ int sock = *(int *)&vsocket; int echolen; RTIME sleep; // as nano-seconds if(ballThreadSpeed % 6 == 0) ballThreadSpeed++; sleep = (RTIME)(50000000 / (ballThreadSpeed % 6)); rt_task_suspend(NULL); while (true){ ballmove(); echolen = strlen(ballData); if(send(sock, ballData, echolen, 0) != echolen) rt_err("send()"); if(AIMode){ opponentMovement(AImoveGenerate()); echolen = strlen(moveData[1]); if(send(sock, moveData[1], echolen, 0) != echolen) rt_err("send()"); } if(reset){ resetBall(); echolen = strlen(gameData); if(send(sock, gameData, echolen, 0) != echolen) rt_err("send()"); } if(bounceplayer){ bounceDirection(player,ball.radius); bounceplayer = false; } if(bounceOpponent){ bounceDirection(opponent,ball.radius); bounceOpponent = false; } rt_task_sleep(sleep); } }
//----------------------------------------------------------- // program entry point //----------------------------------------------------------- int main( void ) //----------------------------------------------------------- { // setup things setupInterrupts(); setupGraphics(); resetBall(); // start main loop while( 1 ) { // update game logic processLogic(); // wait for new frame swiWaitForVBlank(); // update graphics updateGraphics(); } return 0; }
/* * Called when the user presses a key. */ void key_pressed(unsigned char key, int x, int y) { switch (key) { case 27: // Esc case 'q': cleanup(); exit(0); break; // Add any keys you want to use, either for debugging or gameplay. case ' ': play = !play; break; // case '1': // load_world(0); // break; // case '2': // load_world(1); // break; // case '3': // load_world(2); // break; // case '4': // load_world(3); // break; // case '5': // load_world(4); // break; case 'r': /* Reset level. */ load_world(current_level - 1); break; case 'b': /* Reset ball to starting position. */ resetBall(); break; default: break; } }
void GameState::update(int milliseconds) { if (m_balls <= 0) { return; } // update ball position m_ball.position += milliseconds * m_ball.velocity; // have we lost? if (m_ball.position.y >= 1) { resetBall(); --m_balls; if (m_balls == 0) { g_sound_engine.playSound(LOSE_GAME); } else { g_sound_engine.playSound(DIE); } return; } detectCollisions(); }
void DuelMatch::step() { events = external_events; // in pause mode, step does nothing if(mPaused) return; mTransformedInput[LEFT_PLAYER] = mInputSources[LEFT_PLAYER]->updateInput(); mTransformedInput[RIGHT_PLAYER] = mInputSources[RIGHT_PLAYER]->updateInput(); if(!mRemote) { mTransformedInput[LEFT_PLAYER] = mLogic->transformInput( mTransformedInput[LEFT_PLAYER], LEFT_PLAYER ); mTransformedInput[RIGHT_PLAYER] = mLogic->transformInput( mTransformedInput[RIGHT_PLAYER], RIGHT_PLAYER ); } // do steps in physic an logic mLogic->step(); int physicEvents = mPhysicWorld->step( mTransformedInput[LEFT_PLAYER], mTransformedInput[RIGHT_PLAYER], mLogic->isBallValid(), mLogic->isGameRunning() ); // check for all hit events if(!mRemote) events |= physicEvents; // process events if(events & EVENT_LEFT_BLOBBY_HIT) mLogic->onBallHitsPlayer(LEFT_PLAYER); if(events & EVENT_RIGHT_BLOBBY_HIT) mLogic->onBallHitsPlayer(RIGHT_PLAYER); if(events & EVENT_BALL_HIT_LEFT_GROUND) mLogic->onBallHitsGround(LEFT_PLAYER); if(events & EVENT_BALL_HIT_RIGHT_GROUND) mLogic->onBallHitsGround(RIGHT_PLAYER); if(events & EVENT_BALL_HIT_LEFT_WALL) mLogic->onBallHitsWall(LEFT_PLAYER); if(events & EVENT_BALL_HIT_RIGHT_WALL) mLogic->onBallHitsWall(RIGHT_PLAYER); if(events & EVENT_BALL_HIT_NET_LEFT) mLogic->onBallHitsNet(LEFT_PLAYER); if(events & EVENT_BALL_HIT_NET_RIGHT) mLogic->onBallHitsNet(RIGHT_PLAYER); if(events & EVENT_BALL_HIT_NET_TOP) mLogic->onBallHitsNet(NO_PLAYER); switch(mLogic->getLastErrorSide()){ case LEFT_PLAYER: events |= EVENT_ERROR_LEFT; case RIGHT_PLAYER: // if the error was caused by the right player // reset EVENT_ERROR_LEFT events &= ~EVENT_ERROR_LEFT; events |= EVENT_ERROR_RIGHT; mPhysicWorld->setBallVelocity( mPhysicWorld->getBallVelocity().scale(0.6) ); break; default: if ((events & EVENT_BALL_HIT_GROUND) && !mLogic->isBallValid()) { mPhysicWorld->setBallVelocity( mPhysicWorld->getBallVelocity().scale(0.6) ); } break; } // if the round is finished, we // reset BallDown, reset the World // to let the player serve // and trigger the EVENT_RESET if (!mLogic->isBallValid() && canStartRound(mLogic->getServingPlayer())) { resetBall( mLogic->getServingPlayer() ); mLogic->onServe(); events |= EVENT_RESET; } // reset external events external_events = 0; }
void DuelMatch::setServingPlayer(PlayerSide side) { mLogic->setServingPlayer( side ); resetBall( side ); mLogic->onServe( ); }
void Main::updateStateFrame(double simulation_frame_time) { mBallSpeed *= 1.0 + (simulation_frame_time * 0.05); // move paddle 1 float move1 = 0; if(dt::InputManager::get()->getKeyboard()->isKeyDown(OIS::KC_W)) { move1 += 1; } if(dt::InputManager::get()->getKeyboard()->isKeyDown(OIS::KC_S)) { move1 -= 1; } float new_y1 = mPaddle1Node->getPosition().y + move1 * simulation_frame_time * 8; if(new_y1 > FIELD_HEIGHT / 2 - PADDLE_SIZE / 2) new_y1 = FIELD_HEIGHT / 2 - PADDLE_SIZE / 2; else if(new_y1 < - FIELD_HEIGHT / 2 + PADDLE_SIZE / 2) new_y1 = - FIELD_HEIGHT / 2 + PADDLE_SIZE / 2; mPaddle1Node->setPosition(Ogre::Vector3( mPaddle1Node->getPosition().x, new_y1, mPaddle1Node->getPosition().z)); // move paddle 2 float move2 = 0; if(dt::InputManager::get()->getKeyboard()->isKeyDown(OIS::KC_UP)) { move2 += 1; } if(dt::InputManager::get()->getKeyboard()->isKeyDown(OIS::KC_DOWN)) { move2 -= 1; } float new_y2 = mPaddle2Node->getPosition().y + move2 * simulation_frame_time * 8; if(new_y2 > FIELD_HEIGHT / 2 - PADDLE_SIZE / 2) new_y2 = FIELD_HEIGHT / 2 - PADDLE_SIZE / 2; else if(new_y2 < - FIELD_HEIGHT / 2 + PADDLE_SIZE / 2) new_y2 = - FIELD_HEIGHT / 2 + PADDLE_SIZE / 2; mPaddle2Node->setPosition(Ogre::Vector3( mPaddle2Node->getPosition().x, new_y2, mPaddle2Node->getPosition().z)); // move ball Ogre::Vector3 newpos(mBallNode->getPosition() + mBallSpeed * simulation_frame_time); if(newpos.y >= FIELD_HEIGHT / 2 - 0.5 || newpos.y <= -FIELD_HEIGHT / 2 + 0.5) { mBallSpeed.y *= -1; } if(newpos.x >= FIELD_WIDTH / 2 - 0.5) { float paddle_y = mPaddle2Node->getPosition().y; if(newpos.y < paddle_y - PADDLE_SIZE / 2 - 0.5 || newpos.y > paddle_y + PADDLE_SIZE / 2 + 0.5) { dt::Logger::get().info("Player lost!"); ++mScore1; resetBall(); } else { mBallSpeed.x *= -1; } } else if(newpos.x <= -FIELD_WIDTH / 2 + 0.5) { float paddle_y = mPaddle1Node->getPosition().y; if(newpos.y < paddle_y - PADDLE_SIZE / 2 - 0.5 || newpos.y > paddle_y + PADDLE_SIZE / 2 + 0.5) { dt::Logger::get().info("Computer lost!"); ++mScore2; resetBall(); } else { mBallSpeed.x *= -1; } } mBallNode->setPosition(mBallNode->getPosition() + mBallSpeed * simulation_frame_time); Ogre::Quaternion q; q.FromAngleAxis(Ogre::Radian(Ogre::Math::Cos(Ogre::Radian(dt::Root::getInstance().getTimeSinceInitialize() * 0.2))) * 0.1, Ogre::Vector3::UNIT_X); Ogre::Quaternion w; w.FromAngleAxis(Ogre::Radian(Ogre::Math::Sin(Ogre::Radian(dt::Root::getInstance().getTimeSinceInitialize() * 0.2))) * 0.1, Ogre::Vector3::UNIT_Y); mGameNode->setRotation(q * w); }
void Main::onInitialize() { mScore1 = 0; mScore2 = 0; auto scene = addScene(new dt::Scene("testscene")); OgreProcedural::Root::getInstance()->sceneManager = scene->getSceneManager(); dt::ResourceManager::get()->addResourceLocation("","FileSystem", true); Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); Ogre::FontManager::getSingleton().load("DejaVuSans", "General"); auto camnode = scene->addChildNode(new dt::Node("camnode")); camnode->setPosition(Ogre::Vector3(0, 0, 30)); camnode->addComponent(new dt::CameraComponent("cam"))->lookAt(Ogre::Vector3(0, 0, 0)); auto lightnode = scene->addChildNode(new dt::Node("lightnode")); lightnode->setPosition(Ogre::Vector3(-20, 20, 10)); lightnode->addComponent(new dt::LightComponent("light")); // generate meshes OgreProcedural::BoxGenerator().setSizeX(FIELD_WIDTH + 1).setSizeY(FIELD_HEIGHT).setSizeZ(1.f).realizeMesh("Field"); OgreProcedural::BoxGenerator().setSizeX(1.0).setSizeY(1.f).setSizeZ(1.f).realizeMesh("Ball"); OgreProcedural::BoxGenerator().setSizeX(1.0).setSizeY(3.f).setSizeZ(1.f).realizeMesh("Paddle"); mGameNode = scene->addChildNode(new dt::Node("game")); mFieldNode = mGameNode->addChildNode(new dt::Node("field")); mFieldNode->setPosition(Ogre::Vector3(0, 0, -1)); mFieldNode->addComponent(new dt::MeshComponent("Field", "SimplePongField", "mesh")); mBallNode = mGameNode->addChildNode(new dt::Node("ball")); mBallNode->setPosition(Ogre::Vector3(0, 0, 0)); mBallNode->addComponent(new dt::MeshComponent("Ball", "SimplePongBall", "mesh")); mPaddle1Node = mGameNode->addChildNode(new dt::Node("paddle1")); mPaddle1Node->setPosition(Ogre::Vector3(- FIELD_WIDTH / 2 - 0.5, 0, 0)); mPaddle1Node->addComponent(new dt::MeshComponent("Paddle", "SimplePongPaddle", "mesh")); mPaddle2Node = mGameNode->addChildNode(new dt::Node("paddle2")); mPaddle2Node->setPosition(Ogre::Vector3(FIELD_WIDTH / 2 + 0.5, 0, 0)); mPaddle2Node->addComponent(new dt::MeshComponent("Paddle", "SimplePongPaddle", "mesh")); auto score1_node = mGameNode->addChildNode(new dt::Node("score1")); score1_node->setPosition(Ogre::Vector3(-10, FIELD_HEIGHT / 2 + 2, 0)); mScore1Text = score1_node->addComponent(new dt::TextComponent("0", "text")); mScore1Text->setFont("DejaVuSans"); mScore1Text->setFontSize(64); auto score2_node = mGameNode->addChildNode(new dt::Node("score2")); score2_node->setPosition(Ogre::Vector3(10, FIELD_HEIGHT / 2 + 2, 0)); mScore2Text = score2_node->addComponent(new dt::TextComponent("0", "text")); mScore2Text->setFont("DejaVuSans"); mScore2Text->setFontSize(64); auto info_node = scene->addChildNode(new dt::Node("info")); info_node->setPosition(Ogre::Vector3(0, - FIELD_HEIGHT / 2 - 3, 0)); auto info_text = info_node->addComponent(new dt::TextComponent("Left player: W/S -- Right player: Up/Down", "text")); info_text->setFont("DejaVuSans"); info_text->setFontSize(20); resetBall(); }
void moveBall() { // update the ball's position for the next frame ball.x += ball.xv; ball.y += ball.yv; // if the ball is overlapping the rectangle if(ball.yv > 0) { // only if the ball is moving down if(doesOverlap(ball.x,ball.y, playerPaddleEdgeX + (PADDLE_WIDTH*0.0), PADDLE_POSITION_Y, playerPaddleEdgeX + (PADDLE_WIDTH*0.25), PADDLE_POSITION_Y + PADDLE_HEIGHT)==1) { ball.xv = -5; ball.yv = -3; } if(doesOverlap(ball.x,ball.y, playerPaddleEdgeX + (PADDLE_WIDTH*0.25), PADDLE_POSITION_Y, playerPaddleEdgeX + (PADDLE_WIDTH*0.5), PADDLE_POSITION_Y + PADDLE_HEIGHT)==1) { ball.xv = -3; ball.yv = -5; } if(doesOverlap(ball.x,ball.y, playerPaddleEdgeX + (PADDLE_WIDTH*0.5), PADDLE_POSITION_Y, playerPaddleEdgeX + (PADDLE_WIDTH*0.75), PADDLE_POSITION_Y + PADDLE_HEIGHT)==1) { ball.xv = 3; ball.yv = -5; } if(doesOverlap(ball.x,ball.y, playerPaddleEdgeX + (PADDLE_WIDTH*0.75), PADDLE_POSITION_Y, playerPaddleEdgeX + (PADDLE_WIDTH*1.0), PADDLE_POSITION_Y + PADDLE_HEIGHT)==1) { ball.xv = 5; ball.yv = -3; } } // draw the bricks for(int i=0;i<BRICKS_VERTICALLY;i++) { for(int ii=0;ii<BRICKS_HORIZONTALLY;ii++) { if(bricks[i][ii] != 0) { // is the brick still here? if(doesOverlap(ball.x,ball.y, ii*BRICK_WIDTH, i*BRICK_HEIGHT, (ii+1)*BRICK_WIDTH-BRICK_GAP, (i+1)*BRICK_HEIGHT-BRICK_GAP)==1) { // reverse ball's vertical direction ball.yv = -ball.yv; bricks[i][ii] = 0; // erase the brick } } } } // bounce off edges of screen if(ball.x > SCREEN_W) { ball.xv = -ball.xv; } if(ball.x < 0) { ball.xv = -ball.xv; } if(ball.y < 0) { ball.yv = -ball.yv; } // but reset ball if it goes off bottom of screen if(ball.y > SCREEN_H) { // lose! if(mouse_b) { // makes the ball reappear resetBall(); } } }
// determine actions based on logic events that have been stacked between frame void GameLogic::handleEvents() { for (int i = 0; i < this->ge->in_logic_events.size(); i++) { cout << ge->in_logic_events[i]; switch (ge->in_logic_events[i]) { case GameEvents::eLogicEvents::LE_POT_RED: resolvePot("red"); if (red_balls_remaining == 0) { ge->ball_on = GameEvents::eBallOn::BO_YELLOW; } break; case GameEvents::eLogicEvents::LE_POT_YELLOW: if (ge->ball_on == GameEvents::eBallOn::BO_YELLOW) { resolvePot("yellow"); ge->ball_on = GameEvents::eBallOn::BO_GREEN; } else { resetBall("yellow", START_POS_YELLOW); } break; case GameEvents::eLogicEvents::LE_POT_GREEN: if (ge->ball_on == GameEvents::eBallOn::BO_GREEN) { resolvePot("green"); ge->ball_on = GameEvents::eBallOn::BO_BROWN; } else { resetBall("green", START_POS_GREEN); } break; case GameEvents::eLogicEvents::LE_POT_BROWN: if (ge->ball_on == GameEvents::eBallOn::BO_BROWN) { resolvePot("brown"); ge->ball_on = GameEvents::eBallOn::BO_BLUE; } else { resetBall("brown", START_POS_BROWN); } break; case GameEvents::eLogicEvents::LE_POT_BLUE: if (ge->ball_on == GameEvents::eBallOn::BO_BLUE) { resolvePot("blue"); ge->ball_on = GameEvents::eBallOn::BO_PINK; } else { resetBall("blue", START_POS_BLUE); } break; case GameEvents::eLogicEvents::LE_POT_PINK: if (ge->ball_on == GameEvents::eBallOn::BO_PINK) { resolvePot("pink"); ge->ball_on = GameEvents::eBallOn::BO_BLACK; } else { resetBall("pink", START_POS_PINK); } break; case GameEvents::eLogicEvents::LE_POT_BLACK: if (ge->ball_on == GameEvents::eBallOn::BO_BLACK) { resolvePot("black"); ge->out_logic_events.push_back(GameEvents::eLogicEvents::LE_GAMEOVER); } else { resetBall("black", START_POS_BLACK); } break; case GameEvents::eLogicEvents::LE_POT_WHITE: ge->game_state = GameEvents::eGameState::GS_PLACE_WHITE; editEntity("white", "table", false, true); ge->gm->getEntityByName("white", "table")->setVel(VEC_STILL); break; case GameEvents::eLogicEvents::LE_PLACED_WHITE: if (isLegalPosition()){ ge->game_state = GameEvents::eGameState::GS_PLAYING; editEntity("white", "table", true, true); } } } }
//----------------------------------------------------------------------------- void SoccerWorld::onCheckGoalTriggered(bool first_goal) { if (isRaceOver() || isStartPhase()) return; if (m_can_score_points) { (first_goal ? m_red_goal++ : m_blue_goal++); World *world = World::getWorld(); world->setPhase(WorldStatus::GOAL_PHASE); m_goal_sound->play(); if (m_ball_hitter != -1) { ScorerData sd; sd.m_id = m_ball_hitter; sd.m_correct_goal = isCorrectGoal(m_ball_hitter, first_goal); if (sd.m_correct_goal) { m_karts[m_ball_hitter]->getKartModel() ->setAnimation(KartModel::AF_WIN_START, true/* play_non_loop*/); } else if (!sd.m_correct_goal) { m_karts[m_ball_hitter]->getKartModel() ->setAnimation(KartModel::AF_LOSE_START, true/* play_non_loop*/); } if (first_goal) { // Notice: true first_goal means it's blue goal being shoot, // so red team can score m_red_scorers.push_back(sd); if(race_manager->hasTimeTarget()) { m_red_score_times.push_back(race_manager ->getTimeTarget() - world->getTime()); } else m_red_score_times.push_back(world->getTime()); } else { m_blue_scorers.push_back(sd); if (race_manager->hasTimeTarget()) { m_blue_score_times.push_back(race_manager ->getTimeTarget() - world->getTime()); } else m_blue_score_times.push_back(world->getTime()); } } } resetBall(); //Resetting the ball triggers the goal check line one more time. //This ensures that only one goal is counted, and the second is ignored. m_can_score_points = !m_can_score_points; } // onCheckGoalTriggered
void resetSim() { resetBall(ball1_body, 0); resetBall(ball2_body, 1); }
int main(int argc, char* args[]) { Player player1; Player player2; struct Ball ball; struct Vector vel; // Players vars int moveP1, moveP2; player1.score = player2.score = 0; // Keyboard const Uint8* keyState; char buffer[65]; int r = 10; // Color SDL_Color textColor = { 255, 255, 255, 255 }; // Init players positions moveP1 = moveP2 = SCREEN_HEIGHT / 2 - PLAYER_HEIGHT / 2; // Init ball ball.w = ball.h = 10; ball.x = SCREEN_WIDTH / 2 - ball.w / 2; ball.y = SCREEN_HEIGHT / 2 - ball.w / 2; ball.speed = 4; // Init ball velocity vel.x = 1; vel.y = 1; if (initSDL()); { loadFont(); scorePlayer1 = loadTextTexture(_itoa(player1.score, buffer, r), textColor); scorePlayer2 = loadTextTexture(_itoa(player2.score, buffer, r), textColor); // Main loop while (!quit) { // Event loop while (SDL_PollEvent(&e) != 0) { // User presses the close button if (e.type == SDL_QUIT) quit = true; } keyState = SDL_GetKeyboardState(NULL); if (keyState[SDL_SCANCODE_A]) { if ((moveP1 + PLAYER_HEIGHT) < SCREEN_HEIGHT) { moveP1 += PLAYER_SPEED; //printf("Player1: %d\n", moveP1 + PLAYER_HEIGHT); } } if (keyState[SDL_SCANCODE_S]) { if (moveP1 > 10) { moveP1 -= PLAYER_SPEED; //printf("Player1: %d\n", moveP1); } } if (keyState[SDL_SCANCODE_J]) { if ((moveP2 + PLAYER_HEIGHT) < SCREEN_HEIGHT) { moveP2 += PLAYER_SPEED; //printf("Player2: %d\n", moveP2 + PLAYER_HEIGHT); } } if (keyState[SDL_SCANCODE_K]) { if (moveP2 > 10) { moveP2 -= PLAYER_SPEED; //printf("Player2: %d\n", moveP2); } } // Bounce of player1 if ( (ball.x <= (20 + PLAYER_WIDTH)) && ((ball.y >= moveP1) && (ball.y <= moveP1 + PLAYER_HEIGHT)) ) { vel.x *= -1; } // Bounce of player2 else if ( (ball.x + 10 >= (SCREEN_WIDTH - PLAYER_WIDTH - 20)) && ((ball.y >= moveP2) && (ball.y <= moveP2 + PLAYER_HEIGHT)) ) { vel.x *= -1; } // Bounce from top and bottom edges if ( (ball.y + 10 >= SCREEN_HEIGHT) || (ball.y <= 0) ) { vel.y *= -1; } // Player 1 won if (ball.x + ball.w >= SCREEN_WIDTH) { player1.score += 1; scorePlayer1 = loadTextTexture(_itoa(player1.score, buffer, r), textColor); resetBall(&ball, "Player 1 won!\n"); } // Player 2 won if (ball.x + ball.w <= 0) { player2.score += 1; scorePlayer2 = loadTextTexture(_itoa(player2.score, buffer, r), textColor); resetBall(&ball, "Player 2 won!\n"); } ball.x += (int)vel.x * ball.speed; ball.y += (int)vel.y * ball.speed; // Clear screen SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); SDL_RenderClear(renderer); // Draw objects drawPlayers(moveP1, moveP2); drawBall(ball); // Draw text renderTextTexture(scorePlayer1, SCREEN_WIDTH / 4 - scorePlayer1.w / 2, 20); renderTextTexture(scorePlayer2, SCREEN_WIDTH * 3 / 4 - scorePlayer2.w / 2, 20); // Update screen SDL_RenderPresent(renderer); } closeSDL(); } return 0; }
void MainState::checkBallCollisions(Game* game) { if (!mLockBallCollisionCheck) { if (mPhysicsEngine.checkSpriteCollision(mBallSprite, mPlayer1Sprite)) { mBallSprite.setVelX(mBallSprite.getVelX() * -1); int paddleCenter = mPlayer1Sprite.getPosY() + (mPlayer1Sprite.getHeight() / 2); int ballCenter = mBallSprite.getPosY() + (mBallSprite.getHeight() / 2); if (ballCenter >= paddleCenter) { mBallSprite.setVelY(std::abs(mBallSprite.getVelY())); } else { mBallSprite.setVelY(-std::abs(mBallSprite.getVelY())); } mLockBallCollisionCheck = true; if (Mix_PlayChannel(-1, mPaddleHitSound, 0) == -1) { printf("Mix_PlayChannel Error: %s\n", Mix_GetError()); } } else if (mPhysicsEngine.checkSpriteCollision(mBallSprite, mPlayer2Sprite)) { mBallSprite.setVelX(mBallSprite.getVelX() * -1); int paddleCenter = mPlayer2Sprite.getPosY() + (mPlayer2Sprite.getHeight() / 2); int ballCenter = mBallSprite.getPosY() + (mBallSprite.getHeight() / 2); if (ballCenter >= paddleCenter) { mBallSprite.setVelY(std::abs(mBallSprite.getVelY())); } else { mBallSprite.setVelY(-std::abs(mBallSprite.getVelY())); } mLockBallCollisionCheck = true; if (Mix_PlayChannel(-1, mPaddleHitSound, 0) == -1) { printf("Mix_PlayChannel Error: %s\n", Mix_GetError()); } } } else if ((mBallSprite.getVelX() > 0 && mBallSprite.getPosX() > SCREEN_WIDTH / 2) || (mBallSprite.getVelX() < 0 && mBallSprite.getPosX() < SCREEN_WIDTH / 2)) { mLockBallCollisionCheck = false; } if (mBallSprite.getPosY() < 0 || mBallSprite.getPosY() + mBallSprite.getHeight() > SCREEN_HEIGHT) { mBallSprite.setVelY(mBallSprite.getVelY() * -1); Mix_PlayChannel(-1, mWallHitSound, 0); } if (mBallSprite.getPosX() < 0) { resetBall(); ++mPlayer2Score; updateScores(game); } else if (mBallSprite.getPosX() + mBallSprite.getWidth() > SCREEN_WIDTH) { resetBall(); ++mPlayer1Score; updateScores(game); } }
void pong(bool** ledArray) { //Playfield constants: const float TOP_MARGIN = 0.0; //The margins bound the area controlled by the game. const float BOT_MARGIN = 0.0; const float LEFT_MARGIN = 0.0; const float RIGHT_MARGIN = 0.0; const float BOT_END = ARRAY_HEIGHT - BOT_MARGIN - 1.0; const float RIGHT_END = ARRAY_WIDTH - RIGHT_MARGIN - 1.0; //Object constants: const int BALL_DIAMETER = 2; const float INIT_BALL_X_SPEED = 0.5; const float MAX_BALL_Y_SPEED = 0.5; const int PAD_HEIGHT = 8; const int PAD_WIDTH = 2; const int PAD_DISTANCE = 3; //The distance from each paddle to its side. const float LEFT_PAD_X = LEFT_MARGIN + PAD_DISTANCE; //Refers to the innermost pixel on the top of the paddle. const float RIGHT_PAD_X = RIGHT_END - (PAD_WIDTH - 1.0) - PAD_DISTANCE; const float LEFT_IMPACT_X = LEFT_PAD_X + PAD_WIDTH; const float RIGHT_IMPACT_X = RIGHT_PAD_X - BALL_DIAMETER; const float PAD_MOVE_DISTANCE = 1.0; //Object initialization: float ballDeltaX = INIT_BALL_X_SPEED; float ballDeltaY = 0; float ballX = LEFT_MARGIN + (RIGHT_END - BALL_DIAMETER - LEFT_MARGIN) / 2; float ballY = TOP_MARGIN + (BOT_END - BALL_DIAMETER - TOP_MARGIN) / 2; /*the last number is to test stationary impacts*/ float prevBallX = ballX; float prevBallY = ballY; float leftPadY = TOP_MARGIN + (BOT_END + 1 - TOP_MARGIN) / 2 - PAD_HEIGHT / 2; float rightPadY = TOP_MARGIN + (BOT_END + 1 - TOP_MARGIN) / 2 - PAD_HEIGHT / 2; int leftPadDir = 0; int rightPadDir = 0; drawRectangle(ledArray, true, rightPadY + 0.5, RIGHT_PAD_X, PAD_HEIGHT, PAD_WIDTH); drawRectangle(ledArray, true, leftPadY + 0.5, LEFT_PAD_X, PAD_HEIGHT, PAD_WIDTH); //Score initialization int leftScore = 0; int rightScore = 0; int scoreDelay = 10; //Deactivates ball movement for a number of cycles after someone scores while(1) { frameTest(ledArray, TOP_MARGIN, LEFT_MARGIN, BOT_END, RIGHT_END); //Paddle movement: leftPadDir = getLeftInput(); leftPadDir = movePaddle(leftPadDir, &leftPadY, PAD_MOVE_DISTANCE, PAD_HEIGHT, ledArray, LEFT_PAD_X, PAD_WIDTH, TOP_MARGIN, BOT_END); rightPadDir = getRightInput(); rightPadDir = movePaddle(rightPadDir, &rightPadY, PAD_MOVE_DISTANCE, PAD_HEIGHT, ledArray, RIGHT_PAD_X, PAD_WIDTH, TOP_MARGIN, BOT_END); //Ball movement: if (scoreDelay > 0) { scoreDelay--; } else { drawBall(ledArray, false, prevBallY + 0.5, prevBallX + 0.5, BALL_DIAMETER, LEFT_MARGIN, RIGHT_END); drawBall(ledArray, true, ballY + 0.5, ballX + 0.5, BALL_DIAMETER, LEFT_MARGIN, RIGHT_END); prevBallX = ballX; prevBallY = ballY; ballY += ballDeltaY; ballDeltaY *= checkWallImpact(&ballY, BALL_DIAMETER, TOP_MARGIN, BOT_END); ballX += ballDeltaX; if(ballX <= LEFT_IMPACT_X) { //A paddle collision or score is possible drawRectangle(ledArray, true, leftPadY + 0.5, LEFT_PAD_X, PAD_HEIGHT, PAD_WIDTH); checkLeftImpact(ballY, &ballX, LEFT_IMPACT_X, &ballDeltaY, &ballDeltaX, BALL_DIAMETER, leftPadY, PAD_HEIGHT, MAX_BALL_Y_SPEED); //Check if the ball hit the edge of the paddle (not yet done) (non-critical functionality) //Checking if the ball hit the left edge of the screen: if(ballX + BALL_DIAMETER < LEFT_MARGIN) { drawBall(ledArray, false, prevBallY + 0.5, prevBallX + 0.5, BALL_DIAMETER, LEFT_MARGIN, RIGHT_END); rightScore++; //Also change displayed score, if it exists. if(rightScore == 3) { drawRectangle(ledArray, false, rightPadY + 0.5, RIGHT_PAD_X, PAD_HEIGHT, PAD_WIDTH); drawRectangle(ledArray, false, leftPadY + 0.5, LEFT_PAD_X, PAD_HEIGHT, PAD_WIDTH); printWinner(1); break; } resetBall(&ballX, &ballY, &ballDeltaX, BALL_DIAMETER, TOP_MARGIN, BOT_END, LEFT_MARGIN, RIGHT_END, INIT_BALL_X_SPEED); scoreDelay = 10; } } else if(ballX > RIGHT_IMPACT_X) { //A paddle collision or score is possible drawRectangle(ledArray, true, rightPadY + 0.5, RIGHT_PAD_X, PAD_HEIGHT, PAD_WIDTH); checkRightImpact(ballY, &ballX, RIGHT_IMPACT_X, &ballDeltaY, &ballDeltaX, BALL_DIAMETER, rightPadY, PAD_HEIGHT, MAX_BALL_Y_SPEED); //Checking if the ball hit the edge of the paddle: (not yet done) (non-critical functionality) //Checking if the ball hit the right edge of the screen: if(ballX > RIGHT_END) { drawBall(ledArray, false, prevBallY + 0.5, prevBallX + 0.5, BALL_DIAMETER, LEFT_MARGIN, RIGHT_END); leftScore++; //Also change displayed score, if it exists. if(leftScore == 3) { drawRectangle(ledArray, false, rightPadY + 0.5, RIGHT_PAD_X, PAD_HEIGHT, PAD_WIDTH); drawRectangle(ledArray, false, leftPadY + 0.5, LEFT_PAD_X, PAD_HEIGHT, PAD_WIDTH); printWinner(2); break; } resetBall(&ballX, &ballY, &ballDeltaX, BALL_DIAMETER, TOP_MARGIN, BOT_END, LEFT_MARGIN, RIGHT_END, INIT_BALL_X_SPEED); scoreDelay = 10; } } } } return; }
int update() { float sdt = (float) (SPEED*dt); // update paddle if (!paddle.human) { paddle.dy = (paddle.y>ball.y) ? -1 : (paddle.y+paddle.height<ball.y+BALL_SIZE) ? 1 : 0; } paddle.y += sdt*PADDLE_SPEED*paddle.dy; paddle.y = clamp(paddle.y, BORDER_SIZE, COURT_TOP-paddle.height); // update ball ball.x += sdt*ballSpeed*ball.dx; ball.y += sdt*ballSpeed*ball.dy; //update ball 2 ball2.x += sdt*ballSpeed*ball2.dx; ball2.y += sdt*ballSpeed*ball2.dy; // collisions: ball-border vertical if (ball.y<=BORDER_SIZE) { ball.dy = -ball.dy; } else if (ball.y>=COURT_TOP-BALL_SIZE) { ball.dy = -ball.dy; } // collisions: ball-border right if (ball.x+BALL_SIZE>=ASPECT-BORDER_SIZE) { ball.dx = -ball.dx; } //collisions ball2 ball-border if (ball2.y<=BORDER_SIZE) { ball2.dy = -ball2.dy; } else if (ball2.y>=COURT_TOP-BALL_SIZE) { ball2.dy = -ball2.dy; } if (ball2.x+BALL_SIZE>=ASPECT-BORDER_SIZE) { ball2.dx = -ball2.dx; } // collision: ball-paddle if(level==3) { if (ball.x<PADDLE_WIDTH) { if (ball.y+BALL_SIZE>paddle.y && ball.y<paddle.y+paddle.height) { ball.dx = -ball.dx; paddle.height=paddle.height-0.01f; } else { //miss resetBall(); paddle.height=paddle.height-0.03f; playerLives=playerLives-1; score = score - 50; } } } else{ if (ball.x<PADDLE_WIDTH) { if (ball.y+BALL_SIZE>paddle.y && ball.y<paddle.y+paddle.height) { ball.dx = -ball.dx; } else { //miss resetBall(); playerLives=playerLives-1; score = score - 50; } } if (ball2.x<PADDLE_WIDTH) { if (ball2.y+BALL_SIZE>paddle.y && ball2.y<paddle.y+paddle.height) { ball2.dx = -ball2.dx; } } if(playerLives<=0) gameState=GAME_OVER; } // ball - wall if (! checkPointBoxCollision(ball.x, ball.y, WALL_X-BALL_SIZE, WALL_Y-BALL_SIZE, COLS*BRICK_WIDTH+BALL_SIZE, ROWS*BRICK_HEIGHT+BALL_SIZE)) return 0; // possible ball -brick collision so need to do more careful testing if (DEBUG) ballSpeed = 0.2*BALL_MAX_SPEED; // slow ball down // calculate ball position with respect to blocks row and column int ballCol = (int) ((ball.x - WALL_X ) / (BRICK_WIDTH)); int ballRow = (int) ((ball.y - WALL_Y ) / (BRICK_HEIGHT)); bool top=false, bottom=false, left=false, right=false; float const D=BALL_SIZE/2.0f; // temporary values to save on typing // only check the set of 9 possible bricks around the ball current position for (int col=ballCol-1; col<=ballCol+1; col++) { for (int row=ballRow-1; row<=ballRow+1; row++) { // top top = checkPointBrickCollision(ball.x+D, ball.y+2*D, row, col) || top; // bottom bottom = checkPointBrickCollision(ball.x+D, ball.y, row, col) || bottom; // left left = checkPointBrickCollision(ball.x, ball.y+D, row, col) || left; // right right = checkPointBrickCollision(ball.x+2*D, ball.y+D, row, col) || right; if(counter==0) { if(level==1) { gameState = LEVEL_TWO_START; } else if(level==2) { gameState=LEVEL_THREE_START; } else if(level==3) { gameState =LEVEL_FOUR_START; } else if(level==4) { gameState = LEVEL_FIVE_START; } else if(level==5) { gameState = GAME_OVER; } } } } // Now update ball if found any collisions if (top) { ball.dy = -ball.dy; ball.y -= D; //score = score + 10; } if (bottom) { ball.dy = -ball.dy; ball.y += D; //score = score + 10; } if (left) { ball.dx = -ball.dx; ball.x += D; //score = score + 10; } if (right) { ball.dx = -ball.dx; ball.x -= D; //score = score + 10; } ball.y = clamp(ball.y,BORDER_SIZE,COURT_TOP-BALL_SIZE); // exit(1); return 0; // success }
//-------------------------------------------------------------- void testApp::setup(){ ofSetVerticalSync(true); ofSetFrameRate(60); vidGrabber.setVerbose(true); vidGrabber.initGrabber(320,240); colorImg.allocate(320,240); grayImage.allocate(320,240); grayBg.allocate(320,240); grayDiff.allocate(320,240); grayDiffSmall.allocate(320,240); bLearnBakground = true; threshold = 100; blur = 5; printf("Windowsize is %d x %d\n",ofGetWidth(),ofGetHeight()); scaleX = ofGetWidth() / (float)320; scaleY = ofGetHeight() / (float)240; printf("scaleX: %f\nscaleY: %f\n",scaleX,scaleY); //PONG STUFF bgColor = 0; bGamePaused = true; dir = 1; counter = 0; paddleW = 20; paddleH = 100; ballRadius = 20; ballX = 300; ballY = 300; box2d.init(); box2d.setGravity(0, 0); box2d.createFloor(); box2d.checkBounds(true); box2d.setFPS(30.0); ball.setPhysics(1, 1.1, 0.0); ball.setup(box2d.getWorld(), ballX, ballY, ballRadius); ofxBox2dRect ceiling; ceiling.setPhysics(3.0, 0.53, 0.1); ceiling.setup(box2d.getWorld(), 0, 3, ofGetWidth(), 10,true); resetBall(); int yDir = 1; if (ofRandom(0,10) > 5) yDir = -1; ball.setVelocity(ofRandom(5*dir, 10*dir),ofRandom(2*yDir, 5*yDir)); paddle1 = new ofxBox2dRect(); paddle1->setPhysics(3.0, 0.53, 0.1); paddle1->setup(box2d.getWorld(), 200, ofGetHeight()/2, 20, 100, true); paddles.push_back(paddle1); paddle2 = new ofxBox2dRect(); paddle2->setPhysics(3.0, 0.53, 0.1); paddle2->setup(box2d.getWorld(), ofGetWidth()/2-200, ofGetHeight()/2, 20, 100, true); paddles.push_back(paddle2); //WARP warpPoints[0].x = 0; warpPoints[0].y = 0; warpPoints[1].x = 320; warpPoints[1].y = 0; warpPoints[2].x = 320; warpPoints[2].y = 240; warpPoints[3].x = 0; warpPoints[3].y = 240; // 'gui' is a global variable declared in ofxSimpleGuiToo.h gui.addTitle("Options"); gui.config->gridSize.set(340,0,0); gui.addFPSCounter(); gui.addSlider("Threshold",threshold,0,255); gui.addSlider("Background color",bgColor,0,255); gui.addSlider("Blur",blur,0,50); gui.addToggle("Make background", bLearnBakground); gui.addToggle("Draw Blobs on Game",bDrawBlobs); gui.addToggle("Pause",bGamePaused); gui.addContent("Color Image", colorImg,320).newColumn = true;; gui.addContent("Gray Image", grayImage,320); gui.addQuadWarper("Warp", colorImg, warpPoints); gui.addContent("Background Image", grayBg,320); gui.addContent("Difference", grayDiff,320); //GUI gui.loadFromXML(); gui.show(); }
//Make ball visible - for serve void serve(GameVars* gameVars) { //Put at player position resetBall(gameVars); gameVars->ball.visibility = true; //serve }