diff options
-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() |