- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个Java项目,它制作“windows迷宫”并使用射线转换算法。这是屏幕截图:
就像您看到的所有墙壁都具有相同的高度大小一样。我想做同样的事,但是高度大小不同
private void castRay(int xOnScreen,double angle,double direction) {
R rx = castRayInX(angle,direction);
R ry = castRayInY(angle,direction);
// In case of out-of-space rays
if (rx.getDistance()==Double.MAX_VALUE && ry.getDistance()==Double.MAX_VALUE) {
graphics.setColor(BACKGROUND);
graphics.drawLine(xOnScreen,0,xOnScreen,this.image.getHeight());
return;
}
double distance = rx.getDistance();
double normal = rx.getNormal();
Color c = rx.getColor();
double coef = Math.cos((angle+direction+Math.PI)-normal);
Plot collision = rx.getPlot();
if (ry.getDistance()<rx.getDistance()) {
distance = ry.getDistance();
normal = ry.getNormal();
c = ry.getColor();
coef = Math.cos((angle+direction+Math.PI)-normal);
collision = ry.getPlot();
}
coef = Math.abs(coef);
int factor = map.length*SQUARE_SIZE;
double d = (double)(distance+factor)/factor;
coef *= 1/(d*d);
Color c2 = new Color((int)(c.getRed()*coef),(int)(c.getGreen()*coef),(int)(c.getBlue()*coef));
graphics.setColor(c2);
// graphics.setColor(c); // no illumination
distance *= Math.cos(angle); // lens correction
int h = (int)(this.screenDistance/distance*WALL_HEIGHT); // perspective height
int vh = this.image.getHeight();
graphics.drawLine(xOnScreen,(vh-h)/2,xOnScreen,(vh+h)/2);
drawEye(direction,collision);
}
private R castRayInX(double angleRay,double direction) {
double angle = angleRay+direction;
double x1 = eye.getX()+SQUARE_SIZE*Math.cos(angle);
double y1 = eye.getY()+SQUARE_SIZE*Math.sin(angle);
double slope = (y1-eye.getY())/(x1-eye.getX());
if (Math.cos(angle)==0) {
if (Math.sin(angle)>0)
return new R(Double.MAX_VALUE,3*Math.PI/2,BACKGROUND,null);
else
return new R(Double.MAX_VALUE,Math.PI/2,BACKGROUND,null);
}
if (Math.cos(angle)>0) {
int firstX = ((eye.getX()/SQUARE_SIZE)+1)*SQUARE_SIZE;
R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
for (int x = firstX; x<map[0].length*SQUARE_SIZE; x += SQUARE_SIZE) {
int y = (int)(slope*(x-eye.getX())+eye.getY());
if (isOutside(x,y,Color.MAGENTA,this.showRayCastingX)) break;
Color c = colorAt(x,y);
if (c==null) c = colorAt(x,y-1);
if (c==null) c = colorAt(x-1,y);
if (c==null) c = colorAt(x-1,y-1);
if (c!=null) {
int DX = x-eye.getX();
double DY = y-eye.getY();
return new R(Math.sqrt(DX*DX+DY*DY),Math.PI,c,new Plot((int)x,(int)y, WALL_HEIGHT));
}
}
return r;
} else {
int firstX = ((eye.getX()/SQUARE_SIZE))*SQUARE_SIZE;
R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
for (int x = firstX; x>=0; x -= SQUARE_SIZE) {
int y = (int)(slope*(x-eye.getX())+eye.getY());
if (isOutside(x,y,Color.MAGENTA,this.showRayCastingX)) break;
Color c = colorAt(x,y);
if (c==null) c = colorAt(x,y-1);
if (c==null) c = colorAt(x-1,y);
if (c==null) c = colorAt(x-1,y-1);
if (c!=null) {
int DX = x-eye.getX();
double DY = y-eye.getY();
return new R(Math.sqrt(DX*DX+DY*DY),0,c,new Plot((int)x,(int)y, WALL_HEIGHT));
}
}
return r;
}
}
private R castRayInY(double angleRay,double direction) {
// System.out.println("cast ray 2 Y "+angleRay+" "+direction);
double angle = angleRay+direction;
double x1 = eye.getX()+SQUARE_SIZE*Math.cos(angle);
double y1 = eye.getY()+SQUARE_SIZE*Math.sin(angle);
// System.out.println(eye+" "+x1+" "+y1);
double slope = (y1-eye.getY())/(x1-eye.getX());
if (Math.sin(angle)==0) {
if (Math.cos(angle)>0)
return new R(Double.MAX_VALUE,Math.PI,BACKGROUND,null);
else
return new R(Double.MAX_VALUE,0,BACKGROUND,null);
}
if (Math.sin(angle)>0) {
int firstY = ((eye.getY()/SQUARE_SIZE)+1)*SQUARE_SIZE;
R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
for (int y = firstY; y<map.length*SQUARE_SIZE; y += SQUARE_SIZE) {
int x = (int)((y-eye.getY())/slope)+eye.getX();
if (isOutside(x,y,Color.CYAN,this.showRayCastingY)) break;
Color c = colorAt(x,y);
if (c==null) c = colorAt(x,y-1);
if (c==null) c = colorAt(x-1,y);
if (c==null) c = colorAt(x-1,y-1);
if (c!=null) {
double DX = x-eye.getX();
int DY = y-eye.getY();
return new R(Math.sqrt(DX*DX+DY*DY),3*Math.PI/2,c,new Plot((int)x,(int)y, WALL_HEIGHT));
}
}
return r;
} else {
int firstY = ((eye.getY()/SQUARE_SIZE))*SQUARE_SIZE;
R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
for (int y = firstY; y>=0; y -= SQUARE_SIZE) {
int x = (int)((y-eye.getY())/slope)+eye.getX();
if (isOutside(x,y,Color.CYAN,this.showRayCastingY)) break;
Color c = colorAt(x,y);
if (c==null) c = colorAt(x,y-1);
if (c==null) c = colorAt(x-1,y);
if (c==null) c = colorAt(x-1,y-1);
if (c!=null) {
double DX = x-eye.getX();
int DY = y-eye.getY();
return new R(Math.sqrt(DX*DX+DY*DY),Math.PI/2,c,new Plot((int)x,(int)y, WALL_HEIGHT));
}
}
return r;
}
}
R
类具有
Plot (x, y, z)
,现在我将
WALL_HEIGHT
使用的是颜色,距离和法线。目前,这是可行的,但是我想添加一个新函数,例如castRayInZ,但是我没有所有的数学理论都在后面。我的迷宫是由这样的 map 制成的:
private String [][]map = { // each: SQUARE_SIZE x SQUARE_SIZE
{ "Y300", "Z500", "X230", "Y112", "Z321", "X120", "X354" },
{ "X89", " ", " ", " ", "Y120", " ", "X232" },
{ "Z124", " ", "X276", " ", "X123", " ", "X" },
{ "Y290", " ", " ", " ", " ", " ", "X100" },
{ "X32", "Z430", " ", "Y500", "X120", " ", "X123" },
{ "X222", " ", " ", " ", " ", " ", "X210" },
{ "X12", "Y98", "Y763", "X146", "Y111", "Y333", "X321" }
SQUARE_LENGTH
,也许以后再将每个正方形的大小减小到一个像素,并通过生成它来放大 map 。但是我真的很想知道如何更改每个正方形的高度。我从4天开始研究它,没有任何线索...
private void castRay(int xOnScreen,double angle,double direction) {
R rx = castRayInX(angle,direction);
R ry = castRayInY(angle,direction);
// In case of out-of-space rays
if (rx.getDistance()==Double.MAX_VALUE && ry.getDistance()==Double.MAX_VALUE) {
graphics.setColor(BACKGROUND);
graphics.drawLine(xOnScreen,0,xOnScreen,this.image.getHeight());
return;
}
double distance = rx.getDistance();
double normal = rx.getNormal();
Color c = rx.getColor();
double coef = Math.cos((angle+direction+Math.PI)-normal);
Plot collision = rx.getPlot();
if (ry.getDistance()<rx.getDistance()) {
distance = ry.getDistance();
normal = ry.getNormal();
c = ry.getColor();
coef = Math.cos((angle+direction+Math.PI)-normal);
collision = ry.getPlot();
}
coef = Math.abs(coef);
int factor = map.length*SQUARE_SIZE;
double d = (double)(distance+factor)/factor;
coef *= 1/(d*d);
Color c2 = new Color((int)(c.getRed()*coef),(int)(c.getGreen()*coef),(int)(c.getBlue()*coef));
graphics.setColor(c);
distance *= Math.cos(angle); // lens correction
int h;
int hw = (int)(this.screenDistance/distance*WALL_HEIGHT); //WALL_HEIGHT value is 300px at default
if(rx.getPlot() != null)
h = (int)(this.screenDistance/distance*rx.getPlot().getZ()); // perspective height
else
h = (int)(this.screenDistance/distance*WALL_HEIGHT);
int vh = this.image.getHeight();
int y0 = (hw+vh)/2;
int y1 = (vh-h)/2;
graphics.drawLine(xOnScreen,y0,xOnScreen,y1);
drawEye(direction,collision);
castRayInX
函数:
private R castRayInX(double angleRay,double direction) {
double angle = angleRay+direction;
double x1 = eye.getX()+SQUARE_SIZE*Math.cos(angle);
double y1 = eye.getY()+SQUARE_SIZE*Math.sin(angle);
double slope = (y1-eye.getY())/(x1-eye.getX());
if (Math.cos(angle)==0) {
if (Math.sin(angle)>0)
return new R(Double.MAX_VALUE,3*Math.PI/2,BACKGROUND,null);
else
return new R(Double.MAX_VALUE,Math.PI/2,BACKGROUND,null);
}
if (Math.cos(angle)>0) {
int firstX = ((eye.getX()/SQUARE_SIZE)+1)*SQUARE_SIZE;
R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
for (int x = firstX; x<map[0].length*SQUARE_SIZE; x += SQUARE_SIZE) {
int y = (int)(slope*(x-eye.getX())+eye.getY());
if (isOutside(x,y,Color.MAGENTA,this.showRayCastingX)) break;
Color c = colorAt(x,y);
int z = heightAt(x,y);
if (c==null) c = colorAt(x,y-1);
if (c==null) c = colorAt(x-1,y);
if (c==null) c = colorAt(x-1,y-1);
if (z == 0) z = heightAt(x,y-1);
if (z == 0) z = heightAt(x-1,y);
if (z == 0) z = heightAt(x-1,y-1);
if (c!=null) {
int DX = x-eye.getX();
double DY = y-eye.getY();
return new R(Math.sqrt(DX*DX+DY*DY),Math.PI,c,new Plot((int)x,(int)y,(int)z));
}
}
return r;
} else {
int firstX = ((eye.getX()/SQUARE_SIZE))*SQUARE_SIZE;
R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
for (int x = firstX; x>=0; x -= SQUARE_SIZE) {
int y = (int)(slope*(x-eye.getX())+eye.getY());
if (isOutside(x,y,Color.MAGENTA,this.showRayCastingX)) break;
Color c = colorAt(x,y);
int z = heightAt(x,y);
if (c==null) c = colorAt(x,y-1);
if (c==null) c = colorAt(x-1,y);
if (c==null) c = colorAt(x-1,y-1);
if (z == 0) z = heightAt(x,y-1);
if (z == 0) z = heightAt(x-1,y);
if (z == 0) z = heightAt(x-1,y-1);
if (c!=null) {
int DX = x-eye.getX();
double DY = y-eye.getY();
return new R(Math.sqrt(DX*DX+DY*DY),0,c,new Plot((int)x,(int)y,(int)z));
}
}
return r;
}
}
castRayInZ
函数吗?还是我应该将
z
的值获取其他位置?
最佳答案
因此,您显然知道Wolfenstein raycasting技术的基础。要添加可变高度,您需要执行以下操作:
map[][]
中为单元格信息添加另一个值即可。您将这些东西编码为奇数的字符串... y0 = center_of_view_y + projected_half_size
y1 = center_of_view_y - projected_half_size
y0 = center_of_view_y + projected_size
y1 = y0 - 2*projected_half_size*wall_size
projected_half_size
是为恒定像元高度计算的线大小,wall_size=<0,1>
是缩放,center_of_view_y
是 View 中水平线的y坐标。这会将您的墙放在地面上。 wall_size=1
)或用完 map 时,您才能停止。您有2个选项可以实现此目的。O(1)
)
y
坐标,则如果打了背面而不是渲染该表面,则将最后一个y
的顶部颜色渲染为实际的y
(或从地板/天花板纹理复制像素) 。这是用于此的绿色://---------------------------------------------------------------------------
//--- Doom 3D engine ver: 1.000 --------------------------------------
//---------------------------------------------------------------------------
#ifndef _Doom3D_h
#define _Doom3D_h
//---------------------------------------------------------------------------
#include <math.h>
#include <jpeg.hpp>
#include "performance.h"
#include "OpenGLrep4d_double.h"
//---------------------------------------------------------------------------
const DWORD _Doom3D_cell_size=10; // 2D map cell size
const DWORD _Doom3D_wall_size=100; // full height of wall in map
#define _Doom3D_filter_txr
//---------------------------------------------------------------------------
class Doom3D
{
public:
DWORD mxs,mys,**pmap; // 2D map // txr + height<<16
DWORD sxs,sys,**pscr; // pseudo 3D screen
Graphics::TBitmap *scr;
DWORD txs,tys,**ptxr,tn; // 2D textures
Graphics::TBitmap *txr,*txr2; // textures, texture mipmaps resolution: /2 and /4
double plrx,plry,plrz,plra; // player position [x,y,z,angle]
double view_ang; // [rad] view angle
double focus; // [cells] view focal length
struct _ray
{
double x,y,l; // hit or end of map position
DWORD hit; // map cell of hit or 0xFFFFFFFF
char typ; // H/V
_ray() {};
_ray(_ray& a) { *this=a; }
~_ray() {};
_ray* operator = (const _ray *a) { *this=*a; return this; }
//_ray* operator = (const _ray &a) { ..copy... return this; }
};
_ray *ray; // ray[sxs]
keytab keys;
DWORD txr_sel;
DWORD cell_h;
Doom3D();
Doom3D(Doom3D& a) { *this=a; }
~Doom3D();
Doom3D* operator = (const Doom3D *a) { *this=*a; return this; }
//Doom3D* operator = (const Doom3D &a) { ..copy... return this; }
void map_resize(DWORD xs,DWORD ys); // change map resolution
void map_height(DWORD height); // set height for whole map to convert maps from Wolfenstein3D demo
void map_clear(); // clear whole map
void map_save(AnsiString name);
void map_load(AnsiString name);
void scr_resize(DWORD xs,DWORD ys);
void txr_load(AnsiString name);
void draw();
void update(double dt);
void mouse(double x,double y,TShiftState sh)
{
x=floor(x/_Doom3D_cell_size); if (x>=mxs) x=mxs-1; if (x<0) x=0;
y=floor(y/_Doom3D_cell_size); if (y>=mys) y=mys-1; if (y<0) y=0;
DWORD xx=x,yy=y;
keys.setm(x,y,sh);
if (keys.Shift.Contains(ssLeft )) pmap[yy][xx]=(txr_sel)|(cell_h<<16);
if (keys.Shift.Contains(ssRight)) pmap[yy][xx]=0xFFFFFFFF;
keys.rfsmouse();
}
void wheel(int delta,TShiftState sh)
{
if (sh.Contains(ssShift))
{
if (delta<0) { cell_h-=10; if (cell_h<10) cell_h=10; }
if (delta>0) { cell_h+=10; if (cell_h>_Doom3D_wall_size) cell_h=_Doom3D_wall_size; }
}
else{
if (delta<0) { txr_sel--; if (txr_sel==0xFFFFFFFF) txr_sel=tn-1; }
if (delta>0) { txr_sel++; if (txr_sel== tn) txr_sel= 0; }
}
}
};
//---------------------------------------------------------------------------
Doom3D::Doom3D()
{
mxs=0; mys=0; pmap=NULL;
sxs=0; sys=0; scr=new Graphics::TBitmap; pscr=NULL; ray=NULL;
txs=0; tys=0; txr=new Graphics::TBitmap; ptxr=NULL; tn=0;
txr2=new Graphics::TBitmap;
plrx=0.0; plry=0.0; plrz=0.0; plra=0.0;
view_ang=60.0*deg;
focus=0.25;
txr_sel=0;
cell_h=_Doom3D_wall_size;
txr_load("textures128x128.jpg");
map_resize(16,16);
map_load("Doom3D_map.dat");
}
//---------------------------------------------------------------------------
Doom3D::~Doom3D()
{
DWORD y;
map_save("Doom3D_map.dat");
if (pmap) { for (y=0;y<mys;y++) delete[] pmap[y]; delete[] pmap; pmap=NULL; } if (ray) delete[] ray; ray=NULL;
if (pscr) { delete[] pscr; pscr=NULL; } if (scr) delete scr; scr=NULL;
if (ptxr) { delete[] ptxr; ptxr=NULL; } if (txr) delete txr; txr=NULL;
if (txr2) delete txr2; txr2=NULL;
}
//---------------------------------------------------------------------------
void Doom3D::map_resize(DWORD xs,DWORD ys)
{
DWORD y;
if (pmap) { for (y=0;y<mys;y++) delete[] pmap[y]; delete[] pmap; pmap=NULL; }
mys=ys; mxs=xs; pmap=new DWORD*[mys]; for (y=0;y<mys;y++) pmap[y]=new DWORD[mxs];
map_clear();
plrx=(mxs-1)*0.5; plry=(mys-1)*0.5; plrz=0.0; plra=0.0*deg;
}
//---------------------------------------------------------------------------
void Doom3D::map_height(DWORD h)
{
DWORD x,y,c;
for (y=0;y<mys;y++)
for (x=0;x<mxs;x++)
{
c=pmap[y][x];
c&=0xFFFF;
c|=h<<16;
pmap[y][x]=c;
}
}
//---------------------------------------------------------------------------
void Doom3D::map_clear()
{
DWORD x,y,c;
for (y=0;y<mys;y++)
for (x=0;x<mxs;x++)
{
c=0xFFFFFFFF;
if ((x==0)||(x==mxs-1)) c=0;
if ((y==0)||(y==mys-1)) c=0;
pmap[y][x]=c;
}
}
//---------------------------------------------------------------------------
void Doom3D::map_save(AnsiString name)
{
int hnd=FileCreate(name); if (hnd<0) return;
DWORD y;
y=' PAM';
FileWrite(hnd,&y ,4); // id
FileWrite(hnd,&mxs,4); // x resolution
FileWrite(hnd,&mys,4); // y resolution
for (y=0;y<mys;y++) // map
FileWrite(hnd,pmap[y],mxs<<2);
y=' RLP';
FileWrite(hnd,&y ,4); // id
FileWrite(hnd,&plrx,8);
FileWrite(hnd,&plry,8);
FileWrite(hnd,&plrz,8);
FileWrite(hnd,&plra,8);
FileClose(hnd);
}
//---------------------------------------------------------------------------
void Doom3D::map_load(AnsiString name)
{
int hnd=FileOpen(name,fmOpenRead); if (hnd<0) return;
DWORD x,y;
y=' PAM'; FileRead(hnd,&x ,4); // id
if (x==y)
{
FileRead(hnd,&x,4); // x resolution
FileRead(hnd,&y,4); // y resolution
map_resize(x,y);
for (y=0;y<mys;y++) // map
FileRead(hnd,pmap[y],mxs<<2);
}
y=' RLP'; FileRead(hnd,&x ,4); // id
if (x==y)
{
FileRead(hnd,&plrx,8);
FileRead(hnd,&plry,8);
FileRead(hnd,&plrz,8);
FileRead(hnd,&plra,8);
}
FileClose(hnd);
}
//---------------------------------------------------------------------------
void Doom3D::scr_resize(DWORD xs,DWORD ys)
{
scr->HandleType=bmDIB;
scr->PixelFormat=pf32bit;
scr->SetSize(xs,ys);
sxs=scr->Width;
sys=scr->Height;
delete[] pscr; pscr=new DWORD*[sys];
for (DWORD y=0;y<sys;y++) pscr[y]=(DWORD*)scr->ScanLine[y];
if (ray) delete[] ray; ray=new _ray[sxs];
}
//---------------------------------------------------------------------------
void Doom3D::txr_load(AnsiString name)
{
AnsiString ext=ExtractFileExt(name).LowerCase();
for(;;)
{
if (ext==".bmp")
{
txr->LoadFromFile(name);
break;
}
if (ext==".jpg")
{
TJPEGImage *jpg=new TJPEGImage;
if (jpg==NULL) return;
jpg->LoadFromFile(name);
txr->Assign(jpg);
delete jpg;
break;
}
return;
}
DWORD y=tys;
txr->HandleType=bmDIB;
txr->PixelFormat=pf32bit;
txs=txr->Width;
tys=txr->Height;
// mip map
txr2->SetSize(txs>>1,(tys>>1)+(tys>>2));
txr2->Canvas->StretchDraw(TRect(0, 0,txs>>1,tys>>1),txr);
txr2->Canvas->StretchDraw(TRect(0,tys>>1,txs>>2,(tys>>1)+(tys>>2)),txr);
tn=txs/tys; txs=tys;
delete[] ptxr; ptxr=new DWORD*[tys];
for (y=0;y<tys;y++) ptxr[y]=(DWORD*)txr->ScanLine[y];
}
//---------------------------------------------------------------------------
void Doom3D::draw()
{
// total time measurement
tbeg(); double tperf0=performance_tms;
AnsiString tcls,tray,tmap,ttotal;
double a,a0,da,dx,dy,l,mx,my;
DWORD x,y,xs2,ys2,c,m;
double xx0,yy0,dx0,dy0,ll0; DWORD c0,d0;
double xx1,yy1,dx1,dy1,ll1; DWORD c1,d1;
_ray *p;
xs2=sxs>>1;
ys2=sys>>1;
// aspect ratio,view angle corrections
a=90.0*deg-view_ang;
double wall=double(sxs)*(1.25+(0.288*a)+(2.04*a*a)); // [px]
// floor,ceilling/sky
tbeg();
for (y=0;y<ys2;y++) for (x=0;x<sxs;x++) pscr[y][x]=0x000080FF;
for ( ;y<sys;y++) for (x=0;x<sxs;x++) pscr[y][x]=0x00404040;
tend(); tcls=tstr(1)+" cls";
// [cast rays]
tbeg();
// diffuse + ambient lighting
DWORD ch=155.0+fabs(100.0*sin(plra));
DWORD cv=155.0+fabs(100.0*cos(plra));
a0=plra-(0.5*view_ang);
da=divide(view_ang,sxs-1);
mx=mxs; my=mys;
for (p=ray,a=a0,x=0;x<sxs;x++,a+=da,p++)
{
p->x=plrx;
p->y=plry;
p->hit=0xFFFFFFFF;
p->typ=' ';
p->l=1.0e20;
ll0=ll1=p->l;
// grid V-line hits
c0=0; dx0=cos(a);
if (dx0<0.0) { c0=1; xx0=floor(plrx)-0.001; dx0=-1.0; }
if (dx0>0.0) { c0=1; xx0=ceil (plrx)+0.001; dx0=+1.0; }
if (c0) { dy0=tan(a); yy0=plry+((xx0-plrx)*dy0); dy0*=dx0; dx=xx0-plrx; dy=yy0-plry; ll0=(dx*dx)+(dy*dy); }
// grid H-line hits
c1=0; dy1=sin(a);
if (dy1<0.0) { c1=1; yy1=floor(plry)-0.001; dy1=-1.0; }
if (dy1>0.0) { c1=1; yy1=ceil (plry)+0.001; dy1=+1.0; }
if (c1) { dx1=divide(1.0,tan(a)); xx1=plrx+((yy1-plry)*dx1); dx1*=dy1; dx=xx1-plrx; dy=yy1-plry; ll1=(dx*dx)+(dy*dy); }
int height0=sys; // already rendered height [pixels]
bool _hit,_back=false,_bck=true;
if (!c0) ll0=1e20;
if (!c1) ll1=1e20;
for (;c0||c1;)
{
_hit=false;
// grid V-line hits
if (c0)
{
if (xx0<0.0) { c0=0; ll0=1e20; }
if (xx0>=mx) { c0=0; ll0=1e20; }
if (yy0<0.0) { c0=0; ll0=1e20; }
if (yy0>=my) { c0=0; ll0=1e20; }
}
if ((c0)&&(ll0<ll1))
{
m=DWORD(xx0-dx0);
if ((m>=0.0)&&(m<mxs)&&(!_bck)){ c=pmap[DWORD(yy0)][ m ]; if ((c&0xFFFF)!=0xFFFF) { p->hit=c; p->typ='V'; p->l=ll0; p->x=xx0; p->y=yy0; _hit=true; _back=true; _bck=true; }}
if (!_hit) { c=pmap[DWORD(yy0)][DWORD(xx0)]; if ((c&0xFFFF)!=0xFFFF) { p->hit=c; p->typ='V'; p->l=ll0; p->x=xx0; p->y=yy0; _hit=true; _back=false; _bck=false; } xx0+=dx0; dx=xx0-plrx; yy0+=dy0; dy=yy0-plry; ll0=(dx*dx)+(dy*dy); }
}
// grid H-line hits
if (c1)
{
if (xx1<0.0) { c1=0; ll1=1e20; }
if (xx1>=mx) { c1=0; ll1=1e20; }
if (yy1<0.0) { c1=0; ll1=1e20; }
if (yy1>=my) { c1=0; ll1=1e20; }
}
if ((c1)&&(ll0>ll1)&&(!_hit))
{
m=DWORD(yy1-dy1);
if ((m>=0.0)&&(m<mys)&&(!_bck)){ c=pmap[ m ][DWORD(xx1)]; if ((c&0xFFFF)!=0xFFFF) { p->hit=c; p->typ='H'; p->l=ll1; p->x=xx1; p->y=yy1; _hit=true; _back=true; _bck=true; }}
if (!_hit) { c=pmap[DWORD(yy1)][DWORD(xx1)]; if ((c&0xFFFF)!=0xFFFF) { p->hit=c; p->typ='H'; p->l=ll1; p->x=xx1; p->y=yy1; _hit=true; _back=false; _bck=false; } xx1+=dx1; dx=xx1-plrx; yy1+=dy1; dy=yy1-plry; ll1=(dx*dx)+(dy*dy); }
}
// render scan line
if (_hit)
{
union { DWORD dd; BYTE db[4]; } cc;
int tx,ty,sy,sy0,sy1,cnt,dsy,dty;
p->l=sqrt(p->l)*cos(a-plra);// anti fish eye
m=divide(wall*focus,p->l); // projected wall half size
c=0;
if (p->typ=='H') { c=ch; tx=double(double(txs)*(p->x-floor(p->x))); }
if (p->typ=='V') { c=cv; tx=double(double(txs)*(p->y-floor(p->y))); }
tx+=txs*(p->hit&0xFFFF);
// prepare interpolation
sy1=ys2+m;
// sy0=ys2-m; // constant wall height
sy0=sy1-(((m+m)*(p->hit>>16))/_Doom3D_wall_size); // variable wall height
dty=tys-1;
dsy=sy1-sy0+1;
// skip sy>=sys
if (sy1>=sys) sy1=sys-1;
// skip sy<0
for (cnt=dsy,sy=sy0,ty=0;sy<0;sy++) { cnt-=dty; while (cnt<=0) { cnt+=dsy; ty++; }}
#ifdef _Doom3D_filter_txr
DWORD r=0,g=0,b=0,n=0;
#else
cc.dd=ptxr[ty][tx];
cc.db[0]=DWORD((DWORD(cc.db[0])*c)>>8);
cc.db[1]=DWORD((DWORD(cc.db[1])*c)>>8);
cc.db[2]=DWORD((DWORD(cc.db[2])*c)>>8);
#endif
// continue sy>=0
y=height0;
if (sy1>height0) sy1=height0;
if (sy0<height0) height0=sy0;
if (_back){ for (sy=sy0;sy<=y;sy++){ if ((sy>0)&&(sy<sys)) pscr[sy][x]=0x0000FF00; }}
else for (;sy<=sy1;sy++)
{
#ifdef _Doom3D_filter_txr
if (!n)
{
cc.dd=ptxr[ty][tx];
b+=DWORD(cc.db[0]);
g+=DWORD(cc.db[1]);
r+=DWORD(cc.db[2]); n+=256;
}
if ((sy>0)&&(sy<sys))
{
cc.db[0]=DWORD(c*b/n); b=0;
cc.db[1]=DWORD(c*g/n); g=0;
cc.db[2]=DWORD(c*r/n); r=0; n=0;
pscr[sy][x]=cc.dd;
}
cnt-=dty; while (cnt<=0)
{
cnt+=dsy; ty++;
cc.dd=ptxr[ty][tx];
b+=DWORD(cc.db[0]);
g+=DWORD(cc.db[1]);
r+=DWORD(cc.db[2]); n+=256;
}
#else
if ((sy>0)&&(sy<sys)) pscr[sy][x]=cc.dd;
cnt-=dty; while (cnt<=0)
{
cnt+=dsy; ty++;
cc.dd=ptxr[ty][tx];
cc.db[0]=DWORD((DWORD(cc.db[0])*c)>>8);
cc.db[1]=DWORD((DWORD(cc.db[1])*c)>>8);
cc.db[2]=DWORD((DWORD(cc.db[2])*c)>>8);
}
#endif
}
if (height0<0) break;
}
}
}
tend(); tray=tstr(1)+" ray";
// [2D map]
tbeg();
m=_Doom3D_cell_size;
mx=_Doom3D_cell_size;
if ((sxs>=mxs*m)&&(sys>=mys*m))
{
for (y=0;y<mys*m;y++) // pmap[][]
for (x=0;x<mxs*m;x++)
{
if ((pmap[y/m][x/m]&0xFFFF)!=0xFFFF) c=0x00808080; else c=0x00000000;
pscr[y][x]=c;
}
x=double(plrx*mx); // view rays
y=double(plry*mx);
scr->Canvas->Pen->Color=0x00005050;
scr->Canvas->Pen->Mode=pmMerge;
for (c=0;c<sxs;c++)
{
scr->Canvas->MoveTo(x,y);
scr->Canvas->LineTo(DWORD(ray[c].x*mx),DWORD(ray[c].y*mx));
}
scr->Canvas->Pen->Mode=pmCopy;
c=focus*m; // player and view direction
scr->Canvas->Pen->Color=0x000000FF;
scr->Canvas->Brush->Color=0x000000FF;
scr->Canvas->MoveTo(x,y);
scr->Canvas->LineTo(DWORD(ray[xs2].x*mx),DWORD(ray[xs2].y*mx));
scr->Canvas->Ellipse(x-c,y-c,x+c,y+c);
scr->Canvas->Pen->Color=0x00202020;
for (y=0;y<=mys;y++) // map grid
for (x=0;x<=mxs;x++)
{
scr->Canvas->MoveTo(0 ,y*m);
scr->Canvas->LineTo(mxs*m,y*m);
scr->Canvas->MoveTo(x*m, 0);
scr->Canvas->LineTo(x*m,mys*m);
}
x=keys.mx*m; // selected cell
y=keys.my*m;
scr->Canvas->Pen->Color=0x0020FFFF;
scr->Canvas->MoveTo(x ,y );
scr->Canvas->LineTo(x+m,y );
scr->Canvas->LineTo(x+m,y+m);
scr->Canvas->LineTo(x ,y+m);
scr->Canvas->LineTo(x ,y );
}
tend(); tmap=tstr(1)+" map";
// [editor]
if (txr_sel!=0xFFFFFFFF)
{
int x=sxs,y=5,s0,s1,s2,i,j;
s0=txs>>1;
s1=txs>>2;
s2=(s0*cell_h)/_Doom3D_wall_size;
for (i=-3;i<=3;i++)
{
j=txr_sel+i;
while (j< 0) j+=tn;
while (j>=tn) j-=tn;
if (i) { scr->Canvas->CopyRect(TRect(x-s1,y+(s1>>1),x,s1+(s1>>1)),txr2->Canvas,TRect(s1*j,s0,s1*j+s1,s0+s1)); x-=s1+5; }
else { scr->Canvas->CopyRect(TRect(x-s0,y+s0-s2 ,x,s0 ),txr2->Canvas,TRect(s0*j, 0,s0*j+s0,s2 )); x-=s0+5; }
}
}
// total time measurement
performance_tms=tperf0;
tend(); ttotal=tstr(1)+" total";
x=m*mxs+m;
c=16; y=-c;
scr->Canvas->Font->Color=clYellow;
scr->Canvas->Brush->Style=bsClear;
scr->Canvas->TextOutA(x,y+=c,AnsiString().sprintf("player: %.2lf x %.2lf x %.2lf",plrx,plry,plrz));
scr->Canvas->TextOutA(x,y+=c,AnsiString().sprintf(" mouse: %.2lf x %.2lf",keys.mx,keys.my));
scr->Canvas->TextOutA(x,y+=c,tray);
scr->Canvas->TextOutA(x,y+=c,tcls);
scr->Canvas->TextOutA(x,y+=c,tmap);
scr->Canvas->TextOutA(x,y+=c,ttotal);
scr->Canvas->TextOutA(x,y+=c,AnsiString().sprintf(" key: %d",keys.Key));
// aspect ratio test
/*
c=ys2*7/10;
scr->Canvas->Rectangle(xs2-c,ys2-c,xs2+c,ys2+c);
*/
// cross
c=4,m=32;
scr->Canvas->Pen->Color=clRed;
scr->Canvas->MoveTo(xs2-c,ys2-m);
scr->Canvas->LineTo(xs2-c,ys2-c);
scr->Canvas->LineTo(xs2-m,ys2-c);
scr->Canvas->MoveTo(xs2+c,ys2-m);
scr->Canvas->LineTo(xs2+c,ys2-c);
scr->Canvas->LineTo(xs2+m,ys2-c);
scr->Canvas->MoveTo(xs2-c,ys2+m);
scr->Canvas->LineTo(xs2-c,ys2+c);
scr->Canvas->LineTo(xs2-m,ys2+c);
scr->Canvas->MoveTo(xs2+c,ys2+m);
scr->Canvas->LineTo(xs2+c,ys2+c);
scr->Canvas->LineTo(xs2+m,ys2+c);
scr->Canvas->Brush->Style=bsSolid;
}
//---------------------------------------------------------------------------
void Doom3D::update(double dt)
{
int move=0;
double da=120.0*deg*dt;
double dl= 5.0 *dt;
double dx=0.0,dy=0.0,dz=0.0;
if (keys.get(104)) { plra-=da; if (plra< 0.0) plra+=pi2; } // turn l/r
if (keys.get(105)) { plra+=da; if (plra>=pi2) plra-=pi2; }
if (keys.get(101)) { move=1; dx=+dl*cos(plra); dy=+dl*sin(plra); } // move f/b
if (keys.get( 98)) { move=1; dx=-dl*cos(plra); dy=-dl*sin(plra); }
if (keys.get(102)) { move=1; dx= dl*cos(plra-90*deg); dy=dl*sin(plra-90*deg); } // strafe l/r
if (keys.get( 99)) { move=1; dx= dl*cos(plra+90*deg); dy=dl*sin(plra+90*deg); }
if (keys.get(100)) { move=1; dz=+dl; } // strafe u/d
if (keys.get( 97)) { move=1; dz=-dl; }
if (move) // update/test plr position
{
double x,y,z,mx,my;
x=plrx+dx; mx=mxs-focus;
y=plry+dy; my=mys-focus;
z=plrz+dz; if ((z>=0.0)&&(z<=_Doom3D_wall_size)) plrz=z;;
if (x<focus) x=focus; if (x>mx) x=mx;
if (y<focus) y=focus; if (y>my) y=my;
dx*=divide(focus,dl);
dy*=divide(focus,dl);
if ((pmap[DWORD(y+dy)][DWORD(x+dx)]&0xFFFF)==0xFFFF) { plrx=x; plry=y; }
else if ((pmap[DWORD(y+dy)][DWORD(x )]&0xFFFF)==0xFFFF) plry=y;
else if ((pmap[DWORD(y )][DWORD(x+dx)]&0xFFFF)==0xFFFF) plrx=x;
}
keys.rfskey();
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
performance.h
时间测量
tbeg,tend,tstr
,
OpenGLrep4d_double.h
键盘和鼠标处理程序
keytab
以及与端口VCL相关的内容(
Canvas,AnsiString
,文件访问,JPEG ...)。
//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "win_main.h"
#include "Doom3D.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMain *Main;
Doom3D game;
//---------------------------------------------------------------------------
void TMain::draw()
{
game.draw();
Canvas->Draw(0,0,game.scr);
}
//---------------------------------------------------------------------------
__fastcall TMain::TMain(TComponent* Owner) : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMain::FormResize(TObject *Sender)
{
game.scr_resize(ClientWidth,ClientHeight);
}
//---------------------------------------------------------------------------
void __fastcall TMain::tim_redrawTimer(TObject *Sender)
{
game.update(tim_redraw->Interval*0.001);
draw();
}
//---------------------------------------------------------------------------
void __fastcall TMain::FormKeyDown(TObject *Sender, WORD &Key,TShiftState Shift){ game.keys.set(Key,Shift); }
void __fastcall TMain::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { game.keys.rst(Key,Shift); }
void __fastcall TMain::FormActivate(TObject *Sender) { game.keys.reset_keys(); }
//---------------------------------------------------------------------------
void __fastcall TMain::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { game.mouse(X,Y,Shift); }
void __fastcall TMain::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { game.mouse(X,Y,Shift); }
void __fastcall TMain::FormMouseUp (TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { game.mouse(X,Y,Shift); }
void __fastcall TMain::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled) { game.wheel(WheelDelta,Shift); Handled=true; }
//---------------------------------------------------------------------------
关于java - 不同高度尺寸的射线铸件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47239797/
我正在查看 DOOM 源代码,我找到了 this行。 void * Z_Malloc (int size, int tag, void *user)
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve t
我正从 Python 和 Numpy 转向 C++ 和 Eigen。 在 Python 中,我可以使用 .shape 属性获取 Numpy 数组/矩阵的形状(维度),如下所示: import nump
固定嵌入式YouTube视频的宽度并自己照顾自己的高度是否安全? 我有一个应用程序,用户可以将通知发布到公告板上。这些通知主要是文本(带有有限的html标签)和嵌入式图像。我现在要添加对嵌入式YouT
可以轻松创建一个 THREE.BoxGeometry,在创建宽度、高度和深度的三个独立参数时,您必须在其中传递参数。 我想创建任何和所有不带参数的THREE[types](),并在之后设置值。 有没有
我在 HTML 页面上有一个 Canvas : 属性width和height将 Canvas 拉伸(stretch)到某个字段,但不调整其大小。所以 var canvasElement = docu
我在我的 css 中使用 @media all 和 (max-width: 600px) {} 作为响应式菜单,问题是它没有正确显示。 我想让橙色填充绿色空间……当然,还要将绿色空间变成透明的。基本上
(我知道我问了很多关于这个的问题!) 基本上,我正在尝试将一些代码从 Matlab 转换为 C++,我遇到了这个: n = sum(size(blocks)) - len; 现在我计算了 vector
您好,我有一个用于创建产品的表单。用户应该能够选择类别(例如 T 恤),然后 T 恤的所有尺码(例如 S、M、L)都会下拉。用户可以输入每种尺寸的数量。 Javascript 对此不起作用。用户可以选
我正在尝试在页脚中定位和调整我的社交图标链接的大小,但是,这些命令似乎都没有效果,尤其是当我尝试调整它们的大小时。我试过将宽度和高度标记为“!重要”,但这也没有效果。 这是代码的 JSFiddle:h
我目前正在创建一个 HTML5 canvas基于绘图程序。用户可以绘制一张图像或几张图像“页面”,并将其保存到云端以供日后快速检索。这是用于交互式白板的;老师不能总是确定他们计划类(class)使用的
为网站存储图像的最佳方式是什么? 我不应该超过什么尺寸? 现在,我将所有界面文件保存在 png(主要是 Sprite )中,并将常用图像保存在 jpg 中。一些图像大约为 100-150Kb。 保存图
在 fancybox 主页 ( http://fancybox.net/home ) 中,有一个打开尺寸为屏幕 75% 的 iFrame 的示例。 我无法按照网站上的说明通过修改 .js 文件的宽度和
我想做一个仅适用于 iPhone 4 的应用程序,该应用程序使用 iAd AdBannerView。当我添加它时,它的固定大小为 320x50。在更高分辨率下这如何工作? 有人可以解释一下 iPhon
我们有一个 NSString,我们使用 - (NSSize)sizeWithAttributes:(NSDictionary *)attributes 来测量边界框。一切都好。 现在我们使用标准 NS
我想知道 Canvas 的宽度和高度,但我只知道它的 HDC。 我尝试过这段代码: procedure TForm92.Button1Click(Sender: TObject); var hBi
问题是如何使用数学从 START SVG 维度(不带旋转)和 END SVG 维度(带旋转)获取 >开始 SVG 信息。基本上,要从 START SVG 到 END SVG,我需要执行 -115.60
我的问题是,我有一个包含50万行的Oracle表。我设置了sqoop以将其作为 Parquet 文件导入到HDFS。我将--num-partition参数设置为32,得到了32个 Parquet 文件
是否可以更改 WordPress 中当前主题的 YouTube(或其他视频)的默认嵌入尺寸?我搜索了一个插件和一些代码,但似乎找不到。 我的意思是当您将 YouTube 网址粘贴到帖子或页面中时使用的
我有一个组,其中包含一个矩形和顶部的图像。我希望矩形可以调整大小,并且图像应该具有固定大小,除非矩形小于图像的情况。然后图像应该随着矩形缩小。 图像还应该始终居中并有一些填充。 除了图像的缩小尺寸部分
我是一名优秀的程序员,十分优秀!