Java - Colisiones personaje-tile (cuadrado)

 
Vista:

Colisiones personaje-tile (cuadrado)

Publicado por Manu (1 intervención) el 27/02/2021 13:45:01
Buenas, os explico mi problema para ver si podeis echarme un cable:

Estoy haciendo un juego con Processing Java, de un personaje que se desplaza en 2D y quiero hacer el escenario en base a cuadraditos. Hasta ahora lo que hacía era dibujar el escenario y programar las colisiones en base al dibujo. Para mi esto es más fácil, pero bastante más largo de hacer, así que me interesa programar una función de cuadradito o bloque, pero que incluya las colisiones, de modo en que el personaje choque contra él y se detenga y luego ya repetir el bloque 1000 veces para construir el mapa. Llevo una semana y casi lo tengo, pero me aparecen problemitas que me quitan años de vida.
Os dejo el código por aquí:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
int VTESTER,salto,st,sd,limitfall,SCORE,STAGE,HEALTH,EXP,LV,idy,OCULTADOR,d,e,f,tf;
PImage P[] = new PImage [999];
int x[]=new int[999];int y[]=new int[999];int mov[]=new int[999];boolean dch[] = new boolean[999];boolean izd[] = new boolean[999];boolean spw[]=new boolean[999];
int HY[]=new int[999];//animacion
int by[]=new int[999];int cc[]=new int[999];int ox[]=new int[999];int oy[]=new int[999];int AR[]=new int[999];int AB[]=new int[999];
float ct[][]=new float[999][999];//ct for animations
boolean dw,jump,tmf,stopjump,jumpdelay,damage;
boolean it[]=new boolean [999];boolean tt[]=new boolean [999];boolean down[]=new boolean [999];
PFont TX;
 
void setup(){
//imágenes//
P[0]= loadImage("PLAYERI0.png");
P[1]= loadImage("PLAYERD0.png");
P[2]= loadImage("PLAYERI1.png");
P[3]= loadImage("PLAYERD1.png");
P[4]= loadImage("PLAYERI2.png");
P[5]= loadImage("PLAYERD2.png");
P[6]= loadImage("PIDOWN.png");
P[7]= loadImage("PDDOWN.png");
P[8]= loadImage("T0.PNG");
P[9]= loadImage("bc.PNG");
P[10]= loadImage("SKI0.png");
P[11]= loadImage("SKD0.png");
P[12]= loadImage("SKI1.png");
P[13]= loadImage("SKD1.png");
 
size(512,480);
x[0]=32*1;y[0]=32*13;STAGE=1;HEALTH=16;LV=1;d=32;e=d*2;f=d/2;
}
 
void draw(){if(mousePressed){ x[0]=mouseX;;}
  background(0);//limitfall=480;
 
  //BG
if(OCULTADOR==1){image(P[8],0,0,512,480);
  //--------------------
  //BG col
  if(x[0]<=22){x[0]=22;}if(x[0]+56>=490){x[0]=490-56;}
  if(x[0]+56>464&&y[0]+68<=355&&x[0]<490){limitfall=350;}else
  if(x[0]<464){limitfall=381;}
  //if(x[0]+56>100&&x[0]<58){limitfall=480;if(y[0]+68>385){if(x[0]+56>107){x[0]=107-56;}if(x[0]<52){x[0]=52;}}}
  if(x[0]>107&&x[0]+44<167){limitfall=480;if(y[0]+68>385){if(x[0]<114){x[0]=114;}if(x[0]+44>160){x[0]=160-44;}}}
  if(x[0]+11>277&&x[0]+44<331){limitfall=480;if(y[0]+68>385){if(x[0]+11<287){x[0]=287-11;}if(x[0]+44>322){x[0]=322-44;}}}
  if(y[0]+68>368&&x[0]+44>190&&x[0]<190){x[0]=190-44;}
  if(y[0]+68>368&&x[0]+11<256&&x[0]+44>256){x[0]=256-11;}
  if(x[0]+11<247&&x[0]+44>200&&y[0]+68<=355){limitfall=350;}
  if(y[0]+68>368&&x[0]+44>445&&x[0]<445){x[0]=445-44;}}
  //-----------
if(salto==1||salto==2){
if(mov[0]==1){image(P[7],x[0],y[0]-10,d,e);}
if(mov[0]==0){image(P[6],x[0],y[0]-10,d,e);}
}else if(dw==false){
if(izd[0]){PI(0,0,2,4,2);}
else if(dch[0]){PI(0,1,3,5,3);}else{
if(mov[0]==0){image(P[0],x[0],y[0],d,e);}
if(mov[0]==1){image(P[1],x[0],y[0],d,e);}
}}else if(dw){
if(mov[0]==0){image(P[6],x[0],y[0],d,e);}
if(mov[0]==1){image(P[7],x[0],y[0],d,e);}
}
if(dw==false){
if(izd[0]){x[0]=x[0]-2;}
if(dch[0]){x[0]=x[0]+2;}}
 
if (jump){salto=1;jump=false;st=1;}
if(salto==1&&jumpdelay==false){if(cc[0]>=13){cc[0]=0;jumpdelay=true;}else{cc[0]++;y[0]=y[0]-5;}}
if(jumpdelay){if(cc[1]>7){cc[1]=0;jumpdelay=false;salto=2;}else{cc[1]++;}}
if(salto==2){if(y[0]+e<limitfall){y[0]=y[0]+5;}else{salto=0;}}
if(salto==0&&y[0]+e<limitfall){y[0]=y[0]+5;}
//if(salto==0){y[0]=limitfall-e;}
//tiles
o(2,8,6,12);//o(3,8,9,12);//o(1,8,7,14);o(4,8,8,14);o(5,8,9,14);o(6,8,4,14);
//---
 
//enemies ---
//if(VTESTER==0){if(mousePressed){VTESTER=1;spw[1]=true;}}
//emov(1,1,10,12,11,13,32,64,8,32*6,32*10-2,2,3);
//-----------
 
noStroke();
  TX=loadFont("PressStart2P-16.vlw");
  textFont(TX);
  textAlign(LEFT);
  fill(255, 255, 255);
  text("SCORE-" + SCORE,2,32);
  text("PLAYER",2,48);
  text("LVL" + LV,0,64);
  text("STAGE " + STAGE,30*13,32);
  noFill();
//HEALTH--------------
SK(HEALTH,206,50,50,0,34,0);SK(HEALTH,206,50,50,8*3,34,3);SK(HEALTH,206,50,50,8*6,34,6);SK(HEALTH,206,50,50,8*9,34,9);SK(HEALTH,206,50,50,8*12,34,12);SK(HEALTH,206,50,50,8*15,34,15);
SK(HEALTH,206,50,50,8,34,1);SK(HEALTH,206,50,50,8*4,34,4);SK(HEALTH,206,50,50,8*7,34,7);SK(HEALTH,206,50,50,8*10,34,10);SK(HEALTH,206,50,50,8*13,34,13);
SK(HEALTH,206,50,50,8*2,34,2);SK(HEALTH,206,50,50,8*5,34,5);SK(HEALTH,206,50,50,8*8,34,8);SK(HEALTH,206,50,50,8*11,34,11);SK(HEALTH,206,50,50,8*14,34,14);
EX();
//MAX&&MIN
if(HEALTH<0){HEALTH=0;}if(HEALTH>16){HEALTH=16;}
if(EXP<0){EXP=0;}if(EXP>17){EXP=0;LV++;}
if(LV>=999){LV=999;}
//--------------------
//BGOVER
if(OCULTADOR==1){
noStroke();
fill(0,0,0);
rect(0,30*14-4,30*17,30*3);
noFill();
image(P[9],0,32*12+2,512,66);}
//_____
//DEATHBYFALL
if(y[0]+68>=480){HEALTH=0;}
}
 
void keyPressed() {
  if (key == CODED) {
    if (keyCode == RIGHT) {
 
      dch[0]=true;mov[0]=1;
 
    }
    if (keyCode == LEFT) {
 
      izd[0]=true;mov[0]=0;
 
    }
 
    if (keyCode == DOWN) {
 
      dw=true;
 
  }
 
}
if (key == 's'||key == 'S'){
  EXP++;
  if(salto<1){if(st==0){jump=true;}}
}
}
 
void keyReleased() {
  if (key == CODED) {
    if (keyCode == RIGHT) {
 
      dch[0]=false;
 
    }
    if (keyCode == LEFT) {
 
      izd[0]=false;
 
    }
 
    if (keyCode == DOWN) {
 
      dw=false;
 
  }
 
}
 
if (key == 's'||key == 'S'){
  //println("oksalto");
jump=false;if(st==1){st=0;}
}
 
}
 
void SK(int AT, int c1, int c2, int c3, int inc, int y, int n){
if(AT>n){
fill(c1, c2, c3);
rect(110+inc,y,6,12);
}}
void EX(){
SK(EXP,255,110,110,0,49,1);SK(EXP,255,110,110,8*3,49,4);SK(EXP,255,110,110,8*6,49,7);SK(EXP,255,110,110,8*9,49,10);SK(EXP,255,110,110,8*12,49,13);SK(EXP,255,110,110,8*15,49,16);
SK(EXP,255,110,110,8,49,2);SK(EXP,255,110,110,8*4,49,5);SK(EXP,255,110,110,8*7,49,8);SK(EXP,255,110,110,8*10,49,11);SK(EXP,255,110,110,8*13,49,14);
SK(EXP,255,110,110,8*2,49,3);SK(EXP,255,110,110,8*5,49,6);SK(EXP,255,110,110,8*8,49,9);SK(EXP,255,110,110,8*11,49,12);SK(EXP,255,110,110,8*14,49,15);}
 
 void am (int numactivador, int estadosecuencia1, PImage imagen, float im_x, float im_y, int im_an, int im_al, int vcount1, int vcount2, int duracionsecuencia, int estadosecuencia2, int secuenciacabada){
if(HY[numactivador]==estadosecuencia1){
image(imagen,im_x,im_y,im_an,im_al);
if(ct[vcount1][vcount2]==duracionsecuencia){HY[numactivador]=estadosecuencia2;ct[vcount1][vcount2]=secuenciacabada;}else{ct[vcount1][vcount2]++;}}
}
 
void PI(int f, int n1, int n2, int n3, int n4){//animación OV para tiles
if(HY[f]==0){
am(f,0,P[n1],x[f],y[f],d,e,1,0,6,1,0);
  }
else if(HY[f]==1){
am(f,1,P[n2],x[f],y[f],d,e,1,0,6,2,0);
  }
else if(HY[f]==2){
am(f,2,P[n3],x[f],y[f],d,e,1,0,6,3,0);
  }
else if(HY[f]==3){
am(f,3,P[n4],x[f],y[f],d,e,1,0,6,0,0);
  }
noTint();
}
 
void P2(int f, int n1, int n2, int da, int dl, int fr){//animación OV para tiles con 2 anim
if(HY[f]==0){
am(f,0,P[n1],x[f],y[f],da,dl,1,0,fr,1,0);
  }
else if(HY[f]==1){
am(f,1,P[n2],x[f],y[f],da,dl,1,0,fr,0,0);
  }
noTint();
}
 
void o(int n, int nim, int vx, int vy){println(y[0]+e,limitfall);
x[n]=d*vx;
y[n]=d*vy;
image(P[nim],x[n],y[n],d,d);
if(y[n]+d<y[0]&&x[0]+d>x[n]&&x[0]<x[n]+d){it[n]=true;}else{it[n]=false;}
//colisionador
if(it[n]==false){
if(izd[0]&&x[0]>x[n]&&x[0]<x[n]+d&&y[0]+d+f>y[n]&&y[0]<y[n]+d){x[0]=x[n]+d;}
if(dch[0]&&x[0]+d>x[n]&&x[0]<x[n]&&y[0]+d+f>y[n]&&y[0]<y[n]+d){x[0]=x[n]-d;}
if(x[0]+d>x[n]&&x[0]<x[n]+d){limitfall=y[n];if(salto==0){y[0]=limitfall-e;}}else{limitfall=480;y[0]=limitfall-e;}}
 
if(it[n]){
if(y[0]-18<=y[n]+d&&x[0]+d>x[n]&&x[0]<x[n]+d){if(salto>0){y[0]=y[n]+d-18;}}}
 
}

He marcado en negrita las dos zonas del script que creo que son las relevantes: el código para el salto y la función void o (que es la del bloque)

Intento decirle que al caer en la superficie del bloque, ese valor debe ser el nuevo límite para las caidas (cuando salte y caiga) y que si sale del margen del bloque en x, entonces (si no hay otro bloque) el límite será el vacío o el margen inferior de la pantalla vaya. Para eso utilizo la variable "limitfall". Con un bloque funciona, pero cuando pongo dos bloques solo funciona en el que está más abajo en el código, mientras que en el otro el personaje se intercala entre las dos posiciones intermitentemente.

Por otro lado cuando elevo el bloque para que haga de techo, y salto para comprobar que colisiona y se detiene a la altura del bloque, lo que hace es "hundir" al personaje hacia abajo un poco.

Y estos son mayormente los problemas, agradecería cualquier ayuda posible.
Si necesitais que os aclare algo en concreto podeis decírmelo por aquí y os comento.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder