Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Pulling Physics Objects Towards Another Physics Object??

in Questions Posts: 104

Is there any possible way to somehow pull a physics body towards another body if they are in a certain radius from the other physics body? Trying to make it as a challenge for my game.

Thanks :)

Comments

  • dave1707dave1707 Mod
    Posts: 9,441

    Instead of pulling, try pushing. You can use physics.applyForce to the opposite side of the body.

  • edited August 31 Posts: 172

    yes it’s possible, but first allow me to break down the workflow

    every update loop the physics world will make bodies react to each other based on their positions and velocities (and other properties, gravity etc)

    so every update() a physics body will report its current state based on the world of the physics interactions

    you can override most of these properties, for example you can set the x and y position of the body directly, but this means you will not be accounting for complex interactions so that’s why most guides say stay away from direct manipulation, but there’s nothing stopping you

    so if you wanted to create an attractor object, you would just adjust the x,y position of a body that is attracted by an amount appropriate for the attraction strength, so if my attractor was at position x = 100, y = 100 and my object was at 0,0 i would add say 10 and 10 to the x and y so that next update it is 10 pixels closer to the attractor on each axis

  • Posts: 1,292
    @skar is there a “rubber band” joint that can pull bodies together?
  • Posts: 172

    @UberGoober not that i can see, i would just use direct x,y manipulation for this, it’s not much to add, you can make a Body class and wrap the physics.body in custom functions and identifiers, it’s how i have my own Hitboxes and GravityBox classes in my game project

  • Posts: 1,292
    @skar sure, but like you said, doing it the brute-force way robs the physics simulation of its ability to react realistically to lots of different forces at once. I’m honestly surprised there’s no rubber-band style connector, it seems like it’d be a very common request.
  • Posts: 172

    i’m not sure why either, maybe an over sight because “gravity” had already been considered done and part of the physics world,

    but that’s really what we’re talking about, adding an unseen force every frame that slightly moves that physics body, it’s not too far out of scope i think, that’s all the physics engine does in the back end anyway, just processes the bodies and sets their new x,y, velocity values, if you know what you’re doing you can manipulate anything

  • Posts: 104

    @skar, I’m still not quite sure how to do that. Is it possible for you to make an example so that I can fully understand what you’re trying to say??

  • edited August 31 Posts: 1,292
    Wait wait wait—in @John’s Physics Lab built-in example, all the objects can be dragged around with a touch, and they lag a little bit behind the touch as if they’re being pulled around by a rubber band.

    Go dig in thar, son! ;)

    I’ve poked at it a little myself and I can maybe give you a pointer or two: what John does is that when a touch starts on a physics body, he makes a table with the touch and the body in it and puts that table into debugDraw’s touchMap table, and then in the debugDraw.draw() function he looks at each touch/body pair in the touchMap table, and then applies forces to the body to make it head towards the position of the touch.
  • Posts: 172

    here’s a simple example that just adds 10 to the x position, you can make it much more complex by passing custom update functions and parameters

    function setup()
      myBody = Body()
    end
    function draw()
      myBody:update(100, 100)
    end
    
    Body = class()
    function Body:init()
      self.body = physics.body()
      self.body.x = 0
      self.body.y = 0
      self.prevX = 0
      self.prevY = 0
    end
    
    function Body:update()
      self.prevX = self.body.x
      self.body.x = self.prevX + 10
    
    end
    
    
    
    
    
  • dave1707dave1707 Mod
    Posts: 9,441

    Here’s an example using distance joint.

    viewer.mode=STANDARD
    
    function setup() 
        c1 = physics.body(CIRCLE,50)
        c1.x=WIDTH/2
        c1.y=200
        c1.sleepingAllowed=false
    
        c2 = physics.body(CIRCLE,50)
        c2.x=WIDTH/2
        c2.y=800
        c2.type=STATIC
        c2.sleepingAllowed=false
    
        j1=physics.joint(DISTANCE,c1,c2,c1.position,c2.position)    
        d=j1.length
    
        stroke(255)
        strokeWidth(1)
        noFill()   
    end
    
    function draw()
        background(30, 30, 30, 25)    
        ellipse(c1.x,c1.y,100)    
        ellipse(c2.x,c2.y,100)
        text(j1.length,WIDTH/2,HEIGHT/2)
        if d>=0 then
            d=d-1
        end
        j1.length=d
    end
    
  • dave1707dave1707 Mod
    Posts: 9,441

    Here’s another example.

    viewer.mode=FULLSCREEN
    
    function setup() 
        c1 = physics.body(CIRCLE,50)
        c1.x=WIDTH/2
        c1.y=HEIGHT-100
        c1.sleepingAllowed=false
    
        c2 = physics.body(CIRCLE,50)
        c2.x=WIDTH/2
        c2.y=HEIGHT-50
        c2.type=STATIC 
    
        d=0
        stroke(255)
        strokeWidth(1)
        fill(255)   
    end
    
    function draw()
        background(30, 30, 30, 25)    
        ellipse(c1.x,c1.y,100)    
        ellipse(c2.x,c2.y,100)
        if d>=0 and j1~=nil then
            d=d-1
            j1.length=d       
        end
        text("tap screen to cause pull",WIDTH/2,HEIGHT/2)
    end
    
    function touched(t)
        if t.state==BEGAN then
            j1=physics.joint(DISTANCE,c1,c2,c1.position,c2.position)    
            d=j1.length        
        end
    end
    
  • Posts: 1,292
    @dave1707 this is very odd: on my iPhone 8, running your first example, I only see one circle, and I don’t see the text that should print in the middle of the screen at all. Your second example works fine though.
  • dave1707dave1707 Mod
    edited August 31 Posts: 9,441

    @UberGoober Change the c2.y from 800 to HEIGHT-50. Change the noFill to fill(255) . I code on my iPad Air 3 in portrait orientation and forget that others use different orientations and devices.

Sign In or Register to comment.