Sun Mar 13, 2016 9:51 pm
#include <SPI.h>
#include <Gamebuino.h>
#define PLAYER_MOVE_NONE 0
#define PLAYER_MOVE_FORWARD 1
#define PLAYER_MOVE_BACKWARD -1
#define PLAYER_ROTATE_NONE 0
#define PLAYER_ROTATE_LEFT -1
#define PLAYER_ROTATE_RIGHT 1
Gamebuino gb;
int xPos = 0;
int yPos = 0;
int w = 5;
int h = 5;
float dirX = 1, dirY = 0;
float planeX = 0, planeY = 0.66;
uint8_t world[] PROGMEM = {
0, 0, 1, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
};
void setup() {
gb.begin();
gb.titleScreen(F("3D Game"));
}
void loop() {
if(gb.update()) {
for(int x = 0; x < LCDWIDTH; x++) {
//calculate step and initial sideDist
double cameraX = 2 * x / LCDWIDTH - 1; //x-coordinate in camera space
int mapX = xPos;
int mapY = yPos;
int rayPosX = mapX;
int rayPosY = mapY;
float rayDirX = dirX + planeX * cameraX;
float rayDirY = dirY + planeY * cameraX;
double deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
double deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
double sideDistX;
double sideDistY;
int stepX;
int stepY;
int hit = 0; //was there a wall hit?
int side; //was a NS or a EW wall hit?
float perpWallDist;
if (rayDirX < 0)
{
stepX = -1;
sideDistX = (rayPosX - mapX) * deltaDistX;
}
else
{
stepX = 1;
sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;
}
if (rayDirY < 0)
{
stepY = -1;
sideDistY = (rayPosY - mapY) * deltaDistY;
}
else
{
stepY = 1;
sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;
}
//perform DDA
while (hit == 0)
{
//jump to next map square, OR in x-direction, OR in y-direction
if (sideDistX < sideDistY)
{
sideDistX += deltaDistX;
mapX += stepX;
side = 0;
}
else
{
sideDistY += deltaDistY;
mapY += stepY;
side = 1;
}
//Check if ray has hit a wall
if (pgm_read_byte(world + (mapX + mapY * w)) > 0) hit = 1;
}
if (side == 0) perpWallDist = (mapX - rayPosX + (1 - stepX) / 2) / rayDirX;
else perpWallDist = (mapY - rayPosY + (1 - stepY) / 2) / rayDirY;
int lineHeight = (int)(h / perpWallDist);
//calculate lowest and highest pixel to fill in current stripe
int drawStart = -lineHeight / 2 + h / 2;
if(drawStart < 0)drawStart = 0;
int drawEnd = lineHeight / 2 + h / 2;
if(drawEnd >= h)drawEnd = h - 1;
gb.display.fillRect(x * 5, drawStart, 5, lineHeight * 9);
}
}
}