Closed kesiev closed 1 year ago
Ciao, anche il gioco che sto cercando di portare a JS è "arcaico", quindi non è questo il problema: c'è semplicemente un omino che si sposta da una stanza all'altra, ogni stanza compare di volta in volta a seconda di quale porta l'omino prende; ogni tanto l'omino raccoglie un oggetto, e questo è tutto. Però non ho capito dove devo andare a smanettare per modificare queste dimensioni 32x32! Ho provato a cambiare dei 32 a caso qua e là ma senza successo... Sennò, hai altri engine da suggerire? Ho provato con MelonJS, ma non riesco a capire come funzionano le occlusions, quindi il mio omino passa sopra qualunque tile! Ho visto che c'è Phaser3, ma non riesco a trovare documentazione su come usare la nuova feature delle mappe isometriche, invece di un vecchio plugin isometrico per versioni precedenti. Ho trovato anche il tuo Akihabara, che però è ancora più vecchio di Wright; in teoria, a giudicare dalla homepage, direi che supporta l'isometrico:
Ma non riesco a trovare un esempio o un tutorial, hai qualche link da darmi?
Di engine isometrici ne ho trovati diversi, ma non riesco a trovarne uno utilizzabile:
https://github.com/jumpjack/isometric-game-js-test/blob/master/README.md
Wright usa un sistema di stencil, che sono dei modelli che possono essere composti insieme tra di loro. Prendiamo il simbolo della mappa "#":
https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L510
"#":{ "set":{ "_":[ "stencil", "modelTile" ] }, "objectType":"obstacle" },
Questo set
ta lo stencil
chiamato modelTile
:
https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L108
"modelTile":{
"image":"tiles", "width":32, "height":32,
"hitbox":[ { "width":8, "height":12, "x":12, "y":2 }, { "width":18, "height":8, "x":7, "y":4 } ],
"zSubindex":0
},
Che suggerisce di prendere dall'immagine tiles
(https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L20) un'area 32x32 con 2 hitbox e l'attributo zSubindex
valorizzato a 0
. L'attributo frame
non è definito, quindi usa il valore di default 0
ma, volendo, puoi definire il frame per prendere un'altra immagine, come accade per gli altri elementi della mappa.
https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L511
"%":{ "set":{ "_":[ "stencil", "modelTile" ] }, "frame":8, "objectType":"obstacle" },
Il sito di Akihabara è piuttosto vecchio e non l'ho gestito io. Ai tempi un collaboratore voleva dargli un aspetto meno spartano di quello che gli diedi io in origine ;) Probabilmente ha trovato figo metterci un artwork isometrico. Ad ogni modo sarebbe possibile, considerando che è una libreria a più basso livello... ma servirebbe comunque scriversi da se le routine per gestire la profondità.
Su altri engine per fare giochi isometrici non ti sono molto d'aiuto e ti direi i soliti engine commerciali, molti dei quali li hai già elencato tu. Ad ogni modo, se ho qualche idea, non mancherò di farti sapere!
Sì, questo è quello che sono riuscito a capire fino ad ora... ma non basta: anche se uso le mie tile che sono 24x40, vengono comunque spaziate di 32x32 pixel, quindi il risultato è questo:
(considera solo le pareti in alto a sinistra e in alto a destra).
Ho provato a rimediare ridimensionando a 32x32 le mie tile, ma ovviamente il risultato è indecente:
Invece i parametri di hitbox non li ho proprio capiti; visivamente, questa definizione come a cosa corrisponde?
"modelMovingObject":{
"image":"tiles", "width":32, "height":32,
"hitbox":{ "width":16, "height":6, "x":8, "y":5 },
Il codice che arrangia i tile parte da https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L159 e arriva a https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L195:
{ "set":{ "layer":0 } },
{
"times":5,
"execute":[
{ "set":{ "counter":0 } },
{
"times":15,
"execute":[
{ "set":{ "counter2":0 } },
{
"times":9,
"execute":[
{ "set":{ "tile":{ "_":[ "this", "room", { "_":[ "this", "layer" ] }, { "_":[ "this", "counter" ] }, { "_":[ "this", "counter2" ] } ] } } },
{
"when":{ "_":[ "this", "tile", "and", { "_":[ "this", "tile", "isNotEqualTo", "." ] } ] },
"execute":{
"when":{ "_":[ "stencil", { "_":[ "this", "tile" ] } ] },
"execute":{
"object":{
"set":{ "_":[ "stencil", { "_":[ "that", "tile" ] } ] },
"x":{ "_":[ "that", "counter2", "*", 32, "+", { "_":[ "that", "counter", "%", 2, "*", 16 ] }, "-", 16 ] }, "y":{ "_":[ "that", "counter", "*", 8, "+", 56 ] },
"execute":{ "_":[ "stencil", "codeSetZIndex" ] },
"zPos":{ "_":[ "that", "layer", "*", 16 ] }
}
}
}
},
{ "sum":1, "to":{ "_":[ "this", "counter2" ] } }
]
},
{ "sum":1, "to":{ "_":[ "this", "counter" ] } }
]
},
{ "sum":1, "to":{ "_":[ "this", "layer" ] } }
]
}
],
Questo ciclo scorre gli strati sovrapposti (layer), la coordinata x (counter) e la coordinata y (counter2). La riga https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L179 effettivamente calcola le coordinate del tile:
"x":{ "_":[ "that", "counter2", "*", 32, "+", { "_":[ "that", "counter", "%", 2, "*", 16 ] }, "-", 16 ] }, "y":{ "_":[ "that", "counter", "*", 8, "+", 56 ] },
Cambiando la dimensione dei tile probabilmente dovrai cambiare anche questi valori. Circa le hitbox https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L110 :
"modelTile":{
"image":"tiles", "width":32, "height":32,
"hitbox":[ { "width":8, "height":12, "x":12, "y":2 }, { "width":18, "height":8, "x":7, "y":4 } ],
"zSubindex":0
},
Rettangolo rosso: { "width":8, "height":12, "x":12, "y":2 }
Rettangolo blu: { "width":18, "height":8, "x":7, "y":4 }
La composizione dei due rettangoli costituisce la hitbox. Come vedi compone una sorta di croce nella parte "superiore" del blocco.
Scusa ma non riesco a "tradurre" questa sintassi in quella standard javascript; mi viene più o meno una cosa del genere, ma non sono per niente sicuro, dove trovo spiegata la tua sintassi?
for (layer = 0; layer < 5; layer++) {
for (counter= 0; counter <15 ; counter++) {
for (counter2= 0; counter2 < 9; counter2++) {
tile = room[layer,counter, counter2]
if ((tile) && (tile != "." )) {
if (stencil == tile) {
object = stencil[tile];
x = counter2 * 32 + counter%2 * 16 - 16;
y = counter * 8 + 56;
zPos = layer * 16;
}
}
}
}
}
Wright non è pensato per risolvere calcoli difficili ma per farlo il più in fretta e semplicemente, per cui lo fa da sinistra a destra, un po' come le calcolatrici RPN.
Ad ogni modo ti ho preparato questo, risistemando un po' il tuo codice: https://gist.github.com/kesiev/e7cbdcaf7fddb3622a2535e2be3ec635
Disegna questo:
...che è il primo livello di Isocat:
Grazie, adesso vedo di capirci qualcosa. Ma usi un convertitore per scrivere in "Linguaggio JOSN", o fai a mano?
_(Scusami se ti rispondo tramite issue al tuo tweet https://twitter.com/_jumpjack_/status/1597868924347224065 ma non ho trovato contatti che mi permettessero di scrivere più di qualche riga)_
Hey ciao!
Vedo che hai dissezionato Isocat (https://www.kesiev.com/wright/issue/isocat) e abbia pensato di usare Wright.
Wright è un engine pensato principalmente per i giochi 2D più classici (sidescroller, SHMUP, puzzle, etc.) ma ogni tanto ho "sperimentato" quanto si possa tirare un engine semplice per fare qualcosa che non dovrebbe con i giusti hack, come per i giochi isometrici, FPS, giochi VR etc. e Isocat è uno di quegli esperimenti. Ma è un modo davvero "arcaico" di fare giochi di questo tipo per cui, se hai intenzione di provare Wright per un gioco isometrico complesso, preparati ad hack terribili e sinceramente ti consiglio di usare engine un pò più moderni o di fare qualcosa da te.
Provo comunque a risponderti: Isocat usa sprite 32x32 ma poi crea una piccola hitbox a croce per "fingere" che l'oggetto sia tridimensionale. C'é poi un sistema di collisioni "customizzato" sulle dimensioni di questa hitbox che verifica se il personaggio collide con le cose https://github.com/kesiev/Wright/blob/master/tapes/isocat/tape.json#L388. Tutto il sistema è "tunato" su questa dimensione di tile, per cui cambiandone la grandezza e la relativa hitbox probabilmente dovrai anche cambiare diversi parametri per il sistema di collisioni.
Ad ogni modo il progetto che stai portando avanti mi sembra molto figo. Tieni duro!