Hello all, I am new to the forums. I basically need help with my code. A while back I started to create a simple non-textured raycaster which I am failing. I read a few tutorials (no-code) and I got a great understanding of the Raycasting theory however I lack skill in my trigonometry which has made my end result look poor. Before I post my source code I will explain the modules. (Don't worry they are small) I basically have 3 modules.
1) Hero.h (which contains my Hero class, short for now)
2) Globals.h (just global data, screen_height, FOV etc)
3) cast.cpp (main source, where my bugs are)
I am programming in C++ and using the Allegro game library.
Problems i'm having:
1) walking, sometimes walls don't change in height however turning seems ok.
2) I'm not sure how to correctly cast my rays (checking grid intersections) so my code might be skipping walls.
3) please point out the rest.
OK, here is the code...
HERO.H
Code:
class Player
{
public:
Player( ):posX(128),
posY(128), // grid (1,1)
facing_direction(90.0f) // facing 90* degrees
{}
// use default destructor for now
// data members
int posX;
int posY;
float facing_direction;
};
GLOBALS.H
Code:
typedef unsigned short USHORT;
const USHORT WALL = 1;
const USHORT MOVE = 4; // number of units to move in a given direction
const USHORT SCREEN_WIDTH = 640;
const USHORT SCREEN_HEIGHT = 480;
const USHORT HALF_SCREEN_HEIGHT = 240;
const USHORT GRID_SIZE = 64;
const float FOV = 60.0f;
int wall_distance[SCREEN_WIDTH];
float angle[SCREEN_WIDTH];
// 1 = wall
// 0 = no wall
int map[6][6] = {{ 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1 }};
CAST.CPP
Code:
#include <math.h>
#include <allegro.h>
#include <cstdlib>
#include "globals.h"
#include "hero.h"
BITMAP *buffer;
// prototypes
void calculateAngles(Player & ref);
void castRays(Player & ref);
void drawScene(void);
// end of prototypes
int main(void)
{
// setup
allegro_init();
install_keyboard();
set_color_depth(16);
set_gfx_mode(GFX_AUTODETECT, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
buffer = create_bitmap(SCREEN_WIDTH, SCREEN_HEIGHT);
for(int i=0;i<SCREEN_WIDTH;i++)
wall_distance[i] = 0;
// end of setup
// instantiation
Player Hero;
Player & HeroRef = Hero;
// end of instantiation
// main loop
while(!key[KEY_ESC])
{
_sleep(2); // free some CPU time
// check for movements
if(key[KEY_RIGHT])
{
Hero.facing_direction += 0.10f;
}
if(key[KEY_LEFT])
{
Hero.facing_direction -= 0.10f;
}
if(key[KEY_DOWN])
{
Hero.posY++;
}
if(key[KEY_UP])
{
Hero.posY--;
}
// calculate ray angles to later cast
calculateAngles(HeroRef);
// cast rays based on calculated angles
castRays(HeroRef);
// draw vertical line slices to the buffer based on wall distance
drawScene();
// show buffer to the screen
acquire_screen();
blit(buffer, screen, 0, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
release_screen();
clear_bitmap(buffer);
// reset wall_distance
for(int i=0;i<SCREEN_WIDTH;i++)
wall_distance[i] = 0;
}
// clean up
destroy_bitmap(buffer);
// end of clean up
return(0);
}
END_OF_MAIN();
// function definitions
void calculateAngles(Player & ref)
{
for(int i=0;i<SCREEN_WIDTH;i++)
{
angle[i] = ref.facing_direction + (( i * (FOV / 320.0f)) - (FOV / 2.0f));
if(angle[i] < 0.0f)
angle[i] += 360.0f;
if(angle[i] >= 360.0f)
angle[i] -= 360.0f;
}
}
END_OF_FUNCTION(calculateAngles(Player & ref));
void castRays(Player & ref)
{
int ray_x;
int ray_y;
for(int i=0;i<SCREEN_WIDTH;i++)
{
ray_x = ref.posX;
ray_y = ref.posY;
// allow ray to travel until a wall is found
while(map[ray_x/GRID_SIZE][ray_y/GRID_SIZE] != WALL)
{
ray_x = int(GRID_SIZE/4 * cos(angle[i] * M_PI / 180.0f));
ray_y = -int(GRID_SIZE/4 * sin(angle[i] * M_PI / 180.0f));
}
// wall found, calculate the distance from the player
wall_distance[i] = abs((ray_y - ref.posY) / sin(ref.facing_direction));
}
}
END_OF_FUNCTION(castRays(Player & ref));
void drawScene(void)
{
// draw vertical lines
for(int i=0;i<SCREEN_WIDTH;i++)
{
vline(buffer, i, HALF_SCREEN_HEIGHT-(wall_distance[i]/2), wall_distance[i], makecol(3, 170, 218));
}
}
END_OF_FUNCTION(drawScene(void));
I have tried to give as much information I can but if i'm missing something please let me know. Thanks for reading this.
Damien