Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | daniel-mar | 1 | rem Nightmare Forest |
2 | rem by Daniel Marschall |
||
3 | |||
4 | rem TODO |
||
5 | rem - wasser sounds |
||
6 | rem - schwimmen |
||
7 | rem - im wasser langsamer |
||
8 | rem - menü am anfang und pause |
||
9 | rem - bluteffekt |
||
10 | rem - rascheln im busch |
||
11 | rem - baum kollission |
||
12 | rem - die gegner kommen erst nach einer bestimmten zeit. spawnen weit weg vom spieler |
||
13 | |||
14 | rem NICE TO HAVE |
||
15 | rem - radar breitbild |
||
16 | rem - wassermatrix bewegt sich nur in 1 richtung |
||
17 | rem - mausumkehrung einstellbar |
||
18 | rem - stars.bmp (5000px) braucht lange zum laden. 1000px ist verpixelt |
||
19 | |||
20 | rem ToDo: |
||
21 | rem Steifen am Boden |
||
22 | rem Radar wackelt |
||
23 | rem :startgame weglassen |
||
24 | rem Streifen am Boden und am Himmel... |
||
25 | rem Baum teiltransparenz |
||
26 | rem Radar lieber als Matrix. Viele Probleme wie z.B. mit Skorpion transparenz |
||
27 | rem Unscharfes Radar, Radar ganz dyn. zeichnen? Rader stay on top |
||
28 | rem Menü: musik aus --> an: loop von position 0! |
||
29 | |||
30 | // Read configuration |
||
31 | open to read 1, "config.txt" |
||
32 | read string 1, dummy$ : rem header |
||
33 | framerate = fileReadInt(1) |
||
34 | clockSpeedFactor = fileReadInt(1) |
||
35 | clockBlinksPerSecond = fileReadInt(1) |
||
36 | clockShowSeconds = fileReadInt(1) |
||
37 | beginClockSeconds = fileReadInt(1) |
||
38 | enemyRotateSmoothness = fileReadInt(1) |
||
39 | maxRunEnergy = fileReadInt(1) |
||
40 | waterLevel = fileReadInt(1) |
||
41 | waterMovement = fileReadInt(1) |
||
42 | sound3dVolumeCor = fileReadInt(1) |
||
43 | invertMouse = fileReadInt(1) |
||
44 | test = fileReadInt(1) |
||
45 | camerarange = fileReadInt(1) |
||
46 | fogdistance = fileReadInt(1) |
||
47 | close file 1 |
||
48 | |||
49 | rem SCHEISSE! bei 3000 ist die framerate total am arsch! was mach ich nur? |
||
50 | rem #constant cMaxTrees 3000 |
||
51 | #constant cMaxTrees 200 |
||
52 | |||
53 | #constant cMapSizeX 10000 |
||
54 | #constant cMapSizeZ 10000 |
||
55 | |||
56 | #constant idxMonsterBase 1000 |
||
57 | #constant idxTreeBase 1500 |
||
58 | |||
59 | #constant cMaxEnemies 20 : rem todo: 0 heißt 1 , das ist verwirrend |
||
60 | |||
61 | rem Setup & Startbildschirm |
||
62 | if check display mode( desktop width(), desktop height(), screen depth() ) then set display mode desktop width(), desktop height(), screen depth() |
||
63 | hide mouse |
||
64 | |||
65 | randomize timer() |
||
66 | |||
67 | Sync On |
||
68 | Sync Rate framerate |
||
69 | |||
70 | load bitmap "bitmap\titlescreen.jpg" |
||
71 | |||
72 | gosub _menu |
||
73 | |||
74 | _startgame: |
||
75 | |||
76 | ink rgb(255, 230, 0), 0 |
||
77 | load bitmap "bitmap\titlescreen.jpg" |
||
78 | text 28, 550, "Starting game..." |
||
79 | |||
80 | sync |
||
81 | |||
82 | rem Setup |
||
83 | Set camera range 1, camerarange |
||
84 | Autocam off |
||
85 | |||
86 | runEnergy# = maxRunEnergy |
||
87 | clockSeconds = beginClockSeconds |
||
88 | |||
89 | gosub _create_floor |
||
90 | gosub _create_sky |
||
91 | gosub _create_trees |
||
92 | gosub _draw_trees |
||
93 | gosub _create_water |
||
94 | gosub _create_radar |
||
95 | |||
96 | rem Bildschirm neu aufbauen |
||
97 | cls |
||
98 | sync |
||
99 | |||
100 | rem Lichtversuch |
||
101 | make light 1 |
||
102 | |||
103 | rem Radar vorbereiten |
||
104 | radarpointcolor = 150 |
||
105 | |||
106 | gosub _create_enemies |
||
107 | gosub _setupClock |
||
108 | |||
109 | Rem Forest atmo |
||
110 | load sound "sound\forestbg.wav", 1 |
||
111 | loop sound 1 |
||
112 | |||
113 | load sound "music\pause.wav", 5 |
||
114 | |||
115 | load sound "sound\walk.wav", 10 |
||
116 | |||
117 | rem Pause Menu |
||
118 | load image "bitmap\titlescreen.jpg",95 |
||
119 | sprite 95,0,0,95 |
||
120 | set sprite 95, 1, 0 |
||
121 | hide sprite 95 |
||
122 | |||
123 | rem Hauptschleife |
||
124 | do |
||
125 | Disable EscapeKey |
||
126 | gosub _handle_weather |
||
127 | gosub _handle_player |
||
128 | gosub _handle_radar |
||
129 | gosub _handle_enemies |
||
130 | gosub _handleClock |
||
131 | if EscapeKey() = 1 |
||
132 | repeat |
||
133 | sync |
||
134 | until not (EscapeKey() = 1) |
||
135 | gosub _pausemenu |
||
136 | endif |
||
137 | sceneInitialized=1 |
||
138 | sync |
||
139 | loop |
||
140 | |||
141 | _pausemenu: |
||
142 | rem TODO: geht nicht |
||
143 | rem show sprite 95 |
||
144 | rem load bitmap "bitmap\titlescreen.jpg",0 |
||
145 | gosub _stop_game_sounds |
||
146 | loop sound 5 |
||
147 | repeat |
||
148 | text 28, 550, "Pause. ESC=Weiter. Runter=Ende." |
||
149 | sync |
||
150 | |||
151 | if DownKey() = 1 |
||
152 | goto _exit |
||
153 | ENDIF |
||
154 | UNTIL EscapeKey() = 1 |
||
155 | repeat |
||
156 | sync |
||
157 | until not (EscapeKey() = 1) |
||
158 | stop sound 5 |
||
159 | loop sound 1 |
||
160 | hide sprite 95 |
||
161 | |||
162 | rem TODO: das bringt nix. wenn man die maus bewegt, wird nach der pause die kamera gescrollt |
||
163 | set cursor 0, 0 |
||
164 | return |
||
165 | |||
166 | _handle_weather: |
||
167 | rem Wetter |
||
168 | |||
169 | color ambient light rgb(64,64,128) |
||
170 | rem set ambient light 1 |
||
171 | set ambient light 50 |
||
172 | if fog available() = 1 |
||
173 | fog on |
||
174 | fog distance fogdistance |
||
175 | fog color rgb(0, 0, 0) |
||
176 | endif |
||
177 | |||
178 | |||
179 | if test = 1 |
||
180 | SET MATRIX WIREFRAME ON 1 |
||
181 | SET MATRIX WIREFRAME ON 3 |
||
182 | endif |
||
183 | |||
184 | |||
185 | |||
186 | rem Stars are moving |
||
187 | scroll object texture 2, 0.00002, 0 |
||
188 | |||
189 | |||
190 | |||
191 | scroll object texture 3, 0.00004, 0 |
||
192 | |||
193 | return |
||
194 | |||
195 | _handle_enemies: |
||
196 | pX# = Camera Position X() |
||
197 | pZ# = Camera Position Z() |
||
198 | |||
199 | for t = 0 to cMaxEnemies |
||
200 | eX# = Object Position X(idxMonsterBase+t) |
||
201 | eY# = Object Position Y(idxMonsterBase+t) |
||
202 | eZ# = Object Position Z(idxMonsterBase+t) |
||
203 | |||
204 | eRX# = Object Angle X(idxMonsterBase+t) |
||
205 | eRY# = Object Angle Y(idxMonsterBase+t) |
||
206 | eRZ# = Object Angle Z(idxMonsterBase+t) |
||
207 | |||
208 | deltaX# = pX#-eX# |
||
209 | deltaZ# = pZ#-eZ# |
||
210 | |||
211 | rem TODO: cor file |
||
212 | yPosOffset# = 20 |
||
213 | |||
214 | dist# = sqrt( deltaX#*deltaX# + deltaZ#*deltaZ# ) |
||
215 | |||
216 | if clockSeconds > 1 |
||
217 | if not sound playing(idxMonsterBase+t) |
||
218 | set sound volume idxMonsterBase+t, 0 |
||
219 | |||
220 | rem TODO: beliebiges startoffset? |
||
221 | loop sound idxMonsterBase+t |
||
222 | endif |
||
223 | endif |
||
224 | |||
225 | rem The mixing of 3dsound is bullshit (too loud from far distance, and not very loud on close distance), |
||
226 | rem so we mix the volume ourself |
||
227 | if sound3dVolumeCor>0 and dist#<sound3dVolumeCor then set sound volume idxMonsterBase+t, (1-(dist#/sound3dVolumeCor))*100 |
||
228 | |||
229 | if dist# > 10 : rem <-- at least a distance of 10 so that atanfull() does not bug, when deltas becomes 0 |
||
230 | if dist# < enemyAwarenessRadius(t) |
||
231 | enemyAngle(t) = atanfull(deltaX#, deltaZ#) |
||
232 | enemyAngle(t) = WrapValue(enemyAngle(t)+180) |
||
233 | enemyCurSpeed(t) = enemyMaxSpeed(t) |
||
234 | else |
||
235 | if enemyWalkTimeout(t) <= 0 |
||
236 | enemyWalkTimeout(t) = RndBetween(enemyWalkTimeoutMin(t), enemyWalkTimeoutMax(t)) |
||
237 | enemyAngle(t) = RndBetween(0,359) |
||
238 | enemyCurSpeed(t) = RndBetween(0, enemyMaxSpeed(t)) |
||
239 | ENDIF |
||
240 | enemyWalkTimeout(t) = enemyWalkTimeout(t) - 1 |
||
241 | endif |
||
242 | |||
243 | if enemyCurSpeed(t) = 0 |
||
244 | gosub scorpChangeToIdle |
||
245 | else |
||
246 | gosub scorpChangeToWalk |
||
247 | rem TODO: also make animation slower/faster |
||
248 | endif |
||
249 | |||
250 | a# = WrapValue(enemyAngle(t) + 180) |
||
251 | XTest# = Newxvalue(eX#, a#, enemyCurSpeed(t)) |
||
252 | ZTest# = Newzvalue(eZ#, a#, enemyCurSpeed(t)) |
||
253 | if XTest# > 0 and XTest# < cMapSizeX then eX# = XTest# |
||
254 | if ZTest# > 0 and ZTest# < cMapSizeZ then eZ# = ZTest# |
||
255 | if XTest# <= 0 or XTest# >= cMapSizeX or ZTest# <= 0 or ZTest# >= cMapSizeZ |
||
256 | rem Kehrtwende, um den Kartenrand zu verlassen |
||
257 | enemyAngle(t) = WrapValue(enemyAngle(t)+180) |
||
258 | enemyWalkTimeout(t) = RndBetween(enemyWalkTimeoutMin(t), enemyWalkTimeoutMax(t)) |
||
259 | enemyCurSpeed(t) = RndBetween(0, enemyMaxSpeed(t)) |
||
260 | endif |
||
261 | |||
262 | eY# = floorHeight#(eX#, eZ#) + yPosOffset# |
||
263 | Position Object idxMonsterBase+t, eX#, eY#, eZ# |
||
264 | Position Sound idxMonsterBase+t, eX#, eY#, eZ# |
||
265 | |||
266 | eRY# = smoothRotate#(eRY#, enemyAngle(t), enemyRotateSmoothness) |
||
267 | rotate object idxMonsterBase+t, eRX#, eRY#, eRZ# |
||
268 | endif |
||
269 | next |
||
270 | return |
||
271 | |||
272 | _handle_player: |
||
273 | set cursor 0, 0 |
||
274 | oldcAY# = cAY# |
||
275 | oldcAX# = cAX# |
||
276 | |||
277 | X# = camera position x() |
||
278 | Y# = camera position y() |
||
279 | Z# = camera position z() |
||
280 | |||
281 | if invertMouse = 1 |
||
282 | cAX# = WrapValue(cAX# - MousemoveY() * 0.2) |
||
283 | else |
||
284 | cAX# = WrapValue(cAX# + MousemoveY() * 0.2) |
||
285 | endif |
||
286 | cAY# = WrapValue(cAY# + MousemoveX() * 0.2) |
||
287 | cAZ# = Camera angle Z() |
||
288 | |||
289 | rem Sprungroutine |
||
290 | jumpBoost = 1 |
||
291 | if sprungdelay > 0 then dec sprungdelay |
||
292 | if MouseClick() = 2 and sprung = 0 and sprungrev = 0 and sprungdelay = 0 and obentimer = 0 then sprung = sprung + 5 |
||
293 | if sprung > 0 |
||
294 | if sprungrev = 0 |
||
295 | if obentimer = 0 |
||
296 | if sprung < 70 then sprung = sprung + 5 |
||
297 | if sprung > 69 then sprung = sprung + 2 |
||
298 | endif |
||
299 | if sprung > 79 and obentimer < 5 then obentimer = obentimer + 1 |
||
300 | if obentimer > 2 |
||
301 | obentimer = 0 |
||
302 | sprungrev = 1 |
||
303 | endif |
||
304 | else |
||
305 | if sprungrev = 1 |
||
306 | sprung = sprung - 5 |
||
307 | if sprung < 1 |
||
308 | sprungrev = 0 |
||
309 | sprung = 0 |
||
310 | sprungdelay = 15 |
||
311 | endif |
||
312 | endif |
||
313 | endif |
||
314 | endif |
||
315 | |||
316 | rem Laufen |
||
317 | speedboost# = 1 |
||
318 | |||
319 | if upPressed()+downPressed()+leftPressed()+rightPressed() = 0 |
||
320 | runEnergy# = runEnergy# + 2 |
||
321 | stop sound 10 |
||
322 | else |
||
323 | if not sound playing(10) then loop sound 10 |
||
324 | energyChanged = 0 |
||
325 | if ShiftKey()+ControlKey() = 1 : rem shift+control at the same time = walk normal |
||
326 | rem TODO: es ruckelt trotzdem noch |
||
327 | if ControlKey()=1 and runEnergy#>0 : rem Energy >1 , damit es nicht ruckelt (run-walk-run-walk-run-walk) . 3 = walk regain |
||
328 | speedboost# = 2 |
||
329 | runEnergy# = runEnergy# - 1 |
||
330 | energyChanged = 1 |
||
331 | endif |
||
332 | if ShiftKey()=1 |
||
333 | speedboost# = 0.5 |
||
334 | runEnergy# = runEnergy# + 0.5 |
||
335 | energyChanged = 1 |
||
336 | endif |
||
337 | endif |
||
338 | if not energyChanged then runEnergy# = runEnergy# + 1 |
||
339 | if upPressed() |
||
340 | XTest# = Newxvalue(X#, cAY#, 7*speedboost#) |
||
341 | ZTest# = Newzvalue(Z#, cAY#, 7*speedboost#) |
||
342 | if XTest# > 0 and XTest# < cMapSizeX then X# = XTest# |
||
343 | if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest# |
||
344 | endif |
||
345 | if downPressed() |
||
346 | XTest# = Newxvalue(X#, Wrapvalue(cAY# - 180), 5*(speedboost#/2)) |
||
347 | ZTest# = Newzvalue(Z#, Wrapvalue(cAY# - 180), 5*(speedboost#/2)) |
||
348 | if XTest# > 0 and XTest# < cMapSizeX then X# = XTest# |
||
349 | if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest# |
||
350 | endif |
||
351 | if leftPressed() |
||
352 | XTest# = Newxvalue(X#, Wrapvalue(cAY# - 90), 5*(speedboost#/1.3)) |
||
353 | ZTest# = Newzvalue(Z#, Wrapvalue(cAY# - 90), 5*(speedboost#/1.3)) |
||
354 | if XTest# > 0 and XTest# < cMapSizeX then X# = XTest# |
||
355 | if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest# |
||
356 | endif |
||
357 | if rightPressed() |
||
358 | XTest# = Newxvalue(X#, Wrapvalue(cAY# + 90), 5*(speedboost#/1.3)) |
||
359 | ZTest# = Newzvalue(Z#, Wrapvalue(cAY# + 90), 5*(speedboost#/1.3)) |
||
360 | if XTest# > 0 and XTest# < cMapSizeX then X# = XTest# |
||
361 | if ZTest# > 0 and ZTest# < cMapSizeZ then Z# = ZTest# |
||
362 | endif |
||
363 | endif |
||
364 | if runEnergy# > maxRunEnergy then runEnergy# = maxRunEnergy |
||
365 | print "Run energy: ", runEnergy# |
||
366 | |||
367 | Rem Rotate camera |
||
368 | cTestX# = WrapValue(cAX# - 180) |
||
369 | if cTestX# > 225 then cAX# = 45 |
||
370 | if cTestX# < 135 then cAX# = 315 |
||
371 | YRotate camera CurveAngle(cAY#, oldcAY#, 24) |
||
372 | XRotate camera CurveAngle(cAX#, oldcAX#, 24) |
||
373 | |||
374 | Rem Position Camera |
||
375 | Y# = floorHeight#(X#, Z#) + 85 + sprung*jumpBoost |
||
376 | Position Camera X#, Y#, Z# |
||
377 | |||
378 | Rem Position Listener |
||
379 | Position Listener X#, Y#, Z# |
||
380 | Rotate Listener 0, cAY#, 0 |
||
381 | |||
382 | rem Sky sphere follows player |
||
383 | position object 2, X#, Y#, Z# |
||
384 | |||
385 | rem zrotate object 51, cAY# |
||
386 | |||
387 | |||
388 | |||
389 | |||
390 | if (ceil(X#) mod 10 = 0) or (ceil(Z#) mod 10 = 0) or (sceneInitialized=0) |
||
391 | for t = 0 to cMaxTrees |
||
392 | rx = baumx(t) |
||
393 | rz = baumz(t) |
||
394 | incircle = IsInCircle(rx, rz, X#, Z#, camerarange) |
||
395 | rem incircle = IsInCircle(rx, rz, X#, Z#, fogdistance) |
||
396 | if incircle <> baumdrawn(t) |
||
397 | if incircle = 1 |
||
398 | if object exist(idxTreeBase+t) |
||
399 | show object idxTreeBase+t |
||
400 | else |
||
401 | make object idxTreeBase+t, 52, 4 |
||
402 | position object idxTreeBase+t, rx, floorHeight#(rx, rz)+190, rz |
||
403 | set object idxTreeBase+t, 1, 1, 0 |
||
404 | endif |
||
405 | else |
||
406 | delete object idxTreeBase+t |
||
407 | rem hide object idxTreeBase+t |
||
408 | endif |
||
409 | ENDIF |
||
410 | baumdrawn(t) = incircle |
||
411 | next t |
||
412 | endif |
||
413 | |||
414 | |||
415 | |||
416 | |||
417 | return |
||
418 | |||
419 | _fademenu: |
||
420 | if fade > 100 then fadedir = 0 |
||
421 | if fade < 50 then fadedir = 1 |
||
422 | if fadedir = 1 |
||
423 | fade = fade + 2.5 |
||
424 | else |
||
425 | fade = fade - 2.5 |
||
426 | endif |
||
427 | rem Beleuchtet |
||
428 | ink rgb(255, fade, 0), 0 |
||
429 | set text font "Tahoma" |
||
430 | set text size 26 |
||
431 | if menu = 1 |
||
432 | if pos = 1 then text 260, 255, "Neues Spiel starten" |
||
433 | if pos = 2 then text 260, 285, "Spiel laden" |
||
434 | if pos = 3 then text 260, 315, "Einstellungen" |
||
435 | if pos = 4 then text 260, 345, "Spiel beenden" |
||
436 | endif |
||
437 | if menu = 3 |
||
438 | if pos = 1 |
||
439 | if sound = 1 then text 260, 255, "Ton: An" |
||
440 | if sound = 0 then text 260, 255, "Ton: Aus" |
||
441 | endif |
||
442 | if pos = 2 |
||
443 | if music = 1 then text 260, 285, "Musik: An" |
||
444 | if music = 0 then text 260, 285, "Musik: Aus" |
||
445 | endif |
||
446 | if pos = 3 then text 260, 315, "Hauptmenü" |
||
447 | endif |
||
448 | rem Normal |
||
449 | ink rgb(255, 230, 0), 0 |
||
450 | if menu = 1 |
||
451 | if pos <> 1 then text 260, 255, "Neues Spiel starten" |
||
452 | if pos <> 2 then text 260, 285, "Spiel laden" |
||
453 | if pos <> 3 then text 260, 315, "Einstellungen" |
||
454 | if pos <> 4 then text 260, 345, "Spiel beenden" |
||
455 | endif |
||
456 | if menu = 3 |
||
457 | if pos <> 1 |
||
458 | if sound = 1 then text 260, 255, "Ton: An" |
||
459 | if sound = 0 then text 260, 255, "Ton: Aus" |
||
460 | endif |
||
461 | if pos <> 2 |
||
462 | if music = 1 then text 260, 285, "Musik: An" |
||
463 | if music = 0 then text 260, 285, "Musik: Aus" |
||
464 | endif |
||
465 | if pos <> 3 then text 260, 315, "Hauptmenü" |
||
466 | endif |
||
467 | sync |
||
468 | return |
||
469 | |||
470 | _handle_radar: |
||
471 | rem Leuchtpunkt |
||
472 | if radarpointrev = 0 |
||
473 | inc radarpointcolor, 3 |
||
474 | else |
||
475 | dec radarpointcolor, 3 |
||
476 | endif |
||
477 | if radarpointcolor > 255 |
||
478 | radarpointrev = 1 |
||
479 | radarpointcolor = 254 |
||
480 | endif |
||
481 | if radarpointcolor < 150 |
||
482 | radarpointrev = 0 |
||
483 | radarpointcolor = 149 |
||
484 | endif |
||
485 | rem Bäume |
||
486 | for t = 0 to cMaxTrees |
||
487 | x = (baumx(t) / 62.5) + 7.5 |
||
488 | y = screen height() - 7.5 - (baumz(t) / 62.5) |
||
489 | if baumdrawn(t) |
||
490 | rem ink rgb(0, radarpointcolor, 0), 0 |
||
491 | ink rgb(0, 50, 0), 0 |
||
492 | circle x, y, 1 |
||
493 | circle x, y, 0 |
||
494 | endif |
||
495 | next i |
||
496 | rem Player |
||
497 | x = (X# / 62.5) + 7.5 |
||
498 | y = screen height() - 7.5 - (Z# / 62.5) |
||
499 | ink rgb(0, 0, radarpointcolor), 0 |
||
500 | circle x, y, 1 |
||
501 | circle x, y, 0 |
||
502 | rem Enemies |
||
503 | for t = 0 to cMaxEnemies |
||
504 | x = (object position x(idxMonsterBase+t) / 62.5) + 7.5 |
||
505 | y = screen height() - 7.5 - (object position z(idxMonsterBase+t) / 62.5) |
||
506 | ink rgb(radarpointcolor, 0, 0), 0 |
||
507 | circle x, y, 1 |
||
508 | circle x, y, 0 |
||
509 | next |
||
510 | return |
||
511 | |||
512 | _draw_trees: |
||
513 | rem TODO: da ist ein baum an offset 0,0,0 |
||
514 | load image "bitmap\tree.bmp", 4 |
||
515 | make object plain 52, 200, 400 |
||
516 | make mesh from object 52, 52 |
||
517 | add limb 52, 1, 52 |
||
518 | rotate limb 52, 1, 0, 90, 0 |
||
519 | make mesh from object 52, 52 |
||
520 | delete object 52 |
||
521 | |||
522 | for t = 0 to cMaxTrees |
||
523 | rx = baumx(t) |
||
524 | rz = baumz(t) |
||
525 | next t |
||
526 | return |
||
527 | |||
528 | _create_trees: |
||
529 | dim baumx(cMaxTrees) |
||
530 | dim baumz(cMaxTrees) |
||
531 | dim baumdrawn(cMaxTrees) |
||
532 | for t = 0 to cMaxTrees |
||
533 | repeat |
||
534 | x = rnd(cMapSizeX) |
||
535 | z = rnd(cMapSizeZ) |
||
536 | ok = 1 |
||
537 | if isInCircle(x,z,5000,5000,2000) then ok=0 : rem TODO: später für büschel anwenden |
||
538 | until ok=1 |
||
539 | baumx(t) = x |
||
540 | baumz(t) = z |
||
541 | baumdrawn(t) = 0 |
||
542 | NEXT |
||
543 | return |
||
544 | |||
545 | _menu: |
||
546 | load bitmap "bitmap\titlescreen.jpg" |
||
547 | set text font "times" |
||
548 | set text size 27 |
||
549 | fade = 100 |
||
550 | pos = 1 |
||
551 | menu = 1 |
||
552 | sound = 1 |
||
553 | do |
||
554 | gosub _fademenu |
||
555 | if ( downkey() = 1 and pos < 4 and menu = 1 ) or ( downkey() = 1 and pos < 3 and menu = 3 ) |
||
556 | inc pos |
||
557 | while downkey() = 1 |
||
558 | gosub _fademenu |
||
559 | endwhile |
||
560 | endif |
||
561 | if upkey() = 1 and pos > 1 |
||
562 | dec pos |
||
563 | while upkey() = 1 |
||
564 | gosub _fademenu |
||
565 | endwhile |
||
566 | endif |
||
567 | if returnkey() = 1 |
||
568 | if menu = 1 |
||
569 | if pos = 1 then gosub _startgame |
||
570 | if pos = 2 |
||
571 | rem load bitmap "bitmap\titlescreen.jpg" |
||
572 | rem menu = 2 |
||
573 | rem pos = 1 |
||
574 | endif |
||
575 | if pos = 3 |
||
576 | load bitmap "bitmap\titlescreen.jpg" |
||
577 | menu = 3 |
||
578 | pos = 1 |
||
579 | endif |
||
580 | if pos = 4 then end |
||
581 | else |
||
582 | if menu = 3 |
||
583 | if pos = 1 |
||
584 | if sound = 1 |
||
585 | sound = 0 |
||
586 | else |
||
587 | sound = 1 |
||
588 | endif |
||
589 | load bitmap "bitmap\titlescreen.jpg" |
||
590 | endif |
||
591 | if pos = 2 |
||
592 | if music = 1 |
||
593 | music = 0 |
||
594 | else |
||
595 | music = 1 |
||
596 | endif |
||
597 | load bitmap "bitmap\titlescreen.jpg" |
||
598 | endif |
||
599 | if pos = 3 |
||
600 | load bitmap "bitmap\titlescreen.jpg" |
||
601 | menu = 1 |
||
602 | pos = 1 |
||
603 | endif |
||
604 | endif |
||
605 | endif |
||
606 | while returnkey() = 1 |
||
607 | gosub _fademenu |
||
608 | endwhile |
||
609 | endif |
||
610 | loop |
||
611 | return |
||
612 | |||
613 | _create_enemies: |
||
614 | dim enemySpeed(cMaxEnemies) |
||
615 | dim enemyDir(cMaxEnemies) |
||
616 | dim enemyWalkTimeout(cMaxEnemies) |
||
617 | dim enemyWalkTimeoutMin(cMaxEnemies) |
||
618 | dim enemyWalkTimeoutMax(cMaxEnemies) |
||
619 | dim enemyAwarenessRadius(cMaxEnemies) |
||
620 | dim enemyCurSpeed(cMaxEnemies) |
||
621 | dim enemyMaxSpeed(cMaxEnemies) |
||
622 | dim enemyAngle(cMaxEnemies) |
||
623 | dim enemyCurrentAnim(cMaxEnemies) |
||
624 | for t = 0 to cMaxEnemies |
||
625 | if t=0 |
||
626 | Load 3Dsound "test.wav",idxMonsterBase+t |
||
627 | else |
||
628 | Clone Sound idxMonsterBase+t, idxMonsterBase |
||
629 | endif |
||
630 | |||
631 | x# = RndBetween(1000, 9000) |
||
632 | z# = RndBetween(1000, 9000) |
||
633 | enemyAwarenessRadius(t) = RndBetween(600, 1300) |
||
634 | enemyMaxSpeed(t) = RndBetween(1, 4) |
||
635 | enemyWalkTimeoutMin(t) = 200 |
||
636 | enemyWalkTimeoutMax(t) = 300 |
||
637 | |||
638 | if t = 0 |
||
639 | animScorpIdleStart = 0 |
||
640 | Load object "obj\scorpion\ScorpIdle.x", idxMonsterBase+t |
||
641 | animScorpIdleEnd = total object frames(idxMonsterBase+t) |
||
642 | |||
643 | animScorpWalkStart = animScorpIdleEnd+1 |
||
644 | Append object "obj\scorpion\ScorpWalk.x", idxMonsterBase+t, animScorpWalkStart |
||
645 | animScorpWalkEnd = total object frames(idxMonsterBase+t) |
||
646 | else |
||
647 | Clone Object idxMonsterBase+t, idxMonsterBase |
||
648 | endif |
||
649 | |||
650 | y# = floorHeight#(x#, z#) : rem TODO + yPosOffset# |
||
651 | position object idxMonsterBase+t, x#, y#, z# |
||
652 | Position Sound idxMonsterBase+t, x#, y#, z# |
||
653 | |||
654 | fix object pivot idxMonsterBase+t |
||
655 | gosub scorpChangeToWalk |
||
656 | set object collision on idxMonsterBase+t |
||
657 | NEXT |
||
658 | return |
||
659 | |||
660 | scorpChangeToIdle: |
||
661 | rem TODO: smoothness (interpolation) |
||
662 | if enemyCurrentAnim(t) <> 1 |
||
663 | loop object idxMonsterBase+t, animScorpIdleStart, animScorpIdleEnd |
||
664 | enemyCurrentAnim(t) = 1 |
||
665 | endif |
||
666 | return |
||
667 | |||
668 | scorpChangeToWalk: |
||
669 | rem TODO: smoothness (interpolation) |
||
670 | if enemyCurrentAnim(t) <> 2 |
||
671 | loop object idxMonsterBase+t, animScorpWalkStart, animScorpWalkEnd |
||
672 | enemyCurrentAnim(t) = 2 |
||
673 | endif |
||
674 | return |
||
675 | |||
676 | _setupClock: |
||
677 | set text font "arial" : set text size 30 : set text transparent |
||
678 | |||
679 | // Session variables |
||
680 | clockTickCounter=0 |
||
681 | clockCurrentMidDot=0 |
||
682 | clockTicksPerSecond = framerate |
||
683 | return |
||
684 | |||
685 | _handleClock: |
||
686 | if mod(clockTickCounter*clockBlinksPerSecond, clockTicksPerSecond) = 0 |
||
687 | clockCurrentMidDot = 1 - clockCurrentMidDot |
||
688 | endif |
||
689 | |||
690 | if mod(clockTickCounter*clockSpeedFactor, clockTicksPerSecond) = 0 |
||
691 | clockSeconds = clockSeconds + 1 |
||
692 | endif |
||
693 | |||
694 | gosub _printClock |
||
695 | |||
696 | clockTickCounter = clockTickCounter + 1 |
||
697 | RETURN |
||
698 | |||
699 | _create_water: |
||
700 | rem funktioniert nicht mit fog zusammen. Wasser wird je nach Blickwinkel unsichtbar |
||
701 | make object plain 3, cMapSizeX, cMapSizeZ |
||
702 | load image "bitmap\water.bmp",3 |
||
703 | texture object 3, 3 |
||
704 | xrotate object 3, 90 |
||
705 | position object 3, cMapSizeX/2, waterLevel, cMapSizeZ/2 |
||
706 | ghost object on 3 |
||
707 | |||
708 | return |
||
709 | |||
710 | _create_floor: |
||
711 | rem Boden |
||
712 | make matrix 1, cMapSizeX, cMapSizeZ, 15, 15 |
||
713 | |||
714 | load image "bitmap\forest_floor_texture.jpg", 1 |
||
715 | prepare matrix texture 1, 1, 1, 1 |
||
716 | fill matrix 1, 0, 1 |
||
717 | set matrix 1, 0, 0, 1, 1, 1, 1, 1 |
||
718 | randomize matrix 1, 130 |
||
719 | |||
720 | rem TEST |
||
721 | rem TODO: aber man kann 40,40 nicht updaten?! |
||
722 | set matrix height 1, 10, 10, 1000 |
||
723 | |||
724 | update matrix 1 |
||
725 | |||
726 | remstart |
||
727 | currentmatrix=1 |
||
728 | for z=1 to 20 |
||
729 | for x=1 to 20 |
||
730 | |||
731 | rem Get matrix heights |
||
732 | rem print x, " - ", z |
||
733 | rem sync |
||
734 | rem sleep 100 |
||
735 | |||
736 | h8#=get matrix height(currentmatrix,x,z-1) |
||
737 | h4#=get matrix height(currentmatrix,x-1,z) |
||
738 | h#=get matrix height(currentmatrix,x,z) |
||
739 | h2#=get matrix height(currentmatrix,x,z) |
||
740 | |||
741 | rem Calculate projected angle X using heights |
||
742 | x1#=(x-1)*25.0 : y1#=h# |
||
743 | x2#=(x+0)*25.0 : y2#=h4# |
||
744 | dx#=x2#-x1# |
||
745 | dy#=y2#-y1# |
||
746 | ax#=atanfull(dx#,dy#) |
||
747 | ax#=wrapvalue(90-ax#) |
||
748 | |||
749 | rem Calculate projected angle Z using heights |
||
750 | z1#=(z-1)*25.0 : y1#=h2# |
||
751 | z2#=(z+0)*25.0 : y2#=h8# |
||
752 | dz#=z2#-z1# |
||
753 | dy#=y2#-y1# |
||
754 | az#=atanfull(dz#,dy#) |
||
755 | az#=wrapvalue(90-az#) |
||
756 | |||
757 | rem Make normal from projected angle |
||
758 | nx#=sin(ax#) |
||
759 | ny#=cos(ax#) |
||
760 | nz#=sin(az#) |
||
761 | |||
762 | rem Setting matrix normal for smoothness |
||
763 | set matrix normal currentmatrix,x,z,nx#,ny#,nz# |
||
764 | |||
765 | next x |
||
766 | next z |
||
767 | update matrix currentmatrix |
||
768 | remend |
||
769 | return |
||
770 | |||
771 | _create_sky: |
||
772 | if test = 1 |
||
773 | load image "bitmap\tree.bmp", 2 |
||
774 | else |
||
775 | load image "bitmap\stars.bmp", 2 |
||
776 | endif |
||
777 | |||
778 | make object sphere 2, (landsize * 2) - 500 |
||
779 | |||
780 | rem make object sphere 2, -4000 |
||
781 | |||
782 | set object collision off 2 |
||
783 | rem scale object 2, 2000, 750, 2000 |
||
784 | scale object 2, 600, 120, 600 |
||
785 | set object 2, 1, 0, 0, 0, 0, 1, 1 |
||
786 | texture object 2, 2 |
||
787 | rem fade object 2, 0 |
||
788 | backdrop off |
||
789 | |||
790 | if test = 1 |
||
791 | backdrop on |
||
792 | set object wireframe 2, 1 |
||
793 | endif |
||
794 | return |
||
795 | |||
796 | _create_radar: |
||
797 | rem Karte - Abstand zur Kamera: 1.1 |
||
798 | remstart |
||
799 | load image "map\ST01L01a.bmp", 5 |
||
800 | make object plain 51, 0.352, 0.352 |
||
801 | lock object on 51 |
||
802 | position object 51, -0.6908, -0.4675, 1.1 |
||
803 | ghost object on 51 |
||
804 | texture object 51, 5 |
||
805 | remend |
||
806 | |||
807 | rem Karte - Abstand zur Kamera: 1.5 |
||
808 | load image "map\ST01L01a.bmp", 5 |
||
809 | make object plain 51, 0.48, 0.48 |
||
810 | lock object on 51 |
||
811 | position object 51, -0.942, -0.6375, 1.5 |
||
812 | ghost object on 51 |
||
813 | texture object 51, 5 |
||
814 | return |
||
815 | |||
816 | _printClock: |
||
817 | if clockCurrentMidDot = 0 |
||
818 | middle$ = " " |
||
819 | else |
||
820 | middle$ = ":" |
||
821 | endif |
||
822 | min = clockSeconds/60 |
||
823 | hours = min/60 |
||
824 | if clockShowSeconds |
||
825 | secsText$ = middle$+TwoDigit$(mod(clockSeconds,60)) |
||
826 | else |
||
827 | secsText$ = "" |
||
828 | endif |
||
829 | print "Time: ", TwoDigit$(mod(hours,24)), middle$, TwoDigit$(mod(min,60)), secsText$ |
||
830 | return |
||
831 | |||
832 | rem Rotate smooth, and rotate in the direction with the lowest distance |
||
833 | rem "turn object left" ist das kommando |
||
834 | function smoothRotate#(von#, nach#, smoothness) |
||
835 | if (von# > 270) and (nach# < 90) |
||
836 | ret# = WrapValue(von# + (360 - von# + nach#)/smoothness) |
||
837 | else |
||
838 | if (von# < 90) and (nach# > 270) |
||
839 | ret# = WrapValue(von# - (360 - nach# + von#)/smoothness) |
||
840 | else |
||
841 | ret# = von# + (nach# - von#)/smoothness |
||
842 | endif |
||
843 | endif |
||
844 | endfunction ret# |
||
845 | |||
846 | function floorHeight#(X#, Z#) |
||
847 | rem TODO: implement water |
||
848 | ret# = Get Ground Height(1, X#, Z#) |
||
849 | ENDFUNCTION ret# |
||
850 | |||
851 | function upPressed() |
||
852 | ret = UpKey()=1 or keystate(17)=1 or joystick up()=1 |
||
853 | ENDFUNCTION ret |
||
854 | |||
855 | function leftPressed() |
||
856 | ret = LeftKey()=1 or keystate(30)=1 or joystick left()=1 |
||
857 | ENDFUNCTION ret |
||
858 | |||
859 | function rightPressed() |
||
860 | ret = RightKey()=1 or keystate(32)=1 or joystick right()=1 |
||
861 | ENDFUNCTION ret |
||
862 | |||
863 | function downPressed() |
||
864 | ret = DownKey()=1 or keystate(31)=1 or joystick down()=1 |
||
865 | ENDFUNCTION ret |
||
866 | |||
867 | function TwoDigit$(value) |
||
868 | if value < 10 |
||
869 | ret$ = "0"+STR$(value) |
||
870 | else |
||
871 | ret$ = STR$(value) |
||
872 | ENDIF |
||
873 | ENDFUNCTION ret$ |
||
874 | |||
875 | function mod(num,modulus) |
||
876 | value=num-((num/modulus)*modulus) |
||
877 | endfunction value |
||
878 | |||
879 | function fileReadInt(fileNum) |
||
880 | read string 1, s$ |
||
881 | ret=val(s$) |
||
882 | ENDFUNCTION ret |
||
883 | |||
884 | function RndBetween(a,b) |
||
885 | ret = a+Rnd(b-a) |
||
886 | ENDFUNCTION ret |
||
887 | |||
888 | function isInCircle(pX#,pY#,cX#,cY#,cR#) |
||
889 | ret = sqrt( (pX#-cX#)*(pX#-cX#) + (pY#-cY#)*(pY#-cY#) ) <= cR# |
||
890 | ENDFUNCTION ret |
||
891 | |||
892 | _stop_game_sounds: |
||
893 | Stop Sound 1 : rem sound\forestbg.wav |
||
894 | Stop Sound 5 : rem music\pause.wav |
||
895 | Stop Sound 10 : rem sound\walk.wav |
||
896 | for t = 0 to cMaxEnemies |
||
897 | Stop Sound idxMonsterBase+t |
||
898 | next t |
||
899 | return |
||
900 | |||
901 | _exit: |
||
902 | exit |