Page 1 of 1

Joints not destroying

Posted: Mon Feb 13, 2023 12:21 pm
by Applepiesoda
Hello everyone! :ultraglee:

I am currently in the process of developing a game prototype, and right now I am making a grappling hook by using a distance joint (that connects the player and a grapple point). My plan is when the player holds a button, the grappling hook will be connected. And when the button is released, the hook will be disconnected and thus the joint will be destroyed.

But right now, when I hold the button, the joint is created. However, when I release, the joint is not destroyed, even when I call joint:destroy()! The player still behaves as if the joint is connected :huh:

I honestly have no clue what might be causing this, I don't think that I am attempting to use the joint later on, so it should technically be destroyed, right?

I have included a .love file, please ignore the messy code :death: I would be very grateful for all help I get :awesome:
------------------------------------------------------------------------------------------
Instructions for .love file:
Move to the left to find a box with a circle around it, the cube is the grapple point and the circle is the zone you can grapple in.
WASD - Move
K - Hold to grapple

Re: Joints not destroying

Posted: Mon Feb 13, 2023 1:40 pm
by Bigfoot71
In your script "grapple-block.lua" the condition that grapple `if (distLC <= grBlockZoneRadius or distRC <= grBlockZoneRadius) and love.keyboard.isDown('k') then` is true as long as you press K and you are in the grapple area and therefore instantiate several joints, then when you stop pressing K it will just destroy the last instantiated joint, so there are others left.

Here's a better way to write it by checking if a grappling hook already exists or not:

Code: Select all

  function grBlock.update(self)

    topLeftX, topLeftY, bottomRightX = player.shape:computeAABB(player.body:getX(), player.body:getY(), 0)
    distRC = distance(bottomRightX, topLeftY, self.body:getX(), self.body:getY())
    distLC = distance(topLeftX, topLeftY, self.body:getX(), self.body:getY())

    local grappleMustBeCreate = love.keyboard.isDown('k') and (distLC <= grBlockZoneRadius or distRC <= grBlockZoneRadius)

    if grappleMustBeCreate and not maxJoint then
      if distLC < distRC then
        upperLeftC = true
        maxJoint = love.physics.newDistanceJoint(self.body, player.body, self.body:getX(), self.body:getY(), topLeftX, topLeftY, true)
      else
        upperRightC = true
        maxJoint = love.physics.newDistanceJoint(self.body, player.body, self.body:getX(), self.body:getY(), bottomRightX, topLeftY, true)
      end

    elseif not grappleMustBeCreate and maxJoint and not maxJoint:isDestroyed() then
      maxJoint:destroy()
      maxJoint = nil
      upperLeftC = false
      upperRightC = false
      print("destroyed")
    end
  end
My proposal is only a quick tinkering to match the rest of your code, I really advise you to review the way you wrote all this because it will be hellish to maintain in a larger project unfortunately :/

If you need advice don't hesitate ^^

Edit: As a bonus you will notice for example that I placed the key check before the check that the grapple is in the right area, this will avoid unnecessary checks, it is this kind of improvement that makes the code a little more readable and a bit more optimized, although that won't be enough in this case. I also don't really like the idea of ​​having to set "maxJoint" back to "nil" every time (it's more a personal consideration). In short, I will let you make your thoughts unless you have any questions.

Re: Joints not destroying

Posted: Tue Feb 14, 2023 9:10 am
by Applepiesoda
Ah, I see. I thought that maxJoint would just get updated, not that more joints would be instantiated. But when you explain it like that, it makes total sense!

Thanks a lot for the help, I will experiment with this some more in my free time :)