Help Controlling Joystick keeping center circle innerly bounded to larger circle

Hello friends! My name is Kirk and I’ve been dabbling in Codea for about a month now and to be honest, I’m not very good…but that’s just one of those things that takes time and patience and in another 2 months I’ll be Luing like a champ.

in the mean time, I have an idea for a physicsy game in which the person controls a swordsman (bladerMan) who uses his blade to slay monsters, deflect lasers and who knows what else…it’ll be an arena game in that there’s one boxed in stadium that the bladerMan is trapped in and stuff just keeps on coming, progressively getting more and more difficult.

I’ve started, modeling off the physicsLab tutorial in Codea, but my skills are lacking and I’m asking if anyone who has a fair amound of free time and a good amount of experience would be willing to mentor/work with me on this game idea :slight_smile: this will be a learning experience and a little bit of puzzle solving fun with coding :slight_smile:

Thank you very much
Kirk

@Invad3rZIM You’re off to a good start. As far as looking for someone with free time and experience who is willing to mentor/work with you, you’re in the right forum. There are a lot of people here that fit that description. All you need to do is keep working on your code and when you get stuck or need advice, just ask because everyone is here to help. One suggestion, try not to start a new discussion for the same subject. This discussion could have been continued in your other discussion on your game.

How would I handle touches on the screen so that the first touch would activate event sequence 1 and the second would active event sequence 2?

@Invad3rZIM See the example code I have in the discussion below. It shows how to keep different screen touches separate.

http://codea.io/talk/discussion/5252/two-touches-one-moving#Item_10

@Invad3rZIM How are the touches done. Does touch 1 start then end before touch 2 starts or does touch 1 start, then touch 2 starts before touch 1 ends.

Well it’s going to be a double virtual joystick type thing. If you hold your thumb/finger on the right part of the screen, a virtual joystick (smaller circle that’s bounded into a larger circle appears under your thumb. By then moving your finger up the smaller circle will follow and an object will move at a speed relative to the circle inside the larger limit circle. The same will happen with the right part of the screen. However there are 2 objects (a red object and a blue object for now) the red object is controlled by the right dpad-joystick an the blue one is controlled by the left. Additionally if you simply tap the screen on either side, the blue object will accelerate 30 pixels /1 second then decelerate back to normal speed. That’s my final product, over simplified for the purpose of this disambiguation explanation…how would you go about doing this?

@Invad3rZIM Try this example. Each finger on the screen controls a different sprite with a separate joystick.


displayMode(FULLSCREEN)

function setup()
    stab={ 
    readImage("Planet Cute:Character Boy"),
    readImage("Planet Cute:Character Cat Girl"),
    readImage("Planet Cute:Character Pink Girl"),
    readImage("Planet Cute:Character Princess Girl"),
    readImage("Planet Cute:Character Horn Girl")
    }
    rm=-1
    js={}
end

function draw()
    background(40, 40, 50)
    fill(255)
    for a,b in pairs(js) do
        b:draw(a)
   end
end

function touched(t)
    if t.state==BEGAN then
        aa=0
        for a,b in pairs(js) do
            if b.id==0 then
                b.cx=t.x
                b.cy=t.y
                b.id=t.id
                aa=1
                break
            end
        end
        if aa==0 then
            table.insert(js,jst(t.x,t.y,t.id))
        end
    elseif t.state==MOVING or t.state==ENDED then
        for a,b in pairs(js) do
            b:touched(t)
        end
    end
end

jst=class()

function jst:init(cx,cy,id)
    self.cx=cx
    self.cy=cy  
    self.dx=0
    self.dy=0
    self.sx=cx
    self.sy=cy
    self.id=id
end

function jst:draw(a)
    fill(255)
    if self.id>0 then
        fill(255)
        ellipse(self.cx,self.cy,8) -- draw circle center
        noFill()
        stroke(255)
        strokeWidth(4)
        ellipse(self.cx,self.cy,200) -- draw outer circle  
    end 
    self.sx=self.sx+self.dx
    self.sy=self.sy+self.dy
    sprite(stab[a%5+1],self.sx,self.sy)
end

function jst:touched(t)
    if t.state==MOVING then
        if self.id==t.id then
            self.dx=(t.x-self.cx)/10
            self.dy=(t.y-self.cy)/10
        end
    end
    if t.state==ENDED then
        if self.id==t.id then
            rm=t.id
            self.id=0
            self.dx=0
            self.dy=0
            self.cx=0
            self.cy=0
        end
    end   
end

Okay so I dissected your example code Dave (thank you for that) and I fully understand how multi-touch sensors work but I after 2 hours of test programming, I have 2 follow up questions:

(And here’s my code if you’d like to copy it and run to get a better idea…I started fiddling with a circle and using joysticks to modify with it’s vector properties…

-- MyTouches

-- Use this function to perform your initial setup
function setup()
    touches={}
    count=1
    ball = physics.body(CIRCLE,45)
    ball.x = WIDTH/2
    ball.y = HEIGHT/2
    ball.r=170
    ball.g =170
    
    w1= physics.body(EDGE, vec2(0,0),vec2(WIDTH,0))
    w2 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
    w3=physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
    w4=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)

    for key, value in pairs(touches) do
        value:draw()
    end
    -- Do your drawing here
    noStroke()
    fill(ball.r, ball.g, math.random(150,255), 255)
    
    if ball.r > 255 then ball.r=255 end --sets limits on the color values
    if ball.r<0 then ball.r=0 end
    if ball.g > 255 then ball.g = 255 end
    if ball.g < 0 then ball.g = 0 end
    
    ellipse(ball.x,ball.y,ball.radius*2)
end

function touched(t)
 --   table.insert(touches, addTouch(t.id,t.x,t.y) )
    if(t.state == BEGAN) then
        aa = 0--controller to see if the touch is already created
        
        for key, value in pairs(touches) do
          if(value.id == 0) then
                value.x = t.x
                value.y = t.y
                value.id = t.id
                aa=1
                
                print(value.id.."  "..value.x)--debug print
                break
          end
        end
        if(aa==0) then
          table.insert(touches,addTouch(t.id,t.x,t.y))
        end

    else if(t.state == MOVING or t.state == ENDED) then
            for key, value in pairs(touches)do
                value:touched(t)
            end          
        end
    end
end

addTouch =class()

function addTouch:init(id,x,y)
    self.x = x
    self.y = y
    self.dx=0
    self.dy=0
    
    self.count = count
    count = count + 1
    
    self.color = color(math.random(100,255), math.random(100,255),math.random(100,255))
    self.id = id
end

function addTouch:touched(t)
    if(t.state == MOVING) then
        if(t.id == self.id) then
            self.dx = (t.x)--/200
            self.dy = (t.y)--/200
            
            if(self.count==1)then
                ball:applyForce(vec2((self.dx-self.x)/2,(self.dy-self.y)/2))
            end
            if(self.count==2)then--xval for second joystick controls r val, y =g val
                ball.r = ball.r + (self.dx-self.x)/10
                ball.g=ball.g+(self.dy-self.y)/10
            end 
        end 
    end
    
    if(t.state == ENDED) then
        if(self.id == t.id) then
            self.x =0
            self.y=0
            self.id=0 
            self.dx=0
            self.dy=0    
        end 
    end
end

function addTouch:draw()
  if self.id > 0 then
    noFill()
    stroke(self.color)
    ellipse(self.dx,self.dy,40)
    ellipse(self.x,self.y,200)
  end
end
  1. When I’m not moving the joystick continuously, the force in the ball stops accelerating and the ball eventually crashes due to gravity. How can I make it so that just by holding the circle passively it will register as an active touch?
  2. How can I bind the moving circle joystick so that the It can not exit the larger circle?

Thank you for all your help!

@Invad3rZIM For question 1, you’re going to have to move the applyForce out of the touched function and into the draw function. In the touched function, calculate the force like you are when moving the joystick and move that value into another variable, then apply that force in draw so that when you’re not moving the joystick, you’re still applying the last force in the draw routine. For question 2, you’ll have to calculate the distance between where you’re touching and the center of the joystick based on the equation of a circle. If the distance is greater than 100 then limit it to 100.

@Invad3rZIM Just in case you want an example for your question 2, this limits the smaller circle to the size of the larger one.

EDIT: corrected an error


displayMode(FULLSCREEN)

function setup()
    cx,cy=0,0
    v1=vec2(0,0)
end

function draw()
    background(40, 40, 50)
    noFill()
    if cx+cy>0 then
        stroke(255)
        strokeWidth(2)
        ellipse(cx,cy,200)  -- large circle 200 pixels in diameter
        ellipse(v1.x+cx,v1.y+cy,25) -- small circle
    end    
end

function touched(t)
    if t.state==BEGAN then -- center of circle
        cx=t.x
        cy=t.y
    end
    if t.state==MOVING then -- direction to move and limit direction
        v1=vec2(cx,cy)
        d=v1:dist(vec2(t.x,t.y))    -- distance, center to touch point
        v1=vec2(t.x-cx,t.y-cy)
        v1=v1:normalize()*math.min(d,100)   -- limit distance to 100 pixels
    end
    if t.state==ENDED then  -- clear values
        cx,cy=0,0
    end
end