Vous lisez 4 fils de discussion
  • Auteur
    Messages
    • #76296
      Pastourlou
      Participant

      Bonjour,

      Je suis débutant et je travail sur une adaptation de l’atelier « Lunar Lander » pour en faire un jeu de bataille navale inspiré d’Asteroids.
      Le joueur contrôle un bateau qui a le même comportement qu’un tank : il se déplace avec les flèches directionnelles et peut tirer dans toutes les directions à l’aide de la souris.

      Mon problème est le suivant : Je n’arrive pas à faire en sorte que le sprite de l’obus soit au premier plan ! Il apparait en dessous du bateau…

      Pouvez-vous m’aider à régler ce problème ?

      Les fichiers du jeu : https://we.tl/t-eEZQB85UCP

      FICHIER MAIN :

      --[[
      *****BISMARK*****
      Bataille navale. Inspiré d'Asteroids
      SEMAINE 16
      1h / 07:32
      --]]
      
      if arg[#arg] == "-debug" then require("mobdebug").start() end
      io.stdout:setvbuf ("no")
      
      require ("player_manager")
      require ("sprites_manager")
      
      player = {}
      sprites = {} 
      
      function love.load()
        love.window.setMode (1280, 720)
        screen_width = love.graphics.getWidth()
        screen_height = love.graphics.getHeight()
        player = Sprite_create ("player", "player/player", 500, 500)
      end
      
      function love.update(dt)
       Sprites_update (sprites, player, dt)
      end
      
      function love.draw()
        Sprites_draw (sprites)
      end

      MODULE 1 : SPRITES MANAGER

      local TILESIZE = 32
      local sea_img = love.graphics.newImage ("images/sea/sea.png")
      
      function Sprite_create (typ, img, x, y)
        local newSprite = {}
        newSprite.type = typ
        newSprite.img = love.graphics.newImage ("images/"..img..".png")
        newSprite.x = x
        newSprite.y = y
        newSprite.vx = 0
        newSprite.vy = 0
        newSprite.angle = 0
        
        if newSprite.type == "player" then
          newSprite.cannon_angle = 0
          newSprite.cannon_img = love.graphics.newImage ("images/player/cannon.png")
        end
        
        table.insert (sprites, newSprite)
        return newSprite
      end
      
      function Sprites_update (sprites, player, dt)
        local i
        for i = #sprites, 1, -1 do
          local sprite = sprites[i]
          if sprite.type == "player" then
            Player_update (sprite, dt)
          end
          sprite.x = sprite.x + sprite.vx
          sprite.y = sprite.y + sprite.vy
        end
      end
      
      function Sprites_draw (sprites)
         local i, j
        --Sea tiles
        for i = 1, math.floor (screen_height/TILESIZE) + 1 do
          for j = 1, math.floor (screen_width/TILESIZE) do
            love.graphics.draw (sea_img, (j-1) * TILESIZE, (i-1) * TILESIZE)
          end
        end
        
        --All Sprites
        for i=#sprites, 1, -1 do
          local sprite = sprites[i]
          if sprite.type == "player" then
            love.graphics.draw (sprite.img, sprite.x, sprite.y, math.rad (sprite.angle), 1, 1, sprite.img:getWidth()/2, sprite.img:getHeight()/2)
            love.graphics.draw (sprite.cannon_img, sprite.x, sprite.y, sprite.cannon_angle, 1, 1, sprite.cannon_img:getWidth()/2 - 3, sprite.cannon_img:getHeight()/2)
          else
            love.graphics.draw (sprite.img, sprite.x, sprite.y, sprite.angle, 1, 1, sprite.img:getWidth()/2, sprite.img:getHeight()/2)
          end
        end  
        love.graphics.print ("sprites:"..#sprites, 0, 0)
      end

      MODULE 2 : PLAYER MANAGER

      function Player_update (player, dt)
        --Keep angle
        if player.angle > 360 then
          player.angle = 0
        elseif player.angle < 0 then
          player.angle = 360
        end
        
        --Controls
        if love.keyboard.isDown ("up") then
          local angle_to_rad = math.rad (player.angle)
          local force_x = math.cos (angle_to_rad) * 3 * dt
          local force_y = math.sin (angle_to_rad) * 3 * dt
          player.vx = player.vx + force_x
          player.vy = player.vy + force_y
        end
        if love.keyboard.isDown ("right") then
          player.angle = player.angle + 100 * dt
        end
        if love.keyboard.isDown ("left") then
          player.angle = player.angle - 100 * dt
        end
        
        --Speed limits
        if math.abs (player.vx) > 2 then
          if player.vx > 0 then
            player.vx = 2
          else
            player.vx = -2
          end
        end
        if math.abs (player.vy) > 2 then
          if player.vy > 0 then
            player.vy = 2
          else
            player.vy = -2
          end
        end
        
        --Slowdown
        if player.vx > 0 then
          player.vx = player.vx - 1 * dt
          if player.vx < 0 then player.vx = 0 end
        else
          player.vx = player.vx + 1 * dt
          if player.vx > 0 then player.vx = 0 end
        end
        if player.vy > 0 then
          player.vy = player.vy - 1 * dt
          if player.vy < 0 then player.vy = 0 end
        else
          player.vy = player.vy + 1 * dt
          if player.vy > 0 then player.vy = 0 end
        end
        
        --Cannon angle
        player.cannon_angle = math.atan2 (love.mouse.getY() - player.y, love.mouse.getX() - player.x)
        
        --Screen limitations
        if player.x > screen_width then player.x = 0 end
        if player.x < 0 then player.x = player.screen_width end
        if player.y > screen_width then player.y = 0 end
        if player.y < 0 then player.y = screen_height end
        
        --Shoot
        if love.mouse.isDown(1) then
          local bullet = Sprite_create ("bullet", "player/bullet", player.x, player.y)
          local speed = 70
          bullet.angle = math.atan2 (love.mouse.getY() - player.y, love.mouse.getX() - player.x)
          bullet.vx = math.cos (bullet.angle) * speed * dt
          bullet.vy = math.sin (bullet.angle) * speed * dt
        end
      end
      • Ce sujet a été modifié le il y a 5 mois et 1 semaine par Pastourlou.
    • #76298
      Pastourlou
      Participant

      Version Zip des fichiers : https://we.tl/t-3Xm3uDeb6x

    • #76299
      Marven
      Participant

      Bonjour,

      Je suis sur mon tel impossible de tester ton code, mais le principe est le suivant.

      Le dernier sprite affiché dans le draw sera le plus au dessus.

      Si tu a une liste de sprite que tu parcours avec un for, attention où se trouve ton tir. Un for peu aussi se commencer par la fin de la liste de sprite.

      Souvent je mets le décors, puis les sprites de personnages dans une liste, les balles et obus dans une autre à la suite dans un deuxième affichage.

      J’espère que cela peut t’aider.

      Bon code

    • #76301
      Pastourlou
      Participant

      Merci pour tes réponses.
      Le joueur est bien affiché avant les sprites d’obus, mais le résultat à l’écran n’est pas bon.
      Je ne comprends pas vraiment comment mais oui, les obus ne doivent pas être bien positionnés dans la liste.

      je vais suivre ton conseil et placer tous les obus dans une liste à part que je parcourrai après l’affichage du joueur.

      Cela dit j’aimerais comprendre l’origine de l’erreur.

      Merci !

    • #76302
      Pastourlou
      Participant

      Un autre membre a répondu sur le Discord et a donné cette réponse que je mets ici si ça peut aider :

      « Arnkil —
      le tire est sous le bateau car tu affiche dans le sens -1
      for i=#sprites, 1, -1 do
      local sprite = sprites[i]
      if sprite.type == « player » then
      love.graphics.draw (sprite.img, sprite.x, … »

      pour modifier ca tu dois soit changer ton ordre d’affichage soit cree une fonction qui change l’ordre d’affichage via un critere

      Il propose ensuite cette solution :

      si tu veux lua a une fonction sort pour ranger les valeur
      Trier les éléments d’une table (table.sort)
      (…..)
      Une fonction de comparaison peut être fournie pour définir le tri des éléments. La fonction de comparaison doit renvoyer une valeur booléenne indiquant si le premier argument devrait être avant le deuxième argument dans l’ordre de tri. Le comportement par défaut est pour quela comparaison < soit faite. Par exemple, ce qui suit se comporte comme si aucune fonction nétait fournie :

      > t = { 3,2,5,1,4 }
      > table.sort(t, function(a,b) return a<b end)
      > = table.concat(t, « , « )
      1, 2, 3, 4, 5

      Nous constatons que si nous changeons la fonction de comparaison ,l’ordre de tri est renversé.

      > table.sort(t, function(a,b) return a>b end)
      > = table.concat(t, « , « )
      5, 4, 3, 2, 1

      • Cette réponse a été modifiée le il y a 5 mois et 1 semaine par Pastourlou.
Vous lisez 4 fils de discussion
  • Vous devez être connecté pour répondre à ce sujet.