Jetpack Hero - partie II
Il s’agit maintenant d’utiliser le jetpack en simulant la gravité. Simulation naïve, mais simple.
Impulsion du jetpack
Pour afficher un sprite le hash doit comporter les éléments x, y, w, h et
path. Mais on peut aussi y ajouter ce qu’on veut. La variable impulse retiendra
l’impulsion du jetpack, en nombre de pixels.
args.state.hero ||= {
x: 600,
y: 200,
w: 7 * HERO_SCALE,
h: 17 * HERO_SCALE,
path: 'sprites/hero.png',
impulse: 0,
}Lorsqu’on appuie sur la touche CONTROL du clavier ou la touche Y de la manette
(ou A, B, X, ça dépend de la manette) on fait monter le personnage de 4 pixels.
À chaque frame la valeur de impulse va diminuer un peu.
IMPULSE = 4 # Jetpack power
IMPULSE_DECREASE = 0.9 # Jetpack power ratio decrease per frame
if args.inputs.keyboard.control || args.inputs.controller_one.y
args.state.hero.impulse = IMPULSE
end
args.state.hero.impulse *= IMPULSE_DECREASELa chute continuelle
Il est temps de mettre à jour la position y du personnage. Pour simuler une
espèce de gravité le personnage tombe tout le temps avec l’ajout de -1.2.
FALL = -1.2 # Kind of gravity
args.state.hero.y += FALL
args.state.hero.y += args.state.hero.impulseOn surveille les bords de l’écran
On s’occupe aussi de garder le personnage dans les limites de l’écran. DragonRuby
ajoute quelques méthodes à la classe Numeric, comme clamp :
args.state.hero.x = args.state.hero.x.clamp(0, Grid.w - args.state.hero.w)
args.state.hero.y = args.state.hero.y.clamp(0, Grid.h - args.state.hero.h)Le programme complet
Pour le moment le programme entier ressemble à ce qui suit :
# https://github.com/lkdjiin/jetpack-hero/tree/1c840ab53dd0d6dc8947c4efe075a78fc5047db8
HERO_SCALE = 4 # Image ratio
FALL = -1.2 # Kind of gravity
RL_SPEED = 5 # Right/left speed
IMPULSE = 4 # Jetpack power
IMPULSE_DECREASE = 0.9 # Jetpack power ratio decrease per frame
def tick args
args.state.hero ||= {
x: 600,
y: 200,
w: 7 * HERO_SCALE,
h: 17 * HERO_SCALE,
path: 'sprites/hero.png',
impulse: 0,
}
if args.inputs.left
args.state.hero.x -= RL_SPEED
elsif args.inputs.right
args.state.hero.x += RL_SPEED
end
if args.inputs.keyboard.control || args.inputs.controller_one.y
args.state.hero.impulse = IMPULSE
end
args.state.hero.impulse *= IMPULSE_DECREASE
args.state.hero.y += FALL
args.state.hero.y += args.state.hero.impulse
args.state.hero.x = args.state.hero.x.clamp(0, Grid.w - args.state.hero.w)
args.state.hero.y = args.state.hero.y.clamp(0, Grid.h - args.state.hero.h)
args.outputs.solids << { x: 0, y: 0, w: 1280, h: 720, r: 0, g: 0, b: 0 }
args.outputs.sprites << args.state.hero
endPas encore 40 lignes et je trouve déjà que ça devient le boxon :D
Du rangement
Dans un moteur de jeu, et même dans un jeu sans moteur, on retrouve d’une manière ou d’une autre les quatre parties : initialisation, gestion des sorties, gestion des entrées et calcul. Avec DragonRuby le niveau 1 de la structuration d’un programme (juste au-dessus du niveau 0 : «on fourre tout dans tick») est d’utiliser le pattern suivant :
def tick(args)
defaults(args)
render(args)
input(args)
calc(args)
endOn explose tick en quatre méthodes qui s’occuperont seulement de ce qui les concernent.
Voici donc le programme final pour aujourd’hui :
# https://github.com/lkdjiin/jetpack-hero/tree/946a9b9071a86acb3dc4ae2b9c7bef4d5448bf39
HERO_SCALE = 4 # Image ratio
FALL = -1.2 # Kind of gravity
RL_SPEED = 5 # Right/left speed
IMPULSE = 4 # Jetpack power
IMPULSE_DECREASE = 0.9 # Jetpack power ratio decrease per frame
def tick(args)
defaults(args)
render(args)
input(args)
calc(args)
end
def defaults(args)
args.state.hero ||= {
x: 600,
y: 200,
w: 7 * HERO_SCALE,
h: 17 * HERO_SCALE,
path: 'sprites/hero.png',
impulse: 0,
}
end
def render(args)
args.outputs.solids << { x: 0, y: 0, w: 1280, h: 720, r: 0, g: 0, b: 0 }
args.outputs.sprites << args.state.hero
end
def input(args)
if args.inputs.left
args.state.hero.x -= RL_SPEED
elsif args.inputs.right
args.state.hero.x += RL_SPEED
end
if args.inputs.keyboard.control || args.inputs.controller_one.y
args.state.hero.impulse = IMPULSE
end
end
def calc(args)
args.state.hero.impulse *= IMPULSE_DECREASE
args.state.hero.y += FALL
args.state.hero.y += args.state.hero.impulse
args.state.hero.x = args.state.hero.x.clamp(0, Grid.w - args.state.hero.w)
args.state.hero.y = args.state.hero.y.clamp(0, Grid.h - args.state.hero.h)
endRéférences
- Vous trouverez le code de Jetpack Hero sur github
- Documentation de DragonRuby
Cet article fait partie d’une série :
- Jetpack Hero
- Partie II
- Une platforme, des collisions
- Première animation du personnage
- Ajouter des platformes
- Du carburant pour le jetpack
- Collecte de minerai
- Effets sonores
- Du rangement avec la classe Game
- Apparition des aliens
- Tir du personnage
- On dégomme de l’alien
- GAME OVER
- Les aliens bougent enfin
- Plusieurs petites animations
- Un score et des vies
Commentaires
Pas encore trouvé de solution simple et non-invasive pour avoir des commentaires sur le blog. En attendant vous pouvez laisser votre Commentaire sur mastodon@lkdjiin