mikedotcpp / GBRaycaster

An implementation of the classic raycast rendering algorithm for Cocos2d-x. Used in games like Wolfenstein3D, Rise of the Triad, The Terminator: Rampage, Catacomb3-D, Super 3D Noah's Ark, and more.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Grid-Based Raycaster

This project adapts the old-school raycast rendering algorithm to be used with Cocos2d-x. Used in games like Wolfenstein3D, Rise of the Triad, The Terminator: Rampage, Catacomb3-D, Super 3D Noah's Ark, and more.

All of the code is freely available from my GitHub page.

What is Raycasting?

Raycasting refers to an algorithm used by games like the original Wolfenstein3D to sell the illusion of a first-person perspective.

The basic idea is to fire a bunch of rays from the player and draw whatever those rays hit. The number of rays to fire is equal to the number of vertical columns on screen (the pixel width of the screen). For each ray that hits an object in the world (like a wall), a scaled vertical strip of that object is drawn.

In this early experiement, vertical strips were created using 1-pixel wide quads:

Raycasting animation

While a promising start, I wanted to have the option of rendering floors/ceilings and be able to easily use some nice features of cocos - like actions, particle effects, etc. I started experimenting with a slightly different approach...

Raycasting, Cubed

Instead of drawing vertical strips per raycast, I decided to draw "blocks" per unique hit from a raycast. That is, draw cubes for each tile that a ray intersects with in projected 3D space.

Each cube is made from a Sprite3D object with 6 Sprite's as children that each represent a different face. All faces are optional and completely independent, which means one block could generate a cube with potentially 6 unique sides to it.

This gives me the flexibility I wanted in developing a unique look for maps. Video below:

Alt text

You can see in the video that walls, floors, billboards and ceilings are rendered and that player can collect doors by walking into them. This was a convenient way to show how one might use the simple Behavior system to attach a pickup behavior to door objects. It also suggests one might allow the player to change maps in realtime, a la a poor man's version of Minecraft.

Maps themselves are generated from a human-readable JSON text file. Much more on the format can be found here.

Just One More Thing...

By using the raycasting algorithm for visibility determination, I am able to leverage the 3D capabilities of Cocos2d-x to display a simple grid-based map in a first-person perspective. What would happen if I could assign a 3D mesh to the Sprite3D container object? Video below:

Alt text

This demo still utilizes the same raycasting technique from CocosWolf3D, but renders the results in a vastly different way. There's a lot going on here:

Instancing

I am using a technique called instancing to draw many similarly textured objects with little cost. The objects themselves are proper 3D meshes (of cubes) which are assigned to the Sprite3D container object at load time. Like the sprite-based version, these cubes can define unique textures for all 6 faces. Note: instancing requires an OpenGL ES extension for the 2.0 API and is included in 3.0 and above, therefore it may not be available on some hardware.

Lighting

The cube meshes rely on a slightly modified version of the stock 3D shader that comes with Cocos2d-x and has support for normal mapping, multiple light sources, and geometry instancing. This demo makes use of ambient light, a spotlight, and a few point lights.

Reflections

You may have noticed the large columns seem to be reflected in the floor of the main chamber. This is a quick and dirty old-school trick at play: render the columns below the marble floor and change the alpha of the marble floor texture so that the columns are visible through it.

Custom Shaders

Some tiles (like the lava tile) can have their own specialized shader that animates the texture sinusoidally.

Variable Height Walls

Each map can define layers (called Plane's) at different heights to give the illusion of walls with varying height.

Particles

The demo uses 3D particles that come with Cocos2d-x for a more dramatic effect. Used as-is, no changes necessary.

I hope you enjoyed reading about my approach to making a first-person perspective game using Cocos2d-x! These projects have been tested for Mac/iOS only. Code can be found:

Keep me in the loop with all your awesome creations, email me at mikedotcpp@gmail.com

About

An implementation of the classic raycast rendering algorithm for Cocos2d-x. Used in games like Wolfenstein3D, Rise of the Triad, The Terminator: Rampage, Catacomb3-D, Super 3D Noah's Ark, and more.

License:MIT License


Languages

Language:C++ 71.1%Language:Objective-C 14.4%Language:C 6.4%Language:Java 3.4%Language:Objective-C++ 2.4%Language:CMake 1.2%Language:GLSL 0.4%Language:Python 0.3%Language:Makefile 0.2%Language:Shell 0.1%Language:Lua 0.1%Language:JavaScript 0.1%Language:Batchfile 0.0%