about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorStarla Insigna <hatkirby@fourisland.com>2012-06-03 08:47:17 -0400
committerStarla Insigna <hatkirby@fourisland.com>2012-06-03 08:47:17 -0400
commitdb22f4655bfc3dced71b495293f4bab1f6c31ad9 (patch)
treefddfcba4fcd0ea5a59f5944f27d864f678ccb62d /src
parentf97d9581c7b5a1db7db6434938ea594749c08ff5 (diff)
downloadfrigidearth-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.java109
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()