void View::DrawGravityAt(ofPoint position, const Model &model) const { const ofVec2f gravity = OpenFrameworksVector(model.GravityAt(Box2dVector(position))); ofPushStyle(); ofPushMatrix(); ofTranslate(position.x, position.y); ofScale(0.5, 0.5); ofSetColor(ofColor::slateGrey, 64.0); const ofVec2f arrowhead = gravity / 9.81; ofTriangle(arrowhead, kBallRadius * arrowhead.perpendiculared(), -kBallRadius * arrowhead.perpendiculared()); ofPopMatrix(); ofPopStyle(); }
void IntroductionView::Draw(Model &model) { ofBackground(ofColor::black); IntroductionModel &introduction_model = dynamic_cast<IntroductionModel &>(model); ofSetRectMode(OF_RECTMODE_CORNER); ofSetColor(ofColor::white); background.draw(0, 0); ofSetRectMode(OF_RECTMODE_CENTER); ofPushMatrix(); ofMultMatrix(view_matrix); for (auto box : introduction_model.boxes) { DrawBox(OpenFrameworksVector(box->GetPosition()), box->GetAngle()); } ofPopMatrix(); }
void Scene3Controller::RacketCollide(ofVec2f racket_position, ofVec2f hit_direction, float hit_mean, int key_left, int key_right, bool opponent) { if (model_.ball_body) { const ofVec2f position = ofVec2f(model_.ball_body->GetPosition().x, model_.ball_body->GetPosition().y); const float dx = model_.ball_body->GetLinearVelocity().x; const float probability = model_.opponent_index == 8 ? 1.0 : 0.1; if (ofRandomuf() < probability && abs((position - racket_position).x) < ball_radius + 2.0 * racket_radius && abs((position - racket_position).y) < ball_radius + 2.0 * racket_radius) { float variance = 0.0; float angular_velocity = 0.0; if ((keys[key_left] && dx < 0) || (keys[key_right] && dx > 0)) { variance = -hit_variance * ofRandomuf(); } else if ((keys[key_left] && dx > 0) || (keys[key_right] && dx < 0)) { variance = hit_variance * ofRandomuf(); } else { variance = hit_variance * ofRandomf(); } const ofVec2f velocity = hit_mean * (1.0 + variance) * hit_direction; model_.ball_body->SetLinearVelocity(b2Vec2(velocity.x, velocity.y)); model_.bounces = 0; if (opponent && model_.opponent_index == 1) { model_.time_slowed = true; } if (!opponent && model_.opponent_index == 1) { model_.time_slowed = false; } if (opponent && model_.opponent_index == 8) { model_.bounces += 1; } if (opponent && model_.opponent_index == 2) { for (int i = 0; i < 4; ++i) { b2BodyDef ball_body_definition; ball_body_definition.type = b2_dynamicBody; ball_body_definition.position.Set(model_.ball_body->GetPosition().x + 0.1 * ofRandomf(), model_.ball_body->GetPosition().y + 0.1 * ofRandomf()); ball_body_definition.linearVelocity.Set(model_.ball_body->GetLinearVelocity().x + 3.0 * ofRandomf(), model_.ball_body->GetLinearVelocity().y + 0.25 * ofRandomf()); ball_body_definition.angle = model_.ball_body->GetAngle(); ball_body_definition.angularVelocity = model_.ball_body->GetAngularVelocity(); ball_body_definition.linearDamping = linear_damping; ball_body_definition.angularDamping = angular_damping; model_.extra_balls.push_back(model_.world.CreateBody(&ball_body_definition)); b2CircleShape ball_shape; ball_shape.m_radius = ball_radius; b2FixtureDef ball_fixture_definition; ball_fixture_definition.shape = &ball_shape; ball_fixture_definition.density = density; ball_fixture_definition.restitution = restitution; ball_fixture_definition.friction = friction; model_.extra_balls.back()->CreateFixture(&ball_fixture_definition); } } if (opponent && model_.opponent_index == 4 && ofGetElapsedTimef() > model_.last_hit + 0.3) { if (model_.glass_hits == 0) { model_.served = true; } if (model_.glass_hits <= 2) { model_.glass = 0.0; } model_.glass_hits += 1; if (model_.glass_hits == 3) { glassbreak.setPan(model_.opponent.x / half_court_length); glassbreak.play(); for (int i = 0; i < 100; ++i) { Scene3Model::Particle particle; particle.position = model_.opponent + ofVec2f(racket_radius * ofRandomf(), 4.0 * racket_radius * ofRandomuf()); particle.velocity = ofVec2f(3.0 / 4.0 * ofRandomf(), ofRandomf() / 4.0); particle.angle = ofRandomf(); particle.angular_velocity = 10.0 * ofRandomf(); particle.life = 1.0; model_.particles.push_back(particle); } } } if (model_.opponent_index == 7) { Scene3Model::Trail trail; trail.position = OpenFrameworksVector(model_.ball_body->GetPosition()); trail.text = "Volley"; model_.ball_trail.push_back(trail); } model_.served = true; hit1.setSpeed(ofRandom(0.8, 1.2)); hit2.setSpeed(ofRandom(0.8, 1.2)); hit1.setPan(racket_position.x / half_court_length); hit2.setPan(racket_position.x / half_court_length); if (ofGetElapsedTimef() > model_.last_hit + 0.3) { ofRandomuf() > 0.5 ? hit1.play() : hit2.play(); } model_.last_hit = ofGetElapsedTimef(); } } }
void Scene3Controller::Update() { model_.dialogue.Update(); if (model_.score >= 10) { model_.outro += 1.0 / 60.0 / 2.6; } if (model_.outro >= 1.0) { scene_manager.NextScene(); return; } if (model_.bounces >= ((model_.opponent_index == 5) ? 8 : 2)) { DestroyBall(model_.ball_body); model_.ball_body = nullptr; model_.bounces = 0; } if (model_.opponent_index != 2 && model_.extra_balls.size()) { for (auto ball : model_.extra_balls) { model_.world.DestroyBody(ball); } model_.extra_balls.clear(); } UpdateRackets(); model_.world.Step(model_.time_slowed ? 0.1 * delta_time : delta_time, box2d_velocity_iterations, box2d_position_iterations); for (std::vector<Scene3Model::Particle>::iterator particle = model_.particles.begin(); particle != model_.particles.end(); ++particle) { particle->angle += particle->angular_velocity * delta_time; particle->position += particle->velocity * delta_time; particle->velocity += -ofVec2f(0.0, 0.5) * delta_time; particle->life -= 1.0 / 60.0 / 8.0; } model_.particles.erase(std::remove_if(model_.particles.begin(), model_.particles.end(), [] (Scene3Model::Particle &particle) -> bool { return particle.life <= 0.0; }), model_.particles.end()); if (model_.ball_trail.size() > ball_trail_length_scholar || (model_.opponent_index != 7 && model_.ball_trail.size() > 0)) { model_.ball_trail.pop_front(); } if (model_.ball_body && model_.opponent_index == 7) { Scene3Model::Trail trail; trail.position = OpenFrameworksVector(model_.ball_body->GetPosition()); trail.text = nullptr; model_.ball_trail.push_back(trail); } if (model_.ball_in_play && !model_.ball_body) { CreateBall(ofVec2f(0.377 * half_court_length, court_height), ofVec2f(0, 0), 0.0, -ofRandomuf() * angular_velocity); if (model_.opponent_index == 8) { model_.ball_body->GetFixtureList()->SetRestitution(0.0); } if (!(model_.opponent_index == 9 && model_.mirror_score > 0)) { model_.opponent = model_.opponent_target = ofVec2f(half_court_length, racket_radius + court_thickness); } } if (keys[OF_KEY_BACKSPACE] && !previous_keys[OF_KEY_BACKSPACE]) { if (model_.ball_body) { DestroyBall(model_.ball_body); model_.ball_body = nullptr; } } if (model_.angle <= 180.0 - 180.0 / 60.0 / 2.0) { model_.angle += 180.0 / 60.0 / 2.0; } if (model_.glass_hits == 2 && model_.glass <= 1.0 - 1.0 / 60.0) { model_.glass += 1.0 / 60.0; } if (model_.glass_hits > 2 && model_.glass <= 1.0 - 1.0 / 60.0) { model_.glass += 1.0 / 60.0; } if (model_.opponent_index == 7 && model_.nerd_energy >= 1.0 / 60.0 / 30.0) { model_.nerd_energy -= 1.0 / 60.0 / 30.0; } Controller::Update(); }
void Scene3Controller::BeginContact(b2Contact* contact) { const b2Body *body_a = contact->GetFixtureA()->GetBody(); const b2Body *body_b = contact->GetFixtureB()->GetBody(); const b2Body *ball = nullptr, *court = nullptr; if (model_.ball_body == body_a) { ball = body_a; } if (model_.ball_body == body_b) { ball = body_b; } if (model_.court_body == body_a) { court = body_a; } if (model_.court_body == body_b) { court = body_b; } if (contact->GetFixtureA() == model_.eight_body->GetFixtureList()->GetNext() || contact->GetFixtureB() == model_.eight_body->GetFixtureList()->GetNext()) { model_.ball_body->GetFixtureList()->SetRestitution(restitution); } if (ball && court) { if (model_.opponent_index == 3 && model_.bounces == 0) { cardtable.play(); for (int i = 0; i < 13; ++i) { Scene3Model::Particle particle; particle.position = ofVec2f(0.377 * half_court_length, court_thickness + racket_radius); particle.velocity = ofVec2f(3.0 / 4.0 * ofRandomf(), ofRandomf() / 4.0); particle.angle = ofRandomf(); particle.angular_velocity = 10.0 * ofRandomf(); particle.life = 1.0; model_.particles.push_back(particle); } } if (model_.opponent_index == 7) { Scene3Model::Trail trail; trail.position = OpenFrameworksVector(model_.ball_body->GetPosition()); trail.text = "Bounce"; model_.ball_trail.push_back(trail); } if (model_.opponent_index == 8) { if (!model_.eight_on_left_side || ball->GetPosition().x < 0) { model_.opponent_target.x = model_.opponent.x = ball->GetPosition().x; } if (!model_.eight_on_left_side && model_.opponent.x < 0.0) { model_.eight_on_left_side = true; } } if (model_.opponent_index == 8 && (!model_.eight_on_left_side || ball->GetPosition().x < 0)) { for (int i = 0; i < 13; ++i) { Scene3Model::Particle particle; particle.position = ofVec2f(model_.opponent.x, court_thickness + racket_radius); particle.velocity = ofVec2f(ofRandomf(), ofRandomf()); particle.angle = ofRandomf(); particle.angular_velocity = 10.0 * ofRandomf(); particle.life = 1.0; model_.particles.push_back(particle); } } } if (ball && court && ball->GetPosition().x > 0 && model_.served) { model_.bounces += 1; if (model_.opponent_index != 9 && model_.bounces == ((model_.opponent_index == 5) ? 8 : 2)) { model_.angle = 0.0; model_.score += 1; model_.ball_in_play = false; if (model_.opponent_index == 5) { model_.opponent = model_.opponent_target = ofVec2f(half_court_length, racket_radius + court_thickness); } model_.dialogue.Trigger("point"); } else if (model_.opponent_index == 9 && model_.bounces == 2) { if (model_.mirror_score < 2) { model_.mirror_score += 1; model_.ball_in_play = false; model_.dialogue.Trigger("score"); } else { model_.score += 1; model_.ball_in_play = false; model_.dialogue.Trigger("point"); } } } else if (ball && court && ball->GetPosition().x < 0) { model_.bounces = 0; } if (ball) { bounce1.setPan(ball->GetPosition().x / half_court_length); bounce2.setPan(ball->GetPosition().x / half_court_length); bounce3.setPan(ball->GetPosition().x / half_court_length); bounce4.setPan(ball->GetPosition().x / half_court_length); if (ofRandomuf() < 0.5) { if (ofRandomuf() < 0.5) { bounce1.setSpeed(ofRandom(0.8, 1.2)); bounce1.play(); } else { bounce2.setSpeed(ofRandom(0.8, 1.2)); bounce2.play(); } } else { if (ofRandomuf() < 0.5) { bounce3.setSpeed(ofRandom(0.8, 1.2)); bounce3.play(); } else { bounce4.setSpeed(ofRandom(0.8, 1.2)); bounce4.play(); } } } }