Après plusieurs mois de silence, dus à plusieurs facteurs (déménagements, refactoring, ...), voici le retour de Pull N' Bounce, dans une "Black Edition". Ces graphismes sommaires me permettent de me focaliser sur le moteur du jeu, tout en laissant la partie graphique pour plus tard (mais sans avoir à casser le code).
J'ai conçu cette version pour qu'elles puissent être triturée dans tous les sens. Modifiez les fichiers, changez les graphismes, faites ce que bon vous semble. Et si vous le pouvez, n'hésitez pas à m'envoyer vos retours.
Pour jouer à Pull N' Bounce, il faudra un PC sous Windows, avec le framework .NET 3.5 installé, et XNA 3.1.
Configuration du moteur
Pour jouer avec le moteur physique, direction le fichier config.xml, présent dans le même répertoire que l'exécutable. A l'aide d'un éditeur de texte standard (notepad++ par exemple), vous pouvez éditer le fichier. Il est assez simple, puisqu'il consiste en une liste de valeurs (principalement numériques). Tout est éditable, et permet de modifier le comportement des objets physiques. A quoi correspond chaque variable ? Voici la liste :
PuckSpeedLimit : vitesse minimum à partir de laquelle le Pusher est réaffiché
PuckStoppingTime : durée (en secondes) pendant laquelle le Puck doit être en dessous de PuckSpeedLimit pour que le Pusher se réaffiche
PuckLinearDragCoef : frottements sur la vitesse linéaire du Puck
PuckRotationalDragCoef : frottement sur la vitesse de rotation du Puck
PuckRestitutionCoef : valeur utilisée pour le rebond du Puck
PuckFrictionCoef : valeur utilisée pour le rebond du Puck
PuckDisplaySize : valeur utilisée pour le placement du Pusher par rapport au Puck
PusherGaugeTime : durée (en secondes) pour charger complètement la jauge
PusherForceFactor : échelle de puissance pour la force appliquée au Puck
PusherGaugeStart : Position de la jauge sur le Pusher
PusherGaugeEnd : Position de la jauge sur le Pusher
ControlByMouse : contrôle du jeu à la souris (true à la souris, false : manette XBox 360)
SwitcherCollisionLatency : temps de latence entre 2 collisions sur les Switchers
GhostSizeSmall : échelle pour l'affichage des Ghost en Small
GhostSizeMedium : échelle pour l'affichage des Ghost en Medium
GhostSizeBig : échelle pour l'affichage des Ghost en Big
GhostWeight : poids des Ghosts (utilisé pour gérer les collisions)
GhostMovingIntensity : échelle utilisée pour la "force" des déplacements des Ghost
GhostMovingRange : facteur de déplacement (aléatoire entre 0 et la valeur indiquée)
GhostMinTime : durée (en secondes) minimale d'un déplacement
GhostMaxTime : durée (en secondes) maximale d'un déplacement
SlidingBlockSizeMedium : échelle pour l'affichage des SlidingBlock en Medium
SlidingBlockSizeLittle : échelle pour l'affichage des SlidingBlock en Little
SlidingBlockLinearDragCoef : frottement sur la vitesse linéaire des SlidingBlock
SlidingBlockRotationalDragCoef : frottement sur la vitesse de rotation des SlidingBlock
SlidingBlockRestitutionCoef : valeur utilisée pour le rebond du SlidingBlock
SlidingBlockFrictionCoef : valeur utilisée pour le rebond du SlidingBlock
UpDownSizeSmall : échelle pour l'affichage des UpDownBlock en Small
UpDownSizeMedium : échelle pour l'affichage des UpDownBlock en Medium
UpDownSizeBig : échelle pour l'affichage des UpDownBlock en Big
TeleporterSize : taille des Teleporters
TeleporterTimeOut : temps d'inactivité d'un Teleporter après utilisation
LoadGraphicsFromFile : chargement depuis les fichiers (et pas par les XNB). A laisser à true
Pensez à conserver une copie des fichiers qui fonctionnent bien, histoire de pouvoir revenir à une utilisation correcte.
Personnalisation des niveaux
Plus que de pouvoir personnaliser le moteur physique, cette version permet aussi de modifier les niveaux et l'aspect. Direction le répertoire Content pour ça. Les images, au format PNG, peuvent être éditées et seront donc rechargées à l'exécution. L'échelle des images est à gérer, ainsi que leur forme "physique". Les fichiers "shape" ou "mask" servent à gérer cette forme. Ils sont le plus souvent identiques au fichier qui sera affiché, mais on peut gérer une forme solide, et ajouter des ombres, par exemple, qui ne seront pas utilisées par le moteur physique. Un fichier "shape" utilise les pixels non-transparents pour gérer le modèle physique.
Le fichier Content\Arenas\XML\Level01.translated.xml contient les données nécessaires à la définition du niveau, appelé Arena dans le jeu. Les autres fichiers de ce répertoire sont utilisés pour des chargements par ressources. Comme pour le fichier config.xml, faites des copies des fichiers corrects.
C'est encore du XML à éditer. Les différents blocs sont placés sur un repère (x,y) allant de (0,0) en haut à gauche, à (1280,768) en bas à droite. La structure du niveau est gérée par un fichier image, indiqué dans ShapeTextureName. Ce fichier PNG doit être placé dans Content\Arenas\ShapeTextures), et être de taille 1280*768. Sur une base de pixels noirs (#000000), on dessine en blanc (#FFFFFF) la zone où les blocs se déplaceront. Pour un calcul correct de la forme, il faut éviter les zones "fermées". Des pixels rouge (#FF0000) placés dans la première ligne / première colonne permettent de diviser la zone. Toutes les formes sont possibles !
Concernant les blocs, le fichier de départ devrait être assez parlant, mais voici une description des différents éléments.
Le Puck a simplement une position de départ.
OnRailsBlocks est une liste de OnRailsBlockDescriptor. Chacun de ces éléments possède un position de départ Start, et deux booléens. LoopAtEnd indique si le bloc recommence son chemin indéfiniment, Backwards indique si le bloc réalise une marche arrière quand il a terminé un passage. Chaque OnRailStepDescriptor est décrit dans la liste Steps ensuite, avec la Translation effectuée, la Rotation et le temps mis (Time en secondes).
GhostBlocks est la liste des GhostBlockDescriptor, pour lesquels on indique une position de départ, et une taille (Small, Medium, Big). Les Ghosts sont des blocs qui n'interagissent qu'avec le Puck, et se déplacent aléatoirement.
Les SlidingBlocks sont des blocs libres qui glissent sur l'Arène au gré des collisions. Une Shape (StandardLittle ou StandardMedium), une position et un angle de départ (en radians), et une masse sont nécessaires.
Les UpDownBlocks sont des blocs qui fonctionnent en groupes. Pour chaque élément, on a deux groupes de blocs. Le groupe 1 est levé, et quand il est frappé par le Puck, il se baisse et le groupe 2 se lève. Le Group1 et le Group2 peuvent contenir autant de SingleUpDownDescriptor qu'on le souhaite. Une position, un angle et une forme (SmallStandard, MediumStandard ou BigStandard) permettent de les définir.
Les TeleporterBlocks téléportent le puck qui arrive dessus. Chaque téléporter possèdent un ID qui doit être unique. OutTeleporterID permet d'indiquer la sortie du teleporter (qui peut être n'importe quel autre teleporter). Un angle de sortie est également à fournir.
Pour terminer, il faut placer quelques Switchers.
Futur
L'aspect graphique du programme va être modifié. J'étudierai toute proposition de design, même si je garde le travail sur les graphismes (effets, animations) pour plus tard. La prochaine étape sera celle du jeu lui-même. Régler, suite aux retours, le moteur physique. Ajouter les fonctionnalités du jeu (compteur de coups, timer), un enregistrement des high-scores, une sélection des niveaux.
Les premiers tests sur XBox 360 (voir ce que donne le moteur physique notamment) vont également être réalisés bientôt.