J'essaye d'écrire un moteur raycasting.Moteur de jeu Java: Les murs raycasted sont creux, brisés, et ressemblent à la matière fécale
j'ai étudié le tutoriel trouvé à http://www.instructables.com/id/Making-a-Basic-3D-Engine-in-Java/ et C++ raycasting tutoriels trouvés à http://lodev.org/cgtutor/raycasting.html, et après quelques tentatives j'ai eu les rayons d'être jeté dans la bonne direction et donc obtenu un (semi-) sortie de travail.
J'ai fait apparaître les murs dans le monde et j'ai ajouté du mouvement dans le jeu et j'ai pu me déplacer. Cependant, les murs (qui sont censés être un cube) ne montrent que deux côtés du cube, peu importe la direction dans laquelle je me trouve dans le monde. Donc, au lieu de montrer un cube solide, il va sauter du côté du cube qui est le plus proche de la caméra, et montrer le côté éloigné du cube, et cela ne se produit que lorsque je fais face à l'origine (0,0) du tableau 2d dans lequel ma carte est stockée. Cette erreur est visible dans l'image ci-dessus.
Je pense que cette erreur est due à l'arrondi d'entier et à l'emplacement des parois détectées par le rayon étant arrondi vers le bas, mais je n'arrive pas à trouver une solution. Je suis en train de lancer deux rayons pour chaque colonne de pixels, l'un pour détecter les murs verticaux et l'autre pour détecter les murs horizontaux. Les distances de chacun sont calculées et comparées, puis le mur de distance le plus court est tracé.
Ma question est de savoir comment amener les murs à tirer correctement
public class Screen {
//VARIABLE DECLARATIONS
//-----------------------
int FOV = 60; //field of view in degrees
int screenwidth = 800; //variable holds the vertical resolution of the screen
int screenheight = 600; //variable holds the horizontal resolution of the screen
double camx; //cameras x coordinate
double camy; //cameras y coordinate
double camAngle; //direction of camera in degrees
double rayAngle; //angle of ray being cast in radians
int x = 0; //holds the current pixel column being looped through
double IncrementAngle = (double)FOV/(double)screenwidth; //calculates the change in the rays angle for each horizontal pixel
int[][] map; //stores the 2d map that represents the 3d world of the game
public Screen() {
public int[] update(int[] pixels, int[][] m, double ca, double cx, double cy, int fov) {
FOV = fov;
IncrementAngle = (double)FOV/(double)screenwidth; //calculates the change in the rays angle for each horizontal pixel
camAngle = ca;
camx = cx;
camy = cy;
map = m;
int x = 0;
Color c; //declares new color
//fills background
for (int n = 0; n < pixels.length; n++) pixels[n] = Color.BLACK.getRGB();
for (double ray = (double)(FOV/2); ray > (double)(-FOV/2); ray -= IncrementAngle) {
double vdist = Integer.MAX_VALUE, hdist = Integer.MAX_VALUE;
double perpendicularDist = 0;
double theta;
double lineheight;
int drawstart, drawend;
int side = 0;
int r = 0, g = 0, b = 0, a = 0; //variables that determinbe what colours will be drawn (red, green, blue, and alpha for
transparency)
rayAngle = Math.toRadians(camAngle + ray);
try {
vdist = VertDist(rayAngle);
}
catch (ArrayIndexOutOfBoundsException e) {}
try {
hdist = HorDist(rayAngle);
}
catch (ArrayIndexOutOfBoundsException e) {}
theta = Math.abs(rayAngle - Math.toRadians(camAngle)); //angle difference between the ray being cast and the cameras
direction
if (hdist < vdist) {
perpendicularDist = hdist * Math.cos(theta);
lastSide = 0;
r = Color.GRAY.getRed();
g = Color.GRAY.getGreen();
b = Color.GRAY.getBlue();
a = Color.GRAY.getAlpha();
}
else {
perpendicularDist = vdist * Math.cos(theta);
lastSide = 1;
r = Color.DARK_GRAY.getRed();
g = Color.DARK_GRAY.getGreen();
b = Color.DARK_GRAY.getBlue();
a = Color.DARK_GRAY.getAlpha();
}
//creates pulsating effect with wall colours
r -= pulse;
g += pulse * 2;
b -= pulse;
c = new Color(r, g, b, a);
lineheight = screenheight/perpendicularDist;
drawstart = (int)(-lineheight/2) + (screenheight/2);
drawend = (int)(lineheight/2) + (screenheight/2);
if (drawstart < 0) drawstart = 0;
if (drawend >= screenheight) drawend = screenheight - 1;
for (int y = drawstart; y < drawend; y++) {
pixels[x + (y * screenwidth)] = c.getRGB();
}
if (x < screenwidth) x++;
else x = 0;
}
//returns pixels array to main class to be shown to screen
return pixels;
}
public double VertDist(double angle) {
double rx = 0, ry = 0;
double stepX = 0, stepY = 0;
double FstepX = 0, FstepY = 0;
double Fxcomp = 0, Fycomp = 0;
double xcomp = 0, ycomp = 0;
double mapx = camx, mapy = camy;
boolean hit = false;
double obliqueDist = 0;
rx = Math.cos(angle);
ry = Math.sin(angle);
if (rx < 0) {
stepX = -1;
FstepX = (camx - ((int)camx)) * stepX;
}
else if (rx > 0) {
stepX = 1;
FstepX = ((int)(camx + 1)) - camx;
}
ycomp = (stepX * Math.tan(angle) * -1);
Fycomp = Math.abs(FstepX) * ycomp;
if (map[(int)(mapx)][(int)(mapy)] > 0) hit = true;
mapx += FstepX;
mapy += Fycomp;
if (map[(int)(mapx)][(int)(mapy)] > 0) hit = true;
else {
while (!hit && mapx > 0 && mapy > 0) { //loops while a wall has not been found and while positive indexes are still being
checked
mapx += stepX;
mapy += ycomp;
if (map[(int)(mapx)][(int)(mapy)] > 0) {
hit = true;
//if (Math.toDegrees(rayAngle) < 270 && Math.toDegrees(rayAngle) > 90) {
// mapy -= stepX;
// mapx -= ycomp;
//}
}
}
}
mapx = Math.abs(mapx - camx);
mapy = Math.abs(mapy - camy);
obliqueDist = Math.sqrt((mapx*mapx) + (mapy*mapy));
//change to be not fixed angle based
//if (angle > Math.toRadians(135) && angle < Math.toRadians(225)) {
// obliqueDist -= Math.sqrt(stepX*stepX + ycomp*ycomp);
//}
return obliqueDist;
}
public double HorDist(double angle) {
double rx, ry;
double stepX = 0, stepY = 0;
double FstepX = 0, FstepY = 0;
double Fxcomp, Fycomp;
double xcomp, ycomp;
double mapx = camx, mapy = camy;
boolean hit = false;
double obliqueDist = 0;
rx = Math.cos(angle);
ry = Math.sin(angle);
if (ry < 0) {
stepY = 1;
FstepY = ((int)(camy + 1)) - camy;
}
else if (ry > 0) {
stepY = -1;
FstepY = (camy - (int)camy) * stepY;
}
xcomp = stepY/(Math.tan(angle) * -1);
Fxcomp = Math.abs(FstepY) * xcomp;
if (map[(int)(mapx)][(int)(mapy)] > 0) hit = true;
mapx += Fxcomp;
mapy += FstepY;
if (map[(int)(mapx)][(int)(mapy)] > 0) hit = true;
else {
while (!hit) {
mapx += xcomp;
mapy += stepY;
if (map[(int)(mapx)][(int)(mapy)] > 0) hit = true;
}
}
mapx = Math.abs(mapx - camx);
mapy = Math.abs(mapy - camy);
obliqueDist = Math.sqrt((mapx*mapx) + (mapy*mapy));
//change to be not fixed angle based
//if (angle > Math.toRadians(45) && angle < Math.toRadians(135)) {
// obliqueDist -= Math.sqrt(xcomp*xcomp + stepY*stepY);
//}
return obliqueDist;
} }
Veuillez apprendre à utiliser les paragraphes. Un mur massif de texte sans interruptions logiques dissuade les gens et les force à ignorer votre question et/ou votre critique. Puis, en écrivant votre question, soyez concis et précis. Omettre toutes les informations superflues. Nous n'avons pas vraiment besoin de connaître toute l'histoire de la façon dont vous êtes arrivé à ce point. Il suffit de poser la question spécifique. –
J'ai modifié votre message pour plus de clarté et de concision. Si vous avez enlevé trop, n'hésitez pas à revenir et à modifier vous-même. Cependant, il vous serait probablement très utile d'essayer de réduire votre code à un *** *** *** exemple qui démontre le problème. Comme pour votre prose, supprimez tout ce qui n'est pas lié au problème et créez un [mcve]. Le processus de ce faire vous apprendra probablement un peu et vous pourriez même résoudre votre propre problème. Cela fonctionne toujours comme ça pour moi. –
Merci d'avoir laissé quelques critiques constructives sur mon poste au lieu d'aller droit au but et de partir. Ill garder ce que vous avez dit à l'esprit la prochaine fois que je poste. J'étais sur le point d'enlever tous les bits inutiles moi-même, merci pour cela. – xonerex