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.

cygnet-test.cc 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include <cygnet/Window.h>
  2. #include <cygnet/Renderer.h>
  3. #include <cygnet/ResourceManager.h>
  4. #include <swan-common/constants.h>
  5. #include <time.h>
  6. #include <stdint.h>
  7. #include <iostream>
  8. #include <SDL_image.h>
  9. #include <SDL.h>
  10. double getTime() {
  11. struct timespec tv;
  12. clock_gettime(CLOCK_MONOTONIC, &tv);
  13. return tv.tv_sec + tv.tv_nsec / 1000000000.0;
  14. }
  15. void addTile(Cygnet::ResourceBuilder &builder, const char *path) {
  16. static size_t id = 0;
  17. SDL_Surface *surf = IMG_Load(path);
  18. builder.addTile(id++, surf->pixels);
  19. SDL_FreeSurface(surf);
  20. }
  21. Cygnet::RenderSprite loadSprite(Cygnet::ResourceBuilder &builder, const char *path, int fh) {
  22. SDL_Surface *surf = IMG_Load(path);
  23. auto sprite = builder.addSprite(path, surf->pixels, surf->w, surf->h, fh);
  24. SDL_FreeSurface(surf);
  25. return sprite;
  26. }
  27. Cygnet::RenderSprite loadSprite(Cygnet::ResourceBuilder &builder, const char *path) {
  28. SDL_Surface *surf = IMG_Load(path);
  29. auto sprite = builder.addSprite(path, surf->pixels, surf->w, surf->h);
  30. SDL_FreeSurface(surf);
  31. return sprite;
  32. }
  33. int main() {
  34. SDL_Init(SDL_INIT_VIDEO);
  35. IMG_Init(IMG_INIT_PNG);
  36. Cygnet::Window win("Cygnet Test", 680, 680);
  37. Cygnet::Renderer rnd;
  38. Cygnet::ResourceBuilder rbuilder(rnd);
  39. for (auto path: {
  40. "core.mod/assets/tile/dirt.png",
  41. "core.mod/assets/tile/grass.png",
  42. "core.mod/assets/tile/leaves.png",
  43. "core.mod/assets/tile/stone.png",
  44. "core.mod/assets/tile/torch.png",
  45. "core.mod/assets/tile/tree-trunk.png",
  46. }) addTile(rbuilder, path);
  47. unsigned char animTexture[32*32*4*3];
  48. for (size_t i = 0; i < 3; ++i) {
  49. int col = 100 * i + 50;;
  50. for (size_t y = 0; y < 32; ++y) {
  51. for (size_t x = 0; x < 32; ++x) {
  52. animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 0] = col;
  53. animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 1] = col;
  54. animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 2] = col;
  55. animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 3] = 255;
  56. }
  57. }
  58. }
  59. rbuilder.addTile(10, animTexture, 3);
  60. Cygnet::RenderSprite playerSprite = loadSprite(
  61. rbuilder, "core.mod/assets/entity/player-still.png", 64);
  62. Cygnet::ResourceManager resources(std::move(rbuilder));
  63. Cygnet::RenderChunk chunk;
  64. {
  65. uint16_t tiles[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT];
  66. memset(tiles, 0, sizeof(tiles));
  67. tiles[0] = 1;
  68. tiles[1] = 2;
  69. tiles[2] = 3;
  70. for (int y = 0; y < 8; ++y) {
  71. for (int x = 0; x < 8; ++x) {
  72. tiles[y * SwanCommon::CHUNK_WIDTH + x] = 10;
  73. }
  74. }
  75. tiles[10] = 10;
  76. chunk = rnd.createChunk(tiles);
  77. }
  78. Cygnet::RenderCamera cam = {
  79. .pos = { 0, 0 },
  80. .size = win.size(),
  81. .zoom = 1,
  82. };
  83. float animAcc = 0;
  84. bool keys[512] = { 0 };
  85. double tileAnimAcc = 0;
  86. double fpsAcc = 0;
  87. double prevTime = getTime() - 1/60.0;
  88. int frames = 0;
  89. float x = 0, y = 0;
  90. while (true) {
  91. double currTime = getTime();
  92. double dt = currTime - prevTime;
  93. prevTime = currTime;
  94. animAcc += dt;
  95. fpsAcc += dt;
  96. frames += 1;
  97. if (fpsAcc >= 2) {
  98. std::cerr << "FPS: " << (frames / 2.0) << '\n';
  99. fpsAcc -= 2;
  100. frames = 0;
  101. }
  102. tileAnimAcc += dt;
  103. if (tileAnimAcc >= 0.5) {
  104. resources.tick();
  105. tileAnimAcc -= 0.5;
  106. }
  107. SDL_Event evt;
  108. while (SDL_PollEvent(&evt)) {
  109. switch (evt.type) {
  110. case SDL_QUIT:
  111. goto exit;
  112. case SDL_WINDOWEVENT:
  113. switch (evt.window.event) {
  114. case SDL_WINDOWEVENT_SIZE_CHANGED:
  115. win.onResize(evt.window.data1, evt.window.data2);
  116. cam.size = win.size();
  117. break;
  118. }
  119. break;
  120. case SDL_MOUSEWHEEL:
  121. cam.zoom += evt.wheel.y * 0.1 * cam.zoom;
  122. break;
  123. case SDL_KEYDOWN:
  124. keys[evt.key.keysym.scancode] = true;
  125. break;
  126. case SDL_KEYUP:
  127. keys[evt.key.keysym.scancode] = false;
  128. break;
  129. }
  130. }
  131. if (keys[SDL_SCANCODE_A]) {
  132. x -= 1 * dt;
  133. }
  134. if (keys[SDL_SCANCODE_D]) {
  135. x += 1 * dt;
  136. }
  137. if (keys[SDL_SCANCODE_W]) {
  138. y -= 1 * dt;
  139. }
  140. if (keys[SDL_SCANCODE_S]) {
  141. y += 1 * dt;
  142. }
  143. rnd.drawChunk(chunk, {0, 0});
  144. rnd.drawSprite(playerSprite, Cygnet::Mat3gf{}.translate({x, y}), (int)animAcc % 2);
  145. cam.pos = {x + 0.5f, y + 0.5f};
  146. win.clear();
  147. rnd.draw(cam);
  148. win.flip();
  149. }
  150. exit:
  151. IMG_Quit();
  152. SDL_Quit();
  153. }