IX. Tutoriels▲
IX-A. Tutoriel n° 1 : Affichage d'une image▲
Ce premier tutoriel vous montre comment charger puis afficher une image dans notre fenêtre. Un script Gosu consiste toujours par définir la classe de notre fenêtre principale, qui hérite de Window. En redéfinissant les méthodes de cette classe, on obtiendra notre application. Ici, nous redéfinissons que la méthode initialize qui va initialiser notre jeu et la méthode update qui sera appelée toutes les 20 millisecondes pour rafraîchir notre fenêtre. update ne doit donc pas contenir de boucle principale de jeu, car celle-ci est implicite.
class Tut1 < Window
def initialize
super(640, 480, false, 20)
@image = Image.new(self, ".\\tut.bmp", true)
self.caption = "Tutoriel 1 : Affichage d'une image"
end
def update
@image.draw(10,10)
end
end
IX-B. Tutoriel n° 2 : Affichage d'une image en suivant la souris▲
Dans de nombreux jeux 2D, le joueur doit pouvoir bouger un curseur. Pour cela, il faut afficher une image aux coordonnées de la souris. Les coordonnées de la souris sont données par rapport à l'origine qui est le point en haut à gauche de la partie graphique de notre fenêtre (c'est-à-dire sans compter la barre Windows). Si la souris se trouve en dehors de la partie graphique de la fenêtre, cela ne pose pas de problème à Gosu. Pour voir comment cela fonctionne, on affichera également dans la console les coordonnées x et y de la souris. Pour le reste, il s'agit principalement des mêmes concepts employés dans le tutoriel n° 1.
class Tut2 < Window
def initialize
super(640, 480, false, 20)
@image = Image.new(self, ".\\tut.bmp", true)
self.caption = "Tutoriel 2 : Affichage d'une image suivant la souris"
end
def update
@image.draw(self.mouse_x,self.mouse_y)
print mouse_x, " ", mouse_y, "\n"
end
end
IX-C. Tutoriel n° 3 : Affichage de tiles▲
Généralement, un jeu 2D consiste à afficher des personnages, des objets. Mais le plus souvent, plusieurs images sont associées à un même objet : par exemple, une image montrera un personnage de dos, et une autre, ce même personnage, mais de face. Ainsi nous avons une succession d'images représentant le même objet ayant toutes la même taille. Au lieu de mettre chacune de ces images dans un fichier différent, on peut vouloir toutes les stocker dans un seul à la suite. Il faut après pouvoir découper toutes ces images facilement. Gosu propose la méthode load_tiles qui découpe le fichier et retourne un tableau d'images. On passera en paramètre simplement la largeur et la hauteur des images composant la suite.
Note : on peut aussi passer en paramètres le nombre d'images par ligne et par colonne dans notre fichier regroupant toutes les images.
class Tut3 < Window
def initialize
super(640, 480, false, 20)
@image_tab = Image.load_tiles(self, ".\\tut_tiles.bmp", 64, 64, true)
self.caption = "Tutoriel 3 : Affichage de tiles"
end
def update
@image_tab[0].draw(10,10)
@image_tab[1].draw(50,50)
end
end
IX-D. Tutoriel n° 4 : Affichage d'un texte▲
Ce tutoriel montre comment afficher un texte avec Gosu. Pour cela, il suffit de créer un nouvel objet de type Font, puis d'appeler la méthode draw en passant en paramètre les coordonnées où dessiner le texte ainsi que le texte à écrire.
class Tut4 < Window
def initialize
super(640, 480, false, 20)
@font = Font.new(self, "Arial", 36)
self.caption = "Tutoriel 4 : Affichage d'un texte"
end
def update
red = 0xFFFF0000
@font.draw("Youpi", 100, 100, 0, 2, 1, red)
end
end
IX-E. Tutoriel n° 5 : Affichage d'une image avec rotation▲
Une fonctionnalité puissante de Gosu est la possibilité d'afficher des images ayant fait une rotation autour d'un point grâce à la fonction draw_rot.
class Tut5 < Window
def initialize
super(640, 480, false, 20)
@image = Image.new(self, ".\\tut.bmp", true)
self.caption = "Tutoriel 5 : Affichage d'une image avec rotation"
end
def update
@image.draw_rot(30,30,0,30.0,0,0)
end
end
IX-F. Lancement des tutoriaux▲
Il faut faire un nouveau fichier Ruby (.rb) puis ajouter : En début du fichier script :
require "gosu.so"
include Gosu
En fin de fichier script :
t = TutX.new
t.show
Où X est le numéro du tutoriel.
IX-G. Exemple plus complet▲
Ceci est le code de l'exemple complet livré avec la bibliothèque. Il s'agit d'un jeu où vous devez, à l'aide de votre vaisseau, collecter des étoiles : néanmoins l'inertie de votre vaisseau rend la chose difficile. Une autre particularité de cet exemple est que si votre vaisseau dépasse un bord de la zone graphique, il réapparaît de l'autre côté. On notera aussi l'utilisation de son : à chaque fois que vous « mangez » une étoile avec votre vaisseau, un petit « bip » est émis. Cet exemple vous montrera mieux comment fonctionne un jeu écrit avec Gosu.
# On charge notre bibliothèque bien - aimée
require 'gosu'
# Définition du module ZOrder : celui à pour but de rassembler toutes les profondeurs des
# différents objets de notre jeu. Ainsi le fond aura une profondeur de 0, les étoiles de 1, le
# vaisseau du joueur de 2 et l'User Interface (le score) de 3. Plus la profondeur est grande,
# plus le dessin sera dessiné sur les autres dessins de profondeur plus petite.
module ZOrder
Background, Stars, Player, UI = *0..3
end
# Classe représentant une étoile pour notre jeu.
class Star
attr_reader :x, :y
# Initialisation d'une étoile
# On remarquera que sa couleur est aléatoire. De plus l'étoile utilise plusieurs images pour
# faire son animation (comme pour les dessins animés). Elle démarre aléatoire sur une des
# positions de son animation à une position également aléatoire.
def initialize(animation)
@animation = animation
@color = Gosu::Color.new(0xff000000)
@color.red = rand(255 - 40) + 40
@color.green = rand(255 - 40) + 40
@color.blue = rand(255 - 40) + 40
@x = rand * 640
@y = rand * 480
end
# Fonction pour dessiner notre étoile en fonction de son étape d'animation.
def draw
img = @animation[Gosu::milliseconds / 100 % @animation.size];
img.draw(@x - img.width / 2.0, @y - img.height / 2.0,
ZOrder::Stars, 1, 1, @color, :additive)
end
end
# Classe pour les objets incarnant le joueur à l'écran. Pour ce jeu, il s'agit d'un vaisseau
# spatial souffrant d'inertie.
class Player
# Fonction d'initialisation :
# 1 - chargement de l'image et du son propre aux instances de cette classe.
# 2 - initialisation des variables
def initialize(window)
@image = Gosu::Image.new(window, "media/Starfighter.bmp", false)
@beep = Gosu::Sample.new(window, "media/Beep.wav")
@x = @y = @vel_x = @vel_y = @angle = 0.0
end
# Fonction de télé - transportation du joueur : déplace le joueur aux coordonnées passées en
# paramètres.
def warp(x, y)
@x, @y = x, y
end
# Fonction pour tourner à gauche en diminuant l'angle du vaisseau.
# Le vaisseau peut donc tourner sur lui-même sans avoir besoin de vitesse pour le faire.
def turn_left
@angle -= 4.5
end
# Fonction pour tourner à droite en augmentant l'angle du vaisseau.
# Le vaisseau peut donc tourner sur lui-même sans avoir besoin de vitesse pour le faire.
def turn_right
@angle += 4.5
end
# Fonction pour faire accélérer le vaisseau selon son angle.
def accelerate
@vel_x += Gosu::offset_x(@angle, 0.5)
@vel_y += Gosu::offset_y(@angle, 0.5)
end
# Fonction faisant bouger le vaisseau. Chaque mouvement décélère le vaisseau.
def move
@x += @vel_x
@y += @vel_y
@x %= 640
@y %= 480
@vel_x *= 0.95
@vel_y *= 0.95
end
# Fonction pour ramasser les étoiles disséminées dans la fenêtre. Pour cela on parcourt toutes
# les étoiles et on détecte si une étoile entre en collision avec nous. La détection de collision
# se fait en regardant si la distance entre le centre de l'étoile et le centre du vaisseau est
#inférieure à 35 pixels. On joue un son si on est en contact avec une étoile et on augmente le
# score de 10.
def collect_stars(stars)
stars.reject! do |star|
dist_x = @x - star.x
dist_y = @y - star.y
dist = Math.sqrt(dist_x * dist_x + dist_y * dist_y)
if dist < 35 then
yield 10
@beep.play
true
else
false
end
end
end
# Fonction pour dessiner notre vaisseau selon son angle.
def draw
@image.draw_rot(@x, @y, ZOrder::Player, @angle)
end
end
# Classe pour la fenêtre du jeu. Elle va initialisé notre jeu en définissant un joueur et un
# tableau pour les étoiles. Ensuite, elle affichera son score et réagir aux touches pressées sur le
# clavier.
class GameWindow < Gosu::Window
# Initialisation du jeu :
# 1 - chargement des images et de la police de caractère
# 2 - initialisation des variables globales (le score, le titre de la fenêtre, les paramètres
# d'affichages)
# 3 - création des éléments de base du jeu (un joueur et les étoiles)
# Note : le chargement des différentes animations de l'étoile se fait à l'aide d'un load_tiles.
def initialize
super(640, 480, false, 20)
self.caption = "Gosu Tutoriel Game"
@font = Gosu::Font.new(self, Gosu::default_font_name, 20)
@background_image = Gosu::Image.new(self, "media/Space.png", true)
@star_anim = Gosu::Image::load_tiles(self, "media/Star.png", 25, 25, false)
@player = Player.new(self)
@player.warp(320, 240)
@stars = Array.new
@score = 0
end
# Fonction principale du jeu : elle gère la " vie " du jeu :
# 1 - Réaction aux touches pressées (envoie d'un message à l'objet player)
# 2 - Génération d'étoiles
def update
if button_down? Gosu::Button::KbLeft or button_down? Gosu::Button::GpLeft then
@player.turn_left
end
if button_down? Gosu::Button::KbRight or button_down? Gosu::Button::GpRight then
@player.turn_right
end
if button_down? Gosu::Button::KbUp or button_down? Gosu::Button::GpButton0 then
@player.accelerate
end
@player.move
@player.collect_stars(@stars) { |gain| @score += gain }
if rand(100) < 4 and @stars.size < 25 then
@stars.push(Star.new(@star_anim))
end
end
# Fonction pour réagir aux boutons pressés puis relâchés. Typiquement, le bouton pour sortir
# du jeu.
def button_down(id)
if id == Gosu::Button::KbEscape
close
end
end
# Fonction de dessin. Elle est appelée après update et est chargée d'afficher le monde du jeu.
# Son action consiste à dessiner le score, l'arrière-plan puis le joueur et enfin toutes les
# étoiles.
def draw
@font.draw("Score: #{@score}", 10, 10, ZOrder::UI, 1.0, 1.0, 0xffffff00)
@background_image.draw(0, 0, ZOrder::Background)
@player.draw
@stars.each { |star| star.draw }
end
end
GameWindow.new.show