Tutorial:Physics (Français)

Dans cet exemple, nous allons créer une balle rouge qui roule sur un sol vert.

L'exemple fini est à la fin de cette page. Toutes ces fonctions peuvent être placées dans un fichier: main.lua

Nous commencerons dans la function love.load().

love.load()

Premièrement, il nous faut mettre en place un monde(world) dans lequel pourrons exister les corps physiques.

function love.load()
  love.physics.setMeter(64) -- la taille d'un mètre dans notre monde sera de 64px
  world = love.physics.newWorld(0, 9.81*64, true) -- créer un monde avec une gravité horizontale de 0 et une gravité verticale de 9.81

Maintenant que notre monde(world) a été créé, on peut y ajouter des corps(bodies), formes(shapes), et des attaches(fixtures).

   objects = {} -- table pour contenir tous nos objets physiques
 
  -- création du sol
  objects.ground = {}
  objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) -- souvenez vous, la forme (le rectangle qu'on crée juste après) s'encre au corps depuis son centre, donc il faut le déplacer à (650/2, 650-50/2)
  objects.ground.shape = love.physics.newRectangleShape(650, 50) -- créer un rectangle de largeur 650 et de hauteur 50
  objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) -- attacher la forme au corps
 
  -- création d'une balle
  objects.ball = {}
  objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") -- on place le corps au centre du monde et on le rend dynamique, pour qu'il puisse se déplacer
  objects.ball.shape = love.physics.newCircleShape( 20) -- la forme de la balle à un rayon de 20
  objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1) -- on attache la forme au corps et on donne à la fixture une densité de 1
  objects.ball.fixture:setRestitution(0.9) -- Une restitution proche de 1 la fait rebondir
 
  -- création de quelque blocs pour s'amuser
  objects.block1 = {}
  objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
  objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
  objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) -- Une densité plus élevée lui donne plus de masse.
 
  objects.block2 = {}
  objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
  objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)

Enfin, pour terminer la fonction love.load(), on va définir la taille de l'écran et la couleur de fond.

  -- initialisation graphique
  love.graphics.setBackgroundColor(104, 136, 248) -- mettre le fond en un joli bleu
  love.window.setMode(650, 650) -- mettre les dimensions de la fenêtre en 650 par 650 (par défaut sans plein-écran ni antialiasing et avec le vsync activé)
end

Okay, c'est assez pour la configuration initiale du moteur de physique. Maintenant, on doit éditer la fonction love.update().

love.update()

function love.update(dt)
  world:update(dt) -- cela met le monde en mouvement
 
  --ici, on va créer quelques entrées clavier
  if love.keyboard.isDown("right") then -- si on appuie sur la flèche de droite, on pousse la balle vers la droite
    objects.ball.body:applyForce(400, 0)
  elseif love.keyboard.isDown("left") then -- si on appuie sur la flèche de gauche, on pousse la balle vers la gauche
    objects.ball.body:applyForce(-400, 0)
  elseif love.keyboard.isDown("up") then -- si on appuie sur la flèche du haut, on réinitialise la position de la balle dans les airs
    objects.ball.body:setPosition(650/2, 650/2)
    objects.ball.body:setLinearVelocity(0, 0) -- on doit mettre la vélocité à 0 pour éviter que le fait d'avoir changé la position génère une vélocité énorme
  end
end

Maintenant que le monde se met à jour à chaque tick, on peut définir comment on va dessiner le sol et la balle dans la fonction love.draw().

love.draw()

Premièrement, le sol.

function love.draw()
  love.graphics.setColor(72, 160, 14) -- on met la couleur en vert pour le sol
  love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- dessiner un polygone "remplis" en utilisant les coordonnées des points du sol

Et enfin, on peut dessiner le cercle qui représente la balle, et les blocks.

  love.graphics.setColor(193, 47, 14) --on met la couleur en rouge pour la balle
  love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius()) -- on peut dessiner directement un cercle pour la balle
 
  love.graphics.setColor(50, 50, 50) -- on met la couleur en gris pour les blocs
  love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints()))
  love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints()))
end

Et voilà ! Mettez tout ça dans votre main.lua, et lancez le selon votre système d'exploitation. Vous aurez une balle roulant dans un environnement vert luxuriant, comme promis.

Capture d'écran du produit (presque) fini.


Le main.lua

function love.load()
  love.physics.setMeter(64) -- la taille d'un mètre dans notre monde sera de 64px
  world = love.physics.newWorld(0, 9.81*64, true) -- créer un monde avec une gravité horizontale de 0 et une gravité verticale de 9.81
 
  objects = {} -- table pour contenir tous nos objets physiques
 
 -- création du sol
 objects.ground = {}
 objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) -- souvenez vous, la forme (le rectangle qu'on crée juste après) s'encre au corps depuis son centre, donc il faut le déplacer à (650/2, 650-50/2)
 objects.ground.shape = love.physics.newRectangleShape(650, 50) -- créer un rectangle de largeur 650 et de hauteur 50
 objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) -- attacher la forme au corps
 
 -- création d'une balle
 objects.ball = {}
 objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") -- on place le corps au centre du monde et on le rend dynamique, pour qu'il puisse se déplacer
 objects.ball.shape = love.physics.newCircleShape( 20) -- la forme de la balle à un rayon de 20
 objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1) -- on attache la forme au corps et on donne à la fixture une densité de 1
 objects.ball.fixture:setRestitution(0.9) -- Une restitution proche de 1 la fait rebondir
 
 -- création de quelque blocs pour s'amuser
 objects.block1 = {}
 objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
 objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
 objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) -- Une densité plus élevée lui donne plus de masse.
 
 objects.block2 = {}
 objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
 objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
 objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)
 
 -- initialisation graphique
 love.graphics.setBackgroundColor(104, 136, 248) -- mettre le fond en un joli bleu
 love.window.setMode(650, 650) -- mettre les dimensions de la fenêtre en 650 par 650 (par défaut sans plein-écran ni antialiasing et avec le vsync activé)
end
 
 
function love.update(dt)
  world:update(dt) -- cela met le monde en mouvement
 
  --ici, on va créer quelques entrées clavier
  if love.keyboard.isDown("right") then -- si on appuie sur la flèche de droite, on pousse la balle vers la droite
    objects.ball.body:applyForce(400, 0)
  elseif love.keyboard.isDown("left") then -- si on appuie sur la flèche de gauche, on pousse la balle vers la gauche
    objects.ball.body:applyForce(-400, 0)
  elseif love.keyboard.isDown("up") then -- si on appuie sur la flèche du haut, on réinitialise la position de la balle dans les airs
    objects.ball.body:setPosition(650/2, 650/2)
    objects.ball.body:setLinearVelocity(0, 0) -- on doit mettre la vélocité à 0 pour éviter que le fait d'avoir changé la position génère une vélocité énorme
  end
end
 
function love.draw()
  love.graphics.setColor(72, 160, 14) -- on met la couleur en vert pour le sol
  love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- dessiner un polygone "remplis" en utilisant les coordonnées des points du sol
  love.graphics.setColor(193, 47, 14) --on met la couleur en rouge pour la balle
  love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius()) -- on peut dessiner directement un cercle pour la balle
 
  love.graphics.setColor(50, 50, 50) -- on met la couleur en gris pour les blocs
  love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints()))
  love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints()))
end



Other languages