A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Chunk.h 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #pragma once
  2. #include <string.h>
  3. #include <stdint.h>
  4. #include <memory>
  5. #include "util.h"
  6. #include "common.h"
  7. #include "Tile.h"
  8. namespace Swan {
  9. class World;
  10. class Game;
  11. class Chunk {
  12. public:
  13. using RelPos = TilePos;
  14. static constexpr size_t DATA_SIZE =
  15. CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID) + // Tiles
  16. CHUNK_WIDTH * CHUNK_HEIGHT; // Light levels
  17. // What does this chunk want the world gen to do after a tick?
  18. enum class TickAction {
  19. DEACTIVATE,
  20. DELETE,
  21. NOTHING,
  22. };
  23. Chunk(ChunkPos pos): pos_(pos) {
  24. data_.reset(new uint8_t[DATA_SIZE]);
  25. memset(getLightData(), 0, CHUNK_WIDTH * CHUNK_HEIGHT);
  26. }
  27. Tile::ID *getTileData() {
  28. assert(isActive());
  29. return (Tile::ID *)data_.get();
  30. }
  31. uint8_t *getLightData() {
  32. assert(isActive());
  33. return data_.get() + CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID);
  34. }
  35. Tile::ID getTileID(RelPos pos) {
  36. return getTileData()[pos.y * CHUNK_WIDTH + pos.x];
  37. }
  38. void setTileID(RelPos pos, Tile::ID id, SDL_Texture *tex) {
  39. getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id;
  40. draw_list_.push_back({ pos, tex });
  41. }
  42. void setTileData(RelPos pos, Tile::ID id) {
  43. getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id;
  44. need_render_ = true;
  45. }
  46. uint8_t getLightLevel(RelPos pos) {
  47. return getLightData()[pos.y * CHUNK_WIDTH + pos.x];
  48. }
  49. void setLightLevel(RelPos pos, uint8_t level, SDL_Renderer *rnd);
  50. void setLightData(RelPos pos, uint8_t level) {
  51. getLightData()[pos.y * CHUNK_WIDTH + pos.x] = level;
  52. need_light_render_ = true;
  53. }
  54. void render(const Context &ctx, SDL_Renderer *rnd);
  55. void renderLight(const Context &ctx, SDL_Renderer *rnd);
  56. void compress();
  57. void decompress();
  58. void draw(const Context &ctx, Win &win);
  59. TickAction tick(float dt);
  60. bool isActive() { return deactivate_timer_ > 0; }
  61. void keepActive();
  62. void markModified() { is_modified_ = true; }
  63. ChunkPos pos_;
  64. private:
  65. static constexpr float DEACTIVATE_INTERVAL = 20;
  66. void renderList(SDL_Renderer *rnd);
  67. bool isCompressed() { return compressed_size_ != -1; }
  68. std::unique_ptr<uint8_t[]> data_;
  69. std::vector<std::pair<RelPos, SDL_Texture *>> draw_list_;
  70. ssize_t compressed_size_ = -1; // -1 if not compressed, a positive number if compressed
  71. bool need_render_ = false;
  72. bool need_light_render_ = false;
  73. float deactivate_timer_ = DEACTIVATE_INTERVAL;
  74. bool is_modified_ = false;
  75. CPtr<SDL_Texture, SDL_DestroyTexture> texture_;
  76. CPtr<SDL_Texture, SDL_DestroyTexture> light_texture_;
  77. };
  78. }