Howdy, Stranger!

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

Touch function within classes

edited August 2014 in General Posts: 142

I'm pretty lost when it comes to how the touch function works when it comes to classes and was wondering if anyone could help me solve this problem. My code (the touch function code isn't mine) is below and whenever more than one ball is on the screen, they both move. Also, when one is removed from the table, they are all then removed. I would greatly appreciate any help.



--# Main displayMode(FULLSCREEN) function setup() c1 = color(255, 255, 255, 0) c2 = color(0,0,255) c3 = color(255, 0, 0, 255) balls={} counter = 250 limit = 50 thrust = 0 gravity = 0 end function draw() background(255, 255, 255, 255) rectMode(CENTER) fill(0) rect(WIDTH-100,HEIGHT-100,200,200) counter = counter + 1 if counter > limit then if limit <= 240 and limit > 150 then limit = limit-50 end counter = 0 create() end for i,b in pairs(balls) do b:draw() if b.y < -100 then table.remove(balls,i) end end end function create() table.insert(balls,Ball(WIDTH/2,-100,50,20,0,color(0,0,255),0,0)) end function touched(touch) for i,b in pairs(balls) do b:touched(touch) end end --# Ball Ball = class() function Ball:init(x,y,d,t,g,c,vx,vy) -- 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 self.velx = vx self.vely = vy self.velocity = {} self.newVelocity = vec2(0,0) self.touchcircle = false self.n = 0 self.touches = {} end function Ball:draw() -- Codea does not automatically call this method fill(self.color) ellipseMode(RADIUS) 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 self.y = self.y + self.vely self.x = self.x + self.velx self.velx = self.velx * 0.98 self.vely = self.vely * 0.98 if self.x > WIDTH-self.diameter then self.velx = 0 self.x = WIDTH-self.diameter elseif self.x < self.diameter then self.velx = 0 self.x = self.diameter end if self.y > HEIGHT-self.diameter/2 then self.vely = 0 self.y = HEIGHT-self.diameter/2 end if self.x < WIDTH and self.x > WIDTH-200 and self.y < HEIGHT and self.y > HEIGHT-200 then table.remove(balls,b) end end function Ball:touched(touch) -- Codea does not automatically call this if touch.state == MOVING then self.newVelocity = vec2(touch.deltaX, touch.deltaY) table.insert(self.velocity, 1, self.newVelocity) end if touch.state == ENDED then for i = 1, 10 do if self.velocity[i] then self.n = self.n + 1.5 self.vely = self.vely + self.velocity[i].y self.velx = self.velx + self.velocity[i].x end end if self.n > 0 then self.velx = self.velx/self.n self.vely = self.vely/self.n end end end

Comments

  • This should solve the problem with all of the balls being removed from the table:

    --# Main
    displayMode(FULLSCREEN)
    function setup()
        c1 = color(255, 255, 255, 0)
        c2 = color(0,0,255)
        c3 = color(255, 0, 0, 255)
        balls={}
        counter = 250
        limit = 50
        thrust = 0
        gravity = 0
    end
    
    function draw()
        background(255, 255, 255, 255)
        rectMode(CENTER)
        fill(0)
        rect(WIDTH-100,HEIGHT-100,200,200)
        counter = counter + 1
        if counter > limit then
            if limit <= 240 and limit > 150 then
                limit = limit-50
            end
            counter = 0
            create()
        end
        for i,b in pairs(balls) do
            b:draw()
            if b.y < -100 then
                table.remove(balls,i)
            end
            if b.x < WIDTH and b.x > WIDTH-200 and b.y < HEIGHT and b.y > HEIGHT-200 then
                table.remove(balls,i)
            end
        end    
    end
    
    
    
    function create()
        table.insert(balls,Ball(WIDTH/2,-100,50,20,0,color(0,0,255),0,0))
    end
    
    function touched(touch)
        for i,b in pairs(balls) do
        b:touched(touch)
        end
    end
    
    
    --# Ball
    Ball = class()
    
    function Ball:init(x,y,d,t,g,c,vx,vy)
        -- 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
        self.velx = vx
        self.vely = vy
        self.velocity = {}
        self.newVelocity = vec2(0,0)
        self.touchcircle = false
        self.n = 0
        self.touches = {}
    end
    
    function Ball:draw()
        -- Codea does not automatically call this method
        fill(self.color)
        ellipseMode(RADIUS)
        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 
        self.y = self.y + self.vely
        self.x = self.x + self.velx 
        self.velx = self.velx * 0.98
        self.vely = self.vely * 0.98
        if self.x > WIDTH-self.diameter then
            self.velx = 0
            self.x = WIDTH-self.diameter
        elseif self.x < self.diameter then
            self.velx = 0
            self.x = self.diameter
        end
        if self.y > HEIGHT-self.diameter/2 then
            self.vely = 0
            self.y = HEIGHT-self.diameter/2
        end
    end
    
    function Ball:touched(touch)
        -- Codea does not automatically call this
        if touch.state == MOVING then
            self.newVelocity = vec2(touch.deltaX, touch.deltaY)
            table.insert(self.velocity, 1, self.newVelocity)
        end
    
        if touch.state == ENDED then
            for i = 1, 10 do
                if self.velocity[i] then
                    self.n = self.n + 1.5
                    self.vely = self.vely + self.velocity[i].y
                    self.velx = self.velx + self.velocity[i].x
                end 
            end
            if self.n > 0 then
                self.velx = self.velx/self.n
                self.vely = self.vely/self.n
            end
        end
    end
    



    As for making only one ball move with the swipe, I don't know how to do. How are you going to know which ball to control?

  • Posts: 142

    @Saturn031000 I tried something like this

    function Ball:init()
    touchcircle = false
    end
    
    function Ball:touched(t)
    If t.state == BEGAN and t.x < self.x + self.diameter and t.x > self.x + self.diameter and t.y < self.y + self.diameter and t.y > self.x - self.diameter then
    touchcircle = true
    end
    

    And added "and touchcircle == true" to the moving and ended parts. It registered the Boolean as true to each ball, but they stopped being able to move. By the way the self.diameter is actually the radius.

  • dave1707dave1707 Mod
    Posts: 7,805

    @Staples This isn't a fix for your code, but here's an example that shows 2 balls that you can drag individually. Once you lift your finger, that ball is removed from the table and another random ball is added. This might help you understand how to keep touches seperate.


    displayMode(FULLSCREEN) function setup() tab={} table.insert(tab,ball(math.random(WIDTH),math.random(HEIGHT),50)) table.insert(tab,ball(math.random(WIDTH),math.random(HEIGHT),50)) end function draw() background(40, 40, 50) for a,b in pairs(tab) do b:draw() if b.remove then table.remove(tab,a) end end end function touched(t) for a,b in pairs(tab) do b:touched(t) end end ball=class() function ball:init(x,y,s) self.x=x self.y=y self.size=s self.id=0 self.remove=false end function ball:draw() fill(255) ellipse(self.x,self.y,self.size*2) end function ball:touched(t) if t.state==BEGAN then v1=vec2(t.x,t.y) d=v1:dist(vec2(self.x,self.y)) if d<self.size and self.id==0 then self.id=t.id end end if t.state==MOVING and t.id==self.id then self.x=t.x self.y=t.y end if t.state==ENDED and t.id==self.id then self.id=0 self.remove=true table.insert(tab,ball(math.random(WIDTH),math.random(HEIGHT),50)) end end
  • dave1707dave1707 Mod
    Posts: 7,805

    @Staples Here's your code with the touches fixed. It was too easy getting the balls in the black corner, so I made it smaller.


    --# Main displayMode(FULLSCREEN) function setup() c1 = color(255, 255, 255, 0) c2 = color(0,0,255) c3 = color(255, 0, 0, 255) balls={} counter = 250 limit = 50 thrust = 0 gravity = 0 end function draw() background(255, 255, 255, 255) rectMode(CENTER) fill(0) rect(WIDTH-50,HEIGHT-50,100,100) counter = counter + 1 if counter > limit then if limit <= 240 and limit > 150 then limit = limit-50 end counter = 0 create() end for i,b in pairs(balls) do b:draw() if b.remove then table.remove(balls,i) end end end function create() table.insert(balls,Ball(WIDTH/2,-100,50,20,0,color(0,0,255),0,0)) end function touched(touch) for i,b in pairs(balls) do b:touched(touch) end end --# Ball Ball = class() function Ball:init(x,y,d,t,g,c,vx,vy) self.x = x self.y = y self.diameter = d self.thrust = t self.gravity = g self.color = c self.velx = vx self.vely = vy self.velocity=0 self.newVelocity = vec2(0,0) self.n = 0 self.id=0 self.remove=false end function Ball:draw() fill(self.color) ellipseMode(RADIUS) 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 self.y = self.y + self.vely self.x = self.x + self.velx self.velx = self.velx * 0.98 self.vely = self.vely * 0.98 if self.x > WIDTH-self.diameter then self.velx = 0 self.x = WIDTH-self.diameter elseif self.x < self.diameter then self.velx = 0 self.x = self.diameter end if self.y > HEIGHT-self.diameter/2 then self.vely = 0 self.y = HEIGHT-self.diameter/2 end if self.x > WIDTH-60 and self.y > HEIGHT-60 then self.remove=true end end function Ball:touched(touch) if touch.state==BEGAN and self.id==0 then v1=vec2(touch.x,touch.y) d=v1:dist(vec2(self.x,self.y)) if d<self.diameter then self.id=touch.id end end if touch.state == MOVING and touch.id==self.id then self.newVelocity = vec2(touch.deltaX, touch.deltaY) end if touch.state == ENDED and touch.id==self.id then self.n = self.n + 1.5 self.vely = self.vely + self.newVelocity.y self.velx = self.velx + self.newVelocity.x self.id=0 end end
  • Posts: 142

    @dave1707 sorry for the delayed response. I fixed my code with the help of your first code. For some reason, my iPad won't let me copy your second code, but I'm sure it's great in action. I'll test it out later. Thanks!

Sign In or Register to comment.