• 28 Mars 2024, 14:14:50


Auteur Sujet: Scripting Tutorial II - MTA Snow  (Lu 19975 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne spykerc8

  • *
  • 'The GTAOnline.fr GodFather'
  • Messages: 3821
    • Voir le profil
    • http://www.gtaonline.fr
Scripting Tutorial II - MTA Snow
« le: 23 Janvier 2007, 17:23:53 »
Ce tutorial va vous apprendre à faire tomber de la neige dans MTA...Un peu complexe certes, mais le résultat est assez sympa  :D


Vidéo :
[yt=425,350]0fjRoTSYoSw[/yt]

Liens :
Script complet
Vidéo HD

Préparation :

Il faut créer une table dans le code.

Code: (lua) [Sélectionner]
snowflake = {} --This initializes the snowflake IDs table

(Pour plus d'infos sur les tables > Par ici.)

Une fois que la table est opérationnelle, créons des variables dont nous avons besoin.

Code: (lua) [Sélectionner]
flakeID = 1 --This sets the first flake ID as 1
updaterate = 27 --Positions' update rate in miliseconds
height = 4 --Snowflakes starting position above the player's head
snowing = false --This is a variable that tells the script whether it is snowing or not.


Créer nos commandes

On a vu la semaine dernière  que nous pouvons utiliser la fonction addEventHandler pour attacher nos fonctions aux 'events' MTA. Cependant, ce script utilise une commande manuscrite dans la console pour appeler la fonction. Pour ceci, nous avons besoin d'une autre commande : addCommandHandler:

Code: (lua) [Sélectionner]
addCommandHandler ( "snow", "snow_SnowCommand" ) --This assigns the snow_SnowCommand function to the "snow" command in console

On a assigner la commande 'snow_SnowCommand' au fait que le joueur tappe 'snow' dans la console.

Code: (lua) [Sélectionner]
function snow_SnowCommand ( player, commandname, radius, density, speed, size ) --You can pass radius, density, speed and flake size parameters in the command

La fonction addCommandHandler passe automatiquement deux variables à la fonction qui lui est attachée. Il y a donc les variables 'player' et 'commandname'. Tout arguement supplémentaire passera en variable extra.
>> Deux variables obligatoires, le reste optionnel.

Une fois que la commande est crée, il faut que quand le joueur la tappe, la neige soit crée.

Code: (lua) [Sélectionner]
if not snowing then --check the 'snowing' variable and check if it is true. If it is not then it is not snowing
snowing = true --set the snowing variable to true
snow_CreateSnow ( player, radius, density, speed, size ) --call the snow_CreateSnow function to create our snow!
outputChatBox ( "Snow started by " .. getClientName ( player ) ) --announce that snowing was started.

S'il ne neige pas déjà, on va initier notre fonction (lancer) snow_CreateSnow function.
Il faut d'ailleurs noter la fonction getClientName. Elle sert à récupérer le nom du joueur.

La commande est également faite que pour que s'il neige déjà, quand on retappe 'snow' dans la console, la neige s'arrête.

Code: (lua) [Sélectionner]
else
snowing = false --set the snowing variable to false
outputChatBox ( "Snow stopped." ) --announce the snowing has stopped
end
end

Créer la neige

Comme on l'a vu, le script utilise la fonction 'snow_CreateSnow'. Ce n'est pas une fonction de base de MTA, mais une fonction crée pour l'occasion.

Code: (lua) [Sélectionner]
function snow_CreateSnow ( player, radius, density, speed, size )

Le script va créer de la neige tout autour du personnage qui a taper la commande. Pour ceci, nous avons besoin des coordonnées du joueur :

Code: (lua) [Sélectionner]
local px, py, pz = getElementPosition ( player )

On va utiliser la fonction 'getElementPosition' pour récupérer la position du joueur.

Code: (lua) [Sélectionner]
--If player is invalid or has disconnected, stop the function
if not px or not py or not pz then
snowing = false
return
end

Cette partie du script vérifie si le joueur s'est déconnecté ou à quitter le jeu. On check en récupérant les coordonnées px, py ou pz, si elles sont invalides, c'est que le joueur a quitter le serveur.

La prochaine partie du script que nous allons voir est la gestion des paramètres non spécifiés. Par exemple, si vous tapper 'snow' sans arguments, la neige sera celle de défaut prévu dans le script.

Code: (lua) [Sélectionner]
--If any parameter is not set, the script will give it a default value
if not radius then radius = 20 else radius = tonumber ( radius ) end

Si le rayon n'a pas été spécifié par le joueur, le réglage par défaut sera de 20. S'il a été spécifié, il sera converti par lua en un nombre et utilisé dans la fonction.

Code: (lua) [Sélectionner]
if not density then density = 3 else density = math.ceil ( tonumber ( density ) ) end --density should be an integer (flakes/second)

Similairement, si la densité n'a pas été spécifiée, elle est pas défaut de 3. Si elle a été spécifiée, elle sera convertie par lua en un nombre entier grace à la fonction 'math.ceil' et utilisé dans la fonction.

Code: (lua) [Sélectionner]
if not speed then speed = 1.5 else speed = math.abs ( tonumber ( speed ) ) end --speed should only be positive (units/second)

On utilise la fonction 'math.abs' pour avoir un nombre absolu ou positif..

Code: (lua) [Sélectionner]
if not size then size = 0.15 else size = tonumber ( size ) end

Pareillement, si la taille n'est pas spécifiée, on applique celle par défaut.


Nous allons maintenant utiliser une boucle pour créer autant de flocons de neige que voulu. Cela va prendre en compte la densité que nous avons spécifier pour chaque flocon.

Code: (lua) [Sélectionner]
local counter = 0
--We will repeat the flake creating process one time per flake
while counter <= density do

 --For x and y, we will calculate a random position around the player, within the maximum radius circle.
local angle = randInt ( 0, 359 )
local fx = px + math.cos ( angle ) * radius * randFloat ()
local fy = py + math.sin ( angle ) * radius * randFloat ()
--z is just the player's height, plus the height we set before.
local fz = pz + height

Nous utilisons la trigonométrie pour avoir la position où placer le flocon. Lua va créer un nombre aléatoire grace à la fonction 'randInt', compris entre 0 et 359.
La trigonométrie va récupérer l'angle, et trouver la position x et y, puis les multiplier la rayon.  Le tout multiplier ensuite par un float aléatoire compris entre 0 et 1.

Maintenant que les maths trigonométriques sont passées, et qu'on a récup la position, créons le flocon.

Code: (lua) [Sélectionner]
snowflake[flakeID] = createMarker ( fx, fy, fz, "corona", size, 255, 255, 255, 150 )


On va utiliser la fonction 'createMarker'. La semaine dernière nous avons vu que cette fonction avec comme argument 'cylinder' créait un marqueur cylindrique. Aujourd'hui nous allons utiliser le marqueur de type 'corona' qui ressemble à un 'glowball' (boule lumineuse). On va également ajouter un marqueur à la table des  flocons de neige que l'on pourra récupérer plus tard.

Régler les times

Code: (lua) [Sélectionner]
--We calculate the time it takes for a flake to fall, in miliseconds
local time = 1000 * ( height + 1 ) / speed
--We tell the script to update the flake as many times as needed, and store the timer ID in a variable
setTimer ( "snow_moveFlake", updaterate, math.floor ( time / updaterate ), flakeID, speed )
--We set a timer to destroy the flake when the time has passed
setTimer ( "snow_destroyFlake", time, 1, flakeID )

Avec ce code nous allons effectuer un calcul pour établir : le temps requis  - le temps utiliser  = distance / vitesse.

Dans le cas présent, deux timers sont appelés. Un pour faire bouger les flocons, en appelant 'snow_moveFlake' selon la fréquence du timer, et l'autre sert à détruire le flocon quand le laps de temps est écoulé.

Code: (lua) [Sélectionner]
--Repeat this function again in a second, if snow is still on
if snowing then setTimer ( "snow_CreateSnow", 1000, 1, player, radius, density, speed, size ) end
end

Pour finir nous appelons la fonction pour créer un flocon toutes les secondes.


Faire bouger et détruire les flocons

Voyons maintenant la fonction pour faire bouger les flocons.

Code: (lua) [Sélectionner]
function snow_moveFlake ( flakeID, speed )
local fx, fy, fz = getElementPosition ( snowflake[flakeID] )
setElementPosition ( snowflake[flakeID], fx, fy, fz - ( updaterate / 1000 * speed ) )
end

Cette fonction récupère la position du flocon en interrogeant la table. Cela le fait ensuite bouger le flocon vers le bas en calculant la vitesse selon les paramètres.    Et comme cette fonction est appelée beaucoup de fois, selon le timer, le flocon va bouger!

Maintenant il faut détruire le flocon  avec la fonction 'snow_destroyFlake'.  Cette fonction fonctionne avec un timer appelé plus haut.

Code: (lua) [Sélectionner]
function snow_destroyFlake ( flakeID )
destroyElement ( snowflake[flakeID] )
snowflake[flakeID] = nil
end

Nous avons utiliser la même fonction que la semaine dernière, 'destroyElement' pour détruire le marqueur. Nous avons ensuite vidé la table pour ce flocon. 

Voila tout...


SCRIPT ENTIER :

Code: (lua) [Sélectionner]
snowflake = {} --This initializes the snowflake IDs table
flakeID = 1 --This sets the first flake ID as 1
updaterate = 27 --Positions' update rate in miliseconds
height = 4 --Snowflakes starting position above the player's head
snowing = false --This is a variable that tells the script whether it is snowing or not.
 
addCommandHandler ( "snow", "snow_SnowCommand" ) --This assigns the snow_SnowCommand function to the "snow" command in console
function snow_SnowCommand ( player, commandname, radius, density, speed, size ) --You can pass radius, density, speed and flake size parameters in the command
if not snowing then --check the 'snowing' variable and check if it is true. If it is not then it is not snowing
snowing = true --set the snowing variable to true
snow_CreateSnow ( player, radius, density, speed, size ) --call the snow_CreateSnow function to create our snow!
outputChatBox ( "Snow started by " .. getClientName ( player ) ) --announce that snowing was started.
else
snowing = false --set the snowing variable to false
outputChatBox ( "Snow stopped." ) --announce the snowing has stopped
end
end
 
function snow_CreateSnow ( player, radius, density, speed, size )
local px, py, pz = getElementPosition ( player )
--If player is invalid or has disconnected, stop the function
if not px or not py or not pz then
snowing = false
return
end
--If any parameter is not set, the script will give it a default value
if not radius then radius = 20 else radius = tonumber ( radius ) end
if not density then density = 3 else density = math.ceil ( tonumber ( density ) ) end --density should be an integer (flakes/second)
if not speed then speed = 1.5 else speed = math.abs ( tonumber ( speed ) ) end --speed should only be positive (units/second)
if not size then size = 0.15 else size = tonumber ( size ) end
 
local counter = 0
--We will repeat the flake creating process one time per flake
while counter <= density do
--For x and y, we will calculate a random position around the player, within the maximum radius circle.
local angle = randInt ( 0, 359 )
local fx = px + math.cos ( angle ) * radius * randFloat ()
local fy = py + math.sin ( angle ) * radius * randFloat ()
--z is just the player's height, plus the height we set before.
local fz = pz + height
snowflake[flakeID] = createMarker ( fx, fy, fz, "corona", size, 255, 255, 255, 150 )
 
--We calculate the time it takes for a flake to fall, in miliseconds
local time = 1000 * ( height + 1 ) / speed
--We tell the script to update the flake as many times as needed, and store the timer ID in a variable
setTimer ( "snow_moveFlake", updaterate, math.floor ( time / updaterate ), flakeID, speed )
--We set a timer to destroy the flake when the time has passed
setTimer ( "snow_destroyFlake", time, 1, flakeID )
 
flakeID = flakeID + 1
counter = counter + 1
end
 
--Repeat this function again in a second, if snow is still on
if snowing then setTimer ( "snow_CreateSnow", 1000, 1, player, radius, density, speed, size ) end
end
 
function snow_moveFlake ( flakeID, speed )
local fx, fy, fz = getElementPosition ( snowflake[flakeID] )
setElementPosition ( snowflake[flakeID], fx, fy, fz - ( updaterate / 1000 * speed ) )
end
 
function snow_destroyFlake ( flakeID )
destroyElement ( snowflake[flakeID] )
snowflake[flakeID] = nil
end
« Modifié: 23 Janvier 2007, 17:28:41 par spykerc8 »


~ Leader honoraire de la FsK Team ~ -
~ Membre honoraire de la PCP Team ~

Co-fondateur de GTAO - Retraité de la communauté

"Nous ne sommes rien, soyons tout !"


Hors ligne gaspard

  • *
  • Nouveau
  • Messages: 2
    • Voir le profil
c chiant c code qui sont feaux
« Réponse #1 le: 31 Janvier 2007, 16:19:04 »
c chiant !! certain code que je trouve sur internet ne fonctionne po
c a se  :bangin

Hors ligne Lalu

  • *
  • You can run, but you can't hide
  • Messages: 1184
    • Voir le profil
    • Webkot
Re : Scripting Tutorial II - MTA Snow
« Réponse #2 le: 31 Janvier 2007, 16:42:12 »
C'est plutot normal, vu qu'ils sont destinés à MTA : SA Deathmatch qui n'est pas encore sorti.
Drink Like a Russian, Drive like a German, Kiss like a French, Be a Belgian !

Hors ligne Aless

  • *
  • Bandit
  • Messages: 331
    • Voir le profil
Re : Scripting Tutorial II - MTA Snow
« Réponse #3 le: 23 Mai 2007, 00:54:25 »
Je suis sûr que si une personne tire des missiles avec l'hydra sur quelqu'un et que l'autre personne active la neige, ça va dévie les missiles sur une autre trajectoire si vous voyez où je veux en venir...  :happy En gros je pense plutôt que ce sont des boules de chaleures pour faire suivre les missiles...

Mais si non très bonne idée ! :)
My Dedicated Server:

Intel Core2Quad Q6600- 2.4GHz - LGA775 - 1066MHz FSB - 2x4 MB L2/L3
2x2GB - DDR2 - 667MHz - Corsair Value - 3.2 Go utilisable sur 32 bits
80GB 16MB Buffer SATA-2 7200 TPM + 1 TB 32 MB Buffer SATA-2 5400 TPM EcoGreen
OS: Ubuntu Linux Hardy Heron 8.04.3

Info serveur: http://www.aless-server.ch/psi/