Personnalisation du personnage | Blog | Sales Gosses !

Personnalisation du personnage | Blog | Sales Gosses ! Personnalisation du personnage | Blog | Sales Gosses !
  • Steam
  • Itch.io
  • Google Play
Les sales gosses et la maîtresse

Blog

Personnalisation du personnage

2024-10-09

Pour ce jeu vidéo, j'ai attaché une assez grande importance à la personnalisation des personnages, c'est-à-dire du ou de la sale gosse que vous contrôlez… ainsi que des bots, évidemment. C'est également ce que vous pouvez retrouver dans le générateur d'avatar « Sales Gosses ! ».

Je vous propose de découvrir comment cela se passe techniquement avec le moteur de jeu utilisé, Godot.

La création d'un sale gosse type

Le jeu est vu en fausse-3D isométrique avec un style cartoon 2D. J'ai pris le parti de représenter les personnages dans huits directions : haut, droite, bas, gauche, ainsi que les huits directions intermédiaires haut-droite, bas-droite, bas-gauche, haut-gauche.

Screenshot

Pour chacune de ces huit directions, on a également deux animations possibles : au repos ou en mouvement. Ce qui nous fait donc 16 animations différentes en tout. En tirant avantage de la symmétrie, on peut réduire ce nombre à 2 fois 5 (les positions haut-gauche, gauche et bas-gauche sont obtenues en faisant un simple miroir horizontal sur les positions haut-droite, droite et bas-droite).

Au niveau dessin, on a besoin de 12 sprites (morceaux d'image) pour chaque personnage : 2 pieds, 2 jambes, 1 bassin, 1 torse, 2 bras, un visage, des cheveux, une bouche et des yeux. Dans certaines positions, on ne voit pas forcément l'intégralité des sprites, et certains sprites sont réutilisés d'une position sur l'autre (par exemple, les sprites de la tête, du torse et du bassin sont les mêmes dans les positions au repos et en mouvement). À cela s'ajoutent d'autres variantes : différentes humeurs pour les yeux et la bouche, des mouvements comme la baffe, etc.

Sprites

En pratique, on a aussi d'autres animations lorsque le personnage utilise un objet (corde à sauter, yo-yo, balançoire, etc.), mais elles réutilisent pas mal des sprites déjà existants.

Tout cela, c'est très bien, mais maintenant, comment personnalise-t-on ce personnage ?

Les couleurs

Vous l'avez sans doute remarqué : soit mon personnage est albinos avec un goût prononcé pour les vêtements blancs… soit il manque tout simplement de la couleur.

Évidemment, c'est à dessein que j'ai colorié l'intégralité des sprites en blanc, parce que ça me permet d'utiliser une chouette fonctionnalité de Godot : la propriété self_modulate.

C'est une propriété de l'objet CanvasItem (dont Sprite2D hérite) qui permet de… eh bien moduler la couleur de l'objet. Elle est similaire à modulate, à ceci près que modulate s'applique à ce nœud et à tous les nœuds enfants, alors que self_modulate ne s'applique qu'au nœud considéré : les bras, par exemple, sont des enfants du nœud du torse, mais on ne veut clairement pas que la couleur du t-shirt soit appliqué aux bras.

En réglant cette propriété, on peut donc donner la teinte que l'on veut à chacun des sprites de notre personnage :

Colors

Évidemment, en pratique, les couleurs sont restreintes à un sous-ensemble pré-déterminé, pour éviter de se retrouver avec des personnages qui ont une peau d'alien par exemple…

Dans le menu de création du personnage, ce sont des barres de réglages qui permettent de sélectionner la couleur de chaque élément : peau, cheveux, t-shirt, pantalon et chaussures. Chaque barre est connectée à une rampe de couleur avec, encore une fois, des couleurs prédéfinies. Pour enregistrer la couleur de chaque personnage, il suffit donc d'enregistrer la position de chacune de ces barres !

Les variantes de sprites

Changer les couleurs, c'est bien chouette, mais on voudrait aussi pouvoir changer de coiffure, de forme de visage, de lunettes, de t-shirt, etc.

Pour faire cela, on commence par bien organiser notre feuille de sprite : chaque élément se trouve sur une ligne séparée. Ensuite, lorsque l'on veut ajouter une nouvelle variante, il suffit de créer une nouvelle ligne, et en décalant la position du rectangle choisi à l'affichage, on peut tout simplement switcher sur une nouvelle ligne de sprites.

Il est même possible d'utiliser plusieurs feuilles de sprites pour éviter de se retrouver avec une immense image unique. Voici par exemple les quatre feuilles utilisées dans la v1 du jeu :

Spritesheets

Au niveau du script, on fait une fonction qui applique le changement de ligne sur l'ensemble des sprites choisis, ce qui nous donne :


func set_y_for_all(sprites: Array, y: int) -> void:
    for sprite: Sprite2D in sprites:
        sprite.region_rect.position.y = y

Comme je veux pouvoir ajouter des variantes plus tard, provenant parfois d'autres feuilles de sprite, j'ai un fichier de config dans lequel je peux indiquer quelles lignes utiliser pour quelle partie du corps :


const BRAT_BASE: Texture2D = preload("res://assets/characters/brat_base.png")
const BRAT_VARIANT: Texture2D = preload("res://assets/characters/brat_variant.png")
const BRAT_VARIANT2: Texture2D = preload("res://assets/characters/brat_variant2.png")
const BRAT_VARIANT3: Texture2D = preload("res://assets/characters/brat_variant3.png")

const POSSIBLE_HAIR_SKINS: Array = [
    [BRAT_BASE, 2, PRNG.Proba.COMMON], # Straight
    [BRAT_VARIANT, 2, PRNG.Proba.COMMON], # Curly
    [BRAT_VARIANT2, 4, PRNG.Proba.COMMON], # Ponytail
    [BRAT_VARIANT3, 8, PRNG.Proba.COMMON], # Curly ponytail
    [BRAT_VARIANT, 10, PRNG.Proba.COMMON], # Long
    [BRAT_VARIANT2, 10, PRNG.Proba.COMMON], # Thick
    [BRAT_VARIANT3, 10, PRNG.Proba.COMMON], # Wavy
    [BRAT_VARIANT, 8, PRNG.Proba.COMMON], # Nerdy
    [BRAT_VARIANT2, 0, PRNG.Proba.COMMON], # Short
    [BRAT_VARIANT2, 2, PRNG.Proba.COMMON], # Messy
    [BRAT_VARIANT3, 12, PRNG.Proba.COMMON], # Bushy
    [BRAT_VARIANT, 4, PRNG.Proba.RARE], # Pigtails
    [BRAT_VARIANT2, 12, PRNG.Proba.RARE], # Dreadlocks
    [BRAT_VARIANT, 6, PRNG.Proba.RARE], # Punk
    [BRAT_VARIANT2, 6, PRNG.Proba.RARE], # Palmtree
    [BRAT_VARIANT2, 8, PRNG.Proba.RARE], # Mohawk
    [BRAT_BASE, 0, PRNG.Proba.VERY_RARE], # Bald
    ]

const POSSIBLE_HEAD_SKINS: Array = [
    [BRAT_BASE, 4, PRNG.Proba.COMMON],
    [BRAT_VARIANT, 0, PRNG.Proba.COMMON],
    [BRAT_VARIANT3, 0, PRNG.Proba.RARE],
    [BRAT_VARIANT3, 2, PRNG.Proba.RARE],
    [BRAT_VARIANT3, 4, PRNG.Proba.RARE],
    [BRAT_VARIANT3, 6, PRNG.Proba.RARE],
    ]

const POSSIBLE_EYES_SKINS: Array = [
    [BRAT_BASE, 7, PRNG.Proba.COMMON], # No glasses
    [BRAT_VARIANT, 12, PRNG.Proba.RARE], # Round glasses
    [BRAT_VARIANT, 13, PRNG.Proba.RARE], # Square glasses
    [BRAT_VARIANT2, 14, PRNG.Proba.VERY_RARE], # Sun glasses
    [BRAT_VARIANT2, 15, PRNG.Proba.VERY_RARE], # Sun glasses
    [BRAT_VARIANT2, 16, PRNG.Proba.VERY_RARE], # Sun glasses
    ]

const POSSIBLE_TSHIRT_SKINS: Array = [
    [BRAT_BASE, 11],
    [BRAT_VARIANT, 14],
    [BRAT_VARIANT, 15],
    [BRAT_VARIANT, 16],
    [BRAT_VARIANT, 17],
    [BRAT_VARIANT, 18],
    [BRAT_VARIANT3, 14],
    [BRAT_VARIANT3, 15],
    [BRAT_VARIANT3, 16],
    ]

const POSSIBLE_PANTS_SKINS: Array = [
    [BRAT_BASE, 12],
    [BRAT_VARIANT2, 17],
    [BRAT_VARIANT2, 18],
    ]

Sur chaque ligne, on a donc le fichier dans lequel trouver la ligne desprite, et en dessous l'indice de la ligne. Comme vous pouvez le deviner avec le code, on a aussi des notions de rareté pour certains skins, ce qui permet notamment d'éviter de se retrouver avec 10 gamins qui ont une coupe punk ou chauve, ce qui serait quand même assez peu réaliste…

Avec cette méthode, je peux facilement ajouter des skins par la suite, les ranger dans différentes spritesheets, etc.

Dans la v1 du jeu, on a donc 17 coiffures, 6 formes de visage, 6 types de lunettes, 9 t-shirts et 3 pantalons, soit 16524 combinaisons possibles ! Et encore, c'est sans compter sur les variantes de couleur. Bref, une bonne façon d'apporter de la diversité et de s'assurer de ne pas avoir de « clones » dans la cour de récré !

Conclusion

En utilisant deux propriétés simples de Godot (la modulation de couleur et la position du rectangle de sprite), on peut ainsi donner la possibilité de personnaliser le personnage, de générer des bots avec des skins aléatoires variés… tout en conservant les animations et interactions développées pour l'ensemble des personnages. L'enregistrement du skin est une simple liste d'entiers qui correspondent à l'index de chaque sprite et, pour les couleurs, à la position sur la rampe de couleur.

Évidemment, d'autres skins viendront s'ajouter à la liste existante dans les prochaines mises à jour du jeu, alors restez à l'écoute !

Jeu utilisant le moteur libre Godot.

CC-By-Sa 2021-2024 Simon « Gee » Giraudot
Site gracieusement hébergé par Framasoft.

Logo
i