@@ -55,23 +55,23 @@ int worldMap[mapWidth][mapHeight] =
55
55
{
56
56
{8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 4 , 4 , 6 , 4 , 4 , 6 , 4 , 6 , 4 , 4 , 4 , 6 , 4 },
57
57
{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 },
62
62
{8 , 8 , 8 , 8 , 0 , 8 , 8 , 8 , 8 , 8 , 8 , 4 , 4 , 4 , 4 , 4 , 4 , 6 , 0 , 0 , 0 , 0 , 0 , 6 },
63
63
{7 , 7 , 7 , 7 , 9 , 7 , 7 , 7 , 7 , 0 , 8 , 0 , 8 , 0 , 8 , 0 , 8 , 4 , 0 , 4 , 0 , 6 , 0 , 6 },
64
64
{7 , 7 , 0 , 0 , 0 , 0 , 0 , 0 , 7 , 8 , 0 , 8 , 0 , 8 , 0 , 8 , 8 , 6 , 0 , 0 , 0 , 0 , 0 , 6 },
65
65
{7 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 8 , 6 , 0 , 0 , 0 , 0 , 0 , 4 },
66
66
{7 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 8 , 6 , 0 , 6 , 0 , 6 , 0 , 6 },
67
67
{7 , 7 , 0 , 0 , 0 , 0 , 0 , 0 , 7 , 8 , 0 , 8 , 0 , 8 , 0 , 8 , 8 , 6 , 4 , 6 ,10 , 6 , 6 , 6 },
68
68
{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 },
75
75
{2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 2 , 5 ,12 , 5 ,12 , 5 , 0 , 5 , 0 , 5 },
76
76
{1 ,12 , 2 , 0 , 0 , 0 , 0 , 0 , 9 , 0 , 0 , 0 , 0 , 0 ,10 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 5 },
77
77
{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);
137
137
138
138
#define MAX_DOORS 20
139
139
enum DoorState {closed, opening, open, closing};
140
+ enum Direction {dir_N, dir_S, dir_E, dir_W};
140
141
struct Door {
141
142
int x, y;
142
143
int counter;
143
144
DoorState state;
144
145
} doors[MAX_DOORS];
145
146
int numDoors = 0 ;
146
147
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 () {
148
158
numDoors = 0 ;
149
159
for (int x = 0 ; x < mapWidth; x++) {
150
160
for (int y = 0 ; y < mapHeight; y++) {
@@ -158,6 +168,16 @@ void processDoors() {
158
168
door->y = y;
159
169
door->state = closed;
160
170
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;
161
181
}
162
182
}
163
183
}
@@ -173,7 +193,28 @@ Door *findDoor(int x, int y) {
173
193
return NULL ;
174
194
}
175
195
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 () {
177
218
for (int i = 0 ; i < numDoors; i++) {
178
219
Door *door = &doors[i];
179
220
switch (door->state ) {
@@ -190,6 +231,28 @@ void updateDoors() {
190
231
default : break ;
191
232
}
192
233
}
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
+ }
193
256
}
194
257
195
258
#if FOG_LEVEL
@@ -435,7 +498,7 @@ int main(int /*argc*/, char */*argv*/[])
435
498
double time = 0 ; // time of current frame
436
499
double oldTime = 0 ; // time of previous frame
437
500
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);
439
502
440
503
#if SKYBOX
441
504
std::vector<Uint32> skybox{320 * 240 };
@@ -458,6 +521,7 @@ int main(int /*argc*/, char */*argv*/[])
458
521
error |= loadImage (texture[10 ], tw, th, " pics/gate.png" );
459
522
error |= loadImage (texture[11 ], tw, th, " pics/glass.png" );
460
523
error |= loadImage (texture[12 ], tw, th, " pics/glass-break.png" );
524
+ error |= loadImage (texture[13 ], tw, th, " pics/secret.png" );
461
525
if (error) { std::cout << " error loading images" << std::endl; return 1 ; }
462
526
463
527
// load some sprite textures
@@ -471,7 +535,7 @@ int main(int /*argc*/, char */*argv*/[])
471
535
#endif
472
536
473
537
double doorTime = 0 ;
474
- processDoors ();
538
+ preProcessMap ();
475
539
476
540
// start the main loop
477
541
while (!done ())
@@ -640,6 +704,19 @@ int main(int /*argc*/, char */*argv*/[])
640
704
641
705
prepareSprites ();
642
706
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
+
643
720
// WALL CASTING
644
721
std::stack<Strip> stack;
645
722
for (int x = 0 ; x < w; x++)
@@ -716,6 +793,7 @@ int main(int /*argc*/, char */*argv*/[])
716
793
int texNum = worldMap[mapX][mapY] - 1 ; // 1 subtracted from it so that texture 0 can be used!
717
794
718
795
Door *door = NULL ;
796
+ PushWall *pw = NULL ;
719
797
if (texNum == 8 || texNum == 9 || texNum == 10 || texNum == 11 || texNum == 12 ) {
720
798
/* Sunken wall encountered */
721
799
if (texNum == 8 )
@@ -735,6 +813,23 @@ int main(int /*argc*/, char */*argv*/[])
735
813
}
736
814
perpWallDist = dist;
737
815
}
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
+ }
738
833
} else {
739
834
// Calculate distance of perpendicular ray (Euclidean distance would give fisheye effect!)
740
835
if (side == 0 ) perpWallDist = (sideDistX - deltaDistX);
@@ -824,7 +919,7 @@ int main(int /*argc*/, char */*argv*/[])
824
919
825
920
doorTime += frameTime;
826
921
if (doorTime > 1.0 /texWidth) {
827
- updateDoors ();
922
+ updateMap ();
828
923
doorTime -= 1.0 /texWidth;
829
924
}
830
925
@@ -877,8 +972,14 @@ int main(int /*argc*/, char */*argv*/[])
877
972
case open: door->state = closing; break ;
878
973
default : break ;
879
974
}
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
+ }
882
983
}
883
984
}
884
985
if (keyDown (SDLK_q)) {
0 commit comments