Small Basic: Graphismes Dynamiques (fr-FR)
Cet article est une introduction à la programme de jeu graphique avec Small Basic. Il contient les bases de la conception d'un programme, les mouvements, les interactions utilisateur avec le clavier et la souris, la détection de collision, et propose quelques idées avancées à la fin.
Tout au long de cet article nous allons créer un jeu très simple avec les principales fonctions nécessaires pour la conception de jeux plus complexes.
Mouvement des Graphismes
Le mouvement est simulé dans les jeux informatique de la même manière qu'à la télévision ou au cinéma. Une séquence d'images (le contenu de la fenêtre graphique GraphicsWindow dans Small Basic) qui changent par petite zones et qui sont affichées rapidement les unes après les autres. Habituellement nous cherchons à atteindre une cadence de 20 à 50 FPS (Frames Per Second - Images Par Seconde).
Pour contrôler la rapidité de l'action nous faisons souvent une petite pause pendant chaque image pour maintenir la cadence à la vitesse désirée. Donc tout ce qui doit être fait à chaque image doit être fait durant ce laps de temps, sinon le jeu va ralentir ou être trop "nerveux". Une conception soignée du programme est nécessaire pour s'assurer que tout fonctionne avec fluidité. Il est souvent préférable de faire quelque chose d'approximatif et qui suit la cadence, que d'en faire trop et avoir des ralentissements. Le gameplay est bien plus important que les calculs compliqués.
Un jeu contient habituellement un arrière-plan et des sprites. Les sprites sont des objets qui peuvent bouger et interagir par dessus l'arrière-plan qui est statique. L'arrière-plan peut changé avec le jeu, mais il ne doit pas être trop complexe pour maintenir la fluidité du jeu.
Généralement nous avons phases pour mettre à jour une image, elles sont:
- Récupérer toutes les interactions utilisateur. Par exemple, une touche clavier à peut-être été appuyée, la souris déplacée ou un bouton de souris cliqué. Tout ceci est géré par les événements Small Basic.
- Appliquer la logique du jeu basée sur les entrées du joueur ou simplement la progression de la partie. Par exemple le bouton de tir d'un missile peut être appuyé, ou le jeu peut décider d'ajouter un nouvel ennemi or tirer sur le joueur.
- Mettre à jour tous les sprites à l'écran, en prenant en compte les déplacements, les ajouts, le suppression ou les modifications de sorte que la prochaine image soit affichée au joueur.
La tentation lorsque l'on commence à gérer les mouvements dans Small Basic est d'utiliser Shapes.Animate. C'est très facile à utiliser et idéale pour les animations visuelles comme les écrans d'introductions fantaisie avec des apparitions de texte animé. Toutefois, ce n'est pas très adapté pour un jeu dynamique ou nous avons besoin de savoir où chaque élément se trouve dans l'image et ainsi pouvoir détecter les collision ou d'autres aspects du jeu lorsqu'ils dépendent de la position des éléments.
Boucle de Jeu et Structure
Les 3 phases décrites précédemment sont exécutées séquentiellement à chaque mise à jour d'image. Cela se fait habituellement dans une "Boucle de Jeu" répétée continuellement (boucle infinie). Souvent dans Small Basic la boucle de jeu est codée avec une boucle 'While ("True")' qui s'exécute indéfiniment pendant que le jeu évolue, juste en mettant à jour l'écran pendant le déroulement du jeu.
En plus de la boucle de jeu, nous avons généralement d'autres sections dans notre code, comme:
- Initialisation - c'est la configuration de toutes les variables nécessaires, peut-être des instructions de jeu; tout ce qui doit être fait avant que la boucle de jeu ne démarre.
- Sous-routines d'événement - elles enregistrent les interactions utilisateur pour être utilisées dans la première phase de la boucle de jeu. Généralement nous définissons un indicateur (affectation d'une simple variable dans la sous-routine d'événement) qui indique que l'utilisateur à fait quelque chose et on vérifie ou traite ces indicateurs dans la première phase de la boucle de jeu.
- D'autres sous-routines - elles sont utilisées pour exécuter la logique du jeu, les collisions, etc. dans les phases 2 et 3 dans la boucle de jeu. L'idée est de garder le code la boucle de jeu assez court et facile à suivre.
Le code suivant est un bon début pour structurer un jeu graphique. Nous le compléterons un peu plus dans les sections suivantes, mais globalement ceci sera 'votre jeu'.
Initialise()
'------------------------------------------------
'BOUCLE DE JEU
'------------------------------------------------
While ("True")
start = Clock.ElapsedMilliseconds
UpdateGamePlay()
UpdateFrame()
'Un délai de 20 ms (pour 50 fps) dépendant du temps passé à faire le traitement de mise à jour de l'image
delay = 20 - (Clock.ElapsedMilliseconds - start)
If (delay > 0) Then
Program.Delay(delay)
EndIf
EndWhile
'------------------------------------------------
'SOUS-ROUTINES
'------------------------------------------------
Sub Initialise
'Enregistre les événements
GraphicsWindow.KeyDown = OnKeyDown
GraphicsWindow.KeyUp = OnKeyUp
GraphicsWindow.MouseMove = OnMouseMove
GraphicsWindow.MouseDown = OnMouseDown
'A FAIRE
EndSub
Sub UpdateGamePlay
'A FAIRE
EndSub
Sub UpdateFrame
'A FAIRE
EndSub
'------------------------------------------------
'SOUS-ROUTINES D'EVENEMENT
'------------------------------------------------
Sub OnKeyDown
'A FAIRE
EndSub
Sub OnKeyUp
'A FAIRE
EndSub
Sub OnMouseMove
'A FAIRE
EndSub
Sub OnMouseDown
'A FAIRE
EndSub
Gestion de la Souris
Nous pouvons définir un événement pour détecter la position de la souris et si un clic a été effectué. Il s'agit simplement de définir des variables pour indiquer ce qu'il s'est passé.
Pour prendre en compte les mouvements de la souris et les clics, nous ajoutons le code suivant.
Sub OnMouseMove
mouseMove = "True"
EndSub
Sub OnMouseDown
mouseDown = "True"
EndSub
Définir les indicateurs 'mouseMove' et 'mouseDown' initialement à "False" dans la sous-routine Initialise.
Sub Initialise
'Enregistre les événements
GraphicsWindow.KeyDown = OnKeyDown
GraphicsWindow.KeyUp = OnKeyUp
GraphicsWindow.MouseMove = OnMouseMove
GraphicsWindow.MouseDown = OnMouseDown
'Indicateurs d'événement
mouseMove = "False"
mouseDown = "False"
'TODO
EndSub
Pour finir définissons le code pour traiter l'événement dans la boucle de jeu, sous-routine UpdateGamePlay.
Sub UpdateGamePlay
If (mouseMove) Then
'A FAIRE
mouseMove = "False" 'Réinitialise l'événement à "False" (car nous l'avons traité)
EndIf
If (mouseDown) Then
'A FAIRE
mouseDown = "False"
EndIf
EndSub
Nous avons encore des choses à faire avec ces événement, mais la structure pour les gérer est en place. A noter que nous pouvons obtenir la position de la souris avec GraphicsWindow.MouseX et GraphicsWindow.MouseY, par conséquent il n'est pas nécessaire de les enregistrer dans les événements de la souris.
Gestion du Clavier
C'est le même principe que la gestion de la souris, sauf sur un point. Lorsqu'une touche est appuyée, il y a un délai imposé par le système d'exploitation avant qu'un autre appui de touche soit enregistré (délai d'auto répétition). C'est la raison pour laquelle lorsque nous appuyons sur une touche nous n'obtenons pas un caractère à répétition tant que nous n'avons pas relevé la touche avant une certaine période de temps (généralement une demi-seconde).
Dans un jeu, nous voulons détecter qu'une touche a été appuyée et utiliser l'événement d'appui de touche détectera l'appui initial de la touche, et donc ne va pas enregistrer que la touche reste appuyée jusqu'à ce que le délai d'auto répétition soit passé, ce qui provoque un délai entre le premier appui de touche et les suivants.
Pour contourner cela nous pouvons les événements d'appui et de relâchement de touche pour définir l'état des touches qui nous intéressent, sans se préoccuper du délai d'auto-répétition.
Sub OnKeyDown
lastKey = GraphicsWindow.LastKey
If (lastKey = "Left") Then
keyLeft = "True"
ElseIf (lastKey = "Right") Then
keyRight = "True"
ElseIf (lastKey = "Up") Then
keyUp = "True"
ElseIf (lastKey = "Down") Then
keyDown = "True"
EndIf
EndSub
Sub OnKeyUp
lastKey = GraphicsWindow.LastKey
If (lastKey = "Left") Then
keyLeft = "False"
ElseIf (lastKey = "Right") Then
keyRight = "False"
ElseIf (lastKey = "Up") Then
keyUp = "False"
ElseIf (lastKey = "Down") Then
keyDown = "False"
EndIf
EndSub
Initialisation de l'état des touches dans la sous-routine Initialise.
'Indicateurs d'événement
mouseMove = "False"
mouseDown = "False"
keyLeft = "False"
keyRight = "False"
keyUp = "False"
keyDown = "False"
On gère les indicateurs de touche dans UpdateGamePlay. A noter que nous ne réinitialisons pas les indicateurs de touches avec "False" étant donné que c'est géré dans l'événement OnKeyUp et que nous voulons rester réactif tant que la touche est appuyée. Si nous voulons seulement réagir à chaque appui de touche individuellement (peut-être la barre espace pour tirer), alors nous réinitialiserons à "False" l'indicateur une fois que nous aurons fait notre traitement, imposant ainsi un nouvel appui pour provoquer une nouvelle action.
If (keyLeft) Then
'A FAIRE
EndIf
If (keyRight) Then
'A FAIRE
EndIf
If (keyUp) Then
'A FAIRE
EndIf
If (keyDown) Then
'A FAIRE
EndIf
Déplacer les Sprites
Jusqu'à présent nous avons mis en place une structure de base, mais nous n'avons pas encore de jeu. C'est à l'inverse de ce que la plupart des débutants commence à écrire pour un jeu - ils ont les sprites, les règles et les images, mais la structure et la gestion n'est pas encore proprement défini.
La leçon à retenir c'est tout d'abord d'avoir la structure et la gestion, ensuite nous ajoutons le gameplay et le contenu.
Donc maintenant nous allons ajouter quelques sprites, ici que des rectangles - encore une fois l'idée est d'avoir une base de jeu et ensuite d'ajouter les détails, pas l'inverse.
Nous ajouterons quelques ennemis et un joueur. Les ennemis seront stockés dans des tableaux - nous avons besoin d'enregistrer les objets sprites ainsi que leur position et leurs vitesses.
Nous créons les sprites dans la sous-routine Initialise.
Sub Initialise
'GraphicsWindow
GraphicsWindow.Title = "Mon Jeu"
gw = 600
gh = 600
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
'Enregistre les événements
GraphicsWindow.KeyDown = OnKeyDown
GraphicsWindow.KeyUp = OnKeyUp
GraphicsWindow.MouseMove = OnMouseMove
GraphicsWindow.MouseDown = OnMouseDown
'Indicateurs d'événements
mouseMove = "False"
mouseDown = "False"
keyLeft = "False"
keyRight = "False"
keyUp = "False"
keyDown = "False"
'Sprites
size = 50
GraphicsWindow.BrushColor = "Blue"
numEnemy = 5
For i = 1 To numEnemy
enemy[i] = Shapes.AddRectangle(size, size)
enemyPosX[i] = 50 + Math.GetRandomNumber(gw-100)
enemyPosY[i] = 50 + Math.GetRandomNumber(gh-100)
enemyVelX[i] = Math.GetRandomNumber(5) - 3
enemyVelY[i] = Math.GetRandomNumber(5) - 3
EndFor
GraphicsWindow.BrushColor = "Red"
player = Shapes.AddRectangle(size, size)
playerSpeed = 3
playerPosX = gw/2
playerPosY = gh - 2*size
EndSub
Ensuite nous partons du principe que le mouvement du joueur est basé sur les touches fléchées, nous utilisons une variable playerSpeed pour contrôler la vitesse du joueur. C'est une bonne idée d'utiliser des variables plutôt que juste entrer les valeurs quand c'est possible; cela nous permet de les modifier facilement (même pendant le jeu pour accélérer ou ralentir le joueur). Notons également que nous ne laissons pas le joueur sortir de l'écran.
Sub UpdateGamePlay
If (mouseMove) Then
'A FAIRE
mouseMove = "False" 'Réinitialise l'événement à "False" (nous l'avons traité)
EndIf
If (mouseDown) Then
'A FAIRE
mouseDown = "False"
EndIf
If (keyLeft) Then
If (playerPosX > size/2) Then
playerPosX = playerPosX-playerSpeed
EndIf
EndIf
If (keyRight) Then
If (playerPosX < gw-size/2) Then
playerPosX = playerPosX+playerSpeed
EndIf
EndIf
If (keyUp) Then
If (playerPosY > size/2) Then
playerPosY = playerPosY-playerSpeed
EndIf
EndIf
If (keyDown) Then
If (playerPosY < gh-size/2) Then
playerPosY = playerPosY+playerSpeed
EndIf
EndIf
EndSub
Nous allons définir que les ennemis se déplacent avec leurs vitesses, rebondissent sur les murs dans la sous-routine UpdateGamePlay. Sur un rebond contre un mur nous modifions la vitesse et replaçons le sprite de l'ennemi sur le mur; ça évite que les ennemis apparaissent partiellement sortis de l'écran si leur vitesse est grande.
'Mouvement des ennemis
For i = 1 To numEnemy
enemyPosX[i] = enemyPosX[i] + enemyVelX[i]
enemyPosY[i] = enemyPosY[i] + enemyVelY[i]
If (enemyPosX[i] < size/2) Then
enemyVelX[i] = -enemyVelX[i]
enemyPosX[i] = size/2
ElseIf (enemyPosX[i] > gw-size/2) Then
enemyVelX[i] = -enemyVelX[i]
enemyPosX[i] = gw-size/2
EndIf
If (enemyPosY[i] < size/2) Then
enemyVelY[i] = -enemyVelY[i]
enemyPosY[i] = size/2
ElseIf (enemyPosY[i] > gh-size/2) Then
enemyVelY[i] = -enemyVelY[i]
enemyPosY[i] = gh-size/2
EndIf
EndFor
Pour finir nous actualisons l'affichage du joueur et des ennemis dans la sous-routine UpdateFrame.
Sub UpdateFrame
For i = 1 To numEnemy
Shapes.Move(enemy[i], enemyPosX[i]-size/2, enemyPosY[i]-size/2)
EndFor
Shapes.Move(player, playerPosX-size/2, playerPosY-size/2)
EndSub
A noter que la position des sprites que nous utilisons et celle de leur centre, et que l'opération Shapes.Move utilise la position du coin supérieur gauche, par conséquent nous soustrayons la moitié de la largeur (et de la hauteur) pour le déplacement. Ça facilite la logique pour plus tard si nous faisons des calculs basé sur le centre de la forme au lieu du coin supérieur gauche et nécessite uniquement un offset lors du Shapes.Move.
Détection de Collision
De base, la détection de collision cherche si un objet est par dessus un autre. Il y a deux méthodes simples pour faire ça:
- La séparation des formes (distances entre les deux centres) est plus petite que la somme des deux rayons des cercles (bon pour les formes circulaires).
- Les cadres des formes (le plus petit rectangle qui englobe totalement la forme) se chevauchent.
Nous utiliserons la seconde méthode, lorsqu'un ennemi touche le joueur. Nous allons créer une sous-routines appelée Collision, et déterminer si un des ennemis chevauche le joueur en utilisant la méthode 2 ci-dessus.
Sub Collision
For i = 1 To numEnemy
sepX = Math.Abs(enemyPosX[i]-playerPosX)
sepY = Math.Abs(enemyPosY[i]-playerPosY)
If (sepX < size And sepY < size) Then
Sound.PlayClickAndWait()
EndIf
EndFor
EndSub
Nous appelons cette sous-routines à la fin de UpdateGamePlay.
Ce n'est pas encore un jeu et nous n'avons même pas utilisé les événements souris, mais les bases sont là pour commencer à ajouter du contenu intéressant. Voici le code complet.
Initialise()
'------------------------------------------------
'BOUCLE DE JEU
'------------------------------------------------
While ("True")
start = Clock.ElapsedMilliseconds
UpdateGamePlay()
UpdateFrame()
'Un délai de 20 ms (pour 50 fps) dépendant du temps passé à faire le traitement de mise à jour de l'image
delay = 20 - (Clock.ElapsedMilliseconds - start)
If (delay > 0) Then
Program.Delay(delay)
EndIf
EndWhile
'------------------------------------------------
'SOUS-ROUTINES
'------------------------------------------------
Sub Initialise
'GraphicsWindow
GraphicsWindow.Title = "Mon Jeu"
gw = 600
gh = 600
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
'Enregistre les événements
GraphicsWindow.KeyDown = OnKeyDown
GraphicsWindow.KeyUp = OnKeyUp
GraphicsWindow.MouseMove = OnMouseMove
GraphicsWindow.MouseDown = OnMouseDown
'Indicateurs d'événement
mouseMove = "False"
mouseDown = "False"
keyLeft = "False"
keyRight = "False"
keyUp = "False"
keyDown = "False"
'Sprites
size = 50
GraphicsWindow.BrushColor = "Blue"
numEnemy = 5
For i = 1 To numEnemy
enemy[i] = Shapes.AddRectangle(size, size)
enemyPosX[i] = 50 + Math.GetRandomNumber(gw-100)
enemyPosY[i] = 50 + Math.GetRandomNumber(gh-100)
enemyVelX[i] = Math.GetRandomNumber(5) - 3
enemyVelY[i] = Math.GetRandomNumber(5) - 3
EndFor
GraphicsWindow.BrushColor = "Red"
player = Shapes.AddRectangle(size, size)
playerSpeed = 3
playerPosX = gw/2
playerPosY = gh - 2*size
EndSub
Sub UpdateGamePlay
If (mouseMove) Then
'TODO
mouseMove = "False" 'Réinitialise l'événement à "False" (nous l'avons traité)
EndIf
'Mouvement du joueur
If (mouseDown) Then
'A FAIRE
mouseDown = "False"
EndIf
If (keyLeft) Then
If (playerPosX > size/2) Then
playerPosX = playerPosX-playerSpeed
EndIf
EndIf
If (keyRight) Then
If (playerPosX < gw-size/2) Then
playerPosX = playerPosX+playerSpeed
EndIf
EndIf
If (keyUp) Then
If (playerPosY > size/2) Then
playerPosY = playerPosY-playerSpeed
EndIf
EndIf
If (keyDown) Then
If (playerPosY < gh-size/2) Then
playerPosY = playerPosY+playerSpeed
EndIf
EndIf
'Mouvement des ennemis
For i = 1 To numEnemy
enemyPosX[i] = enemyPosX[i] + enemyVelX[i]
enemyPosY[i] = enemyPosY[i] + enemyVelY[i]
If (enemyPosX[i] < size/2) Then
enemyVelX[i] = -enemyVelX[i]
enemyPosX[i] = size/2
ElseIf (enemyPosX[i] > gw-size/2) Then
enemyVelX[i] = -enemyVelX[i]
enemyPosX[i] = gw-size/2
EndIf
If (enemyPosY[i] < size/2) Then
enemyVelY[i] = -enemyVelY[i]
enemyPosY[i] = size/2
ElseIf (enemyPosY[i] > gh-size/2) Then
enemyVelY[i] = -enemyVelY[i]
enemyPosY[i] = gh-size/2
EndIf
EndFor
'Vérification des collisions
Collision()
EndSub
Sub UpdateFrame
For i = 1 To numEnemy
Shapes.Move(enemy[i], enemyPosX[i]-size/2, enemyPosY[i]-size/2)
EndFor
Shapes.Move(player, playerPosX-size/2, playerPosY-size/2)
EndSub
Sub Collision
For i = 1 To numEnemy
sepX = Math.Abs(enemyPosX[i]-playerPosX)
sepY = Math.Abs(enemyPosY[i]-playerPosY)
If (sepX < size And sepY < size) Then
Sound.PlayClickAndWait()
EndIf
EndFor
EndSub
'------------------------------------------------
'SOUS-ROUTINES D'EVENEMENT
'------------------------------------------------
Sub OnKeyDown
lastKey = GraphicsWindow.LastKey
If (lastKey = "Left") Then
keyLeft = "True"
ElseIf (lastKey = "Right") Then
keyRight = "True"
ElseIf (lastKey = "Up") Then
keyUp = "True"
ElseIf (lastKey = "Down") Then
keyDown = "True"
EndIf
EndSub
Sub OnKeyUp
lastKey = GraphicsWindow.LastKey
If (lastKey = "Left") Then
keyLeft = "False"
ElseIf (lastKey = "Right") Then
keyRight = "False"
ElseIf (lastKey = "Up") Then
keyUp = "False"
ElseIf (lastKey = "Down") Then
keyDown = "False"
EndIf
EndSub
Sub OnMouseMove
mouseMove = "True"
EndSub
Sub OnMouseDown
mouseDown = "True"
EndSub
Créer et Supprimer des Sprites
Si vous créez ou supprimez des sprites pendant le jeu, il y a quelques précautions à prendre. En particulier si vous en avez terminé avec un sprite ne vous contentez pas de le masquer (avec Shapes.Hide) ou de le sortir de l'écran et de l'oublier, supprimez le (Shapes.Remove). Si vous supprimez pas les sprites inutilisés votre jeu va ralentir. Ça peut se compliquer lorsque les sprites sont stockés dans des tableaux, lorsque vous devez supprimer tous les éléments de tableau associés à ce sprite (forme, position, vitesse etc), qui peuvent laisser les tableaux avec quelques éléments oubliés, ainsi de simple boucles For sur les indexes de ces tableaux peuvent échouer ou être inefficace.
Une bonne méthode pour gérer cela est de masquer temporairement les sprites, mais de les réutiliser en les affichant lorsqu'un nouveau sprite de même type (par exemple un missile) est nécessaire.
Par conséquent soyez prudent lorsque vous créez un nouveau sprite pendant le jeu (pas lors de l'initialisation). Ne les laissez pas s'accumuler sans discernement.
Collisions Avancées
Avoir des sprites qui rebondissent sur les autres de manière réaliste peut être compliqué. Fondamentalement nous avons besoin de faire la collision sur le centre de gravité du cadre de référence en utilisant la géométrie comme la figure ci-dessous, puis convertir depuis le centre de gravité du cadre vers le cadre.
Traduction de la figure (Note du Traducteur : mes notions de mathématiques sont un peu floues dans ce contexte, j'ai donc des doutes sur ma traduction, n'hésitez pas à laisser un commentaire ou à modifier cet article si ce n'est pas correct) :
B et C sont les centre des balles en collision.
AB est la vitesse de l'incidence du centre de gravité de la balle B
BD est la vitesse du rebond du centre de gravité de la balle B.
BC est le vecteur entre les centres des balles, soit le vecteur d'unité dans cette direction est n
B est donc -2n.AB (2* produit scalaire)
DE = -AB
BE = BD+DE = BD-AB
BD = AB-2n.AB
Voici un exemple de l'implémentation de tout ça dans Small Basic.
Sub CollisionCheck
For i = 1 To Ball_Number-1
For j = i+1 To Ball_Number
dx = Ball_X[i] - Ball_X[j]
dy = Ball_Y[i] - Ball_Y[j]
Distance = Math.SquareRoot(dx * dx + dy * dy)
If Distance < Ball_Diameter Then
Cx = (Ball_vX[i]+ball_vX[j])/2
Cy = (Ball_vY[i]+ball_vY[j])/2
Relative_vX[i] = Ball_vX[i] - Cx
Relative_vY[i] = Ball_vY[i] - Cy
Relative_vX[j] = Ball_vX[j] - Cx
Relative_vY[j] = Ball_vY[j] - Cy
Nx = dx / Distance
Ny = dy / Distance
L[i] = Nx * Relative_vX[i] + Ny * Relative_vY[i]
L[j] = Nx * Relative_vX[j] + Ny * Relative_vY[j]
Relative_vX[i] = Relative_vX[i] - (2 * L[i] * Nx)
Relative_vY[i] = Relative_vY[i] - (2 * L[i] * Ny)
Relative_vX[j] = Relative_vX[j] - (2 * L[j] * Nx)
Relative_vY[j] = Relative_vY[j] - (2 * L[j] * Ny)
Ball_vX[i] = (Relative_vX[i] + Cx)
Ball_vY[i] = (Relative_vY[i] + Cy)
Ball_vX[j] = (Relative_vX[j] + Cx)
Ball_vY[j] = (Relative_vY[j] + Cy)
Ball_X[i] = Ball_X[i] + Nx * (Ball_Diameter-Distance)
Ball_Y[i] = Ball_Y[i] + Ny * (Ball_Diameter-Distance)
Ball_X[j] = Ball_X[j] - Nx * (Ball_Diameter-Distance)
Ball_Y[j] = Ball_Y[j] - Ny * (Ball_Diameter-Distance)
EndIf
EndFor
EndFor
EndSub
Si ce n'est pas clair alors peut-être qu'il faut mettre de coté et envisager d'utiliser un moteur physique pour le faire à votre place, comme par exemple la méthode LDPhysics (Box2D).
Moteur Physique
Un moteur physique prend en charge les collisions dynamiques pour vous, résolvant les forces et interactions des objets dynamiques. Vous interagissez uniquement avec ce genre de simulation en appliquant des forces et couples sur les objets, plutôt que de calculer les vitesse par vous-même.
L'extension LitDev (LDPhysics) utilise le moteur physique Box2D et à beaucoup d'exemple et de documentation. Elle est plutôt évoluée et des bases de compréhension de la physique est nécessaire.
Les Jeux 3D
Jusque là nous n'avons étudiez que les modèles 2D. La 3D est considérablement plus complexe à code par soi-même et le nombre élevé de calculs géométriques et de rendu nécessite l'utilisation de méthode d'accélération matérielle.
L'extension LitDev a également des capacité de modélisation 3D (LD3DView). Là encore, elle peut être assez complexe pour commencer, mais une fois que les bases sont acquises (comment dessiner le maillage en triangle et contrôler la caméra) elle permet de créer des résultats impressionnants malgré que se soit Small Basic qui la pilote.
Voir Aussi
Autres Langues
- Article original : Small Basic: Dynamic Graphics (en-us)