Novembre 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | Calendrier |
|
|
| [Tuto] Lua scripting et Toribash | |
|
+9*=-Nokturnal44-=* timothee meuhgo Kyat PiR vynzs RolFonk Kevinx Melmoth 13 participants | |
Auteur | Message |
---|
Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: [Tuto] Lua scripting et Toribash Dim 21 Fév 2010 - 21:44 | |
| Comme promis, je vais commencer à vous parler un peu des possibilités offertes par l'addition du scripting lua dans Toribash, dans une série de 12 tutos. Ce thread peut aussi vous servir à poser les questions concernant le scripting lua dans TB. J'essaierai de répondre avec autant de rigueur que possible. Ecrire des scripts demande une certaine connaissance de l'informatique. Parfois même des notions mathématiques et une relative connaissance de l'anglais. Je vais détailler un maximum les bases algorithmiques, mais je ne peux prétendre à vous enseigner la "logique" algorithmique. Si vous n'avez absolument aucune base de développement, ce tutorial sera TRES difficile à appréhender, mais -normalement- pas insurmontable. Chapitre 01 - Qu'est ce qu'un script lua ? Que permet lua dans Toribash ? Que ne permet pas lua dans Toribash ?Résumé : Cours purement théorique, pour situer de quoi on parle.Lua est un langage de script incorporé dans de nombreuses applications actuelles (World of Warcraft pour ne citer que la plus connue) afin d'enrichir le contenu ou de customiser les fonctionnalités du jeu ou de l'application. C'est donc un langage de programmation (comme C ou Java), à ceci près qu'il n'est pas compilé (aucun ".exe" n'est créé) mais interprété : c'est (dans notre cas) Toribash qui lit et traduit le code lua. Je vulgarise à mort, mais en gros, c'est ça. Dans le cas de Toribash, donc, les fichiers lua interviennent à plusieurs niveaux. Le Torishop in game et les tutoriaux in game, par exemple, sont codés en lua. Ce qui nous intéressera majoritairement, nous, ce sont les fichiers ".lua" que l'on place directement dans le dossier "Toribash3.8xx\data\script", et qui sont ensuite accessibles par le menu in game "Setup->Scripts". Pour éditer les fichiers .lua, le bloc note suffit. Mais je vous conseille d'utiliser un éditeur un peu plus avancé, NotePad ++ par exemple. Maintenant, LA question. A quoi servent ces scripts lua ? Réponse : à beaucoup de chose. Les scripts vous permettent d'intervenir à plusieurs niveau, que ce soit au niveau du gameplay ou de l'affichage (2D et 3D). Théoriquement, il est possible de créer un éditeur de mod, un ukebot avec intelligence artificielle, un administrateur automatique de serveur toribash, un "mode story"... La seule grosse limitation (mais heureusement qu'elle existe) : vous ne pouvez pas interagir avec les toris dans une scène multiplayer, car les positions des toris, les points, les DMs et les conditions de victoire/défaite sont calculés côté serveur, et votre script s'exécute côté client. Il existe d'autres limitations gênantes, comme l'impossibilité de lire un fichier dans un dossier parent au dossier script, l'impossibilité de modifier la position spatiale d'une goutte de sang... mais la gestion de lua par Toribash est quand même suffisamment riche pour vous offrir satisfaction. Fin du premier cours, si vous avez des questions, utilisez ce thread. Au prochain cours vous écrirez votre premier programme en lua ! Le saviez-vous ?- Vous pouvez éxécuter un script grâce à la commande chat : "/ls nom_du_script.lua"
- J'ai eu l'idée du script atmospheres en essayant de coder un système de sang "réaliste". J'ai remarqué une limitation du nombre de gouttes de sang et je me suis dit "ce serait à peine suffisant pour des flocons de neige !".
Chapitre 02 - Les instructions basiques : les variables, les conditions, les boucles, les opérateurs, l'écriture console, le debugging.Résumé : Tuto sur les bases de l'algorithmique. Travaux pratiques : affichage des nombres pairs dans la console.Lua, comme tout langage informatique, contient un ensemble de mots clés, que l'on doit utiliser pour écrire ses instructions. D'une manière générale, l'exécution des instructions se fait dans l'ordre où elles sont écrites, même si nous verrons plus tard que ce n'est pas tout à fait vrai. Avant toute chose, je vais vous parler un peu des variables. Les variables sont des objets informatiques qui ont un nom, un type et une valeur. Si j'écris dans mon code lua : - Code:
-
truc=145 Alors partout dans mon code, je pourrais utiliser le mot "truc" pour désigner le nombre 145. Pour l'instant, ça vous parait pas très utile, on est d'accord. Mais sans variable, on ne peut pas faire d'informatique.
Parmi les instructions de base, on distingue le if, mot clé de la condition. Sa syntaxe en lua est la suivante : - Code:
-
if (condition) then liste d'instructions else (facultatif) autre liste d'instruction (facultatif) end Par exemple, si j'écris : - Code:
-
truc=145 if (truc<150) then truc=30 end Voila ce qui se passe : Je rentre la valeur 145 dans la variable "truc". Je teste grâce au if : est-ce que "truc" est inférieur à 150 ? 145 est bien mathématiquement inférieur à 150, donc j'exécute les instructions qui sont entre le "then" et le "end" : je mets la valeur 30 dans "truc". A la fin de mon code, "truc" est donc égal à 30. Par contre, si j'ai : - Code:
-
truc=301 if (truc<150) then truc=30 end Comme 301 n'est pas inférieur à 150, je n'exécute pas le "truc=30". A la fin de mon code, "truc" est toujours égal à 301. Un autre exemple avec l'instruction "else" : - Code:
-
truc=301 if (truc<150) then truc=30 else truc=456 end Les instructions écrites entre "else" et "end" sont exécutées si et seulement si la condition du if n'est pasvraie. 301 n'est pas inférieur à 150, donc on n'exécute pas le "truc=30". Par contre, on rentre dans les instructions du else et on exécute "truc=456". A la fin de notre code truc est donc égal à 456.
Voyons maintenant les instructions d'itération. Traduction : les boucles. Les boucles sont utilisées pour faire des opérations répétitives. On distingue deux mots clés différents pouvant générer une boucle en lua : le for et le while. Un petit exemple pour comprendre le for : - Code:
-
for truc=1,8 do machin=truc end est équivalent à : - Code:
-
machin=1 machin=2 machin=3 machin=4 machin=5 machin=6 machin=7 machin=8
Explication : "for truc=1,8 do" veut dire "pour truc allant de 1 à 8, je fais". Donc on fait les instructions pour truc=1, puis pour truc=2, et ainsi de suite jusqu'à truc=8. Donc notre variable "machin" aura pour valeur 8 à la fin du for. Il existe une variante de syntaxe pour le for : - Code:
-
for truc=1,11,2 do machin=truc end Vous avez remarqué le "2" ? Situé comme il est, il veut dire qu'au lieu de compter "truc" de 1 en 1, on le compte de 2 en 2. Ce code est donc équivalent à : - Code:
-
machin=1 machin=3 machin=5 machin=7 machin=9 machin=11
Passons au while. Son utilisation est parfois plus naturelle que le for, mais leurs utilisations est globalement similaire. Syntaxe : - Code:
-
while(condition) do instructions end
Veut dire : tant que la condition est vraie, j'exécute les instructions entre le do et le end. Exemple : - Code:
-
compteur=0 truc = 0 while(compteur<3) do compteur = compteur + 1 truc = truc + 3 end
Première arrivée au while, compteur et truc sont à 0. 0 est inférieur à 3, donc on rentre dans les instructions. Deuxième passage par le while, on a donc compteur à 1 et truc à 3. 1 est toujours < 3, donc on fera un troisième passage dans le while avec compteur = 2 et truc = 6. Au quatrième coup, compteur est égal à 3 et 3 n'est pas strictement inférieur à 3. Donc on ne rentre pas dans les instructions du while et on passe à la partie après le while. C'est la fin de notre programme, et truc est égal à 6. C'est également la fin de notre second cours. TP n°1 : Enumérez moi les nombres pairs de 0 à 40, en utilisant un for ou un while.Correction : - Code:
-
for nbr=0,40,2 do run_cmd("echo " .. nbr) end
- Code:
-
nbr = 0 while(nbr<41) do run_cmd("echo " .. nbr) nbr = nbr + 2 end
Le saviez-vous ?- Une variable peut avoir un nom comportant n'importe quelle suite de lettres, de chiffres ou de "_". Les autres caractères sont interdits.
- Vous pouvez écrire des lignes de commentaires dans votre code lua en commençant votre ligne par "--". Ces lignes de commentaires ne sont pas interprétées par Toribash, vous pouvez donc vous en servir pour prendre des notes ou pour annoter un passage compliqué dans votre code.
Chapitre 03 - les types de variables, les tables, les fonctions.Résumé : Tuto sur l'algorithmique "avancée". Travaux pratiques : optimisation du TP précédent.Nous avons vu que les variables avaient un nom, une valeur et un type, mais je n'ai pas trop parlé des types. Le type d'une variable définit le contexte dans laquelle elle peut être utilisé. Un exemple vaudra mieux que ma définition peu claire : en lua, vous utiliserez en majorité des nombres (sur lesquels ont peut effectuer des opérations mathématiques), des chaînes de caractères (des mots, des phrases, que l'on peut concaténer, afficher, etc.), des booléens (vrai ou faux) et des tableaux (ensemble de nombres ou de chaînes regroupé en un seul élément). Le lua n'est pas fortement typé, cela signifie que vous n'êtes pas obligé de préciser le type d'une variable lors de sa déclaration. Ce qu'il est possible de faire avec des variables numériques : - Les comparer avec : == (égal), ~= (différent), < (strictement inférieur), > (strictement supérieur), <= (inférieur ou égal), >= (supérieur ou égal)
- Utiliser les opérateurs basiques : +, -, *, / (division), % (division entière),^ (puissance)
- Utiliser les fonctions de la bibliothèques 'math' : math.cos(x) retourne le cosinus de x, par exemple. Elles sont détaillées ici en anglais.
Ce qu'il est possible de faire avec des chaînes de caractères : - Les concaténer avec "..". Par exemple "Melmoth " .. "gére l" .. "e steac" .. "k" est équivalent à "Melmoth gére le steack".
- Utiliser les fonctions de la bibliothèques 'string' et pattern (compliqué, à vour plus tard).
Ce qu'il est possible de faire avec des booléens : - Utiliser les opérateur 'and', 'or' et 'not'
- Les utiliser comme condition dans un if ou un while.
Ce qu'il est possible de faire avec un tableau : - Ajouter un élément, le trier, récupérer sa taille ou utiliser les fonctions de la bibliothèque table.
- Récupérer le i-ème élément : si t est notre tableau, t[1] est le premier élèment, t le i-ème .
Exemples concrets d'utilisationAffichage des nombres pair de 0 à 40 sur une seule ligne : - Code:
-
chaine_resultat = "" for i=0,40,2 do chaine_resultat = chaine_resultat .. " " .. i end run_cmd("echo " .. chaine_resultat)
En gros :
- initialisation de la chaine, vide
- pour tous les nombres pairs de 0 à 40
- on concatène notre variable chaine_resultat avec un espace séparateur, puis la valeur de i, qui se convertit tout seul en chaine.
- on affiche notre ligne dans le chat.
Utilisation d'un tableau pour stocker une valeur aléatoire correspondant à l'état des joints, puis affichage :Un petit bout de code utile si vous voulez faire un random ukebot... - Code:
-
-- initialisation joints_uke = { } for i=0,19 do joints_uke[i] = math.random(1,4) run_cmd("echo Le joint n°" .. i .. " est a l'etat : " .. joints_uke[i]) end
On verra dans un prochain cours comment réellement faire un random ukebot... c'est facile vous verrez. Donc ici, on commence par initialiser le tableau vide ( { } ) Pour les 20 joints, on utilise la fonction random entre 1 et 4 pour associer un etat au joint, et on rentre cette valeur dans notre tableau. On affiche ensuite le numéro du joint et son etat. Les fonctions.Attention, ça va se compliquer un peu. Les fonctions sont très utiles pour structurer votre code, le rendre plus lisible, et plus court. Chaque fois qu'on écrit plusieurs fois le même code, il faut se dire qu'on aurait pu faire plus court en utilisant une fonction. Une fonction a un nom, peut avoir un type, peut avoir une liste de paramètres. Voici comment définir une fonction : - Code:
-
function nom_de_lafonction([param1,[param2,[...]]])
....Instructions....
[return une_valeur] end
Tout qui est entre [] est facultatif. Voici une fonction basique qui affiche "Hello World" : - Code:
-
function hw() run_cmd("echo hello world") end
Si vous n'écrivez que ça dans votre programme lua, il ne fera rien. Il ne s'agit que de la définition de la fonction, il faut maintenant l'appeler comme ceci, à la suite de la définition. - Code:
-
hw() Allez, un exemple compliqué. Une fonction qui retourne une phrase décrivant l'état d'un joint (selon notre tableau de toute à l'heure, pas encore l'état des vrais joints). - Code:
-
joints_uke = { }
-- notre fonction function display_joint(no_joint) resultat = "Le joint no " .. no_joint .. " est " if(joints_uke[no_joint] == 1) then resultat = resultat .. "contract" elseif(joints_uke[no_joint] == 2) then resultat = resultat .. "extend" elseif(joints_uke[no_joint] == 3) then resultat = resultat .. "hold" elseif(joints_uke[no_joint] == 4) then resultat = resultat .. "relax" end return resultat end
-- on remplit notre tableau for i=0,19 do joints_uke[i] = math.random(1,4) end
--On appelle notre fonction pour les joints 0 et 4. run_cmd("echo " .. display_joint(0)) run_cmd("echo " .. display_joint(4))
Si vous avez compris cet exemple, vous maîtrisez parfaitement les fonctions. Vous pouvez vous attaquer au TP n°2. Le saviez-vous ?- Pour plus de propreté et de sécurité, vous pouvez mettre le mot clé "local" devant vos déclaration de variables ou de fonction. Cela empêche la variable d'être vue par d'autre script lua, et cela permet d'éviter les conflits de variables entre deux scripts différents.
- Une fonction peut en appeler une autre ! Elle peut même s'appeler elle même, mais attention aux boucles infinies qui bloqueront Toribash
Chapitre 04 - Les HooksRésumé : comment automatiser une fonction dans Toribash. Travaux pratiques : gestion du clavier pour changer la valeur d'une variable, et hook sur l'affichage 2D.On passe aux choses amusantes. La leçon d'aujourd'hui concerne les hooks, qui permettent en fait la gestion des évènements et l'automatisation des fonctions (voir chapitre précédent) dans Toribash. Un exemple pour mieux comprendre, il est possible de détecter l'évènement "appui sur une touche du clavier" et de l'associer à une fonction écrite par vos soins (permettant par exemple la gestion améliorée d'une caméra ou même un jeu 2D intégré à TB !). La syntaxe d'ajout d'un hook est la suivante : - Code:
-
add_hook(evenement, nom_du_groupe, votre_fonction) -> evenement est l'évènement déclencheur du hook. C'est une chaîne de caractère (chaîne entre guillemets) parmi la liste décrite plus bas. -> nom_du_groupe sert à préciser le groupe du hook. Cela permet de 'classer' vos hooks en plusieurs groupes distincts afin de ne retirer les hooks appartenant à un groupe tout en laissant les autres. C'est également une chaîne de caractère, définie par vos soins. -> votre_fonction est le nom (sans guillemets, cette fois) de la fonction que vous voulez appeler quand l'évènement 'evenement' a lieu Vous pouvez également retirer un hook ou un groupe de hook : - Code:
-
remove_hook(evenement, nom_du_groupe, votre_fonction) -- suppression d'un hook remove_hooks(evenement, nom_du_groupe) -- suppression d'un groupe de hooks La liste des évènements "hookables" est décrite dans startup.lua : - Code:
-
"new_game" (début d'une nouvelle partie) "new_mp_game" (début d'une nouvelle partie multiplayer) "enter_frame" (entrée dans une nouvelle frame) "end_game" (fin d'une partie ou d'un replay) "leave_game" (fin d'une partie ou d'un replay, pas vu de différences notables avec le précédent) "enter_freeze" (entrée dans le mode 'edit') "exit_freeze" (sortir du mode 'edit') "key_up" (une touche du clavier a été relachée) "key_down" (une touche du clavier a été pressée) "mouse_button_up" (un bouton de la souris a été relaché) "mouse_button_down" (un bouton de la souris a été pressé) "mouse_move" (la souris a été bougée) "player_select" (un joueur a été sélectionné (par clic sur son Tori, en mode SP)) "joint_select" (un joint a été sélectionné (quand la souris passe dessus)) "body_select" (pareil qu'au dessus avec les parties du corps, je crois) "draw2d" (affichage 2D, intervient 30 à 60 fois par secondes, selon votre FPS, juste après draw3D) "draw3d" (affichage 3D, intervient 30 à 60 fois par secondes, selon votre FPS) "play" (passage en mode "replay") "camera" (camera solicitée) "console" (qq chose a été écrit dans le chat) -- Tous les suivants sont pour la gestion de la souris sur un joueur dans la liste d'attente, en MP) "bout_mouse_down" "bout_mouse_up" "bout_mouse_over" "bout_mouse_outside" "spec_mouse_down" "spec_mouse_up" "spec_mouse_over" "spec_mouse_outside" Allez, deux exemples concrets avant le TD afin de bien comprendre comment ça marche. Exemple 1 : Affichage des coordonnées de la sourisL'affichage des coordonnées du pointeur de la souris peut se faire en deux étapes : 1°) Récupération des coordonnées de la souris (Hook sur le déplacement de la souris) 2°) Affichage de ces coordonnées (Hook sur l'affichage 2D) Pour afficher les coordonnées, je vais me servir de la fonction draw_text(text,x,y,font), que vous apprendrez en détail dans le cours suivant (dessin 2D). Place au code, qui, je pense, est assez clair : - Code:
-
local mouse_pos_x = 0 local mouse_pos_y = 0
-- on ecrira en rouge... explications au cours suivant
local function update_coord(x,y) mouse_pos_x = x mouse_pos_y = y end
local function draw_coord() set_color(1,0,0,1) draw_text("X : " .. mouse_pos_x,20,100,2) draw_text("Y : " .. mouse_pos_y,20,120,2) end
add_hook("mouse_move","coord_souris", update_coord) add_hook("draw2d","coord_souris", draw_coord)
Lancez le script, bougez la souris... c'est magique. Exemple 2 : Un menu au clavierLa particularité de cet exemple est la façon dont les hooks communiquent entre eux : vous pouvez effectivement activer ou désactiver le hook sur l'affichage 2D grace au hook sur le clavier. Lisez bien attentivement pour comprendre ce qu'il se passe. - Code:
-
-- les éléments de notre menu local list_items_menu = {"Item 1","Item 2","Item 3","Item 4","Item 5"}
-- l'élément sélectionné local selected_item = 1
-- booleen servant a savoir si on doit ou non afficher le menu local bool_menu = true
local function menu_clavier() --explications des fonctions 2D la semaine prochaine --dessin du fond du menu set_color(0.1,0.1,0.1,0.5) draw_quad(20, 100, 320, 250)
set_color(0,0.3,0.5,1) draw_text("Fermez et ouvrez le menu avec 'A'", 25, 105,1) draw_text("Naviguez avec les fleches et validez avec 'L'", 25, 125,1) set_color(0,0.1,0.3,1) for i=1,table.getn(list_items_menu) do if(i==selected_item) then set_color(0.8,0,0,1) draw_text(i .. ". " .. list_items_menu[i], 30, 150+(i*20),1) set_color(0,0.1,0.3,1) else draw_text(i .. ". " .. list_items_menu[i], 30, 150+(i*20),1) end end end
local function key_pressed(key) -- les return 1 servent à 'annuler' le vrai effet des touches (les flêches ne bougeront pas la caméra si le menu est actif) if(key == 273 and bool_menu) then selected_item = selected_item - 1 if (selected_item < 1) then selected_item = table.getn(list_items_menu) end return 1 elseif(key == 274 and bool_menu) then selected_item = selected_item + 1 if (selected_item > table.getn(list_items_menu)) then selected_item = 1 end return 1 elseif(key == 108 and bool_menu) then run_cmd("echo Item choisi : " .. list_items_menu[selected_item]) return 1 elseif(key == 113 and not bool_menu) then add_hook("draw2d", "menu_clavier", menu_clavier) bool_menu = true return 1 elseif(key == 113 and bool_menu) then remove_hook("draw2d", "menu_clavier", menu_clavier) bool_menu = false return 1 end if(bool_menu) then return 1 else return 0 end end
add_hook("draw2d", "menu_clavier", menu_clavier) add_hook("key_down","menu_clavier", key_pressed) C'est tout pour aujourd'hui. N'hésitez pas à poser des questions, je sais que ça se complique, là. Chapitre 05 - Dessin 2DRésumé : détail des possibilités offertes par le Hook sur l'affichage 2D. Travaux pratiques : divers effets 2D.Cours un peu plus "récréatif que la semaine dernière, puisqu'il s'agit d'une application directe et amusante des hooks sur l'affichage 2D. En résumé, vous allez pouvoir dessiner sur le premier plan (devant les toris, donc "par dessus" toute la scène 3D). Pour commencer, il semblerait qu'il ne soit possible de dessiner uniquement lors d'un hook sur "draw2d". Les diverses primitives de dessin 2D sont les suivantes : - Code:
-
Primitives : draw_disk(number pos_x, number pos_y, number inner, number outer, integer slices, integer loops, number start, number sweep, integer blend) -> Dessine un donut ou un disque à la position voulue draw_quad(number pos_x, number pos_y, number width, number height [, integer texture_id]) -> dessine un rectangle, texturé ou non, à la position voulue
Ecriture de texte : draw_text(string text, number pos_x, number pos_y [, integer font_type]) -> écrit du texte à la position voulue, de la taille voulue. draw_right_text(string text, number pos_x, number pos_y [, integer font_type]) -> écrit du texte aligné à droite à la position voulue, de la taille voulue. pos_x correspond cette fois à la distance entre la fin du texte et le bord droit de la fenêtre. draw_centered_text(string text, number pos_y [, integer font_type]) -> Ecrit le texte centré horizontalement, à la hauteur voulue, de la taille voulue
Moins utile : draw_chat_message(integer index, number pos_x, number pos_y) -> Ecrit le ième message du chat à la position voulue. draw_chat_messages(number pos_x, number pos_y) -> Ecrit tous les messages du chat à la position voulue
Il existe également d'autres fonctions intéressantes pour le dessin 2D : - Code:
-
set_color(number red, number green, number blue, number alpha) -> fixe la couleur pour le dessin de la prochaine primitive. Red, Green, Blue et Alpha (transparence) sont des valeurs décilmales comprises entre 0 et 1. get_window_size(...) = number,number -> Pour récupérer la taille de la fenêtre (voir exemple dans l'énoncé du TD) get_screen_pos(number x, number y, number z); = number,number -> pour récupérer les coordonnées 2D courantes d'un point 3D
J'imagine qu'il doit rester quelques points obscurs, notamment sur les disks, les quads à textures et les polices de caractères, que j'ai honteusement oublié de décrire en détail. Je vais le faire en exemple : Les polices de caractères : pour mieux comprendre, lisez et exécuter le script suivant, vous allez voir les différents types de polices disponibles : - Code:
-
local function hook2D_display() set_color(0.5,0,0,1) for i=0,3 do draw_text("Ecriture en police " .. i, 10, 100+(60*i),i) end end
add_hook("draw2d", "exemple", hook2D_display)
Les quads, avec ou sans textures : copier une head texture dans votre dossier data/scripts et exécuter le code suivant : - Code:
-
texid = load_texture("head.tga")
local function hook2D_display() set_color(0,0,0,1) draw_text("un rectangle noir sans texture :",10,100) draw_quad(240, 100, 60, 45) draw_text("un rectangle avec texture :",10,160) set_color(1,1,1,1) -- nécessaire de remettre une couche de blanc draw_quad(240, 160, 60, 45, texid) end
add_hook("draw2d", "exemple", hook2D_display)
Les disks, explications des divers paramètresLes différents paramètres des disques permettent en fait le dessin de toutes sortes de formes. draw_disk(number pos_x, number pos_y, number inner, number outer, integer slices, integer loops, number start, number sweep, integer blend) inner = Le rayon du trou au milieu du disque outer = Le rayon extérieur du disque slices = Nombre de subdivision du disque loops = Nombre d'anneau concentriques subdivisant le disque start = L'angle de départ, en degré, de la portion de disque sweep = L'angle total de la portion de disque blend = Je crois que c'est encore une couche alpha mais qui se fond avec le noir, pas avec le blanc... à vérifier. Des exemples : - Code:
-
local function hook2D_display() set_color(0,0,0.3,1) -- Disque complet : draw_disk(70, 100, 0, 50, 32, 1, 0, 360, 0) -- Camembert draw_disk(70, 230, 0, 50, 32, 1, 40, 300, 0) -- Donut : draw_disk(70, 360, 20, 50, 32, 1, 0, 360, 0) -- Carre draw_disk(170, 230, 40, 50, 4, 1, 45, 360, 0) -- Triangle draw_disk(170, 360, 40, 50, 3, 1, 180, 360, 0) end
add_hook("draw2d", "exemple", hook2D_display)
Voila, voila, vous êtes prêts pour le TP. Chapitre 06 - Modélisation 3DRésumé : détail des possibilités offertes par le Hook sur l'affichage 3D. Travaux pratiques : divers effets 3D.Pour ce cours, même principe que la dernière fois, sauf qu'au lieu de dessiner de la 2D au premier plan, on modélisera carrément des objets 3D notre scène 3D. Pour clarifier les choses une fois pour toute : ce n'est pas du modding, les objets que vous ajoutez n'ont qu'une présence visuelle, et non physique. Il n'y aura donc aucune collision avec les éléments ajoutés (à moins que vous les codiez vous même... bonne chance). Pour ceux qui suivent, c'est bien la technique que j'utilise dans mes atmosphères. Il n'est possible de modéliser des objets 3D que dans un hook sur draw3D. La liste des commandes 3D : - Code:
-
Primitives :
draw_box( number pos_x, number pos_y, number pos_z, number size_x, number size_y, number size_z, number rotation_x, rotation_y, rotation_z) -- modélisation d'un pavé
draw_capsule( number pos_x, number pos_y, number pos_z, number height, number radius, number rotation_x, rotation_y, rotation_z) -- modélisation d'une capsule (exemple : les tibias de votre tori sont des capsules)
draw_disk_3d(number pos_x, number pos_y, number pos_z, number inner, number outer, integer slices, integer loops, number start, number sweep, integer blend) -- modélisation d'un disque (cercle plein), qui pour moi bugge à mort
draw_sphere( number pos_x, number pos_y, number pos_z, number radius) -- modélisation d'une sphère
Primitives avec matrices de rotation :
draw_box_m( number pos_x, number pos_y, number pos_z, number size_x, number size_y, number size_z, table matrix_rot)
draw_capsule_m( number pos_x, number pos_y, number pos_z, number height, number radius, table matrix_rot)
draw_sphere_m( number pos_x, number pos_y, number pos_z, number radius, table matrix_rot)
Divers :
set_color(number red, number green, number blue, number alpha) -- fixe la couleur pour le dessin de la prochaine primitive. Red, Green, Blue et Alpha (transparence) sont des valeurs décilmales comprises entre 0 et 1.
draw_ground_impact(integer player_index) -- peu utile, dessine un disque creux sous le joueur indiqué.
Ok, donc la principale difficulté est d'ordre mathématique : vous devez maitriser les coordonnées spatiales (x,y,z) et surtout les rotations spatiales (pas évident du tout). Je suis pas le mieux placé pour expliquer tout ça, je m'aide pas mal des forums mathématiques quand j'ai un problème. Des exemples de difficultés que l'on peut rencontrer : déplacer des objets selon un chemin circulaire ou pseudo aléatoire, concevoir des formes complexes à partir de plusieurs primitives et leur faire faire une rotation ensemble... derrière, il y a des maths, et si vous regardez un peu le code des atmos, vous verrez que c'est pas toujours évident. Mais les exemples simples peuvent aussi être très efficaces. Ensemble je vais vous montrer comment faire un temple basique autour de votre combat. Commençons par le plus simple : le toit du temple : un pavé plat, horizontal, au dessus des toris. J'ai choisi une couleur gris clair sympa. Les positions en x et en y sont à 0 afin de centrer le pavé. La hauteur est de 12, ça parait pas mal pour un temple J'ai choisi une largeur et une longueur de 65, mais rien n'oblige à faire le pavé carré ! L'épaisseur est de 2. Enfin, les 3 "0" qui suivent correspondent à la une rotation nulle sur tous les angles, vu qu'on veut notre toit bien à plat. On met le tout dans un hook sur draw3d, et ça donne ça : - Code:
-
local function draw_temple() set_color(0.9,0.9,0.9,1) draw_box(0, 0, 12, 65, 65, 2, 0, 0, 0) end
add_hook("draw3d", "lua_tuto", draw_temple) On va ajouter les colonnes à l'aide de plusieurs capsules bien réparties. On pourrait les ajouter une par une, mais comme nous sommes fainéants (et intelligents) on va plutôt utiliser des "for". Toutes nos capsules auront la même hauteur, et les mêmes dimensions. Elles auront également toutes une rotation nulle en tout angle. Seuls les paramètres correspondant aux positions et x et en y vont varier d'une colonne à l'autre, c'est ce qu'on va faire varier dans nos for. Mettons que nous voulons 6 colonnes par "côtés" du temple. Commençons par le for alignant 8 colonnes selon l'axe des y (x restera fixé). Nos colonnes auront un rayon de 1, donc on peut faire varier leurs positions entre -30 et 30 (je rappelle que la largeur du temple est 65, centré en 0). Dans un "for i=0,5", notre position y variera selon (-30 + 12*i) (soit bien entre -30 et 30). Bon, c'est un peu décousu comme ça... mais c'est une excellente manière d'avoir des formes géométriques parfaitement droites, donc accrochez vous Dans le même for, on peut modéliser les colonnes parallèles, celles de l'autre côté du temple. Ca donne ça : - Code:
-
for i=0,5 do draw_capsule( 30, (-30 + 12*i), 6, 12, 1, 0, 0, 0) draw_capsule( -30, (-30 + 12*i), 6, 12, 1, 0, 0, 0) end On aurait pu modéliser aussi les 2 autres côtés du temple, en utilisant le même for, deux autres draw_capsule mais avec les coordonnées x et y inversées. L'ennui c'est que chaque angle aurait été doublé, ce qui est inutile est couteux (pas trop, mais mieux vaut prendre tout de suite de bonnes habitudes). On va donc faire un autre for, mais cette fois en supprimant les colonnes extrèmes, donc un for de 0 à 4. - Code:
-
for i=1,4 do draw_capsule( (-30 + 12*i), 30, 6, 12, 1, 0, 0, 0) draw_capsule( (-30 + 12*i), -30, 6, 12, 1, 0, 0, 0) end Si vous n'avez pas les shaders, le sol est transparent dans un monde blanc, donc vous voyez le bas de colonnes et c'est moche. On va donc faire un sol opaque qui cache ça : un pavé très fin à altitude 0. - Code:
-
draw_box(0, 0, 0, 70, 70, 0.001, 0, 0, 0) Et voila notre temple ! Le code complet : - Code:
-
local function draw_temple() set_color(0.9,0.9,0.9,1) draw_box(0, 0, 12, 65, 65, 2, 0, 0, 0) draw_box(0, 0, 0, 70, 70, 0.001, 0, 0, 0)
for i=0,5 do draw_capsule( 30, (-30 + 12*i), 6, 12, 1, 0, 0, 0) draw_capsule( -30, (-30 + 12*i), 6, 12, 1, 0, 0, 0) end for i=1,4 do draw_capsule( (-30 + 12*i), 30, 6, 12, 1, 0, 0, 0) draw_capsule( (-30 + 12*i), -30, 6, 12, 1, 0, 0, 0) end end
add_hook("draw3d", "lua_tuto", draw_temple) Et bien, je crois qu'on peut passer au TD. Chapitre 07 - Récupérer/Modifier les options, les règles et les informations concernant un replayRésumé : comment récupérer et changer la valeur des game rules ou des options. Travaux pratiques : affichage de tout ce qu'il est possible de récupérer. Chapitre 08 - Les entrées/sorties : les fichiersRésumé : comment sauvegarder et charger des données dans un fichier. Travaux pratiques : sauvegarde et chargement du mod et des game rules. Chapitre 09 - Customisation des TorisRésumé : Changer les couleurs des Toris. Travaux pratiques : un ToriArlequin ! Chapitre 10 - Manipuler les Toris et les éléments de la scèneRésumé : Comment récupérer/modifier l'état des joints, comment démembrer/fracturer un joint, comment obtenir ou modifier les coordonnées spatiales des Toris et de la caméra. Travaux pratiques : un extracteur d'opener basique. Chapitre 11 - Compléments d'infoRésumé : Utiliser les scripts d'interface graphique de Blam, les fonctions plus "exotiques" du scripting lua... tout ce qui ne rentre pas dans les autres tutos va là. Travaux pratiques : un éditeur de shader avec interface graphique avancée. Chapitre 12 - Tuto ouvertRésumé : Vous choisissez un projet, je réalise en détaillant tous les aspects.
Dernière édition par Melmoth le Mar 13 Avr 2010 - 16:40, édité 8 fois | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Dim 21 Fév 2010 - 21:46 | |
| Voila, pour l'instant le contenu est vide mais vous aurez une idée de ce qui vous attends. Je commence en fin de semaine prochaine si tout va bien. Je préviens, il n'y aura pas d'update régulière, mais j'essaierai de pas trop m'éterniser. Vous pouvez commencer à poser des questions si vous en avez, et vous pouvez même commencer à parler du projet du tuto 10 | |
| | | Kevinx
Messages : 12 Date d'inscription : 10/02/2010 Age : 28 Localisation : Toulouse
| Sujet: Re: [Tuto] Lua scripting et Toribash Lun 22 Fév 2010 - 1:04 | |
| j'attend se tuto avec impatiance (je pense que je connais un peut les bases mais ce n'est pas exeptionel ^^) | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 24 Fév 2010 - 12:07 | |
| Premier cours ajouté. Juste une intro, rien de très folichon. Le deuxième devrait suivre rapidement. | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 24 Fév 2010 - 18:48 | |
| Second cours ajouté. Enoncé de premier TP : Enumérez moi les nombres pairs de 0 à 40, en utilisant un for ou un while.La commande pour afficher la valeur de la variable "truc" (par exemple) dans le chat Toribash est : - Code:
-
run_cmd("echo " .. truc) A vous de jouer ! Jouez le jeu, vous progresserez plus vite en pratiquant plutôt qu'en ne faisant que lire. | |
| | | RolFonk ToriDédié
Messages : 161 Date d'inscription : 28/12/2009 Age : 32 Localisation : Normandie
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 24 Fév 2010 - 19:11 | |
| Ce tuto est particulièrement intéressant Melmoth! Vivement la suite. Alors j'ai essayé d'écrire mon "script" (à ce niveau là je sais pas si on peut appeler ça comme ça!^^) permettant d'énumérer les nombre pair de 0 à 40, mais, je n'ai pas très bien compris comment "l'utiliser". Si je rentre ma commande dans toribash, si elle est correct, je devrais voir s'afficher les nombres pairs dans la boite de chat? Je n'ai pas compris ta commande pour afficher la variable, je ne vois pas comment m'en servir. :/ Par quoi remplacer "truc"? Et que faire des " . . " entre le "echo" et le nom de la variable? Désolé de poser autant de questions! | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 24 Fév 2010 - 19:18 | |
| Non, te désole pas, le topic est là pour ça. Donc, tu dois écrire ton code dans un fichier blablabla.lua, et mettre ce fichier dans le dossier data/script de Toribash. Ensuite, tu le verras dans le menu "Setup->script" in game, et en cliquant sur load, tu l'exécuteras. Pour la commande ' run_cmd("echo " .. truc) ' , truc est le nom de la variable, tu dois donc le remplacer par le nom de ta variable. Les '..' restent tel quel, je vous expliquerai à quoi ils servent dans le prochain cours. En gros si dans ton code il y a : - Code:
-
ggyyuu=345 run_cmd("echo " .. ggyyuu) Ca écrira 345 Enfin, si vous avez un bout de code qui ne marche pas, postez le ici, que je vois si vous êtes proche du but et que je corrige vos erreurs. | |
| | | RolFonk ToriDédié
Messages : 161 Date d'inscription : 28/12/2009 Age : 32 Localisation : Normandie
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 24 Fév 2010 - 19:35 | |
| Bon bha mon code ne marche pas! Je suis déçu! for nombre=0,40,2 do pair=nombre end J'ai un message d'erreur quand je rentre la commande, j'en déduit donc que le code est faux.. | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 24 Fév 2010 - 20:07 | |
| Mmmmh presque La commande 'run_cmd("echo " .. ) ' est à mettre dans le fichier lua également, c'est elle qui permet l'affichage ! En gros c'est ton fichier lua qui doit aussi se charger d'afficher ces nombres pairs. | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 24 Fév 2010 - 23:13 | |
| Monsieur, j'ai fini l'exercice. Et j'attends avec impatience la suite ! Edit : Par contre, y a un moyen de tout afficher sur la même ligne ? | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Jeu 25 Fév 2010 - 0:39 | |
| - vynzs a écrit:
- Monsieur, j'ai fini l'exercice.
Avec le while aussi ? - vynzs a écrit:
- Par contre, y a un moyen de tout afficher sur la même ligne ?
Oui, ça sera traité au prochain cours. | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Jeu 25 Fév 2010 - 14:41 | |
| | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Ven 26 Fév 2010 - 13:50 | |
| Correction du TP n°1 ajoutée au premier post. Cours n°3 ajouté également.
TP n°2 :
1°/ Ecrivez une fonction "double" prenant en paramètre un nombre, en renvoyant le double de ce nombre. 2°/ Déclarer un tableau, et remplissez le des 20 premiers entiers (0,1,2.... 19) 3°/ Utilisez une boucle for et un appel à votre fonction "double" pour transformer ce tableau, afin qu'il contienne les 20 premiers entiers pairs. 4°/ Affichez le contenu de ce tableau sur une seule ligne, chaque nombre sera séparé du suivant par une virgule.
Le prochain cours sera beaucoup plus marrant ! | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Ven 26 Fév 2010 - 20:24 | |
| Woot le nouveau cours \ò/ Je m'en vais faire le TP. Edit : Finish. Maintenant, faut que j'apprenne la syntaxe par coeur. | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 3 Mar 2010 - 15:54 | |
| Up / Ennui / Toussa. Voici mon code pour ceux qui veulent (je suis le seul à suivre les cours ?) - Code:
-
-- Init a = { }
-- Fonction double function double(z) z = z * 2 return z end
-- Remplissage tableau for i=0,19 do a[i] = i end
-- Doublage tableau for i=0,19 do a[i] = double(a[i]) end
-- Affichage part 1 for i=0,19 do if (i<1) then -- On ne met pas de virgule avant le 0. v = "0" else v = v .. "," .. a[i] end end
-- Affichage final run_cmd("echo " .. v)
Dernière édition par vynzs le Mer 3 Mar 2010 - 19:52, édité 2 fois | |
| | | PiR ToriObsédé
Messages : 881 Date d'inscription : 03/12/2009 Age : 29 Localisation : coucou tu veux un morceau ^^ ?
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 3 Mar 2010 - 15:58 | |
| | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 3 Mar 2010 - 16:30 | |
| Félicitations, tu as bien compris en gros, mais je me permets quelques remarques : Les + : + Ton programme est juste et fonctionne. + Il est lisible et commenté Les - : - Ta variable nbr ne sert à rien. - Ton script n'affiche rien ! Il fait tout le travail mais tu as oublié d'afficher le résultat dans le chat ! - Il ne sert à rien de remettre le compteur à 0 avant un for. Le for s'en charge. - Ton script peut être légèrement simplifié Ma correction : - Code:
-
-- question 1 function double(n) return (2*n) end
-- question 2 tab = { } for i=0,19 do tab[i] = i end
-- question 3 for i=0,19 do tab[i] = double(tab[i]) end
-- question 4 res = tab[0] for i=1,19 do res = res .. "," .. tab[i] end run_cmd("echo " .. res) | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 3 Mar 2010 - 19:48 | |
| - Melmoth a écrit:
- Félicitations, tu as bien compris en gros, mais je me permets quelques remarques :
Les - : 1- Ta variable nbr ne sert à rien. 2- Ton script n'affiche rien ! Il fait tout le travail mais tu as oublié d'afficher le résultat dans le chat ! 3- Il ne sert à rien de remettre le compteur à 0 avant un for. Le for s'en charge. 4- Ton script peut être légèrement simplifié
1/La variable nbr trainait sûrement d'avant 2/J'ai oublié de copier les dernières lignes de mon programme. (vu que je m'ennuyais j'ai fait un générateur de série de lettre à la suite) 3/Merci. 4/Je m'en doutais, mais ça change pas grand chose. | |
| | | Kyat Gentil Organisateur
Messages : 925 Date d'inscription : 24/07/2009 Age : 43
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 3 Mar 2010 - 20:27 | |
| - vynzs a écrit:
- 4/Je m'en doutais, mais ça change pas grand chose.
Pour l'instant sur un petit script, non. Plus tard sur un projet plus important, ça permettra de gagner en clarté/lisibilité et optimiser les performances aussi. Ce qui est superflu encombre en programmation, et un code plus simple permet de mieux s'y replonger quand on revient dessus quelques temps après. | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 3 Mar 2010 - 22:47 | |
| Hmmm. Ouais pour la fin, ça vérifie à chaque fois si le truc est inférieur a 1, c'est vrai que là c'est une "perte de performance" En tout cas merci pour le commentaire sur mon code. | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 10 Mar 2010 - 15:08 | |
| Partie sur les hooks ajoutées.... attention, ça se complique !! N'hésitez pas à me poser des questions.
Sujet du TP 3 :
1°) A l'aide d'un hook sur le clavier et d'un hook sur l'affichage 2D, faites en sorte qu'à chaque appui sur une touche, un message apparaisse en précisant le code de cette touche. 2°) Ajouter un hook sur le clic souris et changer le hook sur l'affichage 2D pour qu'il ecrive aussi un message quand le bouton de la souris est enfoncé
Bon courage ! | |
| | | Kyat Gentil Organisateur
Messages : 925 Date d'inscription : 24/07/2009 Age : 43
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 10 Mar 2010 - 16:52 | |
| Excellent tutoriel !!!
TD 3 - Première question : http://www.box.net/shared/2atz4unrve TD 3 - Seconde question : http://www.box.net/shared/zjcd1cl1iv
Voilà une façon de faire ^^ | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 10 Mar 2010 - 17:33 | |
| Huh, je suis en train de lire, 1ere question : - Code:
-
draw_text("Y : " .. mouse_pos_y,20,120,2) Le 20,120,2.... C'est pour dire où est-ce qu'on affiche le message ? Et la taille du caractère ? Ah et le "local" il sert à quoi ? | |
| | | Melmoth le Malmoth
Messages : 1161 Date d'inscription : 23/11/2009 Age : 41 Localisation : Nice, sud de la France
| Sujet: Re: [Tuto] Lua scripting et Toribash Mer 10 Mar 2010 - 17:56 | |
| draw_text permet d'écrire du texte 2D dans la fenêtre. Sa syntaxe est :
draw_text("le texte ou la variable que tu veux", pos_x, pos_y, police)
pos_x et pox_y sont les coordonnées 2D du début du texte, et police peut prendre les valeurs 0 à 3 (essaye, tu verras, ce sont les diférentes polices utilisées dans TB).
"local" permet de dire qu'une variable n'appartient qu'à l'endroit ou elle est déclarée. si tu déclares une variable dans un for et qu'elle est en local, elle ne sera pas définie en dehors de ce for. D'une manière générale, il est bon d'abuser des "local" afin de faciliter la tâche au garbage collector (programme qui se charge de libérer de la mémoire quand tu n'as plus besoin d'une variable). | |
| | | vynzs Humoriste incompris
Messages : 283 Date d'inscription : 20/06/2009 Age : 30
| Sujet: Re: [Tuto] Lua scripting et Toribash Jeu 11 Mar 2010 - 22:18 | |
| 2eme épisode. - Code:
-
for i=1,table.getn(list_items_menu) do table.getn : Trouver le nombre de cases remplies ? | |
| | | Contenu sponsorisé
| Sujet: Re: [Tuto] Lua scripting et Toribash | |
| |
| | | | [Tuto] Lua scripting et Toribash | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |