MSX Village forum

La Place des Développeurs MSXgl MSX Game Library

ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 04/02/2022 à 07h19

Reprise du message précédent

aoineko :


Désolé, j'ai des trucs plus haut dans ma todo list, mais je n'oublie pas. ^^
En tout cas, il a l'air très chouette ce programme.


Je risque pas t'attendre si longtemps en fait...
vu qu'apparemment t'es une machine à coder :| ;) Edité par ericb59 Le 04/02/2022 à 07h20


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 04/02/2022 à 23h59
Voilà, j'ai mise-à-jour une nouvelle version de MSXgl sur GitHub avec le système de collision par tile.

Pour le moment, le module GamePawn ne s'occupe que des collisions ; les déplacements sont laissés coté jeu car ça pourrait être très différent d'un jeu à l'autre.
Ceci dit, je pense ajouter une gestion de la physique qu'on pourra activer au besoin.
Le sample s_game a été mis à jour pour référence.

Alors, voilà comment ça marche :

1) Dans ton msxgl_config.h il faut activer la feature en ajoutant ce define
Code C :
#define GAMEPAWN_USE_PHYSICS        1


2) Dans ton code d'initialisation, il faut donner :
- Une function qui va être appelé en cas de collision,
- Une fonction qui dit si un tile donné est bloquant ou non,
- La taille x/y de la collision du personnage (16x16 par ex.) ; pour le moment, la position représente le coin haut-gauche de la zone collision, et la taille permet de déterminer le coin bas-doite.
Par ex., dans le sample :
Code C :
GamePawn_InitializePhysics(&g_PlayerPawn, PhysicsEvent, PhysicsCollision, 16, 16);


3) La fonction PhysicsEvent est appelé lorsqu'un event de collision ou de physics ont lieu. Le jeu est libre de réagir comme il le souhaite aux event qu'il souhaite (il suffit d'ignorer ceux qui ne l'intéresse pas).
Voici un exemple qui :
- Stop le saut quand on détecte une collision par le bas (le pawn touche le sol)
- Annule la force ascendante quand on détecte une collision par le haut (le pawn se cogne au plafond)
- Commence une chute quand on est pas en train de sauter et qu'on ne détecte plus de collision par le bas (le joueur avance au dessus du vide)
Code C :
void PhysicsEvent(u8 event)
{
    switch(event)
    {
    case PAWN_PHYSICS_COL_DOWN: // Handle downward collisions 
        g_bJumping = false;
        break;
 
    case PAWN_PHYSICS_COL_UP: // Handle upward collisions
        g_JumpForce = 0;
        break;
 
    case PAWN_PHYSICS_FALL: // Handle falling
        if(!g_bJumping)
        {
            g_bJumping = true;
            g_JumpForce = 0;
        }
        break;
    };
}


4) La PhysicsCollision permet au jeu de dire au module de collision si un tile est bloquant ou non.
Dans l'exemple ci-dessous, un numéro de tile inférieur à 8 est bloquant ; tous les autres ne le sont pas.
Code C :
bool PhysicsCollision(u8 tile)
{
    return (tile < 8);
}


5) Enfin, pour utiliser la fonctionnalité de collision, il faut utiliser la fonction GamePawn_SetTargetPosition pour déplacement le personnage au lieu de GamePawn_SetPosition.
- GamePawn_SetPosition : téléporte le pawn a une position sans tester les collisions,
- GamePawn_SetTargetPosition : le code de collision essaye de déplacer le personnage entre Position et TargetPosition, et ajuste la position final en cas de collision (en plus de déclencher des events).

Voilà... j'espère que c'est compréhensible. ^^



EDIT: Quelques limitations tout de même :
- La collision se fait à l'échelle d'un tile ; par exemple, pas possible d'avoir une pente qu'on puisse grimper à l'intérieur d'un tile. C'est binaire, un tile est bloquant ou non, c'est tout.
- Avec des déplacements latéraux ou verticaux de plus de 8 pixels en 1 frame, il est "possible" que le test de collision passe à travers un tile (à cette vitesse on traverse l'écran en 0,4 secondes ^^).
- Enfin, les tests de collisions ne sont fait qu'en 1 point par direction (cf. schéma ci-dessous). Je pourrais faire une version plus précise à 2 points par direction mais qui sera plus lourde. J'en ferait une option à activer via un define.


On est toujours ignorant avant de savoir.
Github    
Gfx Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 22/02/2021 à 22h22

Messages: 355

Le 05/02/2022 à 11h27
C'est juste génial ! je vais m'installer une extension Git dans VS Code et je teste ça.
Merci @aineko pour ces ajouts précieux :top

EDIT: J'ai fait un clone de ton repo et j'ai encore quelques .cmd avec LF en fin de ligne (notamment 'check_config.cmd') Edité par Gfx Le 05/02/2022 à 12h08


Il faut cultiver notre jardin.
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 05/02/2022 à 12h24
Gfx :
C'est juste génial ! je vais m'installer une extension Git dans VS Code et je teste ça.
Merci @aineko pour ces ajouts précieux :top


De rien :)
Tant que c'est assez générique c'est cool car ça pourra aider d'autres personnes aussi.

Gfx :
EDIT: J'ai fait un clone de ton repo et j'ai encore quelques .cmd avec LF en fin de ligne (notamment 'check_config.cmd')


Zut... c'est vraiment relou ce problème :(
C'est peut-être des fichiers que j'ai pas encore re-push depuis que j'ai essayé de régler le problème avec GitHub.
Je vais essayer de forcer de push tous mes .bat et .cmd.

EDIT: Peux réessayer stp ? J'ai changé la configuration des attribues de fichiers textes. Tu peux me dire si c'est bon pour toi ?

Au fait, tu es sous Windows ? Parce que moi, j'ai déjà cloné MSXgl sur plusieurs machines Windows et j'ai jamais eu de soucis.
Si j'ai bien compris, le comportement par défaut de GitHub c'est de convertir de force les fichiers texte en CRLF sur Windows et en LF pour les autres plateformes.

EDIT2: C'est bon, j'ai réussi à reproduire le problème sur Windows... et à le corriger en pushant tous les BAT et les CMD. La dernière version GitHub devrait fonctionner.


On est toujours ignorant avant de savoir.
Github    
Gfx Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 22/02/2021 à 22h22

Messages: 355

Le 05/02/2022 à 13h20
Oui c'est bon maintenant, tous les cmd et bat sont bien en CR-LF !
Je suis sur windows.
:top


Il faut cultiver notre jardin.
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 05/02/2022 à 13h30
Ouf... je pense que j'en ai ENFIN fini avec ce problème. :glass


On est toujours ignorant avant de savoir.
Github    
Gfx Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 22/02/2021 à 22h22

Messages: 355

Le 06/02/2022 à 01h11
Hello,
je me suis amusé avec le game_pawn et les collision et j'aurais besoin de tes conseils pour coder le comportement sur les échelles. Pour l'instant je teste juste si le pawn est sur une tile de type échelle (ou 1 tile au dessus) et je desactive le saut mais lorsque le sprite arrive en haut de l'échelle il saute... en fait j'aimerais pouvoir marcher sur le haut des échelles sans tomber. Dans The Maze of Galious les échelles ne vont pas jusque en haut des plateformes, je commence à comprendre pourquoi...
Si tu veux voir à quoi ça ressemble : wizzl.rom Edité par Gfx Le 06/02/2022 à 01h18


Il faut cultiver notre jardin.
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 06/02/2022 à 01h26
Déjà, les décors sont vraiment très jolis !

Comme la callback PhysicsCollision est toujours appelé avant un PhysicsEvent, tu peux ruser :
- Tu sauvegarder le tile qui est testé dans PhysicsCollision,
- Quand tu reçoit l'event PAWN_PHYSICS_FALL dans PhysicsEvent, tu check si le tile sauvegarder est l'échelle et si c'est le cas, tu ne tombe pas.

Et voilà, tu peux marcher sur les échelles :)
Je pourrais éventuellement renvoyer le dernier tile testé dans les paramètres de le callback PhysicsEvent... à voir si ça vaut le petit surcout que ça aurait.

Pour le saut, c'est gérer dans ton code donc à toi de faire une transition propre entre le moment ou tu es sur l'échelle et quand tu arrives en haut.


Autre petite astuce auquel j'avais pensé : tu peux utiliser PhysicsCollision pour détecter des items à ramasser dans le décors. Leur tile sera non-bloquant, mais si cette callback est appelé c'est que le pawn touche ce tile et tu peux donc ajouter l'objet dans l'inventaire de ton personnage et remplacer le tile de l'objet par un tile de décor de fond.

Tu peux garder par exemple les 2 bits de poids fort pour coder 4 types de tiles (décor bloquant, décor de fond, item et... je sais pas quoi ^^). Ca te laisse 64 tiles pour chaque catégorie et ça te facilite grandement leur détection.

PS : Tu peux créer facilement un lien vers WebMSX comme ça : https://webmsx.org/?MACHINE=MSX1J&ROM=http://msxvillage.fr/upload/wizzl.rom


On est toujours ignorant avant de savoir.
Github    
Gfx Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 22/02/2021 à 22h22

Messages: 355

Le 06/02/2022 à 01h56
Génial ! Merci je teste ça demain :)


Il faut cultiver notre jardin.
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 06/02/2022 à 13h25
L'impact sur les performances est minime du coup j'ai ajouté le tile qui à déclencher l'évènement dans le prototype de la callback.
Le nouveau prototype est :
Code C :
void PhysicsEvent(u8 event, u8 tile)


En fait, c'est surtout l'affichage GamePawn_Draw() qui prend du temps.
Je vais regarder pour optimiser un peu...


On est toujours ignorant avant de savoir.
Github    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 06/02/2022 à 18h14
@GFX Attention, si tu récupères la dernière version GitHub, j'ai retiré le paramètre DataMultiply de la structure Game_Sprite.
Il y avait une multiplication entre 2 variables très couteuse et inutile.
Par contre ça créé 1 contrainte : Il faut que les différentes couches d'une frame soit les unes derrières les autres ; ce qui est le cas si tu créées tes données avec CMSXimg.
Le seul changement à faire coté code, c'est que le paramètre ID des Game_Frame, doit être le numéro de pattern et plus le numéro de frame.
Par ex., dans mon sample s_game, la ou j'utilisais la frame 1 ou 5, je doit maintenant déclarer 16 ou 80 (frame * 16).
La valeur 16 vient du fait que je suis en 16x16 (4 patterns) et que j'ai 4 couches de sprites.
Le début de la 1re frame est à l'index 0, le 2e à l'index 16, le 3e à l'index 32, etc.

EDIT:
Autre optimisation, j'ai fait disparaitre le SpriteID de la structure Game_Sprite.
Maintenant, le SpriteID est définie dans le Game_Pawn et détermine l'ID du premier layer.
Le layer suivant utilise l'ID suivant et ainsi de suite (ça permet d'optimiser).
L'ID du premier layer se donne via un nouveau paramètre dans la function GamePawn_Initialize() :
Code C :
void GamePawn_Initialize(Game_Pawn* pawn, const Game_Sprite* sprtList, u8 sprtNum, u8 sprtID, const Game_Action* actList);

Il faut donc retirer le premier paramètre dans ta déclaration des Game_Sprite et mettre la valeur du 1er layer dans GamePawn_Initialize().


On est toujours ignorant avant de savoir.
Github    
Gfx Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 22/02/2021 à 22h22

Messages: 355

Le 06/02/2022 à 22h43
@aoineko ça marche, je vais mettre à jour et faire les modifs.
Entre temps j'ai essayé les collisions et j'y suis presque... j'ai toujours un problème si le joueur tourne à droite ou à gauche dans les derniers 8px de l'échelle :
---->WIZZL Edité par Gfx Le 06/02/2022 à 22h49


Il faut cultiver notre jardin.
   
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 06/02/2022 à 22h50
Bravo Gfx, c'est super.

Même si je suis tes avancées et celles de MSXgl, je ne participe plus trop car un gros coup au moral dû à un souci de santé.
Tchao les zamis et bonne continuation ;)


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 06/02/2022 à 23h52
Ricco59 :
Même si je suis tes avancées et celles de MSXgl, je ne participe plus trop car un gros coup au moral dû à un souci de santé.

Bon courage


On est toujours ignorant avant de savoir.
Github    
Gfx Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 22/02/2021 à 22h22

Messages: 355

Le 07/02/2022 à 00h13
@Ricco oui courage, reviens vite


Il faut cultiver notre jardin.
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 08/02/2022 à 00h21
J'ai ajouté 2 options au module PSG de MSXgl :
- On peut choisir un accès direct (aux registres) ou indirect (via un buffer en RAM). Chacune de ces méthodes à ses intérêts. Je vous expliquerai si vous voulez.
- On pout choisir entre le PSG interne du MSX ou un PSG externe (dans une cartouche... comme celui de la MegaFlashROM SCC+ SD).
J'ai aussi ajouté un define pour ajouter/supprimer toutes les fonctions helpers (PSG_SetTone, PSG_SetNoise, PSG_SetVolume, etc.).

C'est sur GitHub.

Je prévois d'ajouter une option pour utiliser et le PSG interne, et un PSG externe, mais c'est pas prio et ça attendra. ^^


On est toujours ignorant avant de savoir.
Github    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie