Subject: ATTN: THIS IS COOL! |
Author:
admin
|
[
Next Thread |
Previous Thread |
Next Message |
Previous Message
]
Date Posted: 02:43:48 08/06/03 Wed
In reply to:
admin (the boss)
's message, "NOTICES" on 08:36:55 05/13/03 Tue
if this work's you will see a brick wall. click it, and use your arrow keys! if you dont see anything. goto
http://www.vandenbrande.com/projects/raycaster/
/*
...................................................................................
Raycaster
(c) 1999-2000 Johan Van den Brande
http://www.vandenbrande.com
...................................................................................
A very simple raycaster with floor and ceiling mapping.
Uses 64x64 tiles.
todo:
* wait for images to load
* find an 'exception' bug
*/
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
public class raycaster extends java.applet.Applet
implements Runnable,
KeyListener
{
Thread runner;
Image dbImg;
int pixels[];
int txtPels1[];
int txtPels2[];
int txtPelsFloor[];
int txtPelsCeiling[];
float cosTab[], invcosTab[];
float sinTab[], invsinTab[];
float tanTab[], invtanTab[];
float distTab[];
MemoryImageSource source;
static final int numberofdirections=1024;
static final int wdwWidth=320;
static final int wdwHeight=256;
static final int wdwSize=wdwWidth*wdwHeight;
static final byte W=1;
static final byte s=0;
static final byte X=2;
static final int mapWidth=16;
static final int mapHeight=16;
static final int gridH=64;
static final int gridW=64;
static final float viewangle= (float) (Math.PI/3);
static final int iFOV = (int) numberofdirections/6;
static final int txtHeight=64;
static final int txtWidth=64;
static final int xColor = 255<<24 | 200<<16 | 200<<8 | 200;
static final int yColor = 255<<24 | 150<<16 | 150<<8 | 150;
static final int wallHeight=64;
static final int columns=wdwWidth;
static final float distanceViewPlane=300;
boolean keyU, keyD, keyL, keyR;
int bkgColor;
float turnSpeed;
float personX;
float personY;
float direction;
int iDirection;
byte[] map=
{
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,
W,s,s,s,s,s,s,W,s,s,s,s,s,s,s,W,
W,s,W,W,W,W,s,W,s,W,W,W,W,W,s,W,
W,s,W,s,s,s,s,W,s,s,s,s,s,W,s,W,
W,s,W,s,X,X,s,W,s,W,W,W,s,W,s,W,
W,s,W,s,X,X,s,W,s,s,s,W,s,W,s,W,
W,s,W,s,s,s,s,W,W,W,s,W,s,W,s,W,
W,s,W,W,W,W,W,W,s,W,s,W,s,W,s,W,
W,s,s,s,W,s,s,s,s,W,s,W,s,W,s,W,
W,s,W,s,W,s,s,W,s,W,s,s,s,W,s,W,
W,s,W,s,W,W,s,W,s,W,s,W,W,W,s,W,
W,s,W,s,s,s,s,W,s,W,s,s,s,s,s,W,
W,s,W,W,W,W,W,W,s,s,s,s,s,W,s,W,
W,s,W,s,s,s,s,W,W,W,W,W,s,W,s,W,
W,s,s,s,W,W,s,s,s,s,s,s,s,s,s,W,
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W
};
public void init() {
int i, value;
float alpha;
keyU=keyD=keyL=keyR=false;
addKeyListener(this);
turnSpeed=1;
Image txtMap1 = getImage(getDocumentBase(), "txtMap1.gif");
Image txtMap2 = getImage(getDocumentBase(), "Metal8_1.gif");
Image txtFloor = getImage(getDocumentBase(), "txtMap2.gif");
Image txtCeiling = getImage(getDocumentBase(), "rrock1_2.gif");
pixels = new int[wdwSize];
txtPels1 = new int[64*64];
txtPels2 = new int[64*64];
txtPelsFloor = new int[64*64];
txtPelsCeiling = new int[64*64];
value=(255 << 24) | 0 ;//getBackground().getRGB();
bkgColor=value;
for (i=0;i
{
pixels[i]=value;
}
source=new MemoryImageSource(wdwWidth,wdwHeight,pixels,0,wdwWidth);
source.setAnimated(true);
dbImg=createImage(source);
personX= (float) gridW*mapWidth/2 + 32;
personY= (float) gridH*mapHeight/2 + 32;
direction=0;
iDirection=0;
// Precalc floats (eventually go to int values ?)
cosTab = new float[numberofdirections];
invcosTab = new float[numberofdirections];
sinTab = new float[numberofdirections];
invsinTab = new float[numberofdirections];
tanTab = new float[numberofdirections];
invtanTab = new float[numberofdirections];
distTab = new float[256];
for (i=0;i
{
alpha = (float) ((i*Math.PI*2)/numberofdirections) + 0.0001F;
cosTab[i] = (float) Math.cos(alpha);
invcosTab[i] = (float) (1F/Math.cos(alpha));
sinTab[i] = (float) Math.sin(alpha);
invsinTab[i] = (float) (1F/Math.sin(alpha));
tanTab[i] = (float) Math.tan(alpha);
invtanTab[i] = (float) (1F/Math.tan(alpha));
}
for (i=0;i<256;i++)
{
distTab[i]=(i==128)?Float.MAX_VALUE:1F/(i-128);
}
PixelGrabber pg1= new PixelGrabber(txtMap1,0,0,64,64,txtPels1,0,64);
try
{
pg1.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
return;
}
PixelGrabber pg2= new PixelGrabber(txtMap2,0,0,64,64,txtPels2,0,64);
try
{
pg2.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
return;
}
PixelGrabber pg3= new PixelGrabber(txtFloor,0,0,64,64,txtPelsFloor,0,64);
try
{
pg3.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
return;
}
PixelGrabber pg4= new PixelGrabber(txtCeiling,0,0,64,64,txtPelsCeiling,0,64);
try
{
pg4.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
return;
}
}
public void start() {
if(runner==null) {
runner=new Thread(this);
runner.start();
}
}
public void stop() {
if (runner!=null)
{
runner.stop();
runner=null;
}
}
public void run() {
while(true) {
clearPixels();
drawRays();
source.newPixels(0, 0, wdwWidth, wdwHeight);
repaint();
updatePerson();
try
{
Thread.sleep(1);
}
catch (InterruptedException e)
{
}
}
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
g.drawImage(dbImg, 0, 0, this);
}
public void drawRays()
{
float xFirstX;
float xFirstY;
float yFirstX;
float yFirstY;
float directionX;
float directionY;
float directionCast;
int iDirectionCast;
float deltaCast;
float deltaX;
float deltaY;
float distanceX;
float distanceY;
float distance;
float xFinal;
float yFinal;
float columnHeight;
int xInt;
int yInt;
int cnt;
int column;
int iColor;
int txtCol;
byte yMap, xMap, WALL;
Color wallColor;
directionCast=iDirection-(iFOV/2);
deltaCast= ((float) iFOV)/columns;
for (column=0;column
{
iDirectionCast=( (int) directionCast & (numberofdirections-1));
directionX=(float) cosTab[iDirectionCast];
directionY=(float) sinTab[iDirectionCast];
// find X intercept
xFirstY=(float) (((int) (personY/gridH))*gridH);
if (directionY>=0)
{
xFirstY+=gridH;
deltaX=(float) (gridH * invtanTab[iDirectionCast]);
deltaY=gridH;
} else {
xFirstY-=1;
deltaY=-gridH;
deltaX=(float) (-1*gridH * invtanTab[iDirectionCast]);
}
xFirstX= (float) personX + (float) ((xFirstY-personY) * invtanTab[iDirectionCast]);
cnt=0;
while (true)
{
xInt=(int) ((int) xFirstX/gridW) & 15;
yInt=(int) ((int) xFirstY/gridH) & 15;
if ((xMap=map[yInt*16+xInt])!=s)
{
break;
}
xFirstX+=deltaX;
xFirstY+=deltaY;
cnt++;
if (cnt>255)
{
break;
}
}
// find Y intercept
yFirstX=(float) (((int) (personX/gridW))*gridW);
if (directionX>=0)
{
yFirstX+=gridW;
deltaX=gridW;
deltaY=(float) (gridW*tanTab[iDirectionCast]);
} else {
yFirstX-=1;
deltaX=-gridW;
deltaY=(float) (-1*gridW*tanTab[iDirectionCast]);
}
yFirstY= (float) personY + (float) ((yFirstX-personX)*tanTab[iDirectionCast]);
cnt=0;
while (true)
{
xInt=(int) ((int) yFirstX/gridW) & 15;
yInt=(int) ((int) yFirstY/gridH) & 15;
if ((yMap=map[yInt*16+xInt])!=s)
{
break;
}
yFirstX+=deltaX;
yFirstY+=deltaY;
cnt++;
if (cnt>255)
{
break;
}
}
distanceX=(float) ((xFirstX-personX)* invcosTab[iDirectionCast]);
distanceY=(float) ((yFirstY-personY)* invsinTab[iDirectionCast]);
if (distanceX<=distanceY)
{
txtCol=(int) xFirstX % 64;
distance=distanceX;
iColor=xColor;
WALL=xMap;
} else {
txtCol=(int) yFirstY % 64;
distance=distanceY;
iColor=yColor;
WALL=yMap;
}
distance*=cosTab[(iDirection-iDirectionCast) & (numberofdirections-1)];
columnHeight=(float) (wallHeight*distanceViewPlane/distance);
// System.out.println(iDirectionCast);
drawWallSlice(pixels,column,(int) (128 - columnHeight/2),(int) columnHeight, iColor, txtCol, WALL);
// draw floor line from bottom of wall to viewplane.
drawFloor(pixels,column,(int) (128 + columnHeight/2), iDirectionCast);
directionCast+=deltaCast;
}
}
public void drawWallSlice(int [] pixels, int column,int ypos,int columnHeight, int iColor, int txtcolumn, byte map)
{
int i,h,ic, t;
float c,deltap;
int offset;
int pels[];
switch (map)
{
case W:
pels=txtPels1;
break;
case X:
pels=txtPels2;
break;
default:
pels=txtPels1;
}
// System.out.println(txtcolumn);
// clip ypos
ypos=(ypos<0)?0:ypos;
ypos=(ypos>255)?255:ypos;
h=ypos + columnHeight;
h=(h>255)?255:h;
// column&=255;
deltap=64F/columnHeight;
t=(columnHeight>255)?columnHeight-256:0;
txtcolumn&=63;
c=(float) t*deltap/2;
offset=ypos*wdwWidth + column;
// System.out.println(deltap + "\t|\t" + columnHeight);
for (i=ypos;i
{
ic=(int) c & 63;
pixels[offset]=pels[ (ic<<6) + txtcolumn];
c+=deltap;
offset+=wdwWidth;
}
}
public void drawFloor(int [] pixels,int column,int ybot, int dir)
{
int y;
int offset_f, offset_c, txtofs;
float dist;
float xc,yc;
float k,kx,ky;
k=distanceViewPlane*wallHeight*invcosTab[(iDirection-dir) & (numberofdirections-1)]/2;
kx=k*cosTab[dir];
ky=k*sinTab[dir];
offset_f=(ybot*wdwWidth)+column;
offset_c=((256-ybot)*wdwWidth)+column;
for (y=ybot;y<256;y++)
{
xc=personX+distTab[y]*kx;
yc=personY+distTab[y]*ky;
txtofs=((int)(yc%64)<<6) + (int) (xc % 64);
pixels[offset_f]=txtPelsFloor[txtofs];
offset_f+=wdwWidth;
pixels[offset_c]=txtPelsCeiling[txtofs];
offset_c-=wdwWidth;
}
}
public void clearPixels()
{
int i;
for (i=0;i
{
pixels[i]=bkgColor;
}
}
public void keyPressed(KeyEvent evt)
{
switch (evt.getKeyCode())
{
case KeyEvent.VK_UP:
keyU=true;
break;
case KeyEvent.VK_DOWN:
keyD=true;
break;
case KeyEvent.VK_LEFT:
keyL=true;
break;
case KeyEvent.VK_RIGHT:
keyR=true;
break;
default:
}
}
public void keyTyped(KeyEvent evt)
{
}
public void keyReleased(KeyEvent evt)
{
switch (evt.getKeyCode())
{
case KeyEvent.VK_UP:
keyU=false;
break;
case KeyEvent.VK_DOWN:
keyD=false;
break;
case KeyEvent.VK_LEFT:
keyL=false;
break;
case KeyEvent.VK_RIGHT:
keyR=false;
break;
default:
}
}
public void updatePerson()
{
float xBox;
float yBox;
if (keyU)
{
xBox=(personX+cosTab[iDirection]*16)/gridW;
yBox=(personY+sinTab[iDirection]*16)/gridH;
if (map[((int) yBox & 15)*16+ ((int) xBox & 15)]==s)
{
personX+=cosTab[iDirection]*6;
personY+=sinTab[iDirection]*6;
}
}
if (keyD)
{
personX-=cosTab[iDirection]*6;
personY-=sinTab[iDirection]*6;
}
if (keyR)
{
iDirection+=(int) turnSpeed;
iDirection&=numberofdirections-1;
turnSpeed+=1;
turnSpeed=(turnSpeed>10)?10:turnSpeed;
}
if (keyL)
{
iDirection-=(int) turnSpeed;
iDirection=(iDirection<0)?numberofdirections-1:iDirection;
iDirection&=numberofdirections-1;
turnSpeed+=1;
turnSpeed=(turnSpeed>10)?10:turnSpeed;
}
if (!(keyL || keyR))
{
turnSpeed-=1;
turnSpeed=(turnSpeed<0)?0:turnSpeed;
}
}
}
[
Next Thread |
Previous Thread |
Next Message |
Previous Message
]
| |