DEV Community

Cover image for Demo Highlight: 2dVis

Posted on

Demo Highlight: 2dVis

Mini Micro comes with over 40 built-in demos in the /sys/demo directory. But a surprising number of users have never taken the time to really explore these. So, I'm going to highlight some of my favorites, starting with the very first one (alphabetically), 2dVis.

Screenshot of 2dVis demo

This is a fun demonstration of a very powerful technique: calculating the two-dimensional visibility region from a given viewpoint, in an arbitrarily complex environment. The code is based on this excellent article from Red Blob Games.

To follow along, download Mini Micro if you don't have it already, launch it, and enter these commands:

cd "/sys/demo"
load "2dVis"
Enter fullscreen mode Exit fullscreen mode

(The dir or directory listing command is not strictly necessary, but is a good habit to get into.)

You should see a display like the screen shot above. Now simply click and drag anywhere in the map. As you do, the yellow "light source" or viewpoint will move around, and you can instantly see where a light at that point would cast into the environment.

Animated GIF of 2DVis demo

You can also think of the yellow dot as the viewpoint — say, the position of the player in a game — and the lit areas as all the parts of the map that can be seen from that point.

The code for this is rather complex, though the Red Blob Games article does a good job of explaining the algorithm. In a nutshell, what it does is:

  1. Sort all the endpoints of the line segments that make up the environment, in counter-clockwise order around the viewpoint.
  2. "Sweep" over these sorted points, figuring out which line segments are visible or partly visible.
  3. For each visible part, add the ends to a growing polygon that represents the visible area.

The demo code then draws this visible-area polygon in a lighter color, before drawing the line segments and yellow ball on top.

Although this is in /sys/demo, it is written in such a way that it can actually be used as an import library! To use it in your own projects, you would do something like this:

  1. Copy into your own folder, or else add /sys/demo to the import paths: env.importPaths.push "/sys/demo"
  2. import "2dVis"
  3. make a new Visibility object (and note that because 2dVis is not a valid identifier, we have to index into locals to find the imported module: vis = new locals["2dVis"].Visibility
  4. build your environment by calling vis.loadMap, vis.addBlock, or vis.addSegments as desired
  5. finally, whenever the viewpoint changes: (a) call vis.setViewpoint with the new location; (b) call vis.sweep; (c) do whatever you need with the vis.output polygon.

So, what could you do with this? You might make a sneaker game where you have to avoid being seen by roving guards. (The mathUtil module in /sys/lib has some handy polygon-related methods, like pointInPoly for testing whether a given point is within a polygon). Or you could make a roguelike dungeon crawler, with everything outside the visible polygon hidden. Or how about a puzzle game, where obstacles change in some predictable way — but only when you can't see them?

Or, like all demos, you can simply explore the code and see what new tips and tricks you discover.

What do you think of this demo? Does it inspire any ideas? Let me know in the comments below!

Top comments (2)

synapticbytes profile image
Russell Hansen

Great demo! Your ideas for using it are also spot on.

sebnozzi profile image
Sebastian Nozzi

Awesome demo. Looks very good.