diff options
| author | Starla Insigna <hatkirby@fourisland.com> | 2012-06-03 08:47:17 -0400 |
|---|---|---|
| committer | Starla Insigna <hatkirby@fourisland.com> | 2012-06-03 08:47:17 -0400 |
| commit | db22f4655bfc3dced71b495293f4bab1f6c31ad9 (patch) | |
| tree | fddfcba4fcd0ea5a59f5944f27d864f678ccb62d /src | |
| parent | f97d9581c7b5a1db7db6434938ea594749c08ff5 (diff) | |
| download | frigidearth-db22f4655bfc3dced71b495293f4bab1f6c31ad9.tar.gz frigidearth-db22f4655bfc3dced71b495293f4bab1f6c31ad9.tar.bz2 frigidearth-db22f4655bfc3dced71b495293f4bab1f6c31ad9.zip | |
Added field of view (using recursive shadowcasting)
Diffstat (limited to 'src')
| -rw-r--r-- | src/com/fourisland/frigidearth/MapViewGameState.java | 109 |
1 files changed, 98 insertions, 11 deletions
| diff --git a/src/com/fourisland/frigidearth/MapViewGameState.java b/src/com/fourisland/frigidearth/MapViewGameState.java index fe32fe2..aa489da 100644 --- a/src/com/fourisland/frigidearth/MapViewGameState.java +++ b/src/com/fourisland/frigidearth/MapViewGameState.java | |||
| @@ -26,7 +26,9 @@ public class MapViewGameState implements GameState | |||
| 26 | private final int MIN_ROOM_HEIGHT = 7; | 26 | private final int MIN_ROOM_HEIGHT = 7; |
| 27 | private final int MAX_CORRIDOR_LENGTH = 6; | 27 | private final int MAX_CORRIDOR_LENGTH = 6; |
| 28 | private final int MIN_CORRIDOR_LENGTH = 2; | 28 | private final int MIN_CORRIDOR_LENGTH = 2; |
| 29 | private final int[][] OCTET_MULTIPLIERS = new int[][] {new int[] {1,0,0,-1,-1,0,0,1}, new int[] {0,1,-1,0,0,-1,1,0}, new int[] {0,1,1,0,0,-1,-1,0}, new int[] {1,0,0,1,-1,0,0,-1}}; | ||
| 29 | private Tile[][] grid; | 30 | private Tile[][] grid; |
| 31 | private boolean[][] gridLighting; | ||
| 30 | private int playerx = 4; | 32 | private int playerx = 4; |
| 31 | private int playery = 4; | 33 | private int playery = 4; |
| 32 | private int viewportx = 0; | 34 | private int viewportx = 0; |
| @@ -35,6 +37,7 @@ public class MapViewGameState implements GameState | |||
| 35 | public MapViewGameState() | 37 | public MapViewGameState() |
| 36 | { | 38 | { |
| 37 | grid = new Tile[GAME_WIDTH][GAME_HEIGHT]; | 39 | grid = new Tile[GAME_WIDTH][GAME_HEIGHT]; |
| 40 | gridLighting = new boolean[GAME_WIDTH][GAME_HEIGHT]; | ||
| 38 | 41 | ||
| 39 | for (int x=0; x<GAME_WIDTH; x++) | 42 | for (int x=0; x<GAME_WIDTH; x++) |
| 40 | { | 43 | { |
| @@ -476,6 +479,86 @@ public class MapViewGameState implements GameState | |||
| 476 | 479 | ||
| 477 | return true; | 480 | return true; |
| 478 | } | 481 | } |
| 482 | |||
| 483 | private void calculateFieldOfView() | ||
| 484 | { | ||
| 485 | for (int x=0; x<GAME_WIDTH; x++) | ||
| 486 | { | ||
| 487 | for (int y=0; y<GAME_HEIGHT; y++) | ||
| 488 | { | ||
| 489 | gridLighting[x][y] = false; | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | for (int i=0; i<8; i++) | ||
| 494 | { | ||
| 495 | castLight(playerx, playery, 1, 1.0, 0.0, Math.max(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2), OCTET_MULTIPLIERS[0][i], OCTET_MULTIPLIERS[1][i], OCTET_MULTIPLIERS[2][i], OCTET_MULTIPLIERS[3][i], 0); | ||
| 496 | } | ||
| 497 | } | ||
| 498 | |||
| 499 | private void castLight(int cx, int cy, int row, double start, double end, int radius, int xx, int xy, int yx, int yy, int id) | ||
| 500 | { | ||
| 501 | if (start < end) | ||
| 502 | { | ||
| 503 | return; | ||
| 504 | } | ||
| 505 | |||
| 506 | int r2 = radius * radius; | ||
| 507 | for (int j=row; j<radius+1; j++) | ||
| 508 | { | ||
| 509 | int dx = -j-1; | ||
| 510 | int dy = -j; | ||
| 511 | boolean blocked = false; | ||
| 512 | double newStart = 0.0; | ||
| 513 | |||
| 514 | while (dx <= 0) | ||
| 515 | { | ||
| 516 | dx++; | ||
| 517 | |||
| 518 | int x = cx + dx*xx + dy*xy; | ||
| 519 | int y = cy + dx*yx + dy*yy; | ||
| 520 | double l_slope = ((double)dx-0.5)/((double)dy+0.5); | ||
| 521 | double r_slope = ((double)dx+0.5)/((double)dy-0.5); | ||
| 522 | |||
| 523 | if (start < r_slope) | ||
| 524 | { | ||
| 525 | continue; | ||
| 526 | } else if (end > l_slope) | ||
| 527 | { | ||
| 528 | break; | ||
| 529 | } else { | ||
| 530 | if ((dx*dx + dy*dy) < r2) | ||
| 531 | { | ||
| 532 | gridLighting[x][y] = true; | ||
| 533 | } | ||
| 534 | |||
| 535 | if (blocked) | ||
| 536 | { | ||
| 537 | if (grid[x][y].isBlocked()) | ||
| 538 | { | ||
| 539 | newStart = r_slope; | ||
| 540 | continue; | ||
| 541 | } else { | ||
| 542 | blocked = false; | ||
| 543 | start = newStart; | ||
| 544 | } | ||
| 545 | } else { | ||
| 546 | if ((grid[x][y].isBlocked()) && (j < radius)) | ||
| 547 | { | ||
| 548 | blocked = true; | ||
| 549 | castLight(cx, cy, j+1, start, l_slope, radius, xx, xy, yx, yy, id+1); | ||
| 550 | newStart = r_slope; | ||
| 551 | } | ||
| 552 | } | ||
| 553 | } | ||
| 554 | } | ||
| 555 | |||
| 556 | if (blocked) | ||
| 557 | { | ||
| 558 | break; | ||
| 559 | } | ||
| 560 | } | ||
| 561 | } | ||
| 479 | 562 | ||
| 480 | public void render(Graphics2D g) | 563 | public void render(Graphics2D g) |
| 481 | { | 564 | { |
| @@ -484,18 +567,21 @@ public class MapViewGameState implements GameState | |||
| 484 | { | 567 | { |
| 485 | for (int y=viewporty; y<viewporty+VIEWPORT_HEIGHT; y++) | 568 | for (int y=viewporty; y<viewporty+VIEWPORT_HEIGHT; y++) |
| 486 | { | 569 | { |
| 487 | char displayChar = grid[x][y].getDisplayCharacter(); | 570 | if (gridLighting[x][y]) |
| 488 | Color displayColor = grid[x][y].getBackgroundColor(); | ||
| 489 | |||
| 490 | if (!displayColor.equals(Color.BLACK)) | ||
| 491 | { | ||
| 492 | g.setColor(displayColor); | ||
| 493 | g.fillRect((x-viewportx)*TILE_WIDTH, (y-viewporty)*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); | ||
| 494 | } | ||
| 495 | |||
| 496 | if (displayChar != ' ') | ||
| 497 | { | 571 | { |
| 498 | g.drawImage(SystemFont.getCharacter(grid[x][y].getDisplayCharacter()), (x-viewportx)*TILE_WIDTH, (y-viewporty)*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT, null); | 572 | char displayChar = grid[x][y].getDisplayCharacter(); |
| 573 | Color displayColor = grid[x][y].getBackgroundColor(); | ||
| 574 | |||
| 575 | if (!displayColor.equals(Color.BLACK)) | ||
| 576 | { | ||
| 577 | g.setColor(displayColor); | ||
| 578 | g.fillRect((x-viewportx)*TILE_WIDTH, (y-viewporty)*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); | ||
| 579 | } | ||
| 580 | |||
| 581 | if (displayChar != ' ') | ||
| 582 | { | ||
| 583 | g.drawImage(SystemFont.getCharacter(grid[x][y].getDisplayCharacter()), (x-viewportx)*TILE_WIDTH, (y-viewporty)*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT, null); | ||
| 584 | } | ||
| 499 | } | 585 | } |
| 500 | } | 586 | } |
| 501 | } | 587 | } |
| @@ -535,6 +621,7 @@ public class MapViewGameState implements GameState | |||
| 535 | } | 621 | } |
| 536 | 622 | ||
| 537 | adjustViewport(); | 623 | adjustViewport(); |
| 624 | calculateFieldOfView(); | ||
| 538 | } | 625 | } |
| 539 | 626 | ||
| 540 | private void adjustViewport() | 627 | private void adjustViewport() |
