#### 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)
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

``````
Tagged:

• Posts: 282

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)
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.

• Posts: 8,554

@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

``````
• Posts: 8,554

@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)
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!