#### Howdy, Stranger!

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

# Playing with balls

edited July 2015 Posts: 8

This is the first project I have worked on in Codea. It's a simple project that shows balls and stuff. :>

``````--# Main
-- Ball Test 3 (complete)

function setup()

parameter.boolean("stat",true)  -- Makes a newly made ball move
parameter.boolean("pchange",true)   -- Set to false if you don't want to change the ball you want to move
parameter.boolean("psize",false)    -- Set to true if you want to change the size your ball
parameter.integer("pspeed",0,10,1)  -- The amount of force exerted on your ball is multiplied by this value + 1
parameter.integer("size",1,100,30)  -- Sets the size of a newly made ball or your ball
parameter.action("Stop Player Movement", function() -- Stops the movement of your ball
for k,v in pairs(b) do
if v.player then
v.linearVelocity = vec2(0,0)
end
end
end)
parameter.action("Stop all ball movement", function() -- Stops the movement of all balls
for k,v in pairs(b) do
v.linearVelocity = vec2(0,0)
end
end)

b = {}  -- Store all the bodies here

-- Walls
local floor = physics.body( EDGE, vec2(0, 0), vec2(WIDTH, 0))
floor.restitution = 1.1

local left = physics.body( EDGE, vec2(0, 0), vec2(0, HEIGHT))
left.restitution =  1.1

local right = physics.body( EDGE, vec2(WIDTH, 0), vec2(WIDTH, HEIGHT))
right.restitution = 1.1

local ceiling = physics.body( EDGE, vec2(0, HEIGHT), vec2(WIDTH, HEIGHT))
ceiling.restitution = 1.1

physics.gravity(0,0)    -- Tabletop physics
physics.continuous = true   -- Balls don't pass through walls if they get too fast

table.insert(b,floor)
table.insert(b,left)
table.insert(b,right)
table.insert(b,ceiling)
end

-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(2)

for k,v in pairs(b) do  -- Draws the balls
drawBodies(v)
if v.player and psize then  -- Changes the size of your ball if psize
end
end

if explode then -- Shows the last contact / Nice effects
sprite("Space Art:Red Explosion", exp.x, exp.y, exps, exps) -- exps is the energy of the impact
end
end

function touched(touch)
t = vec2(touch.x, touch.y)
if touch.state == BEGAN then
makeCirc(t.x,t.y)
else
for k,v in pairs(b) do
if v.shapeType == CIRCLE and not pcheck(v) and v.player then
v:applyForce((t-v.position)*(pspeed+1)) -- Applies force
end
end
end
end
end

function collide(contact)
if contact.state == BEGAN then
exp = contact.position
exps = contact.normalImpulse
explode = true
tween.delay(0.1, function()
explode = false
end)
sound(DATA, "ZgNAFQBJQEBAQEBAAAAAAAAAAAC5ZIg+AABAf0BAQEBAQHJx")
end
end

function makeCirc(x,y)
local a = physics.body(CIRCLE,size)
a.x, a.y = x, y
a.restitution = 1
a.interpolate = true
a.player = false
if not stat then
a:applyForce(vec2(math.random(-1000,1000),math.random(-1000,1000)))
end
table.insert(b, a)
end

function drawBodies(obj)
pushStyle()
fill(255, 0, 0, 0)
stroke(25, 255, 0, 165)
if obj.shapeType == EDGE then
line(obj.points,obj.points,
obj.points,obj.points)
elseif obj.shapeType == CIRCLE and obj.player then
pushStyle()
noStroke()
fill(0, 255, 180, 255)
popStyle()
elseif obj.shapeType == CIRCLE then
end
popStyle()
end

function pcheck(obj)    -- Checks if a tap is inside a ball
for k,v in pairs(b) do
v.player = false
end
obj.player = true
return true
else
return false
end
end

``````
Tagged:

• Posts: 8

Please show ways to make it better. • edited July 2015 Posts: 5,396

Nice work for a first project

``````--instead of
if tx >= obj.x - obj.radius and tx <= obj.x + obj.radius
and ty >= obj.y - obj.radius and ty <= obj.y + obj.radius
and pchange == true then

--try this
--dist is the distance between two vectors (points)
``````
• edited July 2015 Posts: 8

It's actually the 3rd version of the project. The first project only has the creation of balls and the second one is just a fancier version of the first.

I don't understand the code you just posted.
By the way, your ebook helped me a lot Edit:
I understood it but it gives me an error.

Edit2:
Eureka! Apparently, it doesn't work when you just put obj inside.

``````    if pchange and vec2(tx,ty):dist( vec2(obj.x, obj.y) )<=obj.radius then
``````

Just updated the code.

• Posts: 5,396

ah, yes, I overlooked that obj wasn't a vec2

it's worth looking at the other vector functions in Codea, they can be very helpful. If you make your position variables vec2's, then it makes using those functions a little easier (and your code a little tidier)

``````--if your position is t [=vec2(x,y)], instead of tx,ty
--and both of those are vec2, then you have
if pchange and t:dist(obj.pos) )<=obj.radius then
``````

``````v:applyForce(vec2((tx-v.x)*(pspeed+1), (ty-v.y)*(pspeed+1)))
--can be written as
v:applyForce((t-v)*(pspeed+1))
``````

(PS thanks for the kind words about the ebook).

• edited July 2015 Posts: 494

Actually

``````if tx >= obj.x - obj.radius and tx <= obj.x + obj.radius
and ty >= obj.y - obj.radius and ty <= obj.y + obj.radius
and pchange == true then
``````

and

``````if pchange and vec2(tx,ty):dist(obj)<=obj.radius then
``````

are not equivalent. (But the second is probably what you want anyway.)

• Posts: 8

Thanks @Ignatz, I looked at the touched function and noticed that I could shorten the if statements into one if statement. I also made tx and ty into a vec2 in order to shorten other parts of my code.

@LoopSpace I don't understand why they are not equivalent, could you please explain why

• Posts: 5,396

They are not equivalent because my code assumes your objects are circular, whereas your original code worked for squares.

But I thought you probably wanted circles (and even if you have squares, it is close enough, since we have fat fingers that don't touch accurately).

• Posts: 8

Thanks, I get it now. (Fat fingers ))

I also noticed that instead of putting "== true", you could just write the variable/function. It also works with "== false" by putting "not" before the variable/function.

``````if var == true then

-- Just write
if var then

if var == false then

-- Just write
if not var then
``````
• Posts: 5,396

That's right.

A very good trick is using `or` to set defaults for variables, eg in a function like this

``````function ABC(a,b)
--if a is nil or not provided, use 10
a = a or 10
--if b is nil or not provided, use 0.15
b = b or 0.15
return a,b
end

--then
ABC() --> returns 10, 0.15
ABC(3) --> returns 3, 0.15
ABC(nil,2) --> returns 10, 2
``````
• Posts: 8

@Ignatz Thanks for the info I also thank you very much for your ebooks, I started reading the lua ebook before I even knew about Codea and it helped me a ton. 