Howdy, Stranger!

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

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

edited December 2018 in Questions Posts: 9

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!

Tagged:

Comments

  • dave1707dave1707 Mod
    Posts: 7,533

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

  • dave1707dave1707 Mod
    edited December 2018 Posts: 7,533

    @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
    
  • Posts: 1,186

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

  • edited December 2018 Posts: 1,186

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

  • dave1707dave1707 Mod
    Posts: 7,533

    @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,

  • edited December 2018 Posts: 9

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

  • Posts: 1,186

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

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

  • Posts: 1,186

    @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

  • dave1707dave1707 Mod
    Posts: 7,533

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

  • Posts: 1,186

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

  • dave1707dave1707 Mod
    edited December 2018 Posts: 7,533

    @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
    
  • Posts: 1,186
    @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.
  • edited December 2018 Posts: 9

    @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

  • edited December 2018 Posts: 9

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

  • dave1707dave1707 Mod
    Posts: 7,533

    @wenhaozheng I suggest you look over the Ping example. That example has one class for the paddles and one for the ball. You’re code has one class for the ball but 2 classes for the paddles. Trying to take code from ping and make it work in your code isn’t going to work because of the 2 paddle classes.

Sign In or Register to comment.