#### Howdy, Stranger!

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

# General question regarding physics.body EDGE

Posts: 33

I'm just starting to dig into codeas built in physics, and have been playing around with some basic shapes and physics types. Everything's been fairly straight forward, but I'm a little confused about the use of physics.body EDGE. Are edges generally meant to remain stationary?

My goal is to simply be able to control the pitch of the floor with my 2 parameters. So far I can raise the line/edge easily enough, but I am unable to lower the edge once raised, it almost seems as though I'm creating many ghost edges that get left behind… then Codea crashes. This behavior leads me to believe that I may be going about things incorrectly.

How can I make my line as drawn behave more like a solid object?

``````function setup()
-- parameters to control the line
-- line starting point
x1=0
parameter.number("y1",0,HEIGHT/3,100)
-- line end point
x2=WIDTH
parameter.number("y2",0,HEIGHT/3,100)
-- line thickness
lw = 10

-- create an image to represent the physics object
id=img.width/2 -- image dimensions
--create the physics object
p_img = physics.body(POLYGON,vec2(-id,id),vec2(-id,-id),
vec2(id,-id),vec2(id,id))
p_img.x = WIDTH/2
p_img.y = HEIGHT/2
p_img.angle=math.random(0,360)
p_img.gravityScale = 1     -- gravity
p_img.restitution = 0.7    -- bounce
p_img.friction = 0.001     -- friction
p_img.linearDamping = .3   -- drag
p_img.linearVelocity = vec2(math.random(400),math.random(400))
p_img.info="box"           -- object name

CreateWalls()
end

function draw()
background(10,10,20) stroke(255) strokeWidth(lw)
-- Draw line
line(x1,y1,x2,y2)
-- Move the edge along with line?
physics.body(EDGE,vec2(x1,y1),vec2(x2,y2))
-- draw the box
pushMatrix()
translate(p_img.x, p_img.y)
rotate(p_img.angle)
sprite(img,0,0)
popMatrix()
end

--creates the frame
function CreateWalls()
WallL = CreateEdge(1,1,1,HEIGHT-1,1.0)
WallR = CreateEdge(WIDTH-1,0,WIDTH-1,HEIGHT-1,0.9)
WallB = CreateEdge(1,1,WIDTH-1,1,0.2)
WallT = CreateEdge(1,HEIGHT-1,WIDTH-1,HEIGHT-1,0.7)
end

--creates one Edge/wall
function CreateEdge(x,y,x1,y1,r)
local w = physics.body(EDGE,vec2(x,y),vec2(x1,y1)) -- vec2
w.restitution=r
return w
end
``````

• edited May 2017 Posts: 7,604

@Circuit Basically you are creating ghost edges. Once you create a physics object, that object remains until you destroy it. Since an edge is static, it remains where you first defined it. That's why you were able to raise the edge and it looked like it was working, but once you started to lower it, the upper ones were still there. Look in the reference under physics for destroy.

EDIT: Also, you shouldn't create a physics object in the draw function unless you have code to limit how many you create. That will cause Codea to crash because you're creating physic objects at 60 times per second and you'll eventually run out of memory.

• edited May 2017 Posts: 7,604

@Circuit Here's a quick fix. There's probably a better way, but I was in a hurry.

EDIT: Modified my first fix that was here. Here's a better way to handle changing and destroying the physics object. See where I added the comments `added change and added this function`. I also removed some code from the draw function.

``````function setup()
-- parameters to control the line
-- line starting point
x1=0
-- line end point
x2=WIDTH
-- line thickness
lw = 10

-- create an image to represent the physics object
id=img.width/2 -- image dimensions
--create the physics object
p_img = physics.body(POLYGON,vec2(-id,id),vec2(-id,-id),
vec2(id,-id),vec2(id,id))
p_img.x = WIDTH/2
p_img.y = HEIGHT/2
p_img.angle=math.random(0,360)
p_img.gravityScale = 1     -- gravity
p_img.restitution = 0.7    -- bounce
p_img.friction = 0.001     -- friction
p_img.linearDamping = .3   -- drag
p_img.linearVelocity = vec2(math.random(400),math.random(400))
p_img.info="box"           -- object name

CreateWalls()
end

function change()   -- added this function
-- Move the edge along with line?
if p~=nil then
p:destroy()
end
p=physics.body(EDGE,vec2(x1,y1),vec2(x2,y2))
end

function draw()
background(10,10,20) stroke(255) strokeWidth(lw)
-- Draw line
line(x1,y1,x2,y2)
-- draw the box
pushMatrix()
translate(p_img.x, p_img.y)
rotate(p_img.angle)
sprite(img,0,0)
popMatrix()
end

--creates the frame
function CreateWalls()
WallL = CreateEdge(1,1,1,HEIGHT-1,1.0)
WallR = CreateEdge(WIDTH-1,0,WIDTH-1,HEIGHT-1,0.9)
WallB = CreateEdge(1,1,WIDTH-1,1,0.2)
WallT = CreateEdge(1,HEIGHT-1,WIDTH-1,HEIGHT-1,0.7)
end

--creates one Edge/wall
function CreateEdge(x,y,x1,y1,r)
local w = physics.body(EDGE,vec2(x,y),vec2(x1,y1)) -- vec2
w.restitution=r
return w
end
``````
• Posts: 33

@dave1707 thank you for your quick response and both fixes. I kind of figured it was something along those lines causing the issue/crash, but was unaware that I could destroy the objects in that manner. I was starting to think that an edge was not meant to be utilized in this way.

My current issue I'm now trying to wrap my head around is getting my edge to apply force back to the box in a somewhat realistic manner. I was hoping the line would end up with a slightly more pinball paddle like feel, but I'm not sure exactly how to achieve this with an edge. I've been playing around with linearVelocity a bit, but I'm clearly missing something.

• Posts: 7,604

@Circuit Giving the box a greater than 1 restitution value will cause it to react to the edge more.

• Posts: 33

@dave1707 Actually, that's one of the first things I tried, and it did improve things slightly but I felt the box was then too bouncy/unrealistic and almost never stopped moving. What I'm noticing is that the box is only affected by its own momentum. Once the box sits still for a moment, I am unable to transfer momentum to it by moving the line up quickly (in an attempt to toss the box back into the air). It seems to just lift the box to the level of the line and then drops it from that point.

Here I added a 2nd red line using `CHAIN` that is a little more like what I was going for. It has a lot more influence over the box, but I'm having trouble getting the red line to move in the same manner using my original parameters. My experimentation with velocity has been a little confusing to say the very least.

How would I go about getting the red line/CHAIN to move and control like my original white EDGE using my first two parameters?

``````function setup()
-- parameters to control the line
-- line starting point
x1=0
-- line end point
x2=WIDTH
-- line thickness
lw = 10
--line 2 parameters (Red Line)
parameter.number("redY",-400,400,0)
line2=physics.body(CHAIN,false,vec2(-WIDTH/2,0),vec2(WIDTH/2,0))
line2.x=WIDTH/2
line2.y=50
line2.angle = 0
line2.type=KINEMATIC
----
-- create an image to represent the physics object
id=img.width/2 -- image dimensions
--create the physics object
p_img = physics.body(POLYGON,vec2(-id,id),vec2(-id,-id),
vec2(id,-id),vec2(id,id))
p_img.bullet = true
p_img.x = WIDTH/2
p_img.y = HEIGHT/2
p_img.angle=math.random(0,360)
p_img.gravityScale = 1     -- gravity
p_img.restitution = 0.7    -- bounce
p_img.friction = 0.001     -- friction
p_img.linearDamping = .3   -- drag
p_img.linearVelocity = vec2(math.random(400),math.random(400))
p_img.info="box"           -- object name

CreateWalls()
end

function change()   -- added this function
-- Move the edge along with line?
if p~=nil then
p:destroy()
end
p=physics.body(EDGE,vec2(x1,y1),vec2(x2,y2))
end

function draw()
background(10,10,20) stroke(255) strokeWidth(lw)
-- Draw line
line(x1,y1,x2,y2)
--line 2 (CHAIN)
stroke(255, 0, 0, 255)
strokeWidth(2)
line(line2.x-WIDTH/2,line2.y,line2.x+WIDTH/2,line2.y)
line2.linearVelocity=vec2(0 ,redY)
----
-- draw the box
pushMatrix()
translate(p_img.x, p_img.y)
rotate(p_img.angle)
sprite(img,0,0)
popMatrix()
end

--creates the frame
function CreateWalls()
WallL = CreateEdge(1,1,1,HEIGHT-1,1.0)
WallR = CreateEdge(WIDTH-1,0,WIDTH-1,HEIGHT-1,0.9)
WallB = CreateEdge(1,1,WIDTH-1,1,0.2)
WallT = CreateEdge(1,HEIGHT-1,WIDTH-1,HEIGHT-1,0.7)
end

--creates one Edge/wall
function CreateEdge(x,y,x1,y1,r)
local w = physics.body(EDGE,vec2(x,y),vec2(x1,y1)) -- vec2
w.restitution=r
return w
end
``````
• Posts: 7,604

@Circuit The problem you're having with the edge is because you're overriding the physics engine when you're moving it. Anytime you use physics objects, you have to let the physics engine do everything. In my example above, when I destroy and recreate the edge in the function change, the edge doesn't have any velocity, so the box doesn't react to it like you expect. Anytime you want to manually move a physics, you have to give it a linearVelocity or angularVelocity.

• Posts: 33

@dave1707 Yeah, I was reading about that yesterday a bit. I spent about 3 hours last night messing around with both linearVelocity and angularVelocity to interact with my red line. I'm having a hard time figuring out how to use them both to control objects accurately. I get movement, just not always in the way I had intended.

Thanks again for all the help. It's kinda funny that what started as just goofing around with the physics engine has now taken up days of my life. Oh Codea...

• Posts: 7,604

@Circuit Don't look at it as taking up days of your life, look at it as you are learning about the physics engine. The more you play around with it, the more things you'll run into, but the more you'll learn. I've been playing around with Codea for 5 years and there's still things I don't know how to do. Of course there's probably a lot I've forgotten, but relearning doesn't take as long as the first time.

• Posts: 7,604

@Circuit Here's something that might give you an idea. Use the parameter slider to vary the angular velocity of the polygon.

``````function setup()
physics.continuous=true

b2=physics.body(CIRCLE,0)
b2.x=WIDTH/2
b2.y=160
b2.type=STATIC

b3=physics.body(CIRCLE,20)
b3.x=350
b3.y=600
b3.restitution=1

e=physics.body(CHAIN,false,vec2(0,0),vec2(WIDTH,0),
vec2(WIDTH,HEIGHT),vec2(0,HEIGHT),vec2(0,0))
e.type=STATIC

p2=physics.body(POLYGON,vec2(-150,-5),vec2(150,-5),vec2(150,5),vec2(-150,5))
p2.x=WIDTH/2
p2.y=160

j3=physics.joint(REVOLUTE,p2,b2,b2.position)

parameter.integer("ang",-720,720,0,inc)
end

function inc()
p2.angularVelocity=ang
end

function draw()
background(40, 40, 50)
fill(255)
stroke(255)
strokeWidth(2)

ellipse(b2.x,b2.y,5)
ellipse(b3.x,b3.y,40)

pushMatrix()
translate(p2.x,p2.y)
rotate(p2.angle)
line(-150,-5,150,-5)
line(150,-5,150,5)
line(150,5,-150,5)
line(-150,5,-150,-5)
popMatrix()
end
``````
• Posts: 33

@dave1707 Actually, yesterday on my own, I had created an almost identical project to your most recent example. However, spinning the object is about all I can figure out how to do using angularVelocity and my slider. Controlling an object in this manner using angularVelocity and linearVelocity still seems quite awkward, and I find it very difficult to get the exact movement I'm aiming for.

Unfortunately, I'm still having a really hard time simulating the subtle behavior of my white line from my original post. Although, as you had previously stated, I am learning a heck of a lot about the physics engine along the way.

• edited May 2017 Posts: 7,604

@Circuit Try this one. Hold your finger on the left half of the screen above or below the line to move it up or down. Do the same on the right half. You can move both edges at the same time.

``````displayMode(FULLSCREEN)

function setup()
y1,y2=0,0

ball=physics.body(CIRCLE,20)
ball.x=350
ball.y=600
ball.restitution=1

edges=physics.body(CHAIN,false,vec2(0,0),vec2(WIDTH,0),
vec2(WIDTH,HEIGHT),vec2(0,HEIGHT),vec2(0,0))
edges.type=STATIC

ch1,ch2=200,200
ch=physics.body(CHAIN,false,vec2(0,ch1),vec2(WIDTH,ch2))
end

function draw()
background(40, 40, 50)
fill(255)
stroke(255)
strokeWidth(2)
line(0,ch1,WIDTH,ch2)
ellipse(ball.x,ball.y,40)
if l1~=0 or l2~=0 then
ch1=ch1+y1
ch2=ch2+y2
ch:destroy()
ch=physics.body(CHAIN,false,vec2(0,ch1),vec2(WIDTH,ch2))
end
end

function touched(t)
if t.state==BEGAN then
if t.x<WIDTH/2 then
if t.y>ch1 then
y1=2
else
y1=-2
end
else
if t.y>ch2 then
y2=2
else
y2=-2
end
end
end
if t.state==ENDED then
y1,y2=0,0
end
end
``````