How to use function touched when i want to use it in different class


Bat1 = class()

function Bat1:init()
    -- you can accept and set parameters here
    self.x = 0
    self.y = HEIGHT/2
end

function Bat1:draw()
    -- Codea does not automatically call this method
    self.x=math.min(self.x,WIDTH/2-60)
    sprite("Planet Cute:Wood Block",self.x,self.y,80)
    
end

function Bat1:touched(touch)
    -- Codea does not automatically call this method
    self.x=math.min(touch.x,WIDTH/2-60)
    self.y=touch.y
end
Bat2 = class()

function Bat2:init()
    -- you can accept and set parameters here
    self.x = WIDTH
    self.y=HEIGHT/2
end

function Bat2:draw()
    -- Codea does not automatically call this method
    self.x=math.max(self.x,WIDTH/2+60)
    sprite("Planet Cute:Wood Block",self.x,self.y,80)
end

function Bat2:touched(touch)
    -- Codea does not automatically call this method
    self.x=math.max(touch.x,WIDTH/2+60)
    self.y=touch.y
end

--main
    function setup()
    print("hello world")
    displayMode(FULLSCREEN)
    bat1=Bat1()
    bat2=Bat2()
    end
function draw()
    background(0, 0, 0, 255)
    ellipse(WIDTH/2,HEIGHT/2,200)
    strokeWidth(10)
    stroke(255, 255, 255, 255)
    fill(218, 15, 15, 255)
    rect(0,HEIGHT/2-HEIGHT/16,10,HEIGHT/8)
    rect(0.98*WIDTH,HEIGHT/2-HEIGHT/16,10,HEIGHT/8)
    line(WIDTH/2,0,WIDTH/2,HEIGHT)

        bat1:draw()
        bat2:draw()
    
end
function touched(touch)
    bat1:touched(touch)
    bat2:touched(touch)
   
end

I find that two bats share the same touch.x,I want to know how to debug,i want to them move without effecting each other.

I wonder if anyone can help me, Thanks a lot!

@wenhaozheng - you need to expand your bat class to limit movement of the bat.
See below:


Bat = class()

function Bat:init(x,y,nx,fx,ly,uy)
    self.x = x
    self.y = y
    self.minX = nx
    self.maxX = fx
    self.minY = ly
    self.maxY = uy
end

function Bat:draw()
    --
    sprite("Planet Cute:Wood Block",self.x,self.y,size)
end

function Bat:touched(touch)
    if touch.x > self.minX and touch.x <self.maxX then  
        self.x=touch.x
        if touch.y > self.minY and touch.y < self.maxY then       
            self.y=touch.y
        end
    end
end

I’ll leave it to you to figure out the limits nx,fx,ly,uy represent near x, far x, lower y and upper y.

When you post code could you ensure you use ~~~ before and after the code so that it is formatted correctly.

@wenhaozheng When you create a class, don’t seperate everything. Create a bat class then have one bat:init, bat:draw, and bat:touched. Your bat1, bat2 code in setup, draw, and touched look OK.

@dave1707 thanks,but these bats need to move in different limited area(bat1 left screen,bat2 left screen),I can’t find a way to limit them in one class.

@wenhaozheng Here’s an example. Touch each block to move them.

PS. I added code to limit each block to its own area.

displayMode(FULLSCREEN)

function setup()
    bat1=Bat(20,HEIGHT/2,1)
    bat2=Bat(WIDTH-20,HEIGHT/2,2)
end

function draw()
    background(0, 0, 0, 255)
    ellipse(WIDTH/2,HEIGHT/2,200)
    strokeWidth(10)
    stroke(255, 255, 255, 255)
    fill(218, 15, 15, 255)
    rect(0,HEIGHT/2-HEIGHT/16,10,HEIGHT/8)
    rect(0.98*WIDTH,HEIGHT/2-HEIGHT/16,10,HEIGHT/8)
    line(WIDTH/2,0,WIDTH/2,HEIGHT)
    bat1:draw()
    bat2:draw()
end

function touched(touch)
    if touch.state==BEGAN or touch.state==MOVING then
        bat1:touched(touch)
        bat2:touched(touch)
    end
end

Bat = class()

function Bat:init(x,y,v)
    self.x = x
    self.y = y
    self.v = v
end

function Bat:draw()
    sprite("Planet Cute:Wood Block",self.x,self.y,80)
end

function Bat:touched(touch)
    if touch.x>self.x-40 and touch.x<self.x+40 and
            touch.y>self.y-40 and touch.y<self.y+40 then
        if self.v==1 then
            if touch.x<WIDTH/2-40 then
                self.x=touch.x
                self.y=touch.y
            end
        elseif touch.x>WIDTH/2+40 then
            self.x=touch.x
            self.y=touch.y
        end            
    end
end

@wenhaozheng - have you checked out the example project ping. It seems to do most of what you need?

@wenhaozheng - do your bats move in one dimension or in two? What I mean is do they only move sideways along the say X axis, or do they move in both X and Y in their half of the screen?

@dave1707 wow! Thank you for taking the trouble to help me.! I do appreciate it!
It’s really helpful!

@wenhaozheng That’s why were here, to help. If you have other questions, there are a lot of people here with answers.

@Bri_G both x and y,

@dave1707

function Bat:init(x,y,batid)
    self.x = x
    self.y = y
    self.id=batid
end

function Bat:draw()
    sprite("Planet Cute:Wood Block",self.x,self.y,80)

end

function Bat:touched(touch)
if touch.x>self.x-40 and touch.x<self.x+40 and
    touch.y>self.y-40 and touch.y<self.y+40 and self.id==1 then
     self.x=math.min(touch.x,self.x)
    self.y=touch.y
      elseif touch.x>self.x-40 and touch.x<self.x+40 and touch.y>self.y-40 and touch.y<self.y+40 and self.id==2 then
      self.x=math.max(self.x,touch.x)
        self.y=touch.y
        print (touch.id)
end

I’ve changed some of your script to limit the two bats’ position ,but now,i find that these two bats can’t move in correct state,they can’t be limited neither.I’m really sorry to bother you but,I can’t see another way…

@Bri_G thanks,I will spend more time to learn from your script.

@wenhaozheng - the code I posted only restricts the bats to their areas. You still need to consider ID and more than one touch at once. If you move one of the paddles and cross the halfway line you automatically pick up the other paddle. Also if you touch outside the bat the bat appears under your finger.

Ponder over that and post again if you have problems.

Right,I’m working on it !thanks a lot

@wenhaozheng I modified my code above to limit each block to its own area.

@dave1707 - I will post a photo of the error, it is in the ball tab of ping. Just playing around with it. Error in this routine but OK if it’s in setup(). My code below, trying to put a ball in with text() and emojis.


function Ball:draw()
    pushStyle()
    fontSize(48)
    noStroke()
    fill(255, 255, 255, 255)
    rectMode(CENTER)
    rect(self.position.x, self.position.y, self.diameter, self.diameter)
    text("",self.position.x, self.position.y)
    popStyle()
end

Put whatever emoji in the text() call. There may be other clashes - could be just related to textual formatting versus that of text.

@Bri_G I didn’t get an error when I ran it. Here’s what I had in a seperate project. I added the Ball:init function. Don’t know if that matches yours. This is on version 130.

PS. I then added your function to Ping and didn’t have any problem with it there either. I added an emoji in the text line, I don’t think it matters which emoji.

PSS. I tried it on my iPad Pro also without an error.

Ball=class()

function Ball:init(pos,d)
    self.position=pos
    self.diameter=d
end

function Ball:draw()
    pushStyle()
    fontSize(48)
    noStroke()
    fill(255, 255, 255, 255)
    rectMode(CENTER)
    rect(self.position.x, self.position.y, self.diameter, self.diameter)
    text("",self.position.x, self.position.y)
    popStyle()
end

@dave1707 - that’s weird, you can see the error in the screen capture. I’ll check over the whole example as I have been changing bits and pieces. Thanks.

@dave1707 I’ve solved the touch problem,now,I find another one,my ball always shakes when it’s nearby the bats and the screen padding,I use some of script in examples,but It can’t work well in my project
I’m so sorry that I’m a starter and not very good at English,so I wonder if you can figure out the wrong point in my script.And I really don’t know which class is the wrong point in.So,please forgive me to copy all my script again.That would be very thankful!

--# Ball
Ball = class()

function Ball:init(x,y)
    self.x=x
    self.y=y
    self.pos=vec2(3*WIDTH/4,HEIGHT/2)
    self.vel=vec2(3,1)
    self.body=physics.body(CIRCLE,20)
    self.radius=20
end

function Ball:draw()
    -- Codea does not automatically call this 
    
    spriteMode(CENTER)
    sprite("Space Art:UFO",self.pos.x,self.pos.y,50)
   
    
end
function Ball:update()
    self.vel=0.999*self.vel
    self.pos= self.pos+ self.vel
    if (self.pos.x + self.radius) >= WIDTH then
        self.pos.x = WIDTH - self.radius
        self.vel.x = -self.vel.x
    elseif (self.pos.x - self.radius) <= 0 then
        self.pos.x = self.radius
        self.vel.x = -self.vel.x
        
    elseif (self.pos.y + self.radius) >= HEIGHT then
        self.pos.y = HEIGHT - self.radius
        self.vel.y = -self.vel.y
    elseif (self.pos.y - self.radius) <= 0 then
        self.pos.y = self.radius
        self.vel.y = -self.vel.y
    end
    print(self.vel.x)
    print(self.pos.x)
end
function Ball:left()
    return self.pos.x - self.radius
end

function Ball:right()
    return self.pos.x + self.radius
end

function Ball:top()
    return self.pos.y + self.radius
end

function Ball:bottom()
    return self.pos.y - self.radius
end
function Ball:win()
    if self.pos.x<60 and self.pos.y<(HEIGHT/2-HEIGHT/16)and self.pos.y>(HEIGHT/8)
    then
        return 1
    end
    if self.pos.x>0.98*WIDTH and self.pos.y<(HEIGHT/2-HEIGHT/16)and self.pos.y>(HEIGHT/8) then
        return 0
    end
end
function Ball:touched(touch)
    -- Codea does not automatically call this method
    end

--# Bat1
Bat1 = class()

function Bat1:init()
    -- you can accept and set parameters here
    self.pos=vec2(0,HEIGHT/2)
    self.hi=vec2(0,0)
    self.size=vec2(80,130)
end

function Bat1:draw()
    -- Codea does not automatically call this method
    self.pos.x=math.min(self.pos.x,WIDTH/2-60)
    rectMode(CENTER)
    rect(self.pos.x,self.pos.y,80,130)
    fill(143, 0, 255, 255)
end

function Bat1:touched(touch)
    -- Codea does not automatically call this method
    self.pos.x=math.min(touch.x,WIDTH/2-100)
    self.pos.y=touch.y
    self.hi.x=touch.deltaX
    self.hi.y=touch.deltaY
end
function Bat1:collide(ball)
    if ball:left() < self:right() and
       ball:right() > self:left() and
       ball:top() > self:bottom() and
       ball:bottom() < self:top() then
        if ball.pos.y <= self:top() and ball.pos.y >= self:bottom() then
            ball.vel.x = -ball.vel.x+0.5*self.hi.x
        else
            ball.vel.y = -ball.vel.y+0.5*self.hi.y
        end
        end
    end
function Bat1:left()
    return self.pos.x - self.size.x / 2
end

function Bat1:right()
    return self.pos.x + self.size.x / 2
end

function Bat1:top()
    return self.pos.y + self.size.y / 2
end

function Bat1:bottom()
    return self.pos.y - self.size.y / 2
end

--# Bat2
Bat2 = class()

function Bat2:init()
    -- you can accept and set parameters here
    self.pos=vec2(WIDTH,HEIGHT/2)
    self.hi=vec2(0,0)
    self.size=vec2(80,130)
end

function Bat2:draw()
    -- Codea does not automatically call this method
    self.pos.x=math.max(self.pos.x,WIDTH/2)
    rectMode(CENTER)
    rect(self.pos.x,self.pos.y,80,130)
    fill(140,0,255,255)
end

function Bat2:touched(touch)
    -- Codea does not automatically call this method
    self.pos.x=math.max(touch.x,WIDTH/2+100)
    self.pos.y=touch.y
    self.hi.x=touch.deltaX
    self.hi.y=touch.deltaY
end
function Bat2:collide()
    if ball:left() <= self:right() and
       ball:right() >= self:left() and
       ball:top() >= self:bottom() and
       ball:bottom() <= self:top() then
        sound(SOUND_BLIT)
        if self:top()-ball.pos.y>10 and self:top()-ball.pos.y<20 and ball.pos.y-self:bottom()>10 and ball.pos.y-self:bottom()<20 then
            ball.vel.x = -ball.vel.x+self.hi.x
        else
            ball.vel.y = -ball.vel.y+self.hi.y
  
        end
        end
end
function Bat2:left()
    return self.pos.x - self.size.x / 2
end

function Bat2:right()
    return self.pos.x + self.size.x / 2
end

function Bat2:top()
    return self.pos.y + self.size.y / 2
end

function Bat2:bottom()
    return self.pos.y - self.size.y / 2
end

--# Main
--main
    function setup()
    print("hello world")
    displayMode(FULLSCREEN)
    bat1=Bat1()
    bat2=Bat2()
    touches={}
    ball=Ball()
    gameover=false
    end
function draw()
   if gameover==false then
     background(0, 0, 0, 255)
    ellipse(WIDTH/2,HEIGHT/2,200)
    strokeWidth(10)
    stroke(255, 255, 255, 255)
    fill(140, 0,255, 255)
    
    rect(0,HEIGHT/2-HEIGHT/16,10,HEIGHT/8)
    rect(0.98*WIDTH,HEIGHT/2-HEIGHT/16,10,HEIGHT/8)
    line(WIDTH/2,0,WIDTH/2,HEIGHT)
    
        bat1:draw()
        bat2:draw()
        ball:draw()
        ball:update()
    bat1:collide(ball)
    bat2:collide(ball)
        if ball:win()==1 then
            text("win",WIDTH/2,HEIGHT/2)
            gameover=true
        end
     end
end
function touched(touch)
   if touch.x<WIDTH/2 then bat1:touched(touch)
   elseif touch.x>WIDTH/2  then bat2:touched(touch)
  end
         
end

–# Vvv

It often shakes around the corners or on the bats’ frame
And the game seems “die”,I mean none of the bats can moving