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 in Code Sharing 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("add", false) -- For adding balls 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) -- Do your drawing here 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 v.radius = size 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 if add then -- Makes a ball if add 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[1][1],obj.points[1][2], obj.points[2][1],obj.points[2][2]) elseif obj.shapeType == CIRCLE and obj.player then pushStyle() noStroke() fill(0, 255, 180, 255) ellipse(obj.x,obj.y,obj.radius*2) popStyle() elseif obj.shapeType == CIRCLE then ellipse(obj.x,obj.y,obj.radius*2) end popStyle() end function pcheck(obj) -- Checks if a tap is inside a ball if pchange and t:dist(obj.position)<=obj.radius then for k,v in pairs(b) do v.player = false end obj.player = true return true else return false end end


  • Posts: 8

    Please show ways to make it better. :)

  • IgnatzIgnatz Mod
    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)
    if pchange and vec2(tx,ty):dist(obj)<=obj.radius then
  • 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 :)

    I understood it but it gives me an error.

    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.

  • IgnatzIgnatz Mod
    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 your object position is obj.pos instead of obj.x and obj.y
    --and both of those are vec2, then you have
    if pchange and t:dist(obj.pos) )<=obj.radius then

    and your "apply force" line

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

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

  • edited July 2015 Posts: 324


    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


    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

  • IgnatzIgnatz Mod
    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
    -- Instead of
    if var == false then
    -- Just write
    if not var then
  • IgnatzIgnatz Mod
    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
    ABC() --> returns 10, 0.15
    ABC(3) --> returns 3, 0.15
    ABC(nil,2) --> returns 10, 2
  • Posts: 8

    @Ignatz Thanks for the info :D
    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. :D

Sign In or Register to comment.