#include #include #include #include #include #include #include static const char *spriteXML = " \ \ assets/player/player.png \ assets/player/player.png\ assets/player/player.png\ assets/player/player.png\ \ "; static const char *animationXML = "\ \ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ \ \ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ assets/player/player.png\ \ \ \ "; entityx::Entity PlayerSystem::player; bool PlayerSystem::moveLeft = false; bool PlayerSystem::moveRight = false; float PlayerSystem::speed = 1.0f; PlayerSystem::PlayerSystem(void) { } void PlayerSystem::create(void) { player = game::entities.create(); player.assign(); player.assign(0.0f, 100.0f); player.assign(0.0f, 0.0f); //player.assign(-0.001f); player.assign(.25); player.assign(-0.2f); player.assign(100); auto sprite = player.assign(); XMLDocument xmld; xmld.Parse(spriteXML); auto frame = developFrame(xmld.FirstChildElement("Sprite")); if (frame.size() > 0) sprite->sprite = frame.at(0); vec2 dim = player.component().get()->getSpriteSize(); float cdat[2] = {dim.x, dim.y}; player.assign(cdat[0], cdat[1]); // handle player animation xmld.Parse(animationXML); player.assign(nullptr, xmld.FirstChildElement()); } void PlayerSystem::configure(entityx::EventManager &ev) { ev.subscribe(*this); ev.subscribe(*this); ev.subscribe(*this); } void PlayerSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) { (void)en; (void)ev; (void)dt; if (player.component()->health <= 0) abort(); auto& vel = *player.component().get(); if (moveLeft & !moveRight) vel.x = -PLAYER_SPEED_CONSTANT; else if (!moveLeft & moveRight) vel.x = PLAYER_SPEED_CONSTANT; else vel.x = 0; vel.x *= speed; if (std::stoi(game::getValue("Slow")) == 1) vel.x /= 2.0f; } bool PlayerSystem::receive(const KeyUpEvent &kue) { auto kc = kue.keycode; if (kc == getControl(1)) { moveLeft = false; } else if (kc == getControl(2)) { moveRight = false; } else if (kc == getControl(3) || kc == getControl(4)) { speed = 1.0f; } else if (kc == getControl(5)) { // TODO ...? } return true; } bool PlayerSystem::receive(const KeyDownEvent &kde) { auto kc = kde.keycode; auto& loc = *player.component().get(); auto& vel = *player.component().get(); if ((kc == SDLK_SPACE) && game::canJump && ((vel.y > -0.01) & (vel.y < 0.01))) { loc.y += HLINES(2); vel.y = 0.05f; vel.grounded = false; } else if (!UISystem::isDialog()) { if (kc == getControl(0)) { if (!UISystem::isFading()) WorldSystem::goWorldPortal(loc); } else if (kc == getControl(1)) { if (!UISystem::isFading()) { moveLeft = true; moveRight = false; WorldSystem::goWorldLeft(loc); } } else if (kc == getControl(2)) { if (!UISystem::isFading()) { moveLeft = false; moveRight = true; WorldSystem::goWorldRight(loc, *player.component().get()); } } else if (kc == getControl(3)) { if (game::canSprint) speed = 2.0f; ParticleSystem::addMultiple(10, ParticleType::SmallBlast, [&](){ return vec2(loc.x, loc.y); }, 500, 7); } else if (kc == getControl(4)) { speed = .5; } else if (kc == getControl(5)) { // hmmm } } else if (kc == SDLK_DELETE) { game::endGame(); } else if (kc == SDLK_t) { game::time::tick(50); } return true; } vec2 PlayerSystem::getPosition(void) { Position loc; if (player) loc = *game::entities.component(player.id()).get(); return vec2(loc.x, loc.y); } float PlayerSystem::getWidth(void) { float width = 0; if (player) width = game::entities.component(player.id())->width; return width; } bool PlayerSystem::receive(const UseItemEvent& uie) { static std::atomic_bool cool (true); if (cool.load()) { if (uie.item->sound != nullptr) Mix_PlayChannel(0, uie.item->sound, 0); if (uie.item->type == "Sword") { auto loc = getPosition(); auto &solid = *player.component().get(); loc.x += solid.width / 2, loc.y += solid.height / 2; if (player.component()->faceLeft) uie.attack->range.x *= -1; game::events.emit(loc, *uie.attack, true); } else if (uie.item->type == "Bow") { if (InventorySystem::take("Arrow", 1)) { auto e = game::entities.create(); auto pos = getPosition(); e.assign(pos.x, pos.y + 10); auto angle = std::atan2(uie.curs.y - pos.y, uie.curs.x - pos.x); e.assign(0.25f * std::cos(angle), 0.25f * std::sin(angle)); e.assign(-5); e.assign(); auto sprite = e.assign(); auto tex = InventorySystem::getItem("Arrow"); sprite->addSpriteSegment(SpriteData(tex->sprite), 0); auto dim = HLINES(sprite->getSpriteSize()); e.assign(dim.x, dim.y); e.assign(uie.attack->power, false); if (uie.attack->effect.size() > 0) e.component()->effect = uie.attack->effect; } } cool.store(false); std::thread([&](unsigned int ms) { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); cool.store(true); }, uie.item->cooldown).detach(); } return true; }