FAQRechercherPortailAccueilAccueilForumPraline au mielS'enregistrerConnexionMembres

Partagez
 

 *[Tuto Danmakufu v0.12] N°1: Faire des tirs en cercles de différents types

Aller en bas 
AuteurMessage
3phy

 
3phy

Messages : 7433


*[Tuto Danmakufu v0.12] N°1:  Faire des tirs en cercles de différents types Empty
MessageSujet: *[Tuto Danmakufu v0.12] N°1: Faire des tirs en cercles de différents types   *[Tuto Danmakufu v0.12] N°1:  Faire des tirs en cercles de différents types Icon_minitimeLun 29 Oct - 21:44

Voilà. J'entame une petite série de tutos sur danmakufu, logicel de création de danmaku Touhou-like.

Avant propos

Ces tutos sont valables pour la version v0.12 mais peut-être pas pour la ph3. Soyez bien certain de la version que vous utilisez.

Ces tutos s'adressent à des gens qui connaissent déjà un peu la base du logiciel et sont là pour apprendre à faire des choses simples mais pas forcément intuitives. Pour les gens ne connaissant pas les bases, je vous renvoie directement au tuto officiel qui est suffisamment bien expliqué pour faire ses débuts.
Il est important d'avoir les bases sur la création de script danmakufu et des notions en math et en trigonométrie pour comprendre pleinement ce tutoriel.

==============================================================================

Créer un cercle de tir

Dans cette première partie, on va voir comment créer un cercle de tirs basique, constituant essentiel de tout danmaku et shoot em up qui se respecte.

Commençons avec ce squelette de script:
Code:
#TouhouDanmakufu
#Title [Test]
#Text [test de danmakufu]
#ScriptVersion [2]

script_enemy_main {

  @Initialize {
    SetX(GetCenterX);
    SetY(GetClipMinY + 120);
    SetLife(300);
    SetTimer(60);
    SetMovePosition02(GetCenterX, GetClipMinY + 120, 90);
  }

  @MainLoop {
    SetCollisionA(GetX, GetY, 24);
    SetCollisionB(GetX, GetY, 24);
   
  }

  @DrawLoop {
    DrawGraphic(GetX, GetY);
  }

  @Finalize {

  }
}
Et maintenant, dans le MainLoop, ajoutons un spawn d'un cercle de 64 tirs.

Pour commencer, il faut créer le tir. Ou plutôt les tirs. Pour cet exemple on prendra le tir le plus simple en utilisant CreateShot01, créé directement en cercle autour de l'ennemi, à 50 pixels de ce dernier. Cela revient à placer les tirs directement sur un cercle.
On assimilera donc le tir à son centre, c'est à dire à un point et la zone de jeu à un repère orthonormé tel que celui ci:
Spoiler:
 
L'axe horizontal est l'axe X. Le vertical est l'axe Y, dirigé vers le bas.
Le point bleu est l'origine du repère (0;0). Le point rose est le coin en haut à gauche de la zone de jeu est correspond au point (32;16). L'unité du repère est en pixels.

Avant de poursuivre, nous aurons besoin d'une petite mise au point théorique sur les maths et les cercles:

Maintenant, les math nous disent que les coordonnées X et Y d'un point M sur un cercle de rayon R et de centre O sont:
X = XO+R*cos(A)
Y = YO+R*sin(A)
ou XO est la coordonnée X du centre du cercle, YO la coordonnée Y du centre O et A l'angle que fait OM par rapport à la droite horizontale qui passe par le centre du cercle.


Cette petite théorie terminée, revenons en à notre tir. Comme vu précédemment, nous avons assimilé notre tir au point nommé M.
Pour l'exemple, le centre du cercle sera la position de l'ennemi dont les coordonnées sont récupérables via les commandes GetX et GetY (voir la liste des commandes pour plus d'information). Le rayon R correspond à la distance entre le tir et le centre de l'ennemi soit 50 pixels dans notre cas.

On aura donc les coordonnée suivantes pour notre tir:
X=GetX+50*cos(A) et Y=GetY+50*sin(A)


Placés dans la commande CreateShot01 cela nous donne:
Code:
CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, A, RED01, 0);

Une fois cela fait, reste à définir l'angle A. X et Y étant dépendant de cet angle A, c'est lui qui nous permettra de changer la position du tir sur le cercle. Comme A va varier on utilisera... une variable, variable que l'on définira au dessus de @Initialize.
Comme on a 64 tirs, il faudra couper le cercle en 64 parties égales pour avoir un cercle complet avec des tirs placés a égale distance les uns des autres. Un tour de cercle fait 360° donc 1/64ème de cercle est égal à 360/64.
Notre angle devra donc varier de 360/64 entre chaque création de tir.


On a donc le code suivant

Code:
#TouhouDanmakufu
#Title [Test]
#Text [test de danmakufu]
#ScriptVersion [2]

script_enemy_main {
  let A = 0;

  @Initialize {
    SetX(GetCenterX);
    SetY(GetClipMinY + 120);
    SetLife(300);
    SetTimer(60);
    SetMovePosition02(GetCenterX, GetClipMinY + 120, 90);
  }

  @MainLoop {
    SetCollisionA(GetX, GetY, 24);
    SetCollisionB(GetX, GetY, 24);
    CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, A, RED01, 0); //Crée le tir
    A += 360/64; //incrémente la valeur de A de 360/64 à chaque frame.
  }

  @DrawLoop {
    DrawGraphic(GetX, GetY);
  }

  @Finalize {

  }
}

Et on obtient ceci:
*[Tuto Danmakufu v0.12] N°1:  Faire des tirs en cercles de différents types Cercle1-3920498

Comme vous pouvez le voir... c'est une magnifique spirale... mais certainement pas un cercle. Normal puisque nos 64 tirs ne sont pas créé en même temps mais un à chaque frame.
Pour les créer en même temps il faut répéter la commande CreateShot01 64 fois dans la même frame. Heureusement, pas la peine de recopier la ligne de commande 64 fois pour en arriver là.
On va utiliser la commande loop() {} qui va nous permettre de rejouer la commande entre crochet autant de fois qu'indiqué dans les parenthèses.
On a donc, pour une boucle qui se répète 64 fois on obtient:
Code:
loop(64) {

}
Et avec notre commande CreateShot01

Code:
loop(64) {
    CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, A, RED01, 0);
    A += 360/64;
}

Maintenant, on a un cercle de 64 tirs créé à chaque frame. Mais comme on en veut qu'un seul, on va utiliser une seconde variable qui s'incrémentera à chaque frame de manière à ce que le tir ne soit créé que lorsque cette variable a pour valeur 120 (120 car cela correspond à 2 secondes après le début du script, ce qui laisse le temps à l'ennemi de se placer).

Code:

if(timer == 120) {
    loop(64) {
        CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, A, RED01, 0);
        A += 360/64;
    }
}

Une fois la loop et la condition intégrées à notre script nous avons donc:
(attention à ne pas oublier de définir la nouvelle variable (timer) et de l'incrémenter à chaque frame).
Code:
#TouhouDanmakufu
#Title [Test]
#Text [test de danmakufu]
#ScriptVersion [2]

script_enemy_main {
  let A = 0;
  let timer = 0;

  @Initialize {
    SetX(GetCenterX);
    SetY(GetClipMinY + 120);
    SetLife(300);
    SetTimer(60);
    SetMovePosition02(GetCenterX, GetClipMinY + 120, 90);
  }

  @MainLoop {
    SetCollisionA(GetX, GetY, 24);
    SetCollisionB(GetX, GetY, 24);
    timer += 1; //incrémente de 1 la variable timer à chaque frame. Il s'agit bêtement d'un compteur de frame.
    if(timer == 120) {
        loop(64) {
            CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, A, RED01, 0);
            A += 360/64;
        }
    }
  }

  @DrawLoop {
    DrawGraphic(GetX, GetY);
  }

  @Finalize {

  }
}
Nous avons donc ceci:
*[Tuto Danmakufu v0.12] N°1:  Faire des tirs en cercles de différents types Cercle2-3920735
Un cercle parfait de 64 tirs, créé qu'une seule fois et centré sur l'ennemi. Les tirs se déplaceront en ligne droite conduisant à un agrandissement du cercle.

Maintenant que vous savez faire ça, vous pouvez ajouter d'autres commandes CreateShot dans la boucle pour créer plusieurs cercles, varier le nombre de tours de boucle pour faire des cercles avec plus ou moins de tirs, changer la valeur de R pour avoir des cercles plus ou moins grands, modifier le centre du cercle pour le faire apparaître où vous voulez dans la zone de jeu...
A noter que mettre des valeurs de R différentes pour les coordonnées X et Y permettent de faire des ovales de tir.



Créer un cercle dirigé vers le joueur

Maintenant que vous savez comment créer un cercle, vous voudrez peut-être le diriger vers une position particulière comme si il s'agissait d'un seul et même tir plutôt que de voir chaque tir partir de son coté.

Pour cela, rien de plus simple. Reprenons notre commande CreateShot01 de toute à l'heure:
CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, A, RED01, 0);
En rouge, on voit que l'angle de chaque tir est égal A qui est notre variable. Pour diriger le cercle vers un angle précis il suffit de mettre un angle qui lui ne varie pas à la place de A.
Dans notre cas nous voulons envoyer le cercle directement sur le joueur. il faut donc récupérer l'angle entre le joueur et l'ennemi en utilisant la commande GetAngleToPlayer.

On a donc:
Code:
CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, GetAngleToPlayer, GREEN01, 0);

qui une fois intégré dans le code nous donne:
Code:
#TouhouDanmakufu
#Title [Test]
#Text [test de danmakufu]
#ScriptVersion [2]

script_enemy_main {
  let A = 0;
  let timer = 0;

  @Initialize {
    SetX(GetCenterX);
    SetY(GetClipMinY + 120);
    SetLife(300);
    SetTimer(60);
    SetMovePosition02(GetCenterX, GetClipMinY + 120, 90);
  }

  @MainLoop {
    SetCollisionA(GetX, GetY, 24);
    SetCollisionB(GetX, GetY, 24);
    timer += 1;
    if(timer == 120) {
        loop(64) {
            CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, GetAngleToPlayer, GREEN01, 0);
            A += 360/64;
        }
    }
  }

  @DrawLoop {
    DrawGraphic(GetX, GetY);
  }

  @Finalize {

  }
}

On obtient donc un cercle de 64 tirs et de rayon 50 pixels qui se dirige en ligne droite vers la position qu'occupait le joueur au moment où il a été créé.
*[Tuto Danmakufu v0.12] N°1:  Faire des tirs en cercles de différents types Cercle3-39209b2
Notez qu'il n'est PAS possible de faire suivre le joueur par le cercle avec cette méthode. Il faut passer par des commandes bien plus élaborées pour ça.

Créer un cercle dont les tirs sont dirigés vers le joueur

Et maintenant, imaginons que l'on veuille pousser le vice plus loin pour créer un cercle dont les tirs se dirigent chacun vers le joueur (de manière à se croiser à son niveau).
Pour cela, on utilise la même technique que précédemment mais, au lieu de récupérer l'angle entre le centre du cercle (l'ennemi donc) et le joueur, il nous faut récupérer l'angle entre le joueur et chaque tir.
Heureusement pour cela nous disposons d'une fonction magique: atan2.
Cette fonction permet de calculer l'arctangente entre deux points, ce qui correspond concrètement à l'angle entre ces deux points.
Elle nécessite 2 paramètres Y et X pour donner un angle compris entre -180° et 180°.
Si l'on veut calculer l'angle de A(32;48) vers B(96, 64) on obtient une fonction atan2 telle que celle là:
Code:
atan2(64-48, 96-32)
Concrètement Y est la différence entre la coordonnée Y de B et la coordonnée Y de A. X est la différence entre la coordonnée X de B et la coordonnée X de A.

Dans notre cas nous avons donc:
atan2(GetPlayerY-(GetY+50*sin(A)),GetPlayerX-(GetX+50*cos(A)) )
GetY+50*sin(A) et GetX+50*cos(A) sont les coordonnées du tir (comme nous l'avons vu au début de ce tuto).
GetPlayerY et GetPlayerX sont les fonctions pour récupérer les coordonnées Y et X du joueur.

Notre angle sera donc donné par cet atan2 qu'il faudra placer dans le CreateShot01 à la place de l'angle. Cela nous donne:
Code:
CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 2, atan2(GetPlayerY-(GetY+50*sin(A)),GetPlayerX-(GetX+50*cos(A))), PURPLE01, 0);

Et une fois intégré dans notre script nous avons ceci:
Code:
#TouhouDanmakufu
#Title [Test]
#Text [test de danmakufu]
#ScriptVersion [2]

script_enemy_main {
  let A = 0;
  let timer = 0;

  @Initialize {
    SetX(GetCenterX);
    SetY(GetClipMinY + 120);
    SetLife(300);
    SetTimer(60);
    SetMovePosition02(GetCenterX, GetClipMinY + 120, 90);
  }

  @MainLoop {
    SetCollisionA(GetX, GetY, 24);
    SetCollisionB(GetX, GetY, 24);
    timer += 1;
    if(timer == 120) {
        loop(64) {
            CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, atan2(GetPlayerY-(GetY+50*sin(A)),GetPlayerX-(GetX+50*cos(A))), PURPLE01, 0);
            A += 360/64;
        }
    }
  }

  @DrawLoop {
    DrawGraphic(GetX, GetY);
  }

  @Finalize {

  }
}
Et in-game, voici ce que l'on obtient:
*[Tuto Danmakufu v0.12] N°1:  Faire des tirs en cercles de différents types Cercle4-3920d4c
un horrible cercle se qui se déforme dont tous les tirs se déplacent vers le pauvre joueur.

Cette technique avec le atan2 permet également de donner ce déplacement d'un ensemble de tirs vers le joueur a des structures autres que le cercle telles qu'une ligne, un ensemble de ligne, un ensemble de cercles ou ce que vous désirez.

Le mot de la fin

Le tuto s'achève ici. Vous savez maintenant comment créer 3 types de cercles qui pourront vous être grandement utiles dans la création de vos danmaku. Après cela vous pourrez modifier, améliorer et combiner ces types de cercles pour arriver sans trop d'effort à un résultat tel que celui-ci:
*[Tuto Danmakufu v0.12] N°1:  Faire des tirs en cercles de différents types Cercle5-3920ea7

Voici le code que je vous laisse décortiquer:
Code:
#TouhouDanmakufu
#Title [Test]
#Text [test de danmakufu]
#ScriptVersion [2]

script_enemy_main {
  let A = 0;
  let A2 = 0;
  let timer = 0;

  @Initialize {
    SetX(GetCenterX);
    SetY(GetClipMinY + 120);
    SetLife(300);
    SetTimer(60);
    SetMovePosition02(GetCenterX, GetClipMinY + 120, 90);
  }

  @MainLoop {
    SetCollisionA(GetX, GetY, 24);
    SetCollisionB(GetX, GetY, 24);
    timer += 1;
    if(timer == 120) {
        loop(32) {
            CreateShot01(GetX+50*cos(A), GetY+50*sin(A), 1, A, RED01, 0);
            loop(5) {
                  CreateShot01(GetX+20*cos(A), GetY+20*sin(A), 1, GetAngleToPlayer+A2, GREEN01, 0);
                  A2 += 360/5;
            }
            CreateShot01(GetX+40*cos(A), GetY+40*sin(A), 2, atan2(GetPlayerY-(GetY+50*sin(A)),GetPlayerX-(GetX+50*cos(A))), PURPLE21, 0);
            A += 360/32;
            timer = 60;
        }
    }
  }

  @DrawLoop {
    DrawGraphic(GetX, GetY);
  }

  @Finalize {

  }
}

Sur ce, je vous laisse avec vos cercles et à la prochaine fois! Si vous avez des questions n'hésitez pas à les poser, j'essayerais d'y répondre au mieux.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
 
*[Tuto Danmakufu v0.12] N°1: Faire des tirs en cercles de différents types
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» ou retrouver le tuto pour faire le portail
» faire une copie du fichier de la license de SZ ?
» Comment faire pour graver sur un cd a partir d'un film camescope?
» Problème avec le tuto Installer et utiliser plusieurs versions de MapSource
» COMMENT installer et utiliser le systeme de bataille XAS?

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
RPG Maker Détente :: Entrepôt :: Tutos :: Tutos Divers-
Sauter vers: