Howdy, Stranger!

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

Trouble with Movement of Physics Objects

edited November 2014 in Questions Posts: 59

Hey, I'm having trouble with moving my physics objects stated in the setup function. There are tabs of code missing, but none of them are important in this case.

-- Neon Air Hockey -- Main supportedOrientations(PORTRAIT_ANY) displayMode(OVERLAY) rectMode(RADIUS) ellipseMode(RADIUS) function setup() print("Pong") -- Menu menu = true -- Button button = Images:getButton() buttonStart = Button("Start",WIDTH/2,HEIGHT/5*2,350,150,100,0,255,0,button,menuOff) -- Ball ball = physics.body(CIRCLE,25) ball.type = DYNAMIC ball.x = WIDTH/2 ball.y = HEIGHT/2 ball.gravityScale = 0 ball.sleepingAllowed = false -- variables for Player 1 and 2 paddles pos1 = vec2(WIDTH/2, HEIGHT/4) pos2 = vec2(WIDTH/2, HEIGHT/4*3) steer1 = vec2(0,0) steer2 = vec2(0,0) speed = 1600 -- Player 1's Controller controller1 = VirtualStick { moved = function(v) steer1 = v end, released = function(v) steer1 = vec2(0,0) end, x0=0,x1=1,y0=0,y1=0.25,name="Player 1",nameSide="right"} -- Player 1's Paddle Player1 = physics.body(CIRCLE,50) Player1.type = KINEMATIC Player1.x = pos1.x Player1.y = pos1.y Player1.gravityScale = 0 Player1.sleepingAllowed = false -- Player 2's Controller controller2 = VirtualStick { moved = function(v) steer2 = v end, released = function(v) steer2 = vec2(0,0) end, x0=0,x1=1,y0=0.75,y1=1,name="Player 2",nameSide="left",orientation="back"} -- Player 2's Paddle Player2 = physics.body(CIRCLE,50) Player2.type = KINEMATIC Player2.x = pos2.x Player2.y = pos2.y Player2.gravityScale = 0 Player2.sleepingAllowed = false allControllers = All({controller1,controller2}) end function touched(touch) allControllers:touched(touch) end function draw() background(15, 15, 15, 255) if menu == true then drawMenu() buttonStart:draw() else pushStyle() strokeWidth(10) stroke(0, 255, 0, 255) lineCapMode(SQUARE) line(0,HEIGHT/2,WIDTH,HEIGHT/2) strokeWidth(20) fill(0, 0, 0, 0) rect(WIDTH/2,HEIGHT/2,WIDTH/2,HEIGHT/2) popStyle() -- Ball ellipse(ball.x,ball.y,25) -- Player 1 pos1 = pos1 + steer1*speed*DeltaTime pos1.x = math.max(0,pos1.x) pos1.x = math.min(WIDTH,pos1.x) pos1.y = math.max(0,pos1.y) pos1.y = math.min(HEIGHT/2,pos1.y) fill(255,0,0,255) ellipse(Player1.x, Player1.y, 50) -- Player 2 pos2 = pos2 + steer2*speed*DeltaTime pos2.x = math.max(0,pos2.x) pos2.x = math.min(WIDTH,pos2.x) pos2.y = math.max(HEIGHT/2,pos2.y) pos2.y = math.min(HEIGHT,pos2.y) fill(0,255,255,255) ellipse(Player2.x, Player2.y, 50) allControllers:draw() end end

There are 3 physics objects, and 2 of them would be moved by my virtual controller sticks. These controllers work fine on moving sprites by the 2D vectors 'pos1' and 'pos2'. However, these don't seem to apply to the kinematic circles named 'Player1' and 'Player2'.

The physics lines corresponding to these physics objects are under '-- Player 1's Paddle' and '-- Player 2's Paddle'.

Please help.


  • Also, the grey boxes containing the code are being formatted weirdly, unless I'm not quite using them right.

  • IgnatzIgnatz Mod
    Posts: 5,396

    You nearly had the code formatting right, use three ~

    Actually, the missing code could be important, because none of the code above changes the positions of Player1 and Player2....

  • edited November 2014 Posts: 59

    Simply put, the positions are changed like this:

    • pos (1 or 2) is the starting position.
    • steer is the vector direction that changes as the controllers receive information on which way to change. Steer directs which way the object moves (a sprite worked before with this)
    • the speed is just how many pixels the object moves per second (i think)

    Because I know that all the position work on the other tabs is correct, and all physics work is done on this tab only, the rest should not matter, unless you want to know exactly how it changes the movement.

    EDIT - The ball, I think, should move as planned, but with no way to move the paddles (player1 and player2) I am not ale to test it out.

  • IgnatzIgnatz Mod
    Posts: 5,396

    The paddles are kinematic objects, which are not affected by gravity, only by your changing their positions in code.

    That does not happen in the code above. If you have code that does change the paddle positions, please post it. (If you don't have that code, there is your problem).

  • edited November 2014 Posts: 59

    I'm sorry, I mis-posted the explanation about the code. You see, I said that pos1 and pos2 were the starting positions. What I failed to mention was that pos1 and pos2 are variables that start out as the starting position, bu are changed by steer, speed, and deltaTime to produce a change of a position in x and y. In short, they actually ARE changing the position, or they should...
    Is that sufficient for you to work out why the paddles are not moving?

  • IgnatzIgnatz Mod
    edited November 2014 Posts: 5,396

    Ah, I see.

    Your problem may be that when you say (in setup) Player1.x = pos1.x, that makes Player1.x equal to whatever is in pos.x, but won't update it for changes in pos.x.

    The way to make it update automatically is to write this instead in setup


    Now, because you are assigning something more complicated (a vec2) than a number or text, to a variable, Codea will store the address of pos, not the hard coded value, and this means Player.pos will be linked to pos and update when it changes.

    (If you do this, you will need to change any code that used Player1.x and Player1.y to use Player1.pos.x and Player1.pos.y instead).

    Let me know if unclear.

  • Just to make sure -

    Recap: Change the .x and the .y to object.position, because .position is for vec2.


  • IgnatzIgnatz Mod
    Posts: 5,396

    no, the name for a vec2 can be anything, but pos or position is a good choice.

    Previously you said Player1.x=pos1.x

    We can't replace that with Player1=pos1, obviously, we need to create a property under Player1, so I simply called it pos

  • IgnatzIgnatz Mod
    Posts: 5,396

    The key change is assigning a vec2 to the Player1 position variable, so Codea stores an address (of pos1), and not just a fixed number.

  • edited November 2014 Posts: 59

    I see, but I tried what you said anyway, and it has not worked yet. I'll see if there is anything I missed, but...

    EDIT - does it need to be in the draw function, or should it still be in setup()?

  • IgnatzIgnatz Mod
    edited November 2014 Posts: 5,396

    Try this little app (add a new tab to the right,put it there and run). And no, this code doesn't need to be in draw, setup is the right place.

    (In your code, make sure you have changed all previous references to Player1.x and Player1.y)

    function setup()
        --your code
        --my code
        --change pos1
        --print results
    function draw() end
  • I just experimentally moved the object.pos = pos lines into the draw function, seems they now work! Thanks for your support, Ignatz!

  • I'll still try your tab to see if there is any difference there.

  • It made the screen black, literally.

  • results=

    pos= 500 200
    yours= 100 200
    mine= 500 200

  • IgnatzIgnatz Mod
    Posts: 5,396

    oh well, as long as it works now

  • Thanks for your support though, Ignatz, the .pos worked wonders.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @CayDay47 - I realised the reason you got a black screen running my code was you must have made your app full screen, and my printing out was hidden

    If you put this line at the top of my code displayMode(STANDARD) you should see that my solution fixes your problem

    If you haven't come across memory pointers before, try this

  • edited November 2014 Posts: 59

    Was this what happened when you said,

    Now, because you are assigning something more complicated (a vec2) than a
    number or text, to a variable, Codea will store the address of pos, not the hard
    coded value, and this means Player.pos will be linked to pos and update when it
  • IgnatzIgnatz Mod
    Posts: 5,396


    It's really important to understand this. The way I think of it, Codea (actually Lua) can only store numbers or strings in variables, so any time you want to store a vec2, a table, a class, a physics object in a variable, Codea just stores the address where that thing can be found.

    When you say

    function DoSomething(a)

    Codea treats this as

    DoSomething = function(a)

    ie it stores the code somewhere safe, and puts its memory location in DoSomething

    You can see this by printing the following two statements

    print(DoSomething) --will print a memory address
    print(DoSomething**()**)  --will run the function

    The first statement just says "print out what is stored in DoSomething", which is a memory address

    The second statement says "run the function whose address is in DoSomething", because double brackets mean "run the function"

  • Then, when writing in actual Lua, should the first example be used to declare a function, or he second one?

  • IgnatzIgnatz Mod
    Posts: 5,396

    It also means that if you write

    --changing b also affects a!
    print(a) --> (333,200)

    because when you set b=a, it is storing the address of a, ie they are both pointing to the same object! So when you change either, the other changes too.

    To copy the vector, you need to copy the x and y values separately (exactly as you were doing). Because those are just numbers, those numbers will be copied, not a memory address.

Sign In or Register to comment.