Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Finally Drawing Doors Right

In last week’s report, I talked about the challenges I was facing with correctly rendering doors in The Dungeon Under My House, my second Freshly Squeezed Entertainment project.

I finally made some breakthroughs this week.

Sprint 21: Pre-production and initialization

Planned and incomplete:

  • Doors can be opened/closed

After fighting with the math and code for so long, I am happy to say that the doors are visually correct now.

The Dungeon Under My House - door rendering

The fisheye effect I was seeing got eliminated as soon as I realized that the way I was trying to get the perpendicular distance was wrong. The current algorithm for rendering “things” such as a door (which can be effectively treated as 2D line segments) is to:

  1. Sort all things by distance from camera, so I can render them back to front.
  2. For each thing:
    1. Figure out the leftmost and right most columns to draw.
    2. For each column:
      1. Send out a ray from the camera to thing and figure out its intersection point, and use the relative distance along the line segment to determine which part of the source images to use when rendering.
      2. Then determine the distance from that point back to the camera plane (the perpendicular distance), which determines what height the thing should be drawn as and where vertically. Move onto the next column if this distance is greater than the distance to the nearest wall.
      3. Make various calculations to take into account the true height of the line based on whether part of it is cut off from being at the edges of the screen.
      4. Draw the column.

Part 2.ii was wrongly getting the perpendicular distance by trying to use the column to determine which position on the camera plane to shoot a ray out to the intersection point in Part 2.i. That ray was not perpendicular, unfortunately. Instead, I needed to project from the intersection point back to the camera plane. The position on the camera plane won’t have anything to do with the column I am currently drawing, which feels a bit counterintuitive to me, but after really digging deep and analyzing what was happening, it all made sense.

So the fisheye was removed, but there was still the phenomenon of the doors seemingly approaching the camera whenever the camera rotated between cardinal positions.

That is, if I was facing north, the doors all looked fine. And if I was facing east, the doors looked fine. But in between, the doors looked like they were separating from the walls/floors/ceilings and getting closer and then receding back.

After some more debugging and analyzing, I realized something: the way I was interpolating between the orientation vectors was linear.

My orientation vector was (0, -1) if I was facing north, and it was (1, 0) if I was facing east, but when I was facing north-east, it was (0.5, 0.5). The first two vectors are unit vectors, but the ones between them are shorter.

Shorter unit vectors for the orientation vector means that doors appear to get closer to the camera.

Once I changed from linearly interpolating between vectors to linearly interpolating between angles and deriving the orientation vector from that angle, suddenly not only did the doors seem to move in sync with the rest of the dungeon elements but the dungeon in general seems to render more correctly.

I will admit that I kind of liked how the walls and such looked when turning before I made this fix. It was a little off, but not so much that you might think there was something obviously wrong.

But it is amazing how there is one algorithm for the ceilings and floors, another for the walls, and a third of “things”, and they all use the orientation vector, but only one looked wrong if the orientation vector wasn’t a unit vector.

But now that doors render correctly, the next step was to make them solid. Up until now I could walk through them, which made it easy to debug the rendering code so I can see what they looked like on their reverse without having to go out of my way to walk around doors.

But now they block your way. I made a custom message for what you try to walk through a door.

The Dungeon Under My House - door rendering

Next was to ensure the menu changed to let you try to open a closed door.

The Dungeon Under My House - door rendering

And then I ran out of time for the week.

The remaining work on doors is to animate them opening when you click open, to allow you to close a door again, and to also let an open door block your path. That is, if you are facing north, and the hinge is on the left, a closed door blocks your path north, but an opened door blocks your path west.

Since doors can be part of a grid cell but can block movement both out of the grid cell and into it, my obstacle detection code feels a bit long. I need to check if you are trying to leave a grid cell through a door or if you are entering a grid cell through a door, and now I need to check if those doors are similarly blocking adjacent directions if they are opened.

But I am fairly pleased to finally be working on something more interesting than merely drawing the door.

At least, I hope I’m done with that effort.

Thanks for reading!

Want to learn when I release The Dungeon Under My House, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and download the full color Player’s Guides to my existing and future games for free!

One reply on “Freshly Squeezed Progress Report: Finally Drawing Doors Right”

Comments are closed.