Skip to content

Instantly share code, notes, and snippets.

@Alligator
Created September 2, 2012 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Alligator/3604635 to your computer and use it in GitHub Desktop.
Save Alligator/3604635 to your computer and use it in GitHub Desktop.
PFont font;
int drawn;
PVector pos, dir, plane;
boolean DEBUG;
float moveSpeed = 0.1;
float rotSpeed = 0.07;
int scale = 4;
final int m_WIDTH = 24;
final int m_HEIGHT = 24;
int m_map[][] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 4, 0, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 4, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 4, 0, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 4, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
boolean keys[] = new boolean[5];
final int up = 0;
final int down = 1;
final int left = 2;
final int right = 3;
final int alt = 4;
void setup() {
size (S_WIDTH, S_HEIGHT, JAVA2D);
pos = new PVector(22, 12); // player position
dir = new PVector(-1, 0); // player direction, from 1 to -1
plane = new PVector(0, 0.66); // camera plane
DEBUG = false;
frameRate(30);
noCursor();
font = loadFont("CenturyGothic-26.vlw");
textFont(font, 13);
}
void draw() {
fill(0);
noStroke();
background(64, 0, 0);
rect(0, 0, width, height/2);
int m = millis();
// cast the rays m8
checkInput();
raycast();
int diff = millis() - m;
if (DEBUG) println("frame " + drawn);
stroke(255);
text("pos " + pos.toString(), 10, 15);
text("dir " + dir.toString(), 10, 30);
text("avg " + diff, 10, 45);
}
void raycast() {
int m_width = width/scale;
for (int x = 0; x < m_width; x++) {
double camX = 2 * x / (double)m_width - 1; // camera x co-ord from 1 to -1
PVector raypos = new PVector(pos.x, pos.y);
PVector raydir = new PVector((float)(dir.x + plane.x * camX),
(float)(dir.y + plane.y * camX));
double perpWallDist;
int mapX = (int)raypos.x; // current position on the map
int mapY = (int)raypos.y;
PVector sideDist = new PVector();
PVector deltaDist = new PVector(sqrt(1 + (raydir.y * raydir.y) / (raydir.x * raydir.x)),
sqrt(1 + (raydir.x * raydir.x) / (raydir.y * raydir.y)));
int stepX, stepY;
int hit = 0;
int side = 0;
if (raydir.x < 0) {
stepX = -1;
sideDist.x = (raypos.x - mapX) * deltaDist.x;
}
else {
stepX = 1;
sideDist.x = (mapX + 1.0 - raypos.x) * deltaDist.x;
}
if (raydir.y < 0) {
stepY = -1;
sideDist.y = (raypos.y - mapY) * deltaDist.y;
}
else {
stepY = 1;
sideDist.y = (mapY + 1.0 - raypos.y) * deltaDist.y;
}
while (hit == 0) {
if (sideDist.x < sideDist.y) {
sideDist.x += deltaDist.x;
mapX += stepX;
side = 0;
}
else {
sideDist.y += deltaDist.y;
mapY += stepY;
side = 1;
}
// have we hit
if (m_map[mapX][mapY] > 0) {
hit = 1;
}
}
// calculate distance to camera plane
if (side == 0) {
perpWallDist = abs((mapX - raypos.x + (1 - stepX) / 2) / raydir.x);
}
else {
perpWallDist = abs((mapY - raypos.y + (1 - stepY) / 2) / raydir.y);
}
// calc line height
int lineHeight = abs((int)(height / perpWallDist));
// calc start and end points and cap 'em
int drawStart = -lineHeight / 2 + height / 2;
if (drawStart < 0) drawStart = 0;
int drawEnd = lineHeight / 2 + height / 2;
if (drawEnd >= height) drawEnd = height - 1;
if (side == 1) {
stroke(150, 0, 0);
}
else {
stroke(130, 0, 0);
}
fill(255);
// actually draw the thing holy shjit
for (int i = x*scale; i < x*scale + scale; i++) {
line(i, drawStart, i, drawEnd);
}
}
}
void keyPressed() {
if (keyCode == KeyEvent.VK_W) keys[up] = true;
if (keyCode == KeyEvent.VK_S) keys[down] = true;
if (keyCode == KeyEvent.VK_A) keys[left] = true;
if (keyCode == KeyEvent.VK_D) keys[right] = true;
if (keyCode == ALT) keys[alt] = true;
}
void keyReleased() {
if (keyCode == KeyEvent.VK_W) keys[up] = false;
if (keyCode == KeyEvent.VK_S) keys[down] = false;
if (keyCode == KeyEvent.VK_A) keys[left] = false;
if (keyCode == KeyEvent.VK_D) keys[right] = false;
if (keyCode == ALT) keys[alt] = false;
}
void checkInput() {
PVector oldpos = new PVector(pos.x, pos.y);
if (keys[up]) {
pos.x += dir.x * moveSpeed;
pos.y += dir.y * moveSpeed;
}
if (keys[down]) {
pos.x -= dir.x * moveSpeed;
pos.y -= dir.y * moveSpeed;
}
if (keys[left]) {
if(keys[alt]) {
pos.x += plane.x * -moveSpeed;
pos.y += plane.y * -moveSpeed;
} else {
rotateCamera(1, 1);
}
}
if (keys[right]) {
if(keys[alt]) {
pos.x += plane.x * moveSpeed;
pos.y += plane.y * moveSpeed;
} else {
rotateCamera(-1, 1);
}
}
int x = (int) pos.x;
int y = (int) pos.y;
int oldx = (int) oldpos.x;
int oldy = (int) oldpos.y;
if (x >= m_WIDTH-1 || x < 1 || m_map[x][oldy] > 0) {
pos.x = oldpos.x;
}
if (y >= m_HEIGHT-1 || y < 1 || m_map[oldx][y] > 0) {
pos.y = oldpos.y;
}
x = (int) pos.x;
y = (int) pos.y;
}
void rotateCamera(int direction, float speed) {
// 1 left -1 right
float rspeed = speed * rotSpeed;
float oldDirX = dir.x;
dir.x = dir.x * cos(rspeed * direction) - dir.y * sin(rspeed * direction);
dir.y = oldDirX * sin(rspeed * direction) + dir.y * cos(rspeed * direction);
float oldPlaneX = plane.x;
plane.x = plane.x * cos(rspeed * direction) - plane.y * sin(rspeed * direction);
plane.y = oldPlaneX * sin(rspeed * direction) + plane.y * cos(rspeed * direction);
}
/*
void mouseMoved() {
int diff = mouseX - pmouseX;
float sens = 0.3;
if (diff > 20) diff = 20;
int dir = -1;
if (diff < 0) {
dir = 1;
diff = -diff;
}
rotateCamera(dir, (diff*rotSpeed)*sens);
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment