The code comes from Lode Vandevenne's tutorial Raycasting III: Sprites.
The purpose of systematically apply some enhancements and document them along the way.
The rest of the original tutorials are here Lode's Computer Graphics Tutorial
commit 71797ccd2dc8cd6d633d8ef4bb3a4e2ccc1cc242
The first step just fixes some compiler warnings.
I also didn't feel comfortable distributing this project with the Wolfenstein 3D textures (since they ), so I replaced them with some CC0-licensed graphics from Dungeon Crawl Stone Soup (DCSS)
The Dungeon Crawl Stone Soup graphics are from here: https://opengameart.org/content/dungeon-crawl-32x32-tiles
The second step doesn't lead to a difference graphically, but internally it draws all the vertical wall strips and the sprites using only integer arithmetic.
commit e0f5cbbc6e2bb3011b210c3a2a2a779c6896769a
Convert the code that draws the vertical strips to use integer only arithmetic.
The integer arithmetic trick is based on the DDA algorithm from this article
commit 8039f41cc5cb93458bb6b80109ac77edf3ab47be
Then you can use the same trick to draw the vertical strips of the sprites.
commit 34993e41b08c4ec51b0b936ae5d99afa2d5f9ac5
While you're at it, you can do the same for the horizontal part of the sprite loop.
commit c1d6246654886222c54d7fccdcbda7f228669b99
Here I disable the ceiling and draw a skybox.
commit bb0c927871fbf0d17798a698c4c453b262d15436
We fade each pixel to a fog colour, based on its distance from the viewer
commit f5980c0319457d9fc188d3ac40d5f0643f586973
Here we implement doors that can open an close when the player interacts with them.
To draw doors, if a ray strikes a tile with a door, we take half a step backwards, and check whether we're still in the tile with the door. If we are, we use the distance of the half step, otherwise we resume casting the ray to draw what is beside or behind the door.
commit 0ef7d398abb09a70e6952e61d83cc6d2b70f29b7
We implement looking up and down (with the Q and A keys) by shifting the view plane up and down.
commit 61224aa5a8c08def242fb696b6947d0d12ffd35b
We now implement jumping and crouching by shifting the drawStart
and
drawEnd
variables up and down according to the viewer's height.
commit 1940b5c13ca01b096249729e97733f27571d1c9f
We implement thin walls that can have transparent pixels that you can see through.
A 1D Z-buffer doesn't suffice anymore, so we replace it with a 2D depth buffer.
commit 4ccf019721f557c539c28d33fb2d0b6bc9a5b84a
We implement glass windows. They're similar to the walls from the previous step, but we blend the pixels on them with the pixels that are behind them.
Unfortunately, the way we've been drawing sprites up until now means that they are not visible when they're behind glass windows.
The problem is that we draw sprites after we've drawn the glass, by which point the Z-buffer tells us that there is something in front of the sprite and the sprite shouldn't be drawn.
To get around this, we make a couple of changes:
- Step 1: We move the sprite drawing code out into a separate function.
- Step 2: We split the sprite drawing function into two separate functions:
prepareSprites()
to prepare the sprites (to determine where they are to be drawn) anddrawSprites()
to draw the actual sprites themselves. - Step 3: We call the
prepareSprites()
before we start drawing the walls, and then as the wall strips are being drawn back to front, we check whether there's a sprite between the last wall strip we drew and the one we're about to draw.
In this part we implement push walls that move backward when the user interacts with them. These can be used to implement secret passages in your levels.
In this step, we implement walls that run diagonally across the grid.