void Hero::playAnimation(float dt) { const auto & animSprite = getAnimatedSprite(); if(animSprite) { animSprite->update(dt); } }
HSpriteTexture BuiltinEditorResources::getSprite(EditorSprites sprite) { switch(sprite) { case EditorSprites::Spinner: return getAnimatedSprite("Spinner.png"); } return HSpriteTexture(); }
void RenderSystem::receive(const AnimationChangedMessage& msg) { auto animatedSprite = getAnimatedSprite(msg.entity); auto render = entityx::Entity(msg.entity).component<RenderComponent>(); if(render->currentAnimation != animatedSprite->getCurrentAnimation()) { std::string oldAnimation = animatedSprite->getCurrentAnimation(); animatedSprite->setCurrentAnimation(render->currentAnimation); if(render->onAnimationChangedFunc.valid()) render->onAnimationChangedFunc.call(EntityHandle(msg.entity), oldAnimation, render->currentAnimation); } }
void RenderSystem::update(entityx::EntityManager &es, entityx::EventManager &events, entityx::TimeDelta dt) { m_renderingQueue.clear(); if(m_debugHitboxDraw) { es.each<PositionComponent, PlatformerHitboxComponent>([&]( entityx::Entity entity, PositionComponent& position, PlatformerHitboxComponent& hitbox) { auto shape = std::make_shared<sf::ConvexShape>(hitbox.getHitbox().getPointsCount()); shape->setOutlineThickness(1.f); shape->setFillColor(sf::Color::Transparent); shape->setOutlineColor(sf::Color::Black); for(std::size_t i = 0; i < shape->getPointCount(); ++i) { shape->setPoint(i, sf::Vector2f( hitbox.getHitbox().getPoint(i).x, hitbox.getHitbox().getPoint(i).y )); } addToRenderingQueue(shape, sf::RenderStates(position.getPositionTransform()), 100000.f); }); } auto drawFunc = [&](entityx::Entity entity, PositionComponent& position, RenderComponent& render) { //Update the animated sprite and put it in the render queue auto animatedSprite = getAnimatedSprite(entity); animatedSprite->update(dt); animatedSprite->setOrigin(sf::Vector2f(0.5f, 0.5f)); animatedSprite->setPosition(position.x + position.width/2.f, position.y + position.height/2.f); animatedSprite->setScale((render.flipped ? (-1) : (1)) * position.width, position.height); //Call the lua callback if the animation has just been restarted if(animatedSprite->hadRestartedAnimation() && render.onAnimationEndFunc.valid()) render.onAnimationEndFunc.call(EntityHandle(entity), render.currentAnimation); addToRenderingQueue(animatedSprite, sf::RenderStates::Default, position.z); //TODO: Get z position from RenderComponent }; sf::FloatRect viewAABB( m_renderingView.getCenter().x - 1024.f/2.f, m_renderingView.getCenter().y - 768.f/2.f, 1024.f, 768.f ); std::set<entityx::Entity> entitiesToDraw = m_grid.getEntitiesIntersectingAABB(viewAABB); for(entityx::Entity entity : entitiesToDraw) { if(entity.has_component<PositionComponent>() && entity.has_component<RenderComponent>()) { drawFunc(entity, *(entity.component<PositionComponent>().get()), *(entity.component<RenderComponent>().get())); } } if(m_cameraFollowPlayers) { //Update the camera es.each<PlayerComponent, PlatformerComponent, PositionComponent>([&](entityx::Entity entity, PlayerComponent& player, PlatformerComponent& platformer, PositionComponent& position) { if(player.playerNumber != m_centerOnPlayer) return; //Only center on the selected player float newX = position.x + position.width / 2.f; float newY = m_renderingView.getCenter().y; if(platformer.groundEntity && platformer.groundEntity.has_component<PositionComponent>()) { m_lastGroundEntity = platformer.groundEntity; } if(m_lastGroundEntity) { auto groundPosition = m_lastGroundEntity.component<PositionComponent>(); //If the player is on the ground, update to Y position. if(std::abs(newY - groundPosition->y) > 10.f) { newY += (newY > groundPosition->y ? -1 : 1) * 150.f * dt; } //If the player goes beyond some limits, remove the last ground entity and try to center on player if(position.y + position.height > newY + 200.f || position.y + position.height < newY - 200.f) { m_lastGroundEntity = entityx::Entity(); } } else { newY += (newY > position.y ? -1 : 1) * std::abs(newY - position.y) * 2 * dt + (platformer.fallingSpeed - platformer.jumpingSpeed) * dt; } m_renderingView.setCenter(sf::Vector2f(newX, newY)); }); } }
Hero::Hero(int id, std::shared_ptr<Room> room) : Entity(id, room) , isDecelerating(false) , isStanding(false) , isWalking(false) , isSliding(false) , isInTunnel(false) , isJumping(false) , isFalling(false) , isAirborn(false) , isClimbing(false) , isTouchingLadderTop(false) , isFullyAccelerated(false) , isShooting(false) , isTeleporting(false) , isMorphing(false) , isStunned(false) , isInvincible(false) , isUnderWater(false) , wasUnderWaterLastFrame(false) , climbableRegion(0, 0, 0, 0) , actionController(nullptr) , mobilityState(nullptr) , nextMobilityState(nullptr) , temporaryMobilityState(nullptr) , shootingState(nullptr) , nextShootingState(nullptr) { setDeathType(EntityDeathType::Hero); body.setGravitated(true); body.setHasWorldCollision(true); body.setCollisionCallback(std::bind(&Entity::handleCollision, this, std::placeholders::_1, std::placeholders::_2)); body.setLandingCallback([this](Movable& movable, CollisionInfo& collisionInfo) { if(actionController->shouldMoveRight() || actionController->shouldMoveLeft()) { this->isFullyAccelerated = true; } this->isJumping = false; this->isFalling = false; this->isAirborn = false; if(auto events = this->getEventBus().lock()) { events->triggerEvent(EventDataPtr(new EntityStateChangeEventData(getId(), "landed"))); } #ifdef HIKARI_DEBUG_HERO_PHYSICS this->countAscendingFrames = 0; this->countDecendingFrames = 0; #endif // HIKARI_DEBUG_HERO_PHYSICS }); invincibilityTimer = 0; blinkTimer = 0; isBlinking = false; isVisible = true; walkVelocity = Vector2<float>(NESNumber(0x01, 0x4C).toFloat(), 0.0f); climbVelocity = Vector2<float>(walkVelocity.getY(), walkVelocity.getX()); // Climbs at same speed as he walks jumpVelocity = Vector2<float>(0.0f, -(NESNumber(0x04, 0xA5) + NESNumber(0, 0x40) + NESNumber(0, 0x40)).toFloat()); suddenFallVelocity = Vector2<float>(0.0f, NESNumber(0, 0x80).toFloat()); slideVelocity = Vector2<float>(NESNumber(0x02, 0x80).toFloat(), 0.0f); hurtVelocity = Vector2<float>(); accelerationDelay = 0; accelerationDelayThreshold = 6; #ifdef HIKARI_DEBUG_HERO_PHYSICS this->countAscendingFrames = 0; this->countDecendingFrames = 0; #endif // HIKARI_DEBUG_HERO_PHYSICS isFullyAccelerated = false; setFaction(Factions::Hero); changeMobilityState(std::unique_ptr<MobilityState>(new IdleMobilityState(*this))); changeShootingState(std::unique_ptr<ShootingState>(new NotShootingState(*this))); getAnimatedSprite()->setUsePalette(true); getAnimatedSprite()->setUseSharedPalette(true); }