#pragma once #include #include "IEntity.hpp" #include "Collider.hpp" #include "Log.hpp" #include "Sand.hpp" class Grid: public sf::Drawable, public IEntity { public: Grid() = delete; Grid(Collider* collider, sf::RenderWindow* window, std::vector* sand, std::vector* spikes, Renderer* renderer): m_collider(collider), m_window(window), m_visible(false), m_sand(sand), m_spikes(spikes), m_renderer(renderer), m_mouseRelease(false), m_csand(nullptr), m_cspike(nullptr) { m_sprite.setTexture(Asset::texture("data/arrows.png")); setType(-1); } void reset() { setType(-1); m_csand = nullptr; m_cspike = nullptr; } void sendReleaseSignal() { m_mouseRelease = true; } void update(float delta) override { static sf::Vector2i prev_mouse(0, 0); sf::Vector2i pos; sf::Vector2i curr_mouse = sf::Mouse::getPosition(*m_window); pos.x = curr_mouse.x / 64.f; pos.y = curr_mouse.y / 64.f; int mode = m_type; if(m_cspike && !sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) { m_cspike = nullptr; } if(pos.x >= 0 && pos.x < 20 && pos.y >= 0 && pos.y < 12) { int block = m_collider->getBlock(pos.x, pos.y); if(m_cspike) { } else if(m_csand) { if(block == Collider::AIR) { mode = 2; } else { mode = -1; } } else if(block == Collider::SAND) { mode = 1; } else if(block == Collider::SPIKE && (m_collider->getBlock(pos.x, pos.y - 1) == Collider::LEVER || mode == 0)) { // not checking if y>1, not needed rn mode = 0; } else { mode = -1; } } else { mode = -1; } if(mode == 0 && sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) { float mouse_w = m_renderer->getPosition() - 320 + curr_mouse.x / 2; if(!m_cspike) { auto res = std::find_if(m_spikes->begin(), m_spikes->end(), [mouse_w](Spike& s) { return s.getPosition().x <= mouse_w && s.getPosition().x + 32.f >= mouse_w; }); m_cspike = &(*res); } if(m_cspike) { float delta = (curr_mouse.y - prev_mouse.y) / 2.f; int x = (m_cspike->getPosition().x - m_renderer->getPosition() + 320.f) / 32; if(delta < 0) { if(m_collider->getBlock(x, (m_cspike->getPosition().y + delta) / 32.f) == Collider::LEVER || m_collider->getBlock(x, (m_cspike->getPosition().y + delta) / 32.f) == Collider::SPIKE) { m_cspike->move(delta); m_sprite.move(0.f, delta); } else { mode = 0; } } else { if(m_collider->getBlock(x, (m_cspike->getPosition().y + 32.f + delta) / 32.f) == Collider::LEVER || m_collider->getBlock(x, (m_cspike->getPosition().y + 32.f + delta) / 32.f) == Collider::SPIKE || m_collider->getBlock(x, (m_cspike->getPosition().y + 32.f + delta) / 32.f) == Collider::AIR) { m_cspike->move(delta); m_sprite.move(0.f, delta); } else { mode = 0; } } } } else { for(Spike& s: *m_spikes) { s.release(); } if(mode >= 0) { m_sprite.setPosition(pos.x * 32.f, pos.y * 32.f); } setType(mode); } if(m_mouseRelease) { if(mode == 1) { float mouse_w = m_renderer->getPosition() - 320.f + curr_mouse.x / 2.f; float mouse_h = curr_mouse.y / 2.f; auto res = std::find_if(m_sand->begin(), m_sand->end(), [mouse_w, mouse_h](Sand& s) { return s.getPosition().y <= mouse_h && s.getPosition().y + 32.f >= mouse_h && s.getPosition().x <= mouse_w && s.getPosition().x + 32.f >= mouse_w; }); if(res != m_sand->end()) { res->setPosition(-32.f, -32.f); m_csand = &(*res); mode = 2; } } else if(mode == 2) { m_csand->setPosition(m_renderer->getPosition() - 320.f + pos.x * 32.f, pos.y * 32.f); mode = -1; m_csand = nullptr; } m_mouseRelease = false; } prev_mouse = curr_mouse; } private: void setType(int type) { if(type >= 0) { m_sprite.setTextureRect(sf::IntRect( type * 32, 0, 32, 32 )); m_visible = true; } else { m_visible = false; } m_type = type; } void draw(sf::RenderTarget& rt, sf::RenderStates states) const override { if(m_visible) { rt.draw(m_sprite, states); } } Collider* m_collider; sf::RenderWindow* m_window; bool m_visible; std::vector* m_sand; std::vector* m_spikes; Renderer* m_renderer; sf::Sprite m_sprite; int m_type; bool m_mouseRelease; Sand* m_csand; Spike* m_cspike; };