Howdy, Stranger!

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

Using classes with a timer

edited August 2014 in General Posts: 142

I am trying to use a class to draw a ball that animates on the screen. This would be simple by doing for example Ball:draw() , but I also have a timer

counter = counter + 1
    if counter > limit then
        if limit < 181 and limit > 80 then
            limit = limit - 10
        elseif limit < 81 and limit > 40 then
            limit = limit - 5
        elseif limit < 41 and limit > 30 then
            limit = limit - 1 
        elseif limit < 30 then
            limit = limit - 0.1
        end
        counter = 0
        Ball:draw()
    end

and using it as I am, it doesn't work because it is only being called once and needs to be called every frame. How can I get this to work?

Comments

  • IgnatzIgnatz Mod
    Posts: 5,396

    this code needs to go in your main draw function, then it will get run every frame

  • Posts: 142

    @Ignatz It is there, but because counter must be greater than limit, when counter is then set to 0, Ball:draw() is never drawn.

  • IgnatzIgnatz Mod
    Posts: 5,396

    I don't understand the problem, isn't the timer there to decide when the ball is drawn? If so, isn't it working properly?

    If you want the ball drawn every frame, take it outside the if statement

  • Posts: 142

    @Ignatz when Ball:draw() is called, it calls an animation that lasts a couple of seconds. So, when Ball:draw() is called where it is, it is only called for one frame because counter = 0 sets counter to less than limit. So the timer works for the first ball if I set a Boolean e.g. Go = false in setup. Then I declare go = true instead of Ball:draw() and outside of the statement,

    If go == true then
    Ball:draw()
    End
    

    This works, but only for the first one because you can't keep resetting the Boolean because multiple balls will eventually be drawn on the screen and that would only allow for one. If you still don't understand, I can pm you my whole code (it's not very long).

  • IgnatzIgnatz Mod
    edited August 2014 Posts: 5,396

    Yep, I suggest you post all your code, just put it here in the forum, one of us will fix it

  • edited August 2014 Posts: 142

    --# Main -- radial gradient displayMode(FULLSCREEN) function setup() c1 = color(255, 255, 255, 0) c2 = color(0,0,255) c3 = color(255, 0, 0, 255) yellow = color(255, 250, 0, 255) green = color(0, 255, 0, 255) g = radial(250,c1,green) y = radial(250,c1,yellow) blue = radial(250, c1, c2) r = radial(250,c1,c3) balls={} counter = 250 limit = 180 thrust = 20 gravity = 0 b1 = Ball(WIDTH/2,-100,50,20,0,c2) go = false end function draw() background(255, 255, 255, 255) counter = counter + 1 if counter > limit then if limit < 181 and limit > 80 then limit = limit - 10 elseif limit < 81 and limit > 40 then limit = limit - 5 elseif limit < 41 and limit > 30 then limit = limit - 1 elseif limit < 30 then limit = limit - 0.1 end counter = 0 go = true end end --# Ball Ball = class() function Ball:init(x,y,d,t,g,c) -- you can accept and set parameters here self.x = x self.y = y self.diameter = d self.thrust = t self.gravity = g self.color = c end function Ball:draw() -- Codea does not automatically call this method fill(self.color) ellipse(self.x,self.y,self.diameter) self.y = self.y + self.thrust - self.gravity self.thrust = self.thrust * 0.98 self.gravity = self.gravity + 0.05 end function Ball:touched(touch) -- Codea does not automatically call this method end
  • dave1707dave1707 Mod
    Posts: 8,624

    @Staples I added the 3~'s to format your code.

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Staples - I couldn't see how Ball:draw() was running a two second animation, it just seems to adjust position and draw the ball.

    Can you clarify what you want to draw when the counter is below the limit, and how it changes when it hits the limit?

  • Posts: 142

    Every time counter is larger than limit, I want a ball to pop up and for now, fall down. The code is a little different to how it was originally because I was trying to get it to work. As of right now, they are not deleting when they fall back down, but I think I can handle that. The counter is the main problem.

  • IgnatzIgnatz Mod
    edited August 2014 Posts: 5,396

    @Staples - you can do this most simply by setting a variable that tells Codea whether the ball is being animated at the moment. So when the counter hits the limit, you set

    animating=true
    

    then you have this statement in draw(), but outside the if statement, so it runs every time that draw() runs

    if animating then Ball:draw() end
    

    This will keep drawing the ball until animating is turned off.

    So your Ball:draw() function needs to set animating=false, when the animation finishes.

  • Posts: 142

    @Ignatz doesn't this only work for one ball. I want a new ball to come onto the screen every time counter is greater than limit. This will eventually lead to multiple balls on the screen.

  • IgnatzIgnatz Mod
    edited August 2014 Posts: 5,396

    @Staples - then you need a table containing balls, and each time the counter hits the limit, you add a ball to the table

    table.insert(ballsTable,Ball())
    

    then after doing the if tests (still inside draw), you draw all the balls currently on the screen.

    But the Balls:draw function needs to tell the main draw function when it is done, so the ball can be deleted from the table. Suppose Balls:draw returns true when it is done, then you can put this in your main draw function, both to draw, and delete if necessary, each ball

    for i,b in ballsTable() do
        if b:draw() then ballsTable[i]=nil end --delete ball if Balls:draw returns true
    end
    

    NB untested

  • Posts: 142

    @Ignatz I think that will work, but where do I actually draw the balls I.e. Where do I put Ball:draw(), b1:draw, or b:draw?

  • IgnatzIgnatz Mod
    Posts: 5,396

    @Staples - if you don't know how to use classes, I suggest you do that before going any further

    I explain them here

    http://coolcodea.wordpress.com/2013/03/22/7-classes-in-codea/

    http://coolcodea.wordpress.com/2013/03/23/8-classes-in-codea-2/

  • edited August 2014 Posts: 142

    @Ignatz sorry this is taking so long! I've read your classes tutorials, but I'm still struggling with this. Here is my code, the ball is only being drawn once.


    --# Main -- radial gradient displayMode(FULLSCREEN) function setup() c1 = color(255, 255, 255, 0) c2 = color(0,0,255) c3 = color(255, 0, 0, 255) yellow = color(255, 250, 0, 255) green = color(0, 255, 0, 255) balls={} counter = 250 limit = 180 thrust = 20 gravity = 0 b1 = Ball(WIDTH/2,100,50,20,0,c2) go = false end function draw() background(255, 255, 255, 255) counter = counter + 1 if counter > limit then if limit < 181 and limit > 80 then limit = limit - 10 elseif limit < 81 and limit > 40 then limit = limit - 5 elseif limit < 41 and limit > 30 then limit = limit - 1 elseif limit < 30 then limit = limit - 0.1 end counter = 0 create() end for i,b in pairs(balls) do b:draw() if b.y < 0 then table.remove(balls,i)end end end function create() table.insert(balls,b1) end --# Ball Ball = class() function Ball:init(x,y,d,t,g,c) -- you can accept and set parameters here self.x = x self.y = y self.diameter = d self.thrust = t self.gravity = g self.color = c end function Ball:draw() -- Codea does not automatically call this method fill(self.color) ellipse(self.x,self.y,self.diameter) self.y = self.y + self.thrust - self.gravity self.thrust = self.thrust * 0.98 self.gravity = self.gravity + 0.05 end function Ball:touched(touch) -- Codea does not automatically call this method end
  • IgnatzIgnatz Mod
    Posts: 5,396

    @Staples - get rid of the line with b1 and use this

    function create()
        table.insert(balls,Ball(WIDTH/2,100,50,20,0,c2))
    end
    
  • Posts: 142

    @Ignatz finally! Thanks so much I couldn't figure that out! Works great.

Sign In or Register to comment.