123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- // SuperTux
- // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- #ifndef HEADER_SUPERTUX_OBJECT_TILEMAP_HPP
- #define HEADER_SUPERTUX_OBJECT_TILEMAP_HPP
- #include <algorithm>
- #include <unordered_set>
- #include "math/rect.hpp"
- #include "math/rectf.hpp"
- #include "math/size.hpp"
- #include "object/path_object.hpp"
- #include "object/path_walker.hpp"
- #include "supertux/autotile.hpp"
- #include "supertux/game_object.hpp"
- #include "video/color.hpp"
- #include "video/flip.hpp"
- #include "video/drawing_target.hpp"
- class CollisionObject;
- class CollisionGroundMovementManager;
- class DrawingContext;
- class Tile;
- class TileSet;
- /**
- * This class is responsible for managing an array of tiles.
- * @scripting
- * @summary A ""TileMap"" that was given a name can be controlled by scripts.
- The tilemap can be moved by specifying a path for it.
- * @instances A ""TileMap"" is instantiated by placing a definition inside a level.
- It can then be accessed by its name from a script or via ""sector.name"" from the console.
- */
- class TileMap final : public GameObject,
- public PathObject
- {
- public:
- static void register_class(ssq::VM& vm);
- public:
- TileMap(const TileSet *tileset);
- TileMap(const TileSet *tileset, const ReaderMapping& reader);
- ~TileMap() override;
- virtual void finish_construction() override;
- static std::string class_name() { return "tilemap"; }
- virtual std::string get_class_name() const override { return class_name(); }
- virtual std::string get_exposed_class_name() const override { return "TileMap"; }
- virtual const std::string get_icon_path() const override { return "images/engine/editor/tilemap.png"; }
- static std::string display_name() { return _("Tilemap"); }
- virtual std::string get_display_name() const override { return display_name(); }
- virtual GameObjectClasses get_class_types() const override { return GameObject::get_class_types().add(typeid(PathObject)).add(typeid(TileMap)); }
- virtual ObjectSettings get_settings() override;
- virtual void after_editor_set() override;
- void save_state() override;
- void check_state() override;
- virtual void update(float dt_sec) override;
- virtual void draw(DrawingContext& context) override;
- virtual void editor_update() override;
- virtual void on_flip(float height) override;
- void set(int width, int height, const std::vector<unsigned int>& vec,
- int z_pos, bool solid);
- /** resizes the tilemap to a new width and height (tries to not
- destroy the existing map) */
- void resize(int newwidth, int newheight, int fill_id = 0,
- int xoffset = 0, int yoffset = 0);
- void resize(const Size& newsize, const Size& resize_offset);
- int get_width() const { return m_width; }
- int get_height() const { return m_height; }
- Size get_size() const { return Size(m_width, m_height); }
- void set_offset(const Vector &offset_) { m_offset = offset_; }
- Vector get_offset() const { return m_offset; }
- void set_ground_movement_manager(const std::shared_ptr<CollisionGroundMovementManager>& movement_manager)
- {
- m_ground_movement_manager = movement_manager;
- }
- void move_by(const Vector& pos);
- /** Get the movement of this tilemap. The collision detection code
- may need a non-negative y-movement. Passing `false' as the
- `actual' argument will provide that. Used exclusively in
- src/supertux/sector.cpp. */
- Vector get_movement(bool actual) const
- {
- if (actual) {
- return m_movement;
- }
- return Vector(m_movement.x, std::max(0.0f, m_movement.y));
- }
- /** Returns the position of the upper-left corner of tile (x, y) in
- the sector. */
- Vector get_tile_position(int x, int y) const
- { return m_offset + Vector(static_cast<float>(x), static_cast<float>(y)) * 32.0f; }
- Rectf get_bbox() const {
- return Rectf(get_tile_position(0, 0),
- get_tile_position(m_width, m_height));
- }
- Rectf get_tile_bbox(int x, int y) const {
- return Rectf(get_tile_position(x, y),
- get_tile_position(x + 1, y + 1));
- }
- /** Returns the half-open rectangle of (x, y) tile indices that
- overlap the given rectangle in the sector. */
- Rect get_tiles_overlapping(const Rectf &rect) const;
- /** Called by the collision mechanism to indicate that this tilemap has been hit on
- the top, i.e. has hit a moving object on the bottom of its collision rectangle. */
- void hits_object_bottom(CollisionObject& object);
- void notify_object_removal(CollisionObject* other);
- int get_layer() const { return m_z_pos; }
- void set_layer(int layer) { m_z_pos = layer; }
- bool is_solid() const { return m_real_solid && m_effective_solid; }
- /**
- * @scripting
- * @description Switches the tilemap's real solidity to ""solid"".${SRG_TABLENEWPARAGRAPH}
- Note: The effective solidity is also influenced by the alpha of the tilemap.
- * @param bool $solid
- */
- void set_solid(bool solid = true);
- /**
- * @scripting
- * @description Returns the effective solidity of the tilemap.
- */
- bool get_solid() const;
- bool is_outside_bounds(const Vector& pos) const;
- const Tile& get_tile(int x, int y) const;
- const Tile& get_tile_at(const Vector& pos) const;
- /**
- * @scripting
- * @description Returns the ID of the tile at the given coordinates or 0 if out of bounds.
- The origin is at the top left.
- * @param int $x
- * @param int $y
- */
- uint32_t get_tile_id(int x, int y) const;
- /**
- * @scripting
- * @description Returns the ID of the tile at the given position (in world coordinates).
- * @param float $x
- * @param float $y
- */
- uint32_t get_tile_id_at(float x, float y) const;
- uint32_t get_tile_id_at(const Vector& pos) const;
- /**
- * @scripting
- * @description Changes the tile at the given coordinates to ""newtile"".
- The origin is at the top left.
- * @param int $x
- * @param int $y
- * @param int $newtile
- */
- void change(int x, int y, uint32_t newtile);
- /**
- * @scripting
- * @description Changes the tile at the given position (in-world coordinates) to ""newtile"".
- * @param float $x
- * @param float $y
- * @param int $newtile
- */
- void change_at(float x, float y, uint32_t newtile);
- void change_at(const Vector& pos, uint32_t newtile);
- /**
- * @scripting
- * @description Changes all tiles with the given ID.
- * @param int $oldtile
- * @param int $newtile
- */
- void change_all(uint32_t oldtile, uint32_t newtile);
- /** Puts the correct autotile block at the given position */
- void autotile(int x, int y, uint32_t tile);
- enum class AutotileCornerOperation {
- ADD_TOP_LEFT,
- ADD_TOP_RIGHT,
- ADD_BOTTOM_LEFT,
- ADD_BOTTOM_RIGHT,
- REMOVE_TOP_LEFT,
- REMOVE_TOP_RIGHT,
- REMOVE_BOTTOM_LEFT,
- REMOVE_BOTTOM_RIGHT,
- };
- /** Puts the correct autotile blocks at the tiles around the given corner */
- void autotile_corner(int x, int y, uint32_t tile, AutotileCornerOperation op);
- /** Erases in autotile mode */
- void autotile_erase(const Vector& pos, const Vector& corner_pos);
- /** Returns the Autotileset associated with the given tile */
- AutotileSet* get_autotileset(uint32_t tile) const;
- void set_flip(Flip flip) { m_flip = flip; }
- Flip get_flip() const { return m_flip; }
- /**
- * @scripting
- * @description Starts fading the tilemap to the opacity given by ""alpha"".
- Destination opacity will be reached after ""time"" seconds. Also influences solidity.
- * @param float $alpha
- * @param float $time
- */
- void fade(float alpha, float time);
- /** Start fading the tilemap to tint given by RGBA.
- Destination opacity will be reached after @c seconds seconds. Doesn't influence solidity. */
- void tint_fade(const Color& new_tint, float time = 0.f);
- /**
- * @scripting
- * @description Starts fading the tilemap to tint given by RGBA.
- Destination opacity will be reached after ""time"" seconds. Doesn't influence solidity.
- * @param float $time
- * @param float $red
- * @param float $green
- * @param float $blue
- * @param float $alpha
- */
- void tint_fade(float time, float red, float green, float blue, float alpha);
- Color get_current_tint() const { return m_current_tint; }
- /**
- * @scripting
- * @description Instantly switches the tilemap's opacity to ""alpha"". Also influences solidity.
- * @param float $alpha
- */
- void set_alpha(float alpha);
- /**
- * @scripting
- * @description Returns the tilemap's opacity.${SRG_TABLENEWPARAGRAPH}
- Note: While the tilemap is fading in or out, this will return the current alpha value, not the target alpha.
- */
- float get_alpha() const;
- float get_target_alpha() const { return m_alpha; }
- void set_tileset(const TileSet* new_tileset);
- const std::vector<uint32_t>& get_tiles() const { return m_tiles; }
- private:
- void update_effective_solid(bool update_manager = true);
- void float_channel(float target, float ¤t, float remaining_time, float dt_sec);
- bool is_corner(uint32_t tile) const;
- void apply_offset_x(int fill_id, int xoffset);
- void apply_offset_y(int fill_id, int yoffset);
- public:
- bool m_editor_active;
- private:
- const TileSet* m_tileset;
- typedef std::vector<uint32_t> Tiles;
- Tiles m_tiles;
- #ifdef DOXYGEN_SCRIPTING
- /**
- * @scripting
- * @description Equivalent to ""get_solid()"" and ""set_solid()"".
- */
- bool m_solid;
- #endif
- /* read solid: In *general*, is this a solid layer? effective solid:
- is the layer *currently* solid? A generally solid layer may be
- not solid when its alpha is low. See `is_solid' above. */
- bool m_real_solid;
- bool m_effective_solid;
- float m_speed_x;
- float m_speed_y;
- int m_width;
- int m_height;
- int m_z_pos;
- Vector m_offset;
- Vector m_movement; /**< The movement that happened last frame */
- /** Objects that were touching the top of a solid tile at the last frame */
- std::unordered_set<CollisionObject*> m_objects_hit_bottom;
- std::shared_ptr<CollisionGroundMovementManager> m_ground_movement_manager;
- Flip m_flip;
- /**
- * @scripting
- * @description Determines the tilemap's current opacity.
- */
- float m_alpha; /**< requested tilemap opacity */
- float m_current_alpha; /**< current tilemap opacity */
- float m_remaining_fade_time; /**< seconds until requested tilemap opacity is reached */
- /** The tint can have its own alpha channel, but this alpha channel doesn't affect
- the solidity of the tilemap. This alpha channel makes the tilemap only less or
- more translucent.*/
- Color m_tint; /**< requested tilemap tint */
- Color m_current_tint; /**< current tilemap tint */
- float m_remaining_tint_fade_time; /**< seconds until requested tilemap tint is reached */
- /** Set to LIGHTMAP to draw to lightmap */
- DrawingTarget m_draw_target;
- int m_new_size_x;
- int m_new_size_y;
- int m_new_offset_x;
- int m_new_offset_y;
- bool m_add_path;
- int m_starting_node;
- private:
- TileMap(const TileMap&) = delete;
- TileMap& operator=(const TileMap&) = delete;
- };
- #endif
- /* EOF */
|