Fog of War with Hexagons implementation advice

Hello everyone!

I’ve previously written a pure javascript implementation of a top down “RPG” using hexagons, fog of war, and path finding. Now I’m experimenting on replicating it with Phaser3. I’m looking for adviceon how you would implement this in Phaser3.

Here is a quick video of what I have now.

I have a bottom layer of the background map image. On top of that, I have a hexagon grid drawn using polygons. Each polygon has an alpha value based on whether the player can see passed the tile or not. It also has slightly transparent values for hexes that the player has previously seen.

The game also prevents the player from moving over areas of the map that are impassable. (mountains, water, etc)

How could I do this in Phaser3? Can I still use one background image for the map and use some sort of DynamicTilemapLayer on top of that for visibility and movement restriction?

Thanks!

Dan

1 Like

I don’t think a Tilemap would work because it doesn’t allow overlapping tiles.

But you could use a Blitter to draw the hex tiles pretty easily.

Thanks @samme I’ll check into using Blitter objects.

In the meantime, I discovered @rexrainbow phaser3-rex-plugins. I’ve been trying to follow his examples on CodePen and have at least got my player (he calls it a Chess object ?) to move around with no restrictions.

Next is to add blockers and add his “Field of View”

Any suggestions @rexrainbow ?

1 Like

Here is a demo of my field of view behavior, in my board system.
It might take lots of computingpower if searching FOV in a big map.

1 Like

Kind of not related, but you may find the answers to advent of code’s 2019 day 10 to be somewhat relevant to what you are trying to do

https://adventofcode.com/2019/day/10

Thank you,

I’ve implemented your FOV and LOS into my sample app and it works well. Now I’m trying to figure out how to implement the opacity for each tile. I’ve initially tried to add a shape forEachTileXY with an initial alpha of 0 and when it came to findFOV, I was going to set the alpha to 1 but I haven’t been able to get that to work yet. Also, it prevented my player from moving because (I think) each tile has a blocker now. shrug.

Is there a way to set a bitmap as a blocker for both FOV and moving? I want to give the player certain items that will grant abilities that will allow him to see/move past hexes. If so, is there a way to provide a custom hasBlocker method?

Thank you again. I think I can make it work, but might need some initial suggestions.

Dan

Visible in FOV behavior could be controlled by costCallback property in config ( see this demo, line 34), without using blocker (blockerTest). Path finding also has costCallback property, too. (see this demo, line 105)
Therefore you can design 2 cost functions for FOV and path-finding.

I’ve been able to implement FOV with a costCallback, thank you. Here’s a demo of what I have so far and I’m still getting 60 FPS.

I have a shape over each hex that originally have a fill color of BLACK and alpha of 1. During findFOV, I grab the visible hexes and set the alpha to 0 (make them visible).

const fovShape = board.tileXYToChessArray(tileXY.x, tileXY.y);

 if (fovShape && fovShape.length > 0) {
        fovShape[0].fillAlpha = Constants.ALPHA_HIDDEN;
 }

I keep the array of visible hexes until the next move and then compare the array of (now) visible hexes with the last move. The ones that are no longer visible, I set the alpha to 0.4 (PREVIOUSLY_SEEN).

I do have a problem with that when trying to get a shape to set alpha to PREVIOUSLY_SEEN, sometimes it can’t find the UID. It seems tileZToUIDs is null for some reason. Do the UIDs get cleaned up or removed each time?

(TileXYToChessArray)
var tileZToUIDs = this.boardData.getUID(tileX, tileY);

  if (tileZToUIDs == null) {
    return out;  // why null?
  }

Board position (tileX, tileY) might not have any chess, or (tileX, tileY) is not in board. Thus tileZToUIDs might be undefined.
Could you provide a test code for this issue? It is better in 1 page js code. in codepen, for example.

Hi,

I made a CodePen with my example. EmberQuest Field Of View problem

Move the player with the Q W S A D E keys.

I think my problem is with the black hole where the player chess is. I make all the obscuring shapes when I create the board at line 163. When I create the player, and add the chess at line 108, the AddChess method is kicking the shape out with

var occupiedChess = this.tileXYZToChess(tileX, tileY, tileZ);

if (occupiedChess) {
this.emit(‘kickout’, gameObject, occupiedChess, curTileXYZ);
}

this.removeChess(gameObject);

if (occupiedChess) {
this.removeChess(occupiedChess, tileX, tileY, tileZ);
}

Is there a way to have the Shape AND the player chess occupy the same location?

I implement visiblePoints with the cost method (its hard to see through the trees). I would also like to do the same with movingPoints (it should be hard to walk through the trees too). Also, maybe set the player speed slower when walking through the trees.

Thanks again!

Dan

Chess and tile position :

  • Any chess has a (tileX, tileY, tileZ) index
  • Any (tileX, tileY, tileZ) index contains only 1 chess.
  • (tileX, tileY) could have more then 1 chess with different tileZ index.
  • tileZ is not equal to depth .

tileZ could be treated as ‘layer’. So you can put fog shape object in ‘fog’ layer (set tileZ to ‘fog’), and put player to ‘chess’ layer (set tileZ to ‘chess’).

When using board plugin in a rpg world ( not a small board game like Bejeweled, or Color Linez ), super large amount of background tile sprites, or other objects like fog sprites, will be a performance issue. A possible solution is place background/fog in blitter objects.

That’s great! That fixes the “hole” and the cleanup of the visited hexes. See the updated CodePen.

Thanks!

Thanks for the suggestion. I see if I can refactor what I have with blitter objects.

Now I found that it uses a single image as background tiles. Cool~ But is there any memory issue if loading a larger image asset?

Yeah, I’m not using Tiled. I wrote a map editor that creates the big array of sceneTiles at the end of the CodePen and it uses one image for the background. I don’t think there should be any memory issues based on the one image; not that I have noticed anyways.

I have updated the CodePen example to now include speed costs for moving over rough terrain like forests, sand, snow, swamp, hills, mountains, etc.

Feel free to point people there if you want. I’ve just combined your examples into one.

Dan

1 Like

How do you detect chessA collisions? Getting around to adding other objects on the screen but can’t figure out how to get my player chess to detect when I move over another chess

Nevermind. I didn’t enable physics for my player. :slight_smile:

Board.contains method

  • Is (tileX, tileY) inside board?
    var isTileInBoard = board.contains(tileX, tileY);
    
  • Does (tileX, tileY, tileZ) have chess?
    var isTileInBoard = board.contains(tileX, tileY, tileZ);