Joystick 1.1 - Move and Shoot

I got a little further with my joystick project:

https://gist.github.com/interactivenyc/039971dda0ba0926a155933146876a02

The bullets are a bit laggy - any tips?

Thanks in advance!

Steve

Can you please keep all your joystick stuff in one thread? You can edit the topic title to show when things have changed.

I’m not sure why you include both joysticks in one class and then have to include lots of tests to figure out which one is being used. Why use a class at all in this case?

The usual way to use classes is to write a joystick class, then create two instances of them in different positions. Touches on the joysticks will return values telling you what changes have happened.

For example, you can use the joystick class I just posted on my other thread like this

--in setup
joy1=JoyStick(settings1)
joy2=JoyStick(settings2) --where settings1and 2 are tables specifying position etc

--in draw
local d1,d2=joy1:update(), joy2:update() --get changes from joysticks
--adjust velocity by up to 1/20 pixels/sec in any direction
vel1,vel2=vel1+d1/20,vel2+d2/20
pos1,pos2=pos1+vel1,pos2+vel2 --adjust positions

--in touched
function touched(t)
    joy1:touched(t)
    joy1:touched(t)
end

I see your point Ignatz, and thanks for the input! I’m not entirely sure I know how to fix this in a way that I can grok. I see the tests for which side the controllers are on in Main are unnecessary, and how inside the joystick class I’m checking for am I LEFT or am I RIGHT with the self.moving and self.firing variables wrecking the class a bit. I will totally meditate on your comments until I see the light, but if you feel like elaborating any more, I’m all ears and eyes!

Can I delete this thread, and continue in the old thread to keep all the comments together?

I think I’m having performance issues with the CharacterSprite and the way it’s handling the table self.bullets. I’m used to using arrays with push and pop control, and this table stuff is a little foreign to me. I know I can be doing that better, and will continue to try to optimize that part of my code. Again, any input is welcome, but have faith in me - I am enjoying this process immensely and will persevere :slight_smile:

I’m a Flash/ActionScript programmer by day, 47 years old, programming since I was 15. Not to say that I’m a great programmer, but I’ve hit the wall more times than I can count and have survived in my field where others have been forced out. I don’t want to be the last of a dying breed - rather, an I’m an old dog who wants to learn new tricks.

Respectfully,

Steve

I’m curious about you - are you part of the Codea team, or an independent evangelist? Where are you located? I read your blog and see you’re a semi-retired actuary who loves programming. Are you still working by day, or have you left the work force?

I’m in NYC. If you ever come through town, look me up.

Best,

Steve

I’m happily retired, and completely independent of the developers, as is dave1707 and a few others who like to help new starters. I’m a little far from NYC, being in Perth Australia, but thanks for the offer.

@interactivenyc Anytime you see a lag when you run your program, check for print statements. The longer your program runs and prints something, the slower it runs. Print statements are nice when you’re trying to figure out why something isn’t working properly, but once your code works, remove or comment them out.

Thanks Dave! Are you David Such? I’m going through your tutorials now - great stuff! I’m a big fan of the Button - a Class I’ve written over and over again in ActionScript. I like how you offered your button, then linked to other people’s code for their buttons.

I see on your site that you’re updating the code for the latest version of Codea. Thanks for taking the time to do that. I just got to the page on Dependencies and Libraries, and it’s the first time I haven’t been able to tweak the code and get it to run. Of course, having a great Library is the key to rapid application development. Besides your Library (which I can’t wait to see updated) are there any other Classes offered up by the community that you’d suggest to include?

Thanks youze Aussie dudes!

@interactivenyc Sorry, I’m not David Such. I’m not that good.

@interactivenyc Here’s another version of your code for you to look at. It allows only 1 joystick for movement, but multiple joysticks for shooting.

displayMode(FULLSCREEN)

function setup()
    sx,sy=WIDTH/2,HEIGHT/2
    j,m={},{}
end

function draw()
    background(40, 40, 50)
    for a,b in pairs(j) do
        b:draw()
    end
    fill(255)
    for a,b in pairs(m) do
        ellipse(b.x,b.y,5)
        b.x=b.x+b.z
        b.y=b.y+b.w
        if b.x<0 or b.x>WIDTH or b.y<0 or b.y>HEIGHT then
            table.remove(m,a)
        end
    end
    sprite("Platformer Art:Guy Standing",sx,sy,25)
end

function touched(t)
    if t.state==BEGAN then
        if t.x<WIDTH/2 then
            for a,b in pairs(j) do
                if b.type=="move" then
                    return  -- limit 1 move joystick
                end
            end
            table.insert(j,js(t.x,t.y,t.id,"move"))
        else
            table.insert(j,js(t.x,t.y,t.id,"shoot"))    -- allow multiple shoot
        end
    end
    for a,b in pairs(j) do
        b:touched(t)
    end
end

js=class()

function js:init(x,y,id,ty)
    self.id=id
    self.ox=x
    self.oy=y
    self.cx=x    
    self.cy=y
    self.dx=0
    self.dy=0
    self.type=ty
    self.c=20
end

function js:draw()
    stroke(255)
    strokeWidth(2)
    fill(255,255,255,100)
    ellipse(self.ox,self.oy,150)
    if self.type=="move" then
        sx=sx+(self.cx-self.ox)/10
        sy=sy+(self.cy-self.oy)/10
    end
    if self.type=="shoot" then
        v1=vec2(self.cx-self.ox,self.cy-self.oy)
        v1=v1:normalize()
        if math.abs(v1.x+v1.y)>0 then
            self.dx=v1.x*8
            self.dy=v1.y*8
            self.c=self.c+1
            if self.c>12 then
                table.insert(m,vec4(sx,sy,self.dx,self.dy)) 
                self.c=0
            end  
        end        
    end
end

function js:touched(t)
    for a,b in pairs(j) do
        if t.id==b.id then
            if t.state==MOVING then
                b.cx=t.x
                b.cy=t.y
            end
            if t.state==ENDED then
                table.remove(j,a)
            end
        end
    end    
end

Woah - that’s crazy! You cut my code in like, half, and it works great! THANK YOU THANK YOU - I will study this tonight.

Is there a nice way to view the values of the j and m tables in a parameter.watch()? When I do parameter.watch(j) - it looks like a pointer address.

@interactivenyc Using parameter.watch, you would have to use each entry. That is: m[1] or j[1].id, etc. Here’s a version that uses a function to control what the joystick does instead of if statements. See the move and shoot functions.

displayMode(FULLSCREEN)

function setup()
    sx,sy=WIDTH/2,HEIGHT/2
    j,m={},{}
end

function draw()
    background(40, 40, 50)
    for a,b in pairs(j) do
        b:draw()
    end
    fill(255)
    for a,b in pairs(m) do
        ellipse(b.x,b.y,5)
        b.x=b.x+b.z
        b.y=b.y+b.w
        if b.x<0 or b.x>WIDTH or b.y<0 or b.y>HEIGHT then
            table.remove(m,a)
        end
    end
    sprite("Platformer Art:Guy Standing",sx,sy,25)
end

function touched(t)
    if t.state==BEGAN then
        if t.x<WIDTH/2 then
            table.insert(j,js(t.x,t.y,t.id,move))  -- use move function
        else
            table.insert(j,js(t.x,t.y,t.id,shoot)) -- use shoot function
        end
    end
    for a,b in pairs(j) do
        b:touched(t)
    end
end

function move(self)
    sx=sx+(self.cx-self.ox)/10
    sy=sy+(self.cy-self.oy)/10
end

function shoot(self)
    v1=vec2(self.cx-self.ox,self.cy-self.oy)
    v1=v1:normalize()
    if math.abs(v1.x+v1.y)>0 then
        self.dx=v1.x*8
        self.dy=v1.y*8
        self.c=self.c+1
        if self.c>12 then
            table.insert(m,vec4(sx,sy,self.dx,self.dy)) 
            self.c=0
        end  
    end        
end

js=class()

function js:init(x,y,id,fn)
    self.id=id
    self.ox=x
    self.oy=y
    self.cx=x    
    self.cy=y
    self.dx=0
    self.dy=0
    self.c=20
    self.func=fn
end

function js:draw()
    stroke(255)
    strokeWidth(2)
    fill(255,255,255,100)
    ellipse(self.ox,self.oy,150)
    self.func(self)
end

function js:touched(t)
    for a,b in pairs(j) do
        if t.id==b.id then
            if t.state==MOVING then
                b.cx=t.x
                b.cy=t.y
            end
            if t.state==ENDED then
                table.remove(j,a)
            end
        end
    end    
end

Dave - can you explain a bit what “for a,b in pairs” does, and what the two tables j and m are doing?

I find very concise variable names a little hard to wrap my head around, and prefer more descriptive names. I hope you don’t mind - I’m planning to use your code, but want to tweak it to my taste :slight_smile:

To save typing I tend to use very short variable names. The for a,b in pairs is a way of iterating thru a table. The variable a is the index value and b is the value at that position. Table j holds the instances for the joysticks. Table m holds the information for the missiles or bullets. If you have any other questions, don’t hesitate to ask.

Never mind. I’m working it out for myself!

Edit: We both posted at around the same time :slight_smile:

Thanks for your help, and thanks Ignatz for your help as well! You guys are the shizzle m’nizzle! (Snoop Dogg is a guilty pleasure of mine)

You should read up on tables because they are incredibly flexible. They combine arrays, dictionaries, singleton classes, and much more.

I wrote something about them here

https://coolcodea.wordpress.com/2013/04/07/26-tables/

https://coolcodea.wordpress.com/2014/10/01/169-why-tables-and-classes-are-so-useful/

https://coolcodea.wordpress.com/2013/04/15/34-tip-using-tables-as-parameters/

Interesting feature of Dave’s joysticks - he limits it to only one movement stick, but you can have multiple shoot sticks. Putting down three fingers lets you move, and shoot in two directions. Four fingers would let you shoot in three directions at the same time! Was that a design choice? It looks like it was!

Here’s my partially refactored code based on your work, Dave. I think it might be easier for other beginners to wrap their heads around.

https://gist.github.com/interactivenyc/136e6f41e7d2ca4776a1e72a53be5450

I’m planning to get the Hero back into it’s own class, as I want to add some bitmap animations. I have a friend who’s going to provide me with some artwork for a robot - he designed it in 3D and will output frames so I can spin him around as he walks. This guy, Patrick works with me at Speakaboos (you can find our app in the IOS and Android app stores written in Flash/ActionScript) and he and his son Griffin are both making artwork for me. Patrick gave me a very stylized simple robot with rounded curves, and Grif gave me a boxier robot complete with a gun in his hand. They’re great - I’ll post them here when I get to my Mac. On my iPad now.

As much as you want to help, I’d really appreciate it. I’d love to figure out a way to GitHub this stuff properly so we could potentially have a community project. I was thinking with this control system we could build a top down shooter, or an asteroids like game, or even a jumping platformer. I wonder how hard it would be to make a galaxy with other ships in it, with multiplayer possibilities. I’ve toyed around with some free multiuser servers, and I see Codea supports sockets. Any thoughts?