Class VisionFrameworkRgb

java.lang.Object
com.github.yellowstonegames.grid.VisionFramework
com.github.yellowstonegames.grid.VisionFrameworkRgb
All Implemented Interfaces:
com.github.yellowstonegames.core.ISerializersNeeded

public class VisionFrameworkRgb extends VisionFramework implements com.github.yellowstonegames.core.ISerializersNeeded
A "one-stop shop" for handling field-of-view, line-of-sight, (colorful) light sources, and more. Encapsulates currently-visible and previously-seen cell data, and allows updating and modifying light levels/colors. This controls a LightingManager, which manages Radiance light sources. This tracks which cells on a place-map grid have been seen before, which are currently visible, which just became visible and which just became hidden, among other things. This tracks a map as a char[][], typically but not always using box-drawing characters, but these chars can merely be used as abbreviations for what graphic to display in a non-text-based game. This modifies the box-drawing characters it is given based on which walls are actually visible.
After creating a VisionFramework, You can call restart(char[][], CoordFloatOrderedMap, int) when you have a 2D char array to use as the map and one or more viewer positions. After that, add light sources to VisionFramework.lighting. Then you can render the map "background" colors by calling update(float) (every frame) and getting the colors/opacities for anything that can move around (monsters, some traps or effects) using getForegroundColor(int, int, float) (also every frame, once per creature/effect). The update() and getForegroundColor() methods take a float, millisSinceLastMove, which is measured in milliseconds since the last action the player took; this allows cells to fade into or out of view over a short period of time. The background colors are available at VisionFramework.backgroundColors once update() has been called. When the player character or characters change position (or any special vision the player has moves, like a remote camera), call VisionFramework.moveViewer(Coord, Coord). You probably want to move any light source a character carries immediately before calling moveViewer(), so the new position shows the changed lighting right away; moving lights uses LightingManager.moveLight(Coord, Coord). When a small part of the world changes, call VisionFramework.editSingle(Coord, char) (such as for a door opening), or VisionFramework.editAll(char[][]) if a large part of the world changes at once. After any viewer, light source, or map feature changes (or several if they all changed at once), you should call VisionFramework.finishChanges(), which updates VisionFramework.prunedPlaceMap with the actually visible map cells, handles lighting changes, and so on.
To recap, the methods here get called in this order:
  1. Call restart(char[][], Coord, float, int) when an area map is loaded, giving it the viewer(s) and their vision range(s).
  2. Call LightingManager.addLight(Coord, Radiance) on VisionFramework.lighting for every light source.
  3. Every "turn" (when an input is entered), call LightingManager.moveLight(Coord, Coord) if a light source moved.
  4. Every "turn" (when an input is entered), call VisionFramework.removeViewer(Coord) if a viewer was removed.
  5. Every "turn" (when an input is entered), call VisionFramework.moveViewer(Coord, Coord) if a viewer moved.
  6. Every "turn" (when an input is entered), call VisionFramework.editSingle(Coord, char) if a map cell was altered (such as a door opening).
  7. Every "turn" (when an input is entered), call VisionFramework.editAll(char[][]) if the whole current map was altered (such as going downstairs to a new area).
  8. Every "turn" (when an input is entered), if any of the previous every-turn methods was called, call VisionFramework.finishChanges() to complete the change.
  9. Every frame, call update(float), passing it the number of milliseconds since the last turn was handled (this number can be altered).
  10. Every frame, call getForegroundColor(Coord, float) for every position with a moving creature or object in it, passing it a position to query and the number of milliseconds since the last turn was handled (this number can be altered).
  11. You can get the current colors every frame from VisionFramework.backgroundColors, which update() changes.

This class uses the RGBA color space throughout. Use VisionFramework if you prefer Oklab colors. This extends VisionFramework, as LightingManagerRgb extends LightingManager, which allows the VisionFramework.lighting field to be a LightingManager that happens to always be a LightingManagerRgb in this class.
  • Constructor Details

  • Method Details

    • restart

      public void restart(char[][] place, Coord playerPosition, float fovRange, int baseColor)
      Some form of restart() must be called when the map is first created and whenever the whole local map changes.
      This overload simplifies the viewers to just the common case of one viewer, the player character. You can specify an fovRange for how much the player can see without a light source, and you can also choose to add a light at the player's position with VisionFramework.lighting and its LightingManager.addLight(Coord, Radiance) method. Remember to move the player with VisionFramework.moveViewer(Coord, Coord) and any light they carry with LightingManager.moveLight(Coord, Coord). If the player's FOV range changes, you can update it with VisionFramework.putViewer(Coord, float) using the player's current position.
      This overload allows specifying a baseColor that will be used cells that were seen previously but can't be seen now; typically this is dark gray or very close to that, and it is an RGBA8888 int color as produced by DescriptiveColorRgb. The default, if not specified, is VisionFramework.rememberedColor.
      Overrides:
      restart in class VisionFramework
      Parameters:
      place - a 2D char array representing a local map; '#' or box drawing characters represent walls
      playerPosition - where the one viewer will be put in the place; must be in-bounds for place
      fovRange - how far, in grid cells, the player can see without needing a light source
      baseColor - the RGBA8888 int color used for previously-seen, but not in-view, cells
    • restart

      public void restart(char[][] place, CoordFloatOrderedMap viewers, int baseColor)
      Some form of restart() must be called when the map is first created and whenever the whole local map changes.
      This overload allows having one or more viewer positions at the start, with all viewers sharing seen information with each other (enemy characters are not generally viewers here). Each Coord position for a viewer is associated with how much that viewer can see without a light source; you can also choose to add a light at a viewer's position with VisionFramework.lighting and its LightingManager.addLight(Coord, Radiance) method. Remember to move any viewer with VisionFramework.moveViewer(Coord, Coord) and any light they carry with LightingManager.moveLight(Coord, Coord). If a viewer's FOV range changes, you can update it with VisionFramework.putViewer(Coord, float) using that viewer's current position. You can also add new viewers that way.
      This overload allows specifying a baseColor that will be used cells that were seen previously but can't be seen now; typically this is dark gray or very close to that, and it is an RGBA8888 int color as produced by DescriptiveColorRgb. The default, if not specified, is VisionFramework.rememberedColor.
      Overrides:
      restart in class VisionFramework
      Parameters:
      place - a 2D char array representing a local map; '#' or box drawing characters represent walls
      viewers - a CoordFloatOrderedMap of the positions of viewers to their viewing ranges; directly referenced
      baseColor - the RGBA8888 int color used for previously-seen, but not in-view, cells
    • getForegroundColor

      public int getForegroundColor(Coord pos, float millisSinceLastMove)
      For a "foreground" creature or effect that can move between cells, call this every frame to get the color to draw that thing with. The color is an RGBA8888 int, as DescriptiveColorRgb produces. This can return 0 if a creature or thing cannot be seen and is not fading in or out of view. Otherwise, the int color this returns will be white with some level of transparency -- if the creature is in view now and was in view previously, then it will be opaque white, otherwise it will have some transparency between 0 and 1. This takes a float argument, millisSinceLastMove, that is the number of milliseconds since the player last entered an input that changed the map or its inhabitants. This is used to handle fading creatures into view when the player's input suddenly revealed those creatures, or fading them out of view if they become hidden. You don't need to give milliseconds precisely; while the input is effectively clamped between 0 and 1000, you can multiply the actual milliseconds that have passed by (for example) 4 to reduce the time a fade effect takes to complete (to a quarter-second). Multiplying by a large number will make fades instantaneous.
      Overrides:
      getForegroundColor in class VisionFramework
      Parameters:
      pos - the position to get the "foreground" color for; does not actually have to have a creature in it
      millisSinceLastMove - how many milliseconds have elapsed since the human player last entered an input, for fading
      Returns:
      the RGBA8888 int color to tint any foreground creature or object with at pos
    • getForegroundColor

      public int getForegroundColor(int x, int y, float millisSinceLastMove)
      For a "foreground" creature or effect that can move between cells, call this every frame to get the color to draw that thing with. The color is an RGBA8888 int, as DescriptiveColorRgb produces. This can return 0 if a creature or thing cannot be seen and is not fading in or out of view. Otherwise, the int color this returns will be white with some level of transparency -- if the creature is in view now and was in view previously, then it will be opaque white, otherwise it will have some transparency between 0 and 1. Note that because white is the lightest color that can be represented, and it is the "neutral color" for a tint like this, there is no way for this tint to be used to lighten a sprite or other visual object.
      This takes a float argument, millisSinceLastMove, that is the number of milliseconds since the player last entered an input that changed the map or its inhabitants. This is used to handle fading creatures into view when the player's input suddenly revealed those creatures, or fading them out of view if they become hidden. You don't need to give milliseconds precisely; while the input is effectively clamped between 0 and 1000, you can multiply the actual milliseconds that have passed by (for example) 4 to reduce the time a fade effect takes to complete (to a quarter-second). Multiplying by a large number will make fades instantaneous.
      Overrides:
      getForegroundColor in class VisionFramework
      Parameters:
      x - the x-position to get the "foreground" color for; does not actually have to have a creature in it
      y - the y-position to get the "foreground" color for; does not actually have to have a creature in it
      millisSinceLastMove - how many milliseconds have elapsed since the human player last entered an input, for fading
      Returns:
      the RGBA8888 int color to tint any foreground creature or object with at x,y
    • update

      public void update(float millisSinceLastMove)
      Updates the lighting effects and writes to VisionFramework.backgroundColors so the current tint color is stored in every cell of backgroundColors, for every cell in the place map. Call this every frame while lights are updating (for flicker and strobe effects); this does not need to be called if the game has rendering paused for any reason. This takes a float argument, millisSinceLastMove, that is the number of milliseconds since the player last entered an input that changed the map or its inhabitants. This is used to handle fading creatures into view when the player's input suddenly revealed those creatures, or fading them out of view if they become hidden. You don't need to give milliseconds precisely; while the input is effectively clamped between 0 and 1000, you can multiply the actual milliseconds that have passed by (for example) 4 to reduce the time a fade effect takes to complete (to a quarter-second). Multiplying by a large number will make fades instantaneous.
      This sets VisionFramework.backgroundColors to hold visible RGBA8888 int colors where a cell is visible.
      Overrides:
      update in class VisionFramework
      Parameters:
      millisSinceLastMove - how many milliseconds have elapsed since the human player last entered an input, for fading
    • getSerializersNeeded

      public List<Class<?>> getSerializersNeeded()
      Specified by:
      getSerializersNeeded in interface com.github.yellowstonegames.core.ISerializersNeeded
      Overrides:
      getSerializersNeeded in class VisionFramework