La vue dans un jeu est défini par des caméras virtuelles. Ces caméras peuvent être contrôlées de bien des façons pour donner des effets scénaristiques. La gestion de la (ou des) caméra(s) est tellement importante qu'on catégorise même les jeux par ce critère. Nous allons voir ici comment définir le point de vue dans différents contextes.
Popularisé par des jeux comme Doom (ou Open Arena), souvent utilisé en visualisation architecturale, ce mode de jeu est très immersif puisqu'il place le joueur selon le même point de vue que le personnage qu'il incarne. L'immersion est habituellement renforcée en ajoutant à l'écran des éléments comme les bras du personnage.
Reprenons notre exemple du chapitre Créer son premier jeu, et positionnons la caméra exactement à l'emplacement des yeux du personnage. L'objet qui représente notre personnage gêne évidemment la vue, nous allons donc le rendre invisible (panneau Physics, cocher Invisible). Il nous reste à "parenter" la caméra au personnage pour qu'elle colle à ses déplacements : sélectionnons la caméra, puis le personnage, Ctrl + p, Set Parent to Object.
Dans ce type de jeu, la direction dans laquelle regarde le personnage est généralement contrôlée à la souris. Un script bien pratique est dédié à résoudre cette problématique, il s'agit de mousemove.py, partagé sous licence Creative Commons (CC-BY-3.0) par riyuzakisan. Nous allons voir comment le mettre en place en quelques instants.
La méthode de déplacement est maintenant comparable à celle d'un jeu à la première personne.
Depuis la 2.72, un actuator Mouse a fait son apparition.
En mode Look, connectée à un sensor Always, elle a le même effet que le script.
On peut modifier sa réactivité aux mouvements de la souris en modifiant sa senbilité Sensitivity et le seuil de déclenchement de l'action Thresold et imposer des limites de rotation.
De la même manière, plaçons l'objet qui affiche le score quelques centimètres devant la caméra, et "parentons"-le à la caméra.
Passons en vue caméra (Num0), lançons le jeu et vérifions que tout se passe bien. C'est normalement le cas, à une exception près : lorsque l'on s'approche d'un mur, le score disparaît ! En réalité, il traverse le mur.
Une parade efficace est de créer une nouvelle scène contenant simplement une caméra avec notre objet score, puis de l'ajouter en mode Overlay à notre scène principale, comme décrit dans le chapitre précédent sur la gestion de scènes.
Il reste à régler la communication entre les deux scènes car elles n'ont rien en commun à l'exception de deux choses :
logic.globalDict
). Les objets Python qui sont stockés dans ce dictionnaire persistent tout au long du jeu et sont accessibles de toutes les scènes.Nous pourrions utiliser le dictionnaire global pour stocker le score et envoyer un message à la scène Overlay pour ordonner le rafraîchissement de l'affichage mais nous pouvons aussi envoyer le score directement dans un message grâce à l'actuator Message :
Lorsque l'option Body est sur Property, nous spécifions le nom d'uneGame Property de l'objet et la valeur de cette propriété est automatiquement envoyée, sous forme de texte, dans le corps du message.
Voici notre logique de jeu pour la mise à jour du score :
Nous voyons que le contact du joueur avec un objet bonus modifie le score, cela n'a pas changé. Mais nous avons ajouté une logique qui détecte toute modification du score et envoie un message à l'objet scoreDispavec le nouveau score. C'est grâce au sensor Property > Changedque cela est possible : ce type de sensor surveille une propriété de l'objet et génère une impulsion dès qu'il détecte un changement.
L'objet scoreDisp est dans la scène hud que avons ajoutée au début du jeu. Pour récupérer le message, nous utilisons un sensor Message :
Tel qu'il est configuré, le sensor détecte les messages qui sont envoyés à l'objet (plus précisément au nom de l'objet, ici scoreDisp) et dont le sujet est "score". Comme la nouvelle valeur du score est dans le corps du message, nous avons besoin de Python pour le lire car les briques ne permettent pas d'y avoir accès. Le script suivant transfère le contenu du message dans la propriété Text de l'objet, ce qui a pour effet de modifier l'affichage.
from bge import logic
cont = logic.getCurrentController() obj = cont.owner sMsg = cont.sensor["sMsg"]
for body in sMsg.bodies: obj["Text"] = int(body)
Notons que le score est stocké à l'origine dans une propriété de type entier (Integer) car c'est nécessaire pour l'arithmétique du score. Il se transforme cependant en texte une fois copié dans le message car c'est le type obligé pour tous les messages (String). Comme la propriété Text de l'objet scoreDisp est aussi un entier nous devons reconvertir le message en entier avec l'expression int(body)
. Nous aurions pu tout aussi bien choisir une propriété de type String pour scoreDisp de façon à éviter la conversion.
Grâce à la scène en Overlay, le score est toujours visible :
Comme nous l'avons vu au chapitre Logique du jeu, il est possible d'envoyer un message directement d'un script Python. Nous pourrions remplacer l'actuatorMessage par un controller Python qui exécute ce script :
from bge import logic cont = logic.getCurrentController() obj = cont.owner # arguments: sujet, corps, destinataire logic.sendMessage("score",str(obj["score"]),"Score")
Popularisé par des jeux comme Tomb Raider (ou YoFrankie!), ce mode est peut être moins immersif mais permet au joueur d'admirer le personnage, ses animations, ses interactions avec le décor. La caméra flotte à quelques mètres du personnage, ce qui implique qu'il faudra porter un soin particulier à ce qu'elle ne traverse pas un mur, qu'un objet ne se place pas entre les deux, que les mouvements ne soient pas saccadés.
L'actuator Camerafournit une première approche. Sélectionnons notre caméra, ajoutons lui un actuator Camera déclenché par un sensor Always. Renseignons le nom de la cible (l'objet qui sera suivi par la caméra). Les noms des paramètres sont explicites, mais leur réglages demandent quelques tâtonnements.
Toutefois on s'aperçoit vite que quels que soient les réglages, plusieurs problèmes restent présents :
Voyons comment contourner ces petits soucis. Il s'agit souvent d'utiliser des techniques déjà abordées dans des chapitres précédents.
On peut parenter un objet quelconque (un Empty convient parfaitement) à notre personnage, et déclarer cet objet dans l'actuator Camera. Il est ensuite facile de le déplacer, pour régler finement le cadrage de la caméra.
On peut activer les collisions dans l'onglet Physics de la Caméra. Le mode Dynamic devrait convenir. Ces points sont détaillés dans la section Comportement des objets et personnages au chapitre Le comportement des objets de notre monde. Attention, la caméra devient alors sensible à la gravité, ce qui n'est généralement pas souhaitable. Pour pallier à cela, il est courant de lui donner constamment une force contraire (un actuatorde type Motion avec une Force de 0.098 en Z).
On peut utiliser les nœuds de matériaux, sur le matériel des murs, pour rendre transparent les parties proches de la caméra. Cette technique est détaillée dans le chapitre Matériaux dynamiques et textures animées de la section Développer l'univers du jeu.
L'idée ici est que plusieurs caméras ont été placées à des endroits clés d'une scène de jeu. Différentes fonctions, règles de jeu ou commandes de l'utilisateur déclenchent le passage de l'une à l'autre. Par exemple, il est courant, dans un jeu de voiture de pouvoir choisir sa vue, alors même que la voiture roule déjà, ou de rapidement regarder en arrière, lorsqu'on n'a pas de rétroviseurs. Il y a d'autres types de jeux qui activent le changement de caméra en fonction de la place du joueur sur la scène de jeu.
Nous avons placé dans notre scène un certain nombre de caméras. Par soucis de clarté, nous avons donné à chacune un nom qui la caractérise bien. L'avantage de cette méthode est qu'on peut, dans le cas de caméras fixes, régler finement leurs points de vues.
Pour passer d'une caméra à une autre, il faut juste créer un actuator Sceneet le mettre en mode Set Camera. Très simplement, il faut juste alors lui indiquer le nom de la nouvelle caméra à partir de la quelle on désire voir la scène. L’événement qui déclenchera cet actuator peut être une collision, une frappe au clavier ou le changement d'une Game Property, tout cela dépend des règles du jeu et de la jouabilité que l'on cherche à développer, mais le résultat activera la vue de la scène à partir de la caméra dont le nom est inscrit dans l'actuator.
Voici un code pour lister toutes les caméras présentes dans la scène et passer à la suivante dans la liste des caméras disponibles lorsque le code est activé :
from bge import logic scene = logic.getCurrentScene() # Quel est l'indice de la camera active indice = scene.cameras.index( scene.active_camera ) # Incrémenter cet indice indice += 1 # Vérifier que l'indice n'est pas hors limites if indice >= len( scene.cameras ) : indice = 0 # Changer la caméra active scene.active_camera = scene.cameras[indice]
Après import des modules et récupération de la scène courante, nous recherchons l'indice de la caméra active (scene.active_camera
) dans la liste de toutes les caméras présentes dans la scène (scene.cameras
). Nous incrémentons ensuite cet indice. Et nous vérifions que cette nouvelle valeur n'est pas hors limite par rapport au nombre de caméras disponibles dans la scène. Sinon, nous remettons l'indice à 0. En bref, nous bouclons sur toutes les caméras disponibles. Pour modifier la caméra courante, il suffit d'assigner la nouvelle caméra à l'attribute scene.active_camera
.
Il y a une erreur de communication avec le serveur Booktype. Nous ne savons pas actuellement où est le problème.
Vous devriez rafraîchir la page.