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.

DefaultWorldGen.cc 2.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "DefaultWorldGen.h"
  2. #include <algorithm>
  3. #include <cstdint>
  4. #include "entities/PlayerEntity.h"
  5. static int getGrassLevel(const siv::PerlinNoise &perlin, int x) {
  6. return (int)(perlin.noise(x / 50.0, 0) * 13);
  7. }
  8. static int getStoneLevel(const siv::PerlinNoise &perlin, int x) {
  9. return (int)(perlin.noise(x / 50.0, 10) * 10) + 10;
  10. }
  11. void DefaultWorldGen::drawBackground(
  12. const Swan::Context &ctx, Cygnet::Renderer &rnd, Swan::Vec2 pos) {
  13. // TODO: Do something interesting?
  14. }
  15. Cygnet::Color DefaultWorldGen::backgroundColor(Swan::Vec2 pos) {
  16. float y = pos.y;
  17. return Swan::Draw::linearGradient(y, {
  18. { 0, Cygnet::ByteColor{128, 220, 250}},
  19. { 70, Cygnet::ByteColor{107, 87, 5}},
  20. { 100, Cygnet::ByteColor{107, 87, 5}},
  21. { 200, Cygnet::ByteColor{ 20, 20, 23}},
  22. { 300, Cygnet::ByteColor{ 20, 20, 23}},
  23. { 500, Cygnet::ByteColor{ 25, 10, 10}},
  24. {1000, Cygnet::ByteColor{ 65, 10, 10}},
  25. });
  26. }
  27. Swan::Tile::ID DefaultWorldGen::genTile(Swan::TilePos pos) {
  28. int grassLevel = getGrassLevel(perlin_, pos.x);
  29. int stoneLevel = getStoneLevel(perlin_, pos.x);
  30. // Caves
  31. if (pos.y > grassLevel + 7 && perlin_.noise(pos.x / 43.37, pos.y / 16.37) > 0.2)
  32. return tAir_;
  33. // Trees
  34. if (pos.y == grassLevel - 1) {
  35. constexpr int treeProb = 4;
  36. bool spawnTree = Swan::random(pos.x) % treeProb == 0;
  37. if (spawnTree) {
  38. // Avoid trees which are too close
  39. for (int rx = 1; rx <= 5; ++rx) {
  40. if (Swan::random(pos.x + rx) % treeProb == 0) {
  41. spawnTree = false;
  42. break;
  43. }
  44. }
  45. if (spawnTree) {
  46. return tTreeSeeder_;
  47. }
  48. }
  49. }
  50. if (pos.y > stoneLevel)
  51. return tStone_;
  52. else if (pos.y > grassLevel)
  53. return tDirt_;
  54. else if (pos.y == grassLevel)
  55. return tGrass_;
  56. else
  57. return tAir_;
  58. }
  59. void DefaultWorldGen::genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) {
  60. for (int cx = 0; cx < Swan::CHUNK_WIDTH; ++cx) {
  61. int tilex = chunk.pos_.x * Swan::CHUNK_WIDTH + cx;
  62. for (int cy = 0; cy < Swan::CHUNK_HEIGHT; ++cy) {
  63. int tiley = chunk.pos_.y * Swan::CHUNK_HEIGHT + cy;
  64. Swan::TilePos pos(tilex, tiley);
  65. Swan::Chunk::RelPos rel(cx, cy);
  66. chunk.setTileData(rel, genTile(pos));
  67. }
  68. }
  69. }
  70. Swan::EntityRef DefaultWorldGen::spawnPlayer(const Swan::Context &ctx) {
  71. int x = 0;
  72. return ctx.plane.spawnEntity<PlayerEntity>(
  73. ctx, Swan::Vec2{ (float)x, (float)getGrassLevel(perlin_, x) - 4 });
  74. }