diff options
| author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-05-29 16:32:28 -0400 |
|---|---|---|
| committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-05-29 16:32:28 -0400 |
| commit | 72e83df4876d799cc7b7993813533041a112e250 (patch) | |
| tree | 7e877b11fb6c0257b1ef9b08a7186452ccedcd90 /src | |
| parent | 0dbd1d249d0138c460eaf6ca39568d8d87666cfb (diff) | |
| download | ether-72e83df4876d799cc7b7993813533041a112e250.tar.gz ether-72e83df4876d799cc7b7993813533041a112e250.tar.bz2 ether-72e83df4876d799cc7b7993813533041a112e250.zip | |
dust kickup spreads outward instead of being instantaneous
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 194 | ||||
| -rw-r--r-- | src/untitled.txt | 0 | ||||
| -rw-r--r-- | src/util.h | 20 |
3 files changed, 149 insertions, 65 deletions
| diff --git a/src/main.cpp b/src/main.cpp index 2840439..e26a5a8 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -2,10 +2,11 @@ | |||
| 2 | #include <stdexcept> | 2 | #include <stdexcept> |
| 3 | #include <memory> | 3 | #include <memory> |
| 4 | #include <vector> | 4 | #include <vector> |
| 5 | #include <list> | ||
| 5 | #include <random> | 6 | #include <random> |
| 6 | #include <fov.h> | 7 | #include <fov.h> |
| 7 | #include <deque> | ||
| 8 | #include <iostream> | 8 | #include <iostream> |
| 9 | #include "util.h" | ||
| 9 | 10 | ||
| 10 | class sdl_error : public std::logic_error { | 11 | class sdl_error : public std::logic_error { |
| 11 | public: | 12 | public: |
| @@ -59,6 +60,14 @@ struct Input { | |||
| 59 | bool down = false; | 60 | bool down = false; |
| 60 | }; | 61 | }; |
| 61 | 62 | ||
| 63 | struct Kickup { | ||
| 64 | int x; | ||
| 65 | int y; | ||
| 66 | size_t cur; | ||
| 67 | size_t radius; | ||
| 68 | size_t chain; | ||
| 69 | }; | ||
| 70 | |||
| 62 | class Map { | 71 | class Map { |
| 63 | public: | 72 | public: |
| 64 | 73 | ||
| @@ -73,7 +82,9 @@ public: | |||
| 73 | std::vector<bool> lighting; | 82 | std::vector<bool> lighting; |
| 74 | std::vector<bool> oldLighting; | 83 | std::vector<bool> oldLighting; |
| 75 | std::vector<double> lightStrength; | 84 | std::vector<double> lightStrength; |
| 85 | std::list<Kickup> kickups; | ||
| 76 | int lightedSpots = 0; | 86 | int lightedSpots = 0; |
| 87 | bool dirtyLighting = true; | ||
| 77 | }; | 88 | }; |
| 78 | 89 | ||
| 79 | int player_x = VIEW_WIDTH / 2; | 90 | int player_x = VIEW_WIDTH / 2; |
| @@ -210,6 +221,8 @@ void movePlayer(int x, int y, Map& map) | |||
| 210 | 221 | ||
| 211 | player_x = x; | 222 | player_x = x; |
| 212 | player_y = y; | 223 | player_y = y; |
| 224 | |||
| 225 | map.dirtyLighting = true; | ||
| 213 | } | 226 | } |
| 214 | } | 227 | } |
| 215 | 228 | ||
| @@ -266,22 +279,19 @@ void recalculateLighting(Map& map, fov_settings_type* fov) | |||
| 266 | { | 279 | { |
| 267 | for (int x = 0; x < VIEW_WIDTH; x++) | 280 | for (int x = 0; x < VIEW_WIDTH; x++) |
| 268 | { | 281 | { |
| 269 | if ((player_x == x && player_y == y) || map.tiles[x+VIEW_WIDTH*y] == Tile::Dust || map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) | 282 | if ((player_x == x && player_y == y) || |
| 283 | map.tiles[x+VIEW_WIDTH*y] == Tile::Dust || | ||
| 284 | map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) | ||
| 270 | { | 285 | { |
| 271 | fov_circle(fov, static_cast<void*>(&map), nullptr, x, y, RADIUS); | 286 | fov_circle(fov, static_cast<void*>(&map), nullptr, x, y, RADIUS); |
| 272 | } | ||
| 273 | 287 | ||
| 274 | if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp || | ||
| 275 | map.tiles[x+VIEW_WIDTH*y] == Tile::Dust) | ||
| 276 | { | ||
| 277 | map.lighting[x+VIEW_WIDTH*y] = true; | 288 | map.lighting[x+VIEW_WIDTH*y] = true; |
| 278 | map.lightStrength[x+VIEW_WIDTH*y] = 1.0; | 289 | map.lightStrength[x+VIEW_WIDTH*y] = 1.0; |
| 279 | } | 290 | } |
| 280 | } | 291 | } |
| 281 | } | 292 | } |
| 282 | 293 | ||
| 283 | map.lighting[player_x+VIEW_WIDTH*player_y] = true; | 294 | map.dirtyLighting = false; |
| 284 | map.lightStrength[player_x+VIEW_WIDTH*player_y] = 1.0; | ||
| 285 | } | 295 | } |
| 286 | 296 | ||
| 287 | void processKeys(Map& map, const Input& keystate) | 297 | void processKeys(Map& map, const Input& keystate) |
| @@ -315,6 +325,81 @@ void processKeys(Map& map, const Input& keystate) | |||
| 315 | } | 325 | } |
| 316 | } | 326 | } |
| 317 | 327 | ||
| 328 | void kickUpDust(Map& map, int x, int y, size_t chain) | ||
| 329 | { | ||
| 330 | std::cout << "kickup " << x << " " << y << " " << chain << std::endl; | ||
| 331 | Kickup dk; | ||
| 332 | dk.x = x; | ||
| 333 | dk.y = y; | ||
| 334 | dk.chain = chain; | ||
| 335 | dk.cur = 0; | ||
| 336 | dk.radius = RADIUS + (chain + 1) * (chain + 1); | ||
| 337 | |||
| 338 | map.kickups.push_back(dk); | ||
| 339 | } | ||
| 340 | |||
| 341 | void processKickup(Map& map) | ||
| 342 | { | ||
| 343 | for (Kickup& kickup : map.kickups) | ||
| 344 | { | ||
| 345 | kickup.cur++; | ||
| 346 | |||
| 347 | if (map.tiles[kickup.x+VIEW_WIDTH*kickup.y] == Tile::Floor) | ||
| 348 | { | ||
| 349 | map.tiles[kickup.x+VIEW_WIDTH*kickup.y] = Tile::Dust; | ||
| 350 | } | ||
| 351 | |||
| 352 | std::unique_ptr<fov_settings_type> dusty(new fov_settings_type); | ||
| 353 | fov_settings_set_opacity_test_function( | ||
| 354 | dusty.get(), | ||
| 355 | [] (void* map, int x, int y) { | ||
| 356 | return | ||
| 357 | x >= 0 && | ||
| 358 | x < VIEW_WIDTH && | ||
| 359 | y >= 0 && | ||
| 360 | y < VIEW_HEIGHT && | ||
| 361 | static_cast<Map*>(map)->tiles.at(x+VIEW_WIDTH*y) == Tile::Wall; | ||
| 362 | }); | ||
| 363 | |||
| 364 | fov_settings_set_apply_lighting_function( | ||
| 365 | dusty.get(), | ||
| 366 | [] (void* data, int x, int y, int, int, void* source) { | ||
| 367 | Map& map = *static_cast<Map*>(data); | ||
| 368 | Kickup& kickup = *static_cast<Kickup*>(source); | ||
| 369 | |||
| 370 | if ((x >= 0) && (x < VIEW_WIDTH) && | ||
| 371 | (y >= 0) && (y < VIEW_HEIGHT)) | ||
| 372 | { | ||
| 373 | if (map.tiles[x+VIEW_WIDTH*y] == Tile::Floor) | ||
| 374 | { | ||
| 375 | map.tiles[x+VIEW_WIDTH*y] = Tile::Dust; | ||
| 376 | map.dirtyLighting = true; | ||
| 377 | } else if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) | ||
| 378 | { | ||
| 379 | map.tiles[x+VIEW_WIDTH*y] = Tile::Dust; | ||
| 380 | map.dirtyLighting = true; | ||
| 381 | |||
| 382 | kickUpDust(map, x, y, kickup.chain + 1); | ||
| 383 | } | ||
| 384 | } | ||
| 385 | }); | ||
| 386 | |||
| 387 | fov_circle( | ||
| 388 | dusty.get(), | ||
| 389 | static_cast<void*>(&map), | ||
| 390 | static_cast<void*>(&kickup), | ||
| 391 | kickup.x, | ||
| 392 | kickup.y, | ||
| 393 | kickup.cur); | ||
| 394 | } | ||
| 395 | |||
| 396 | erase_if( | ||
| 397 | map.kickups, | ||
| 398 | [] (const Kickup& kickup) { | ||
| 399 | return kickup.cur == kickup.radius; | ||
| 400 | }); | ||
| 401 | } | ||
| 402 | |||
| 318 | int main(int, char**) | 403 | int main(int, char**) |
| 319 | { | 404 | { |
| 320 | std::random_device randomEngine; | 405 | std::random_device randomEngine; |
| @@ -371,8 +456,21 @@ int main(int, char**) | |||
| 371 | bool quit = false; | 456 | bool quit = false; |
| 372 | Input keystate; | 457 | Input keystate; |
| 373 | SDL_Event e; | 458 | SDL_Event e; |
| 459 | |||
| 460 | size_t dustDt = 30; | ||
| 461 | size_t dustAcc = 0; | ||
| 462 | |||
| 463 | size_t inputDt = 50; | ||
| 464 | size_t inputAcc = 0; | ||
| 465 | |||
| 466 | size_t lastTime = SDL_GetTicks(); | ||
| 467 | |||
| 374 | while (!quit) | 468 | while (!quit) |
| 375 | { | 469 | { |
| 470 | size_t currentTime = SDL_GetTicks(); | ||
| 471 | size_t frameTime = currentTime - lastTime; | ||
| 472 | lastTime = currentTime; | ||
| 473 | |||
| 376 | //bool input = false; | 474 | //bool input = false; |
| 377 | //int presses = 0; | 475 | //int presses = 0; |
| 378 | bool pressedSpace = false; | 476 | bool pressedSpace = false; |
| @@ -396,10 +494,6 @@ int main(int, char**) | |||
| 396 | case SDLK_SPACE: | 494 | case SDLK_SPACE: |
| 397 | { | 495 | { |
| 398 | pressedSpace = true; | 496 | pressedSpace = true; |
| 399 | //input = true; | ||
| 400 | |||
| 401 | std::deque<std::tuple<int, int>> lamps; | ||
| 402 | lamps.emplace_back(player_x, player_y); | ||
| 403 | 497 | ||
| 404 | setIfValid(map, player_x , player_y , Tile::Lamp); | 498 | setIfValid(map, player_x , player_y , Tile::Lamp); |
| 405 | 499 | ||
| @@ -414,56 +508,12 @@ int main(int, char**) | |||
| 414 | player_x + RADIUS, | 508 | player_x + RADIUS, |
| 415 | player_y + RADIUS); | 509 | player_y + RADIUS); |
| 416 | 510 | ||
| 417 | render(ren.get(), map, false); | 511 | //render(ren.get(), map, false); |
| 418 | SDL_Delay(30); | 512 | //SDL_Delay(30); |
| 419 | } | 513 | } |
| 420 | 514 | ||
| 421 | int lamped = 0; | 515 | map.dirtyLighting = true; |
| 422 | while (!lamps.empty()) | 516 | kickUpDust(map, player_x, player_y, 0); |
| 423 | { | ||
| 424 | lamped++; | ||
| 425 | |||
| 426 | int px, py; | ||
| 427 | std::tie(px, py) = lamps.front(); | ||
| 428 | lamps.pop_front(); | ||
| 429 | |||
| 430 | std::unique_ptr<fov_settings_type> dusty(new fov_settings_type); | ||
| 431 | fov_settings_set_opacity_test_function( | ||
| 432 | dusty.get(), | ||
| 433 | [] (void* map, int x, int y) { | ||
| 434 | return | ||
| 435 | x >= 0 && | ||
| 436 | x < VIEW_WIDTH && | ||
| 437 | y >= 0 && | ||
| 438 | y < VIEW_HEIGHT && | ||
| 439 | static_cast<Map*>(map)->tiles.at(x+VIEW_WIDTH*y) == Tile::Wall; | ||
| 440 | }); | ||
| 441 | |||
| 442 | fov_settings_set_apply_lighting_function( | ||
| 443 | dusty.get(), | ||
| 444 | [] (void* map, int x, int y, int, int, void* source) { | ||
| 445 | Map& m = *static_cast<Map*>(map); | ||
| 446 | auto& lamps = *static_cast<std::deque<std::pair<int, int>>*>(source); | ||
| 447 | |||
| 448 | if ((x >= 0) && (x < VIEW_WIDTH) && | ||
| 449 | (y >= 0) && (y < VIEW_HEIGHT)) | ||
| 450 | { | ||
| 451 | if (m.tiles[x+VIEW_WIDTH*y] == Tile::Floor) | ||
| 452 | { | ||
| 453 | m.tiles[x+VIEW_WIDTH*y] = Tile::Dust; | ||
| 454 | } else if (m.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) | ||
| 455 | { | ||
| 456 | m.tiles[x+VIEW_WIDTH*y] = Tile::Dust; | ||
| 457 | lamps.emplace_back(x, y); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | }); | ||
| 461 | |||
| 462 | fov_circle(dusty.get(), static_cast<void*>(&map), static_cast<void*>(&lamps), px, py, RADIUS+lamped*lamped); | ||
| 463 | |||
| 464 | render(ren.get(), map, false); | ||
| 465 | SDL_Delay(50); | ||
| 466 | } | ||
| 467 | 517 | ||
| 468 | break; | 518 | break; |
| 469 | } | 519 | } |
| @@ -479,7 +529,10 @@ int main(int, char**) | |||
| 479 | 529 | ||
| 480 | bool input = keystate.left || keystate.right || keystate.up || keystate.down || pressedSpace; | 530 | bool input = keystate.left || keystate.right || keystate.up || keystate.down || pressedSpace; |
| 481 | 531 | ||
| 482 | if (input) | 532 | dustAcc += frameTime; |
| 533 | inputAcc += frameTime; | ||
| 534 | |||
| 535 | while (dustAcc >= dustDt) | ||
| 483 | { | 536 | { |
| 484 | for (int y = 0; y < VIEW_HEIGHT; y++) | 537 | for (int y = 0; y < VIEW_HEIGHT; y++) |
| 485 | { | 538 | { |
| @@ -488,16 +541,27 @@ int main(int, char**) | |||
| 488 | if (map.tiles[x+y*VIEW_WIDTH] == Tile::Dust) | 541 | if (map.tiles[x+y*VIEW_WIDTH] == Tile::Dust) |
| 489 | { | 542 | { |
| 490 | map.tiles[x+y*VIEW_WIDTH] = Tile::Floor; | 543 | map.tiles[x+y*VIEW_WIDTH] = Tile::Floor; |
| 544 | map.dirtyLighting = true; | ||
| 491 | } | 545 | } |
| 492 | } | 546 | } |
| 493 | } | 547 | } |
| 548 | |||
| 549 | processKickup(map); | ||
| 550 | |||
| 551 | dustAcc -= dustDt; | ||
| 494 | } | 552 | } |
| 495 | 553 | ||
| 496 | processKeys(map, keystate); | 554 | while (inputAcc >= inputDt) |
| 497 | recalculateLighting(map, fov.get()); | 555 | { |
| 556 | processKeys(map, keystate); | ||
| 498 | 557 | ||
| 499 | if (input) | 558 | inputAcc -= inputDt; |
| 559 | } | ||
| 560 | |||
| 561 | if (map.dirtyLighting) | ||
| 500 | { | 562 | { |
| 563 | recalculateLighting(map, fov.get()); | ||
| 564 | |||
| 501 | for (int y = 0; y < VIEW_HEIGHT; y++) | 565 | for (int y = 0; y < VIEW_HEIGHT; y++) |
| 502 | { | 566 | { |
| 503 | for (int x = 0; x < VIEW_WIDTH; x++) | 567 | for (int x = 0; x < VIEW_WIDTH; x++) |
| @@ -520,7 +584,7 @@ int main(int, char**) | |||
| 520 | } | 584 | } |
| 521 | 585 | ||
| 522 | render(ren.get(), map, true); | 586 | render(ren.get(), map, true); |
| 523 | SDL_Delay(50); | 587 | //SDL_Delay(50); |
| 524 | } | 588 | } |
| 525 | } catch (const sdl_error& ex) | 589 | } catch (const sdl_error& ex) |
| 526 | { | 590 | { |
| diff --git a/src/untitled.txt b/src/untitled.txt deleted file mode 100644 index e69de29..0000000 --- a/src/untitled.txt +++ /dev/null | |||
| diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..150a6a5 --- /dev/null +++ b/src/util.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #ifndef UTIL_H_E9110D4C | ||
| 2 | #define UTIL_H_E9110D4C | ||
| 3 | |||
| 4 | template <typename Container, typename Predicate> | ||
| 5 | void erase_if(Container& items, const Predicate& predicate) | ||
| 6 | { | ||
| 7 | for (auto it = std::begin(items); it != std::end(items);) | ||
| 8 | { | ||
| 9 | if (predicate(*it)) | ||
| 10 | { | ||
| 11 | it = items.erase(it); | ||
| 12 | } | ||
| 13 | else | ||
| 14 | { | ||
| 15 | ++it; | ||
| 16 | } | ||
| 17 | } | ||
| 18 | }; | ||
| 19 | |||
| 20 | #endif /* end of include guard: UTIL_H_E9110D4C */ | ||
