Translations of this page:

This is an old revision of the document!
—-

4. Commencer un projet

Juste avant nous avons fait des essais sur une démo pré-compilées, Mais maintenant il est tant de revenir à la racine et de créer un nouveau projet complet comme on a envie. Démarrez le gestionnaire de projet et presser Ctrl+N (sinon cliquez sur l’icône nouveau projet (new project)ou choisissez Nouveau projet (New Project) dans le menu Fichiers (File) ). Nommez votre projet comme vous le souhaitez et laissez WME le créer.

Vous pouvez voir que WME a créé un nouveau projet en y mettant quelques éléments prédéfinis ainsi le démarrage de notre nouveau jeu sera plus simple car nous pouvons dès maintenant lancer ce projet minimaliste et ça marche. Ce que nous allons quand même faire, c'est de porter notre attention sur le point avec lequel le jeu commence réellement. Ce point c'est un simple fichier appelé game.script (Qui se trouve dans data→scripts).

Vous pouvez facilement vérifier dans votre gestionnaire de projet, que le jeu a un script attaché à lui et ça ne sera pas une surprise pour vous, que ce script c'est … game.script. Tout simplement dit, la toute première chose que fait WME après avoir initialisées toutes les fenêtres du système c'est d’exécuter ce fichier. Je parle de ça assez largement, parce que je veut que vous compreniez bien la souplesse de WME. A ce niveau rien n'est décidé, à quoi va ressembler le jeu, comment le jeu se joue, etc…

Essayons de découvrir ce que le script du jeu fait par petit blocs:

#include "scripts\base.inc" 
#include "scripts\keys.inc"

D'abord nous intégrons le fichier base.inc, qui contient 3 variables globales - actor, Scene et Keyboard. Comme ça on a pas besoin, dans chaque script, à déclarer global Scene; avant d'appeler par exemple Scene.GetNode();.
Base.inc à son tour, introduit un autre fichier appelé const.inc qui contient les constantes les directions de l'acteur et les alignement de texte. Au cours de la création de notre jeu nous ajouterons des variables globales et des constantes dans ces fichiers pour garder notre jeu bien rangé. Nous pouvons également séparer nos Includes dans plus de fichiers si on est obligé. Le deuxième fichier contient la définition des codes claviers, nous n'avons donc pas à deviner des chiffres mais tapez simplement leur représentation textuelle comme VK_ESCAPE au lieu de 27 si on veut tester la touche Esc.

Keyboard = Game.Keyboard; 
Scene = Game.Scene;

Comme vous devriez déjà le savoir maintenant, tous les objets de base sont membres de l'objet Game. Mais il y a deux raisons pour lesquelles nous avons besoin de variables pour stocker ces objets imbriqués. Premièrement WME ne permet pas les imbrications donc vous ne pouvez pas utiliser par exemple:

var e = Game.Scene.GetNode("Door");

et deuxièmement ça semble, de toute façon, plus clair si vous écrivez Scene.GetNode("Door");.

Donc, retour à ces lignes - Nous avons créé une variable globale Keyboard qui fait référence à l'objet Game.Keyboard et qui sera utilisé pour interrogé les saisies clavier et une variable globale qui fait référence à l'objet Scene.

Comme petite annotation dans la marge - Cet objet est toujours le même, même si vous décidez de changer des scènes ainsi vous n'avez pas à la réassigner à chaque fois que vous avez changé la scène.

global WinMenu = Game.LoadWindow("interface\menu\menu.window"); 
WinMenu.Visible = false;

Par défaut vous avez un truc prédéfini, que si vous faites un clic droit sur ​​un hot-spot, un petit menu apparait dans lequel vous pouvez choisir entre trois actions. Maintenant, faite moi plaisir et dégommer moi ces 2 lignes. Nous allons essayer de le dépouiller.

Vous devez vous demander, qu'est que window (fenêtre)? Window c'est un groupe d'éléments graphique (boutons, images, champs d’édition pour saisir un texte) ce qui est bien pratique pour concevoir un GUI (Interface Graphique pour l'Utilisateur). Le gros avantage c'est que c'est indépendant de la scène, vous pouvez donc l'avoir à l'écran pour toutes les scènes sans avoir à replacé, expressément, les éléments à chaque fois.

Nous verrons la fabrication des fenêtres plus tard, focalisons nous pour le moment sur ce que veulent dire ses deux lignes. La première ligne charge un fichier .window (qui contient une définition de la fenêtre graphique) et la seconde la rend invisible. Cette fenêtre est attachée à l'objet Game donc le changement de scène ne l'affecte pas. Notez que les fenêtres sont des exceptions. Les entités utilise Active, les fenêtres utilise Visible.

var win = Game.LoadWindow("interface\system\caption.window"); 
global WinCaption = win.GetWidget("caption");

Et encore un chargement de fenêtre! Celle-ci est destinée au légendes (infos-bulles) chaque fois que vous passez votre souris sur le hot-spot. De plus, nous introduisons une toute nouvelle méthode pour faire référence à une partie spécifique de la fenêtre. Celui-ci est le champ réel qui contient le texte. Maintenant pour me faire plaisir - GetWidget est l'ancienne manière d'obtenir le contrôle. Maintenant nous utilisons plus facilement GetControl , donc réécrivez moi la seconde ligne en :

global WinCaption = win.GetControl("caption"); //Vous pouvez également constater la similitude Scene.GetNode(name); Window.GetControl(name);

vient ensuite:

global MenuObject = null;


Nous stockons un null dans MenuObject qui sera utilisé plus tard pour voir ce qui est cliqué. Null est une valeur speciale, qui indique qui n'y a absolument rien. Et vous pouvez, aussi bien, effacer cette ligne.

actor = Game.LoadActor("actors\molly\molly.actor"); 
Game.MainObject = actor;

Maintenant ces lignes sont importantes. La variable "actor" est une variable globale dans base.inc qui sera remplis, maintenant, avec la définition de notre fichier .actor. Encore plus tard nous verrons comment les fichiers d'acteur sont construit. Pour le moment vivons avec le fait que nous avons Molly et qu'elle peut faire tout ce qu'on veut.

Aussi en note dans la marge, nous pouvons une deuxième fonction Scene.LoadActor(actor); qui charge l'acteur mais l'attache à la scène courante et l'acteur est détruit quand vous quittez la scène.

La dernière ligne, nous plaçons notre acteur fraichement chargé dans l'attribut MainObject, ce qui fait la seul chose - lorsque l'acteur se déplace et que la scène est censée défiler, le défilement s'oriente vers l'acteur. Au cas ou il y aurait plusieurs acteurs échangeables (Comme par exemple dans Day of the Tentacle) Cet attribut permettra d'avoir un défilement correct quelque soit le personnage sélectionné. Vous pouvez régler Null dans cet attribut.

Game.AttachScript("scripts\game_loop.script"); //anciennement connu comme game_daemon.script

Nous allons fixer le processus clés, qui s'occupe de l'affichage des légendes et de l'apparition de l'inventaire quand vous glissé votre souris en haut. Ce sera notre second fichier que nous allons examiner dans une minute. Là encore vous pouvez voir, que ce fichier est globalement attaché au jeu entier.

Et voici quelque chose autrefois extrêmement important - désormais paramétrable à partir du gestionnaire de projet:

Game.ChangeScene("scenes\Room\Room.scene");

C'est le point où vous définissez à quel scène commence votre jeu. Habituellement ça sera un genre d’écran menu sauf si vous démarrez par une intro. ou du genre. Maintenant vient la partie principale de nettoyage. Comme nous sommes en plein épuration de notre jeu, nous allons maintenant virer toutes les interactions avec l'inventaire seulement pour les ajouter plus tard lorsque nous serons plus qualifiés.

Donc modifiez simplement les événements dans “LeftClick” pour avoir:

on "LeftClick" 
{ 
  var ActObj = Game.ActiveObject; 
  if(ActObj!=null) 
  { 
     ActObj.ApplyEvent("LeftClick"); 
  } 
  else 
  { 
    Scene.ApplyEvent("LeftClick"); 
  } 
}

Quand nous cliquons avec le bouton droit dans la scène, on regarde en premier si le clique était sur un Hot-spot. WME sait s'il y a un hot-spot sous le pointeur de la souris et remplit l'attribut ActiveObjecten conséquence.
Nous avons, maintenant, réduit notre logique à deux états. Si nous avons cliqué sur un objet, nous allons appelé sont événement “LeftClick”. Ça nous ramène à nos essais dans le dernier chapitre, où nous avons attribué l'événement “LeftClick” de la porte. C'est la raison pour laquelle cet événement s'est appelé en premier. ApplyEvent c'est une méthode qui est utilisée pour lancer des événements manuellement.

Si on clique n’importe où (Pas de hot-spot sous le pointeur), l'événement de la scène "LeftClick" est déclenché. Là, j'ai cru vous entendre crier : " Attends un peu, c'est quoi l’événement de la scène “LeftClick”?!".

C'est une autre astuce de WME qui sort du modèle de scène (Scene template). Si vous créez une nouvelle scène, ou vous ouvrez votre salle de la scène dans l’éditeur de scène et que vous allez dans l'onglet Properties et que vous cliquez sur le bouton "Scripts…", vous allez voir qu'il y a deux scripts attachés. Votre scene_init.script préféré et scripts/scene.script. et comme c'est le modèle que chaque scène utilise, découvrons ce sombre mystère que contient ce fichier?

#include "scripts\base.inc" 
 
on "LeftClick" 
{ 
  actor.GoTo(Scene.MouseX, Scene.MouseY); 
}

HA! C'est ça. Si cet évenement est déclenché, notre acteur va à la position actuelle de la souris dans la scene. Donc pour resumer avec des choses simples: Si on clique sur un hot-spot c'est le "left click" qui est declenché alors notre acteur marche vers la position courante de la souris. Et c'est juste le clique gauche pour le moment.

Déplaçons nous vers l’événement suivant “RightClick” et effacez le bloc entier. Nous n'en avons pas besoin tout suite et ne ferais que vous faire tourner la tête.

Les deux derniers événement (“Keypress” et “QuitGame”) fonctionnent avec les menus d'affichage et la manipulation des combinaison de touches Alt + F4. Nous n'avons pas à nous embêter avec elle pour l'instant, mais rassurez-vous, nous allons les voir rapidement aussi.

Récapitulons les nouvelles méthodes et les attributs que nous avons appris jusqu'à présent dans ce chapitre:

var window = Game.LoadWindow(window filename); - Charge une définition de fenêtre, qu'il attache à l'objet Game et lui retourne éventuellement un référence (dans ce cas à la variable window)
window.Visible = true / false; - Fait que la fenêtre chargée est visible/invisible à l'écran.
window.GetContro(controlname); - Retourne une référence à un contrôle se trouvant dans la fenêtre.
Game.LoadActor(actor filename); - Charge un acteur d'un fichier et l'attache à l'objet Game.
Scene.LoadActor(actor filename); - Charge un acteur d'un fichier et l'attache à un objet scène se détruisant après avoir quitter la scène.
Game.MainObject = actor; Défini vers quel acteur le défilement de la scène est synchronisé.
Game.ActiveObject; - Stocke la reference de l'objet au dessus duquel votre souris se trouve.
Game.ApplyEvent(eventName); - c'est une méthode qui déclenche les événements associés à l'objet Game.
Scene.ApplyEvent(eventName); - C'est une méthode qui déclenche les événements associés à un objet scène.
Node.ApplyEvent(eventName); - C'est une méthode qui déclenche les événements associés au nœud (entité) stocké dans l'objet en question.

Pour mieux comprendre la dernière commande, nous pourrions facilement nous précipiter dans notre dernier chapitre à l’événement “LeftClick” de notre porte qui était comme ceci:

var door = Scene.GetNode("Door"); 
door.ApplyEvent("LeftClick");

J'espère que vous voyez ce que je veux dire maintenant … Examinons maintenant si vous avez le même fichier game.script que j'ai fait avant que nous commencions:

#include "scripts\base.inc" 
#include "scripts\keys.inc" 
 
// store some of the game's attributes in global variables for convenience 
Keyboard = Game.Keyboard; 
Scene = Game.Scene; 
 
// load the "caption" window 
var win = Game.LoadWindow("interface\system\caption.window"); 
global WinCaption = win.GetControl("caption"); 
 
// load our main actor 
actor = Game.LoadActor("actors\molly\molly.actor"); 
Game.MainObject = actor; 
 
// run the "daemon" script 
Game.AttachScript("scripts\game_daemon.script"); 
 
// which scene to load? 
Game.ChangeScene("scenes\Room\Room.scene"); 
 
 
 
on "LeftClick" 
{ 
  var ActObj = Game.ActiveObject; 
  if(ActObj!=null) 
  { 
     ActObj.ApplyEvent("LeftClick"); 
  } 
  else 
  { 
    Scene.ApplyEvent("LeftClick"); 
  } 
} 
 
on "Keypress" 
{ 
  // on Esc or F1 key 
  if(Keyboard.KeyCode==VK_ESCAPE || Keyboard.KeyCode==VK_F1) 
  { 
    // load and display the main menu window 
    WinCaption.Visible = false; 
    var WinMainMenu = Game.LoadWindow("interface\system\mainmenu.window"); 
    WinMainMenu.Center(); 
    WinMainMenu.GoSystemExclusive(); 
    Game.UnloadObject(WinMainMenu); 
  } 
} 
 
on "QuitGame" 
{ 
  // on Alt+F4 (window close) 
  // load and display the quit confirmation window 
  WinCaption.Visible = false; 
  var WinQuit = Game.LoadWindow("interface\system\quit.window"); 
  WinQuit.Center(); 
  WinQuit.GoSystemExclusive(); 
  // and if the user selected Yes 
  if(WinQuit.xResult) 
  { 
    // quit the game 
    Game.QuitGame(); 
  } 
  // otherwise just unload the quit window from memory 
  else Game.UnloadObject(WinQuit); 
}

——————————————
EN COURS DE TRADUCTION
——————————————-

Now test the game and you’ll see that it’s still running although we made quite some changes to it. And as we want to continue boiling our example game down to the necessary minimum, we need to look at the game_loop.script (formerly named game_daemon.script) as well.

#include "scripts\base.inc" 
 
global WinCaption; 
global WinMenu;

We can easily delete the line global WinMenu; because we’ve already dropped the idea of right click menu.

while(true){

This will be always true. This way we are looking at the infinite loop. To end this loop, one would have to call Game.DetachScript("scripts\game_loop.script");

var ActObj = Game.ActiveObject;


We’ve seen exactly the same line before in the game script.

 if(Game.Interactive && ActObj!=null) 
 {

So first we test if the game is interactive and our mouse cursor is over some active object. But we’ll make this condition a bit simpler so we’ll put away all inventory items logic and it’ll look like this:

if(Game.Interactive && ActObj!=null) 
{ 
      WinCaption.X = Game.MouseX; 
      WinCaption.Y = Game.MouseY + 20; 
      WinCaption.TextAlign = TAL_LEFT; 
      WinCaption.Text = ActObj.Caption; 
 
      WinCaption.SizeToFit(); 
      if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth - WinCaption.Width; 
      if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight - WinCaption.Height; 
 
     WinCaption.Visible = true; 
     WinCaption.Focus(); 
} 
else WinCaption.Visible = false;

So what happens if we have our mouse over the object?

WinCaption.X = Game.MouseX; 
WinCaption.Y = Game.MouseY + 20;

WinCaption contains the reference to the text field inside of the caption window loaded in the game script. We set its position to the same coordinates as our mouse X-position and Mouse Y-position + 20 so it’ll be 20 pixels below.

WinCaption.TextAlign = TAL_LEFT; 
WinCaption.Text = ActObj.Caption;

Then we set text aligning to left and set the text of the caption to the node caption as defined in the scene editor.

WinCaption.SizeToFit();

We resize the caption so its size is the same as the size of the displayed text.

if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth - WinCaption.Width;

If the caption width however extends out of the screen, we set our caption X-position to end exactly with the screen border (based on the resolution).

if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight - WinCaption.Height;

We do the same with the height and the bottom border.

WinCaption.Visible = true; 
WinCaption.Focus();

We display our caption by making it visible and give it focus, which is in this case not necessary, because we don’t interact with it. So we can simply delete this line too.

} 
else WinCaption.Visible = false;

The rest means that either the game went into non interactive mode or we moved our mouse out of any active hotspots. In both cases we simply hide the caption.

 if(Game.Interactive && Game.MouseY < 45 && !Game.ResponsesVisible && !WinMenu.Visible) Game.InventoryVisible = true; 
  else if(Game.MouseY > 100 || Game.ResponsesVisible || !Game.Interactive) Game.InventoryVisible = false;

Those two lines deal with inventory showing / disappearing and so we simply delete them.

Sleep(20);

Remember what I’ve told you about infinite loops and hanging computers? Enough said.
So let’s look at our revised game_daemon.script

#include "scripts\base.inc" 
 
global WinCaption; 
 
// infinite loop 
while(true){ 
  var ActObj = Game.ActiveObject; 
 
  if(Game.Interactive && ActObj!=null) 
  { 
      WinCaption.X = Game.MouseX; 
      WinCaption.Y = Game.MouseY + 20; 
      WinCaption.TextAlign = TAL_LEFT; 
      WinCaption.Text = ActObj.Caption; 
      WinCaption.SizeToFit(); 
      if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth - WinCaption.Width; 
      if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight - WinCaption.Height; 
     WinCaption.Visible = true; 
  } 
  else WinCaption.Visible = false; 
  Sleep(20); 
}

As you can see, those are the barebones of our starting project. No inventory, no menus, simple point and click game. Moreover you understand now, what’s the brain behind the game and as we build upon it, you’ll feel more comfortable knowing that you have the rock solid background. Next step: the actor!

 
fr/wmebook/ch4.1319036034.txt.gz · Last modified: 2011/10/19 16:53 by Anto0085
Recent changes RSS feed Creative Commons License Driven by DokuWiki