void physics_system::contact_listener::EndContact(b2Contact* contact) { auto& sys = get_sys(); auto& cosmos = cosm; for (int i = 0; i < 2; ++i) { auto fix_a = contact->GetFixtureA(); auto fix_b = contact->GetFixtureB(); if (i == 1) std::swap(fix_a, fix_b); auto body_a = fix_a->GetBody(); auto body_b = fix_b->GetBody(); messages::collision_message msg; msg.type = messages::collision_message::event_type::END_CONTACT; auto subject = cosmos[fix_a->GetUserData()]; auto collider = cosmos[fix_b->GetUserData()]; msg.subject = subject; msg.collider = collider; auto& subject_fixtures = subject.get<components::fixtures>(); auto& collider_fixtures = collider.get<components::fixtures>(); auto& collider_physics = collider_fixtures.get_owner_body().get<components::special_physics>(); if (subject_fixtures.is_friction_ground() && during_step) { #if FRICTION_FIELDS_COLLIDE if (!collider_fixtures.is_friction_ground) #endif { for (auto it = collider_physics.owner_friction_grounds.begin(); it != collider_physics.owner_friction_grounds.end(); ++it) if ((*it).target == subject_fixtures.get_owner_body()) { auto& fixtures_connected = (*it).fixtures_connected; ensure(fixtures_connected > 0); --fixtures_connected; if (fixtures_connected == 0) { LOG("Unreg: %x", subject_fixtures.get_owner_body().get_id()); collider_physics.owner_friction_grounds.erase(it); sys.rechoose_owner_friction_body(collider_fixtures.get_owner_body()); } else { LOG("Decr: %x", subject_fixtures.get_owner_body().get_id()); } break; } } } msg.subject_impact_velocity = -body_a->GetLinearVelocity(); msg.collider_impact_velocity = -body_b->GetLinearVelocity(); sys.accumulated_messages.push_back(msg); } }
bool csBulletRigidBody::RemoveBulletObject () { if (insideWorld) { if (anchorCount > 0) { csFPrintf (stderr, "csBulletRigidBody: Please remove the soft body attached with this body first.\n"); return false; } for (size_t i = 0; i < joints.GetSize (); i++) sector->RemoveJoint (joints[i]); linearVelocity = GetLinearVelocity (); angularVelocity = GetAngularVelocity (); sector->bulletWorld->removeRigidBody (btBody); delete btBody; btBody = NULL; btObject = NULL; insideWorld = false; csBulletRigidBody* rb = dynamic_cast<csBulletRigidBody*> (objectCopy); if (objectCopy) rb->sector->RemoveRigidBody (rb); rb = dynamic_cast<csBulletRigidBody*> (objectOrigin); if (objectOrigin) rb->objectCopy = NULL; objectCopy = NULL; objectOrigin = NULL; return true; } return false; }
//Aボタンハンドラ void Player::OnPushA() { auto Ptr = GetComponent<Transform>(); if (Ptr->GetPosition().y > 0.125f) { return; } auto PtrPs = GetComponent<PsSphereBody>(); auto Velo = PtrPs->GetLinearVelocity(); Velo += Vec3(0, 4.0f, 0.0); PtrPs->SetLinearVelocity(Velo); }
//----------------------------------------------------------------------------- // GetLinearVelocity //----------------------------------------------------------------------------- NxVec3 CPhysicObj::GetLinearVelocity (void) const { assert( m_bActivated ); // NOTA: Por defecto devolvemos la velocidad media de todas las partes NxVec3 result = CERO; int nNumParts = GetNumParts(); float fNumPartsInv = 1.f / float(nNumParts); for (int i = 0; i < nNumParts; i++) { result += fNumPartsInv * GetLinearVelocity (i); } return result; }
/* ================ idPhysics_Base::DrawVelocity ================ */ void idPhysics_Base::DrawVelocity( int id, float linearScale, float angularScale ) const { idVec3 dir, org, vec, start, end; idMat3 axis; float length, a; dir = GetLinearVelocity( id ); dir *= linearScale; if( dir.LengthSqr() > Square( 0.1f ) ) { dir = dir.Truncate( 10.0f ); org = GetOrigin( id ); gameRenderWorld->DebugArrow( colorRed, org, org + dir, 1 ); } dir = GetAngularVelocity( id ); length = dir.Normalize(); length *= angularScale; if( length > 0.1f ) { if( length < 60.0f ) { length = 60.0f; } else if( length > 360.0f ) { length = 360.0f; } axis = GetAxis( id ); vec = axis[2]; if( idMath::Fabs( dir * vec ) > 0.99f ) { vec = axis[0]; } vec -= vec * dir * vec; vec.Normalize(); vec *= 4.0f; start = org + vec; for( a = 20.0f; a < length; a += 20.0f ) { end = org + idRotation( vec3_origin, dir, -a ).ToMat3() * vec; gameRenderWorld->DebugLine( colorBlue, start, end, 1 ); start = end; } end = org + idRotation( vec3_origin, dir, -length ).ToMat3() * vec; gameRenderWorld->DebugArrow( colorBlue, start, end, 1 ); } }
//更新 void Player::OnUpdate() { auto Vec = GetMoveVector(); auto PtrPs = GetComponent<PsSphereBody>(); auto Velo = PtrPs->GetLinearVelocity(); Velo.x = Vec.x * 5.0f; Velo.z = Vec.z * 5.0f; PtrPs->SetLinearVelocity(Velo); //コントローラの取得 auto CntlVec = App::GetApp()->GetInputDevice().GetControlerVec(); if (CntlVec[0].bConnected) { //Aボタン if (CntlVec[0].wPressedButtons & XINPUT_GAMEPAD_A) { OnPushA(); } //Xボタン else if (CntlVec[0].wPressedButtons & XINPUT_GAMEPAD_X) { OnPushX(); } } }
int main(int argc, char** argv) { RenderWindow window(sf::VideoMode(W_WIDTH,W_HEIGHT),"Hello",sf::Style::Close); View view{ FloatRect{0,0,V_WIDTH,V_HEIGHT} }; View defaultView = View{ FloatRect{ 0,0, 1600, 1200 } }; //window.setView(view); Physics physics{ {0.f, 9.8f}, 10.f }; //LightMap lights{view}; LightMap lights{ defaultView }; auto playerLight = lights.createLight("../assets/lightmask.png", 400, 370, 3.f); //lights.createLight("../assets/lightmask.png", 200, 100, 3.f); Clock clock; physics.spawnStaticBox(40.f, 60.f, 800.f, 40.f); physics.spawnStaticBox(80.f, 110.f, 800.f, 40.f); auto pPlayerBody = physics.spawnDynamicCircle(3.f, 400.f, 0.f); Texture tex; tex.loadFromFile("../assets/tile.png"); tex.setSmooth(true); Shader blendShader; if (!blendShader.loadFromFile("../src/test.frag", Shader::Fragment)) std::cout << "Failed to load blend fragment shader" << std::endl; Texture playerTex; playerTex.loadFromFile("../assets/player.png"); playerTex.setSmooth(true); sf::Event ev; Texture worldTex; worldTex.create(W_WIDTH, W_HEIGHT); Sprite displaySprite; Font font; font.loadFromFile("../assets/kenney_bold.ttf"); Text framerate; framerate.setFont(font); framerate.setCharacterSize(40); framerate.setPosition(1100, 200); framerate.setColor(sf::Color::White); while (window.isOpen()) { while (window.pollEvent(ev)) { if (ev.type == Event::Closed) { window.close(); } if (ev.type == Event::KeyPressed) { if (ev.key.code == sf::Keyboard::Left) { if (pPlayerBody->GetLinearVelocity().x - (MS_X / 100) > -(2 * MS_X / 100)) pPlayerBody->ApplyForceToCenter({-MS_X, 0.f},true); else pPlayerBody->ApplyForceToCenter({ -(2 * MS_X / 100) - pPlayerBody->GetLinearVelocity().x , 0.f }, true); } if (ev.key.code == sf::Keyboard::Right) { if (pPlayerBody->GetLinearVelocity().x + (MS_X / 100) < (2 * MS_X / 100)) pPlayerBody->ApplyForceToCenter({ MS_X, 0.f }, true); else pPlayerBody->ApplyForceToCenter({ (2 * MS_X / 100) - pPlayerBody->GetLinearVelocity().x , 0.f }, true); } if (ev.key.code == sf::Keyboard::Space) { if (pPlayerBody->GetLinearVelocity().y + (MS_X / 100) < (2 * MS_X / 100)) pPlayerBody->ApplyForceToCenter({ 0.f, -MS_X * 2 }, true); //else //pPlayerBody->ApplyForceToCenter({ 0.f, (3 * MS_X / 100) - pPlayerBody->GetLinearVelocity().y }, true); } } if (ev.type == Event::JoystickButtonPressed) { std::cout << ev.joystickButton.button << std::endl; } if (ev.type == Event::JoystickMoved) { std::cout << ev.joystickMove.axis << std::endl; } } physics.step(1.f / 30.f); window.clear(); auto playerPos = pPlayerBody->GetPosition(); view.setCenter(SCALE * playerPos.x, SCALE * playerPos.y); //window.setView(view); auto lightSize = playerLight->getSprite().getTexture()->getSize(); // 3.f is the player body radius playerLight->setPosition( playerPos.x * SCALE - lightSize.x - 3.f * SCALE * 2 , playerPos.y * SCALE - lightSize.y - 3.f * SCALE * 2); auto bodyIt = physics.getBodyList(); //lights.updateView(view); lights.render(); while (bodyIt != nullptr) { auto pos = bodyIt->GetPosition(); if (bodyIt->GetType() == b2_dynamicBody) { CircleShape sprite; sprite.setTexture(&playerTex); auto playerShape = *(b2CircleShape*)(bodyIt->GetFixtureList()->GetShape()); sprite.setRadius(playerShape.m_radius * SCALE); sprite.setOrigin(playerShape.m_radius * SCALE, playerShape.m_radius * SCALE); sprite.setPosition(SCALE * pos.x, SCALE * pos.y); sprite.setRotation(bodyIt->GetAngle() * 180 / b2_pi); window.draw(sprite); } else // ground { RectangleShape sprite; sprite.setSize({800.f, 40.f}); sprite.setOrigin(400, 20); sprite.setPosition(pos.x * SCALE, pos.y * SCALE); sprite.setRotation(bodyIt->GetAngle() * 180 / b2_pi); sprite.setTexture(&tex); window.draw(sprite); } bodyIt = bodyIt->GetNext(); } window.draw(Sprite{ lights.getLightMapTexture() }, BlendMultiply); float frameTime = 1.f / clock.getElapsedTime().asSeconds(); clock.restart(); framerate.setString(std::to_string((int)frameTime) + " fps"); window.draw(framerate); window.display(); } }
void CommandMoveLeft::update(float dt) { if (!_block) return; auto body1 = _block->getBody(); if (!body1) { stopBlock(); return; } auto body2 = _block->getAttachedBody(); if (!body2) { stopBlock(); return; } float32 offset = ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::MOVEOFFSET); float32 blockSizeInMeters = _blockSize.width / ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D); if (body1->GetFixtureList()->GetFilterData().categoryBits == Block::blockFlags::PASSIVE || body2->GetFixtureList()->GetFilterData().categoryBits == Block::blockFlags::PASSIVE) stopBlock(); if (body1->GetFixtureList()->GetFilterData().categoryBits == Block::blockFlags::NEED_TO_STOP || body2->GetFixtureList()->GetFilterData().categoryBits == Block::blockFlags::NEED_TO_STOP) { Vec2 posOnField = _block->getPosOnField(); Sprite *sprite1 = (Sprite*)body1->GetUserData(); Sprite *sprite2 = (Sprite*)body2->GetUserData(); Size size = sprite1->getContentSize(); b2Filter filter; if (GameField::getBlock({ posOnField.x - 1, posOnField.y })){ stopBlock(); filter = body1->GetFixtureList()->GetFilterData(); filter.categoryBits = Block::blockFlags::ACTIVE; body1->GetFixtureList()->SetFilterData(filter); filter = body2->GetFixtureList()->GetFilterData(); filter.categoryBits = Block::blockFlags::ACTIVE; body2->GetFixtureList()->SetFilterData(filter); body1->SetTransform(_positionOldFirst, 0); body2->SetTransform(_positionOldSecond, 0); sprite1->setPosition({ (body1->GetPosition().x * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.width / 2 , (body1->GetPosition().y * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.height / 2 }); sprite2->setPosition({ (body2->GetPosition().x * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.width / 2 , (body2->GetPosition().y * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.height / 2 }); SimpleUI *simpleUI = MainGameScene::getUI(); UserInput *input = (UserInput*)simpleUI->getChildrenByName(UserInput::name()); input->dropInputEvents(); return; } if (!_isUndo) { body1->SetTransform({ _positionOldFirst.x - blockSizeInMeters, body1->GetPosition().y }, 0); body2->SetTransform({ _positionOldSecond.x - blockSizeInMeters, body2->GetPosition().y }, 0); } else { body1->SetTransform({ _positionOldFirst.x + blockSizeInMeters, body1->GetPosition().y }, 0); body2->SetTransform({ _positionOldSecond.x + blockSizeInMeters, body2->GetPosition().y }, 0); } sprite1->setPosition({ (body1->GetPosition().x * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.width / 2 , (body1->GetPosition().y * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.height / 2 }); sprite2->setPosition({ (body2->GetPosition().x * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.width / 2 , (body2->GetPosition().y * ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::SCALE_RATIO_BOX2D)) - size.height / 2 }); stopBlock(); filter = body1->GetFixtureList()->GetFilterData(); filter.categoryBits ^= Block::blockFlags::NEED_TO_STOP; filter.categoryBits = Block::blockFlags::STOPPED; body1->GetFixtureList()->SetFilterData(filter); filter = body2->GetFixtureList()->GetFilterData(); filter.categoryBits ^= Block::blockFlags::NEED_TO_STOP; filter.categoryBits = Block::blockFlags::STOPPED; body2->GetFixtureList()->SetFilterData(filter); body1->SetActive(false); body1->SetActive(true); body2->SetActive(false); body2->SetActive(true); } if ((_positionOldFirst.x - body1->GetPosition().x) < blockSizeInMeters && !_isUndo && _isExecute) { if ((_positionOldFirst.x - (body1->GetPosition().x - offset)) >= blockSizeInMeters) { while (offset > 0) { offset -= ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::MOVEOFFSET) / 100; if ((_positionOldFirst.x - (body1->GetPosition().x - offset)) < blockSizeInMeters) { stopBlock(); body1->SetTransform({ body1->GetPosition().x - offset, body1->GetPosition().y }, 0); body2->SetTransform({ body2->GetPosition().x - offset, body2->GetPosition().y }, 0); return; } } } CCASSERT(offset, "offset can't be 0"); if (body1->GetLinearVelocity().x > 0 && (_positionOldFirst.x - body1->GetPosition().x) < (blockSizeInMeters / 7)) { stopBlock(); body1->SetTransform(_positionOldFirst, 0); body2->SetTransform(_positionOldSecond, 0); return; } body1->SetLinearVelocity({ (float32)(body1->GetLinearVelocity().x - offset), body1->GetLinearVelocity().y }); body2->SetLinearVelocity({ (float32)(body2->GetLinearVelocity().x - offset), body2->GetLinearVelocity().y }); _positionOldFirst.y = body1->GetPosition().y; _positionOldSecond.y = body2->GetPosition().y; } else if ((body1->GetPosition().x - _positionOldFirst.x) < blockSizeInMeters && _isUndo && _isExecute) { if (((body1->GetPosition().x + offset) - _positionOldFirst.x) >= blockSizeInMeters) { while (offset > 0) { offset -= (ConstantsRegistry::getValueForKey(ConstantsRegistry::constants::MOVEOFFSET) / 100) * 10; if (((body1->GetPosition().x + offset) - _positionOldFirst.x) < blockSizeInMeters) { stopBlock(); body1->SetTransform({ body1->GetPosition().x + offset, body1->GetPosition().y }, 0); body2->SetTransform({ body2->GetPosition().x + offset, body2->GetPosition().y }, 0); return; } } } CCASSERT(offset, "offset can't be 0"); if (body1->GetLinearVelocity().x < 0 && (_positionOldFirst.x - body1->GetPosition().x) < (blockSizeInMeters / 7)) { stopBlock(); body1->SetTransform(_positionOldFirst, 0); body2->SetTransform(_positionOldSecond, 0); return; } body1->SetLinearVelocity({ (float32)(body1->GetLinearVelocity().x + offset), body1->GetLinearVelocity().y }); body2->SetLinearVelocity({ (float32)(body2->GetLinearVelocity().x + offset), body2->GetLinearVelocity().y }); _positionOldFirst.y = body1->GetPosition().y; _positionOldSecond.y = body2->GetPosition().y; } else stopBlock(); }