ASSIGNMENT 5: HARD MODE offered by @Wintermute
Tante sfide, per tutti i gusti. Le pubblico ora, manca forse qualche dettaglio che spero di aggiungere dopo, magari fatemelo notare.
Level editor integration
Pochi algoritmi o neural network che siano possono battere un buon livello fatto da un designer bello/a "scoppolato/a" 😃
Implementate la possibilita' di leggere dei livelli da file, se presenti all'interno di una cartella "levels". Ogni file in questione deve essere un "CSV" file con nome "level_N.csv" dove N e' ovviamente variabile, anche se il primo livello deve essere sempre "level_0.csv". I file CSV sono validi se:
- Ogni riga ha lo stesso numero di elementi, che deve essere 20
- Il numero di colonne e' 10
In pratica, ogni valore della matrice definita dal file detta cosa spawnare in quella posizione. Le possibilita' sono
- "P" indica il giocatore (valore valido solo per il livello 0)
- "B" indica il bottone che apre le porte
- "K" indica uno scheletro
- "G" indica un fantasma
- "L" indica uno slime
- "W" indica una parete (che puo' apparire ovunque, non solo ai lati)
- I numeri indicano le uscite del livello. Se il giocatore raggiunge una di queste uscite, il livello da caricare e' quello indicato dal numero. Se il livello non e' presente tra i files, uno random deve essere generato
Inoltre:
- Ogni valore nella prima e ultima colonna e nella prima o ultima riga che non e' un numero verra' rimpiazzato da W (cioe', solo pareti o uscite sono ammissibili ai bordi)
- Un livello con almeno un'uscita posizionata in un angolo e' invalido
- Un livello senza player spawn, senza bottone, senza nemici o con meno di 2 porte e' invalido
Nel caso di livello invalido, potete generare random o crashare.
Seguiranno livelli prefatti per testare la vostra implementazione.
Chasing skeletons
I nemici del codice originale sono troppo stupidi, implementate uno scheletro che rincorre costantemente il giocatore. Usate uno spritesheet diverso per questo scheletro (basta un colorize via paint .NET, se riesco ve lo faccio pure io). Allo scheletro in questione corrispondera' il valore "K2" nel formato dei livelli.
[Per le sfide seguenti, ho supposto che i nemici abbiano una vita base pari a 10 e che un colpo del player faccia 10 danni]
IT'S A TRAP!
I livelli del prototipo sono troppo vuoti, no? Implementate 2 trappole addizionali
- melma: occupa una tile, quando qualcuno ci e' sopra e prova a muoversi, la sua velocita' e' ridotta del 60%. Valore "M" nel formato dei livelli.
- fuoco: occupa una tile, quando qualcuno ci passa sopra prende fuoco, e quindi per i prossimi 3 secondi prendera' mezzo cuore di danno ogni mezzo secondo (2.5 danni se nemico). Pero', se si tocca un'altra entita', il fuoco passa a questa (la durata si resetta) ma "l'untore" verra' guarito (e non prendera' danno da una eventuale collisione).
Smarter skeletons
Uno sceletro ti tipo "K2" potrebbe comunque comportarsi in modo stupido, tipo cercando di muoversi verso il player anche se davanti a lui c'e' un muro di pareti, e va bene, anche se la stessa cosa potrebbe succedere con le altre trappole! Implementate anche uno scheletro (valore "K3") che non perda tempo a muoversi inutilmente verso pareti e che eviti sempre le trappole.
Watch your back!
Implementate un nuovo tipo di pipistrello (valore "B2") che abbia come obiettivo quello di beccare il player sempre arrivando da dietro. L'effetto voluto e' una combo letale con lo scheletro K2 in modo da chiudere il giocatore tra 2 fuori in spazi stretti. Nell'implementarlo, vi potrebbe tornare utile questo articolo sul movimento dei fantasmi nel pac-man originale: http://gameinternals.com/post/2072558330/understanding-pac-man-ghost-behavior, o forse anche no, non ne sono sicuro 😃
L' I N F A M E
Abbiamo scheletri e pipistrelli nuovi... Ma ora arriva lo slime "infame" (valore "L2"). La sua velocita' e' il 50% in piu' di quella del giocatore, ha 25 di vita, si muove bene quanto lo scheletro K3, quindi evita anche le trappole, A MENO CHE non sia piu' conveniente passarci sopra, ad esempio per arrivare comunque piu' velocemente al giocatore, o per prendere e poi attaccare subito il fuoco al player. Ora, per implementare questa cosa per bene vi potrebbero tornare utili articoli tipo questo: https://users.cs.duke.edu/~reif/paper/sunz/weightedpath/weightedpath.pub.pdf ... Solo non fate caso alla parte che sostiene che il problema non sia risolvibile 😃