Skip to content

Commit 37efb2e

Browse files
committed
Added push walls.
1 parent 45a37f0 commit 37efb2e

File tree

1 file changed

+118
-17
lines changed

1 file changed

+118
-17
lines changed

raycaster.cpp

Lines changed: 118 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,23 @@ int worldMap[mapWidth][mapHeight] =
5555
{
5656
{8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 6, 4, 4, 6, 4, 6, 4, 4, 4, 6, 4},
5757
{8, 0, 0, 0, 0, 0, 0, 0,12, 0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4},
58-
{8, 0, 3, 3, 0, 0, 0, 0, 8, 8, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
59-
{8, 0, 0, 3, 0, 0, 0, 0,10, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
60-
{8, 0, 3, 3, 0, 0, 0, 0, 8, 8, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4},
61-
{8, 0, 0, 0, 0, 0, 0, 0,11, 0, 8, 4, 0, 0, 0, 0, 0, 6, 6, 6, 0, 6, 4, 6},
58+
{8, 0, 3, 3, 0, 0, 0, 0, 8, 8, 8, 4, 0, 0, 0, 1, 1,14, 1, 1, 0, 0, 0, 6},
59+
{8, 0, 0, 3, 0, 0, 0, 0,10, 0,10, 0, 0, 0, 0,14, 0, 0, 0,14, 0, 0, 0, 6},
60+
{8, 0, 3, 3, 0, 0, 0, 0, 8, 8, 8, 4, 0, 0, 0, 1, 1, 0,14, 1, 0, 0, 0, 4},
61+
{8, 0, 0, 0, 0, 0, 0, 0,11, 0, 8, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 4, 6},
6262
{8, 8, 8, 8, 0, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 6, 0, 0, 0, 0, 0, 6},
6363
{7, 7, 7, 7, 9, 7, 7, 7, 7, 0, 8, 0, 8, 0, 8, 0, 8, 4, 0, 4, 0, 6, 0, 6},
6464
{7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 0, 8, 0, 8, 0, 8, 8, 6, 0, 0, 0, 0, 0, 6},
6565
{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 0, 0, 0, 0, 0, 4},
6666
{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 0, 6, 0, 6, 0, 6},
6767
{7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 0, 8, 0, 8, 0, 8, 8, 6, 4, 6,10, 6, 6, 6},
6868
{7, 7, 7, 7, 9, 7, 7, 7, 7, 8, 8, 4,12, 6, 8, 4, 8, 3, 3, 3, 0, 3, 3, 3},
69-
{2, 2, 2, 2, 0, 2, 2, 2, 2, 4, 6, 4, 0, 0, 6, 0, 6, 3, 0, 0, 0, 0, 0, 3},
70-
{2, 2, 0, 0, 0, 0, 0, 2, 2, 4, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 3},
71-
{2, 0, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 3},
72-
{1, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 4, 4, 6, 0, 6, 3, 3, 0, 0, 0, 3, 3},
73-
{2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 1, 2, 2, 2,12, 6, 0, 0, 5, 0, 5, 0, 5},
74-
{2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 0, 0, 0, 0, 5, 0, 0, 5, 5},
69+
{2, 2, 2, 2, 0, 2, 0, 0, 0, 4, 6, 4, 0, 0, 6, 0, 6, 3, 0, 0, 0, 0, 0, 3},
70+
{2, 2, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 3},
71+
{2, 0, 0, 0, 0, 2, 2, 0, 2, 4, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 3},
72+
{1, 0, 0, 0, 0, 1, 0, 0, 1, 4, 4, 4, 4, 4, 6, 0, 6, 3, 3, 0, 0, 0, 3, 3},
73+
{2, 0, 0, 0, 0, 2, 0, 0, 2, 2, 2, 1, 2, 2, 2,12, 6, 0, 0, 5, 0, 5, 0, 5},
74+
{2, 2, 0, 0, 0, 2,14, 2, 2, 2, 0, 0, 0, 2, 2, 0, 0, 0, 0, 5, 0, 0, 5, 5},
7575
{2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 5,12, 5,12, 5, 0, 5, 0, 5},
7676
{1,12, 2, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 5},
7777
{2, 0,11, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 5,12, 5,12, 5, 0, 5, 0, 5},
@@ -137,14 +137,24 @@ void sortSprites(int* order, double* dist, int amount);
137137

138138
#define MAX_DOORS 20
139139
enum DoorState {closed, opening, open, closing};
140+
enum Direction {dir_N, dir_S, dir_E, dir_W};
140141
struct Door {
141142
int x, y;
142143
int counter;
143144
DoorState state;
144145
} doors[MAX_DOORS];
145146
int numDoors = 0;
146147

147-
void processDoors() {
148+
#define MAX_PUSH_WALLS 20
149+
struct PushWall {
150+
int x, y;
151+
int counter;
152+
DoorState state;
153+
Direction direction;
154+
} pushWalls[MAX_PUSH_WALLS];
155+
int numPushWalls = 0;
156+
157+
void preProcessMap() {
148158
numDoors = 0;
149159
for(int x = 0; x < mapWidth; x++) {
150160
for(int y = 0; y < mapHeight; y++) {
@@ -158,6 +168,16 @@ void processDoors() {
158168
door->y = y;
159169
door->state = closed;
160170
door->counter = texWidth;
171+
} else if(worldMap[x][y] == 14) {
172+
if(numPushWalls == MAX_PUSH_WALLS) {
173+
std::cout << "Too many push walls!" << std::endl;
174+
return;
175+
}
176+
PushWall *pw = &pushWalls[numPushWalls++];
177+
pw->x = x;
178+
pw->y = y;
179+
pw->state = closed;
180+
pw->counter = texWidth;
161181
}
162182
}
163183
}
@@ -173,7 +193,28 @@ Door *findDoor(int x, int y) {
173193
return NULL;
174194
}
175195

176-
void updateDoors() {
196+
PushWall *findPushWall(int x, int y) {
197+
for(int i = 0; i < numPushWalls; i++) {
198+
PushWall *pw = &pushWalls[i];
199+
if(pw->x == x && pw->y == y) {
200+
return pw;
201+
}
202+
}
203+
return NULL;
204+
}
205+
206+
bool wallCanMove(PushWall *pw, Direction dir) {
207+
int nx, ny;
208+
switch(dir) {
209+
case dir_N : nx = pw->x; ny = pw->y-1; break;
210+
case dir_S : nx = pw->x; ny = pw->y+1; break;
211+
case dir_E : nx = pw->x+1; ny = pw->y; break;
212+
case dir_W : nx = pw->x-1; ny = pw->y; break;
213+
}
214+
return worldMap[nx][ny] == 0;
215+
}
216+
217+
void updateMap() {
177218
for(int i = 0; i < numDoors; i++) {
178219
Door *door = &doors[i];
179220
switch(door->state) {
@@ -190,6 +231,28 @@ void updateDoors() {
190231
default: break;
191232
}
192233
}
234+
for(int i = 0; i < numPushWalls; i++) {
235+
PushWall *pw = &pushWalls[i];
236+
if(pw->state == opening) {
237+
int mx, my;
238+
if(--pw->counter == 0) {
239+
switch(pw->direction) {
240+
case dir_N : mx = pw->x; my = pw->y-1; break;
241+
case dir_S : mx = pw->x; my = pw->y+1; break;
242+
case dir_E : mx = pw->x+1; my = pw->y; break;
243+
case dir_W : mx = pw->x-1; my = pw->y; break;
244+
}
245+
pw->counter = texWidth;
246+
worldMap[pw->x][pw->y] = 0;
247+
pw->x = mx;
248+
pw->y = my;
249+
worldMap[mx][my] = 14;
250+
251+
if(!wallCanMove(pw, pw->direction))
252+
pw->state = open;
253+
}
254+
}
255+
}
193256
}
194257

195258
#if FOG_LEVEL
@@ -435,7 +498,7 @@ int main(int /*argc*/, char */*argv*/[])
435498
double time = 0; //time of current frame
436499
double oldTime = 0; //time of previous frame
437500

438-
for(int i = 0; i < 11; i++) texture[i].resize(texWidth * texHeight);
501+
for(int i = 0; i < 13; i++) texture[i].resize(texWidth * texHeight);
439502

440503
#if SKYBOX
441504
std::vector<Uint32> skybox{320 * 240};
@@ -458,6 +521,7 @@ int main(int /*argc*/, char */*argv*/[])
458521
error |= loadImage(texture[10], tw, th, "pics/gate.png");
459522
error |= loadImage(texture[11], tw, th, "pics/glass.png");
460523
error |= loadImage(texture[12], tw, th, "pics/glass-break.png");
524+
error |= loadImage(texture[13], tw, th, "pics/secret.png");
461525
if(error) { std::cout << "error loading images" << std::endl; return 1; }
462526

463527
//load some sprite textures
@@ -471,7 +535,7 @@ int main(int /*argc*/, char */*argv*/[])
471535
#endif
472536

473537
double doorTime = 0;
474-
processDoors();
538+
preProcessMap();
475539

476540
//start the main loop
477541
while(!done())
@@ -640,6 +704,19 @@ int main(int /*argc*/, char */*argv*/[])
640704

641705
prepareSprites();
642706

707+
Direction playerDirection;
708+
if(abs(dirX) > abs(dirY)) {
709+
if(dirX > 0)
710+
playerDirection = dir_E;
711+
else
712+
playerDirection = dir_W;
713+
} else {
714+
if(dirY > 0)
715+
playerDirection = dir_S;
716+
else
717+
playerDirection = dir_N;
718+
}
719+
643720
// WALL CASTING
644721
std::stack<Strip> stack;
645722
for(int x = 0; x < w; x++)
@@ -716,6 +793,7 @@ int main(int /*argc*/, char */*argv*/[])
716793
int texNum = worldMap[mapX][mapY] - 1; //1 subtracted from it so that texture 0 can be used!
717794

718795
Door *door = NULL;
796+
PushWall *pw = NULL;
719797
if(texNum == 8 || texNum == 9 || texNum == 10 || texNum == 11 || texNum == 12) {
720798
/* Sunken wall encountered */
721799
if(texNum == 8)
@@ -735,6 +813,23 @@ int main(int /*argc*/, char */*argv*/[])
735813
}
736814
perpWallDist = dist;
737815
}
816+
} else if(texNum == 13 && (pw = findPushWall(mapX, mapY))) {
817+
/* Secret push wall encountered */
818+
if(side == 0) {
819+
double dist = sideDistX - deltaDistX * (double)pw->counter / texWidth;
820+
if(sideDistY < dist) {
821+
hit = 0;
822+
goto rayscan;
823+
}
824+
perpWallDist = dist;
825+
} else {
826+
double dist = sideDistY - deltaDistY * (double)pw->counter / texWidth;
827+
if(sideDistX < dist) {
828+
hit = 0;
829+
goto rayscan;
830+
}
831+
perpWallDist = dist;
832+
}
738833
} else {
739834
//Calculate distance of perpendicular ray (Euclidean distance would give fisheye effect!)
740835
if(side == 0) perpWallDist = (sideDistX - deltaDistX);
@@ -824,7 +919,7 @@ int main(int /*argc*/, char */*argv*/[])
824919

825920
doorTime += frameTime;
826921
if(doorTime > 1.0/texWidth) {
827-
updateDoors();
922+
updateMap();
828923
doorTime -= 1.0/texWidth;
829924
}
830925

@@ -877,8 +972,14 @@ int main(int /*argc*/, char */*argv*/[])
877972
case open: door->state = closing; break;
878973
default: break;
879974
}
880-
} else if(worldMap[faceX][faceY] == 12) {
881-
worldMap[faceX][faceY] = 13;
975+
} else {
976+
PushWall *pw = findPushWall(faceX, faceY);
977+
if(pw && pw->state == closed && wallCanMove(pw, playerDirection)) {
978+
pw->direction = playerDirection;
979+
pw->state = opening;
980+
} else if(worldMap[faceX][faceY] == 12) {
981+
worldMap[faceX][faceY] = 13;
982+
}
882983
}
883984
}
884985
if(keyDown(SDLK_q)) {

0 commit comments

Comments
 (0)