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.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include <string.h>
  3. #include <stdint.h>
  4. #include <memory>
  5. #include <cygnet/Renderer.h>
  6. #include "util.h"
  7. #include "common.h"
  8. #include "Tile.h"
  9. namespace Swan {
  10. class World;
  11. class Game;
  12. class Chunk {
  13. public:
  14. using RelPos = TilePos;
  15. static constexpr size_t DATA_SIZE =
  16. CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID) +
  17. CHUNK_WIDTH * CHUNK_HEIGHT;
  18. // What does this chunk want the world gen to do after a tick?
  19. enum class TickAction {
  20. DEACTIVATE,
  21. DELETE,
  22. NOTHING,
  23. };
  24. Chunk(ChunkPos pos): pos_(pos), data_(new uint8_t[DATA_SIZE]) {}
  25. Tile::ID *getTileData() {
  26. assert(isActive());
  27. return (Tile::ID *)data_.get();
  28. }
  29. uint8_t *getOpacityData() {
  30. assert(isActive());
  31. return data_.get() + CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID);
  32. }
  33. Tile::ID getTileID(RelPos pos) {
  34. return getTileData()[pos.y * CHUNK_WIDTH + pos.x];
  35. }
  36. void setTileID(RelPos pos, Tile::ID id, uint8_t opacity) {
  37. getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id;
  38. getOpacityData()[pos.y * CHUNK_WIDTH + pos.x] = opacity;
  39. changeList_.emplace_back(pos, id, opacity);
  40. isModified_ = true;
  41. }
  42. void setTileData(RelPos pos, Tile::ID id) {
  43. getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id;
  44. }
  45. void addLight(RelPos pos, float level) { lights_.push_back({pos, level}); }
  46. void removeLight(RelPos pos);
  47. void generateDone(World &world);
  48. void keepActive();
  49. void decompress();
  50. void compress(Cygnet::Renderer &rnd);
  51. void destroy(Cygnet::Renderer &rnd) { rnd.destroyChunk(renderChunk_); }
  52. void draw(const Context &ctx, Cygnet::Renderer &rnd);
  53. TickAction tick(float dt);
  54. bool isActive() { return deactivateTimer_ > 0; }
  55. ChunkPos pos_;
  56. private:
  57. static constexpr float DEACTIVATE_INTERVAL = 20;
  58. bool isCompressed() { return compressedSize_ != -1; }
  59. std::unique_ptr<uint8_t[]> data_;
  60. std::vector<std::pair<RelPos, float>> lights_;
  61. std::vector<std::tuple<RelPos, Tile::ID, uint8_t>> changeList_;
  62. ssize_t compressedSize_ = -1; // -1 if not compressed, a positive number if compressed
  63. Cygnet::RenderChunk renderChunk_;
  64. bool needChunkRender_ = true;
  65. float deactivateTimer_ = DEACTIVATE_INTERVAL;
  66. bool isModified_ = false;
  67. };
  68. }