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