/* * PlayerController.cpp * * Created on: Nov 27, 2016 * Author: tibi */ #include #include #include #include #include #include #include #include #include using namespace farmlands::base; using namespace farmlands::controller::items; using namespace farmlands::graphics; using namespace farmlands::input; using namespace farmlands::model; namespace farmlands { namespace controller { namespace player { static const float PlayerWalkVelocity = 2.0f; // The default velocity of the player when walking (units/sec). static const float PlayerRunVelocity = 4.0f; // The default velocity of the player when running (units/sec). static const float PlayerAttackVelocity = 0.1f; // Movement speed when attacking. /** * Direction enum based on sign of velocity on x and y */ static const Direction VelocitySignDirections[3][3] = { { Direction::NorthWest, Direction::West, Direction::SouthWest }, { Direction::North, Direction::None, Direction::South }, { Direction::NorthEast, Direction::East, Direction::SouthEast }, }; PlayerController::PlayerController() : m_transform(nullptr), m_facingDirection(Direction::South), m_walking(false), m_running(false), m_currentItem(nullptr) { } PlayerController::~PlayerController() { } base::Component* PlayerController::clone() { return new PlayerController(); } void PlayerController::onInitialize() { m_transform = gameObject->component(); } bool PlayerController::onEvent(SDL_Event& event) { handleAttackEvents(event); handleInventoryEvents(event); return false; } void PlayerController::handleAttackEvents(SDL_Event& event) { bool attack = (Input::instance().down(GameKey::Action, event)); if (attack && m_currentItem != nullptr) { // Weapon behavior Weapon* weapon = m_currentItem->component(); if (weapon) weapon->performAttack(m_transform->x, m_transform->y, m_facingDirection); // Gift behavior Giftable* giftable = m_currentItem->component(); if (giftable) giftable->offerGift(m_transform->x, m_transform->y, m_facingDirection); } } void PlayerController::handleInventoryEvents(SDL_Event& event) { // See what key was pressed int slot = -1; if (Input::instance().down(GameKey::Inventory1, event)) slot = 1; if (Input::instance().down(GameKey::Inventory2, event)) slot = 2; if (Input::instance().down(GameKey::Inventory3, event)) slot = 3; if (Input::instance().down(GameKey::Inventory4, event)) slot = 4; if (Input::instance().down(GameKey::Inventory5, event)) slot = 5; if (Input::instance().down(GameKey::Inventory6, event)) slot = 6; if (Input::instance().down(GameKey::Inventory7, event)) slot = 7; if (Input::instance().down(GameKey::Inventory8, event)) slot = 8; if (Input::instance().down(GameKey::Inventory9, event)) slot = 9; if (Input::instance().down(GameKey::Inventory10, event)) slot = 10; // For now we don't have an inventory, so just instantiate some object if (0 <= slot && slot <= GameState::current().itemPrefabs.size()) { GameObject* itemPrefab = GameState::current().itemPrefabs[slot - 1]; // Get rid of old object if (m_currentItem != nullptr) gameObject->destroyChild(m_currentItem); // Instantiate new object m_currentItem = GameObject::instantiate(itemPrefab, "Current item", gameObject); // Print some information // Item* item = itemPrefab->component(); // std::string name = (item == nullptr) ? "unknown" : item->name; // std::cout << "Instantiated object " << slot << " (" << name << ")\n"; } else if (0 <= slot) { std::cout << "Slot " << slot << "empty\n"; } } void PlayerController::onUpdateLogic() { m_running = false; m_walking = false; // Compute movement velocity float velMultiplier = PlayerWalkVelocity; // if (m_attackTimeLeft) // { // velMultiplier = PlayerAttackVelocity; // --m_attackTimeLeft; // } else if (Input::instance().pressed(GameKey::Run)) { velMultiplier = PlayerRunVelocity; m_running = true; } // Make movement time independent velMultiplier *= GameState::current().elapsedTime; // Get velocity of axes float vx = Input::instance().getX() * velMultiplier; float vy = Input::instance().getY() * velMultiplier; // Check if we can move to the new position float newX = m_transform->x + vx; float newY = m_transform->y + vy; if ((vx || vy) && canMove(newX, newY)) { m_walking = true; m_transform->x = newX; m_transform->y = newY; m_facingDirection = getDirection(vx, vy); } } void PlayerController::onPreRender() { // Get sprite SpriteRenderer* spriteRenderer = gameObject->component(); // Compute current state std::string stateName = (m_walking) ? "Walking " : "Idle "; if (m_facingDirection & Direction::East) stateName += "right"; else if (m_facingDirection & Direction::West) stateName += "left"; else if (m_facingDirection & Direction::North) stateName += "up"; else stateName += "down"; spriteRenderer->sprite->setState(stateName); // Set animation velocity float animVelocity = (m_running) ? 1.0f : 0.7f; // if (m_attackTimeLeft) // animVelocity = 0.1f; spriteRenderer->sprite->setAnimationVelocity(animVelocity); // Set weapon if (m_currentItem) { Transform* itemTransf = m_currentItem->component(); itemTransf->x = 0.2f; itemTransf->y = -0.8f; } // Set camera base::Transform* cam = GameState::current().renderContext.cameraTransform(); cam->x = m_transform->x; cam->y = m_transform->y - 1; } bool PlayerController::canMove(float x, float y) { // TODO: check collisions & stuff. For now, nothing return true; } Direction PlayerController::getDirection(float vx, float vy) { int xx = (0 < vx) - (vx < 0); int yy = (0 < vy) - (vy < 0); return VelocitySignDirections[xx + 1][yy + 1]; } void PlayerController::attack() { // For now - nothing } void PlayerController::dump(unsigned level) { for (unsigned i = 0; i < level; i++) std::cout<<" "; std::cout << " .Component: PlayerController\n"; } } } /* namespace controller */ } /* namespace farmlands */