I am trying to make a tridimensional game with P3D (a finite world of solid boxes of different colors). I always have the same problem: only the 9 center blocks seem to have a working collider. The code :
float x=0;
int[] col = {0, 0, 0};
float y=10;
float z=0;
float xsp = 0;
float ysp = 0;
float zsp = 0;
float ang=0;
float ang2=0;
float speed = 0.1;
ArrayList<bloc> terrain = new ArrayList<bloc>();
boolean w=false;
boolean a=false;
boolean s=false;
boolean d=false;
boolean q=false;
boolean e=false;
boolean testjump=false;
boolean touchGround=false;
javax.swing.JFrame invisibleFrame = new javax.swing.JFrame();
void setup() {
fullScreen(P3D);
terrain.add(new bloc(100, 20, 30, (byte)3));
terrain.add(new bloc(110, 10, 30, (byte)2));
terrain.add(new bloc(120, 20, 30, (byte)1));
terrain.add(new bloc(100, 20, 60, (byte)0));
terrain.add(new bloc(130, 20, 30, (byte)1));
terrain.add(new bloc(100, -20, 30, (byte)2));
terrain.add(new bloc(-100, -20, -30, (byte)3));
terrain.add(new bloc(00, 0, 00, (byte)2));
terrain.add(new bloc(30, 30, 30, (byte)5));
terrain.add(new bloc(00, 00, 00, (byte)5));
terrain.add(new bloc(10, 00, 00, (byte)5));
terrain.add(new bloc(-10, 00, 0, (byte)5));
terrain.add(new bloc(00, 00, 10, (byte)5));
terrain.add(new bloc(10, 00, 10, (byte)5));
terrain.add(new bloc(-10, 00, 10, (byte)5));
terrain.add(new bloc(0, 0, -10, (byte)5));
terrain.add(new bloc(10, 0, -10, (byte)5));
terrain.add(new bloc(-10, 0, -10, (byte)5));
terrain.add(new bloc(-20, 0, -10, (byte)5));
terrain.add(new bloc(-30, 0, -10, (byte)2));
println(cubeCollision(0, 0, 0, 1, 1, 1, 0.5, 0.5, 0.5, 1, 1, 1));
}
String prompt(String message) {
return javax.swing.JOptionPane.showInputDialog(invisibleFrame, message);
}
void alert(String message) {
javax.swing.JOptionPane.showMessageDialog(invisibleFrame, message);
}
void draw() {
pushMatrix();
col[0]+=5;
if (col[0]>255) {
col[0]=0;
col[1]+=5;
if (col[1]>255) {
col[1]=0;
col[2]+=5;
if (col[2]>255) {
col[2]=0;
}
}
}
clear();
background(0, 128, 255);
translate(width/2, height/2, 657);
if (mouseX<width/8) {
ang-=TAU/360;
}
if (mouseY<height/8) {
ang2-=TAU/360;
}
if (mouseX>width*0.875) {
ang+=TAU/360;
}
if (mouseY>height*0.875) {
ang2+=TAU/360;
}
rotateY(ang);
//rotateZ(ang2);
if (w) {
float[] mv = forward(-ang, speed);
xsp+=mv[0];
zsp+=mv[1];
}
if (a) {
float[] mv = forward(-ang+(TAU/4), speed);
xsp+=mv[0];
zsp+=mv[1];
}
if (s) {
float[] mv = forward(-ang+(TAU/2), speed);
xsp+=mv[0];
zsp+=mv[1];
}
if (d) {
float[] mv = forward(-ang+((TAU/4)*3), speed);
xsp+=mv[0];
zsp+=mv[1];
}
stroke(color(0, 255, 0));
pushMatrix();
translate(x, y, z);
for (int i=0; i<terrain.size(); i++) {
terrain.get(i).draw(0, 0, 0);
}
popMatrix();
touchGround=false;
for (int i=0; i<llog(terrain.size()); i++) {
if (cubeCollision(terrain.get(i).x, terrain.get(i).y, terrain.get(i).z, terrain.get(i).x+10, terrain.get(i).y+10, terrain.get(i).z+10, x, y, z, x+10, y+10, z+10)) {
touchGround = true;
break;
}
}
xsp*=0.9;
zsp*=0.9;
x+=xsp;
z+=zsp;
if (!touchGround) {
if (ysp>-0.1)
ysp-=1;
else ysp*=1.00001;
} else ysp = 0;
if (testjump) {
testjump = false;
if (touchGround) ysp+=10;
}
y+=ysp;
new bloc(0, 0, 0, (byte) 4).draw(0, 0, 0);
popMatrix();
fill(255, 128, 128);
rect(0, 0, 100, 100);
}
class bloc extends Object {
float x, y, z;
byte type;
public bloc(float xx, float yx, float zx, byte type) {
this.type=type;
this.x=xx;
this.y=yx;
this.z=zx;
}
public void draw(float xx, float yx, float zx) {
this.show(this.x+xx, this.y+yx, this.z+zx, findc(this.type));
}
private void show(float xx, float yx, float zx, color c) {
pushMatrix();
translate(xx, yx, zx);
fill(c);
box(10);
popMatrix();
}
}
static float llog(float x) {
println(x);
return x;
}
color findc(byte type) {
switch(type) {
case 0:
return color(0);
case 1:
return color(255, 0, 0);
case 2:
return color(0, 255, 0);
case 3:
return color(0, 0, 255);
case 4:
return color(255, 255, 0);
case 5:
return color(col[0], col[1], col[2]);
default:
return color(255);
}
}
float[] forward(float angle, float distance) {
float[] ret=new float[2];
ret[0]=sin(angle)*distance;
ret[1]=cos(angle)*distance;
return ret;
}
void keyPressed() {
switch(key) {
case 'w':
w=true;
break;
case 'a':
a=true;
break;
case 's':
s=true;
break;
case 'd':
d=true;
break;
case ' ':
println("jump!");
testjump=true;
break;
case 'e':
e=true;
break;
case 'x':
exit();
return;
default:
break;
}
}
void keyReleased() {
switch(key) {
case 'w':
w=false;
break;
case 'a':
a=false;
break;
case 's':
s=false;
break;
case 'd':
d=false;
break;
case 'q':
q=false;
break;
case 'e':
e=false;
break;
default:
break;
}
}
boolean lineCollision(float start1, float end1, float start2, float end2) {
return end1 >= start2 && end2 >= start1;
}
boolean squareCollision(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2) {
return lineCollision(x1, w1, x2, w2)&&lineCollision(y1, h1, y2, h2);
}
boolean cubeCollision(float x1, float y1, float z1, float w1, float h1, float d1, float x2, float y2, float z2, float w2, float h2, float d2) {
return squareCollision(x1, y1, w1, h1, x2, y2, w2, h2)&&lineCollision(z1, d1, z2, d2);
}
void mousePressed() {
if (mouseX<100&&mouseY<100) {
float xx = float(prompt("New block's X coordinate:"));
float yy = float(prompt("New block's Y coordinate:"));
float zz = float(prompt("New block's Z coordinate:"));
byte co = byte(int(prompt("Color of the new block (0-5):")));
terrain.add(new bloc(xx*10, yy*10, zz*10, co));
}
}
I think maybe the colliders are just not aligned with their visual representation, but the detection is really precise.