SHARE - Player class from Aedifico, usable in any physics game

Hello everyone, when I first made my game Aedifico I was asked by a couple people how I got the player to move with the feet. At first I was using a method of averaging all the body parts and applying a force between them which worked nicely, although it had drawbacks in some scenarios. Now I’ve decided to only average the feet and apply a force between the feet and body, this seems to give a less fluid look but is overall more stable. Here is a video of the most recent update before I started the player class revision: http://www.youtube.com/watch?v=XudkW-h6QCI

The end of this video acts as a testimony to the fact that even after a year of work, a bug can pop out that hints to no direction or cause. That was a reason why I decided to revise the player, another reason is if you have code that is say 3 months + old you may not need to change it but if you do you’re going to come out with something better than before. The point is you can never run out of things to change or ideas to learn about.

There are still many tweaks to be made and a tiny bug which makes the left foot act differently to the right foot, despite the code being identical (as far as I have checked). I’ve tried to make the implementation quite straight forward.

--To initialise the player use this function in setup()
plyvar = Player(x,y,joystick position,joystick diameter)

--For touch handling create table 'tchs' in setup() and paste the following in touched()
    if t.state == BEGAN then
        local jpos,jsize = ply.joypos,ply.joysize
        local epos,esize = ply.epos,ply.esize
        if vec2(t.x,t.y):dist(jpos) < jsize/2 then
            table.insert(tchs,{t,ply,"ply"})
        elseif vec2(t.x,t.y):dist(epos) < esize/2 then
            table.insert(tchs,{t,ply,"jump"})
        else
            table.insert(tchs,{t,ply,"look"})
        end
    end
    for k,v in pairs(tchs) do
        if t.id == v[1].id then
            tchs[k][1] = t
            tchs[k][2]:touched(tchs[k])
            if v[1].state == ENDED then
                tchs[k] = nil
            end
        end
    end

--Draw the player by putting ply:draw() and ply:drawJoystick() in draw()

--Any body you use as the ground should have the categories {0,2} 
--Use the code however you like

Code:
http://pastebin.com/PwHKNH9G

I’m planning on making a similar designed enemy which uses AI to get around which should be interesting. Any feedback on the code itself or the player ‘engine’ is more than welcome. Hope you enjoy it

This game looks incredible! Will you be putting it on the appStore? I have followed the updates you have posted, but I have not seen any word about where this is going when done. Might be just me not noticing :P. I also would like to say this game looks just up my alley, and it looks quite like a 2d gMod.

Seriously, this game looks like it will be awesome!

Would be cool if it were like a obstacle climbing game, where you have crazy obstacles to climb over, and you have to built a tank that can get over them. Starts out with just one rock to climb over, then gets harder and harder, and you can modify your tank between each obstacle.

Hope to see it on the app store one day!

@Crumble @TheSoldierKing it will get to the App Store eventually just not today, or tomorrow, or even a few months from now. There’s a lot to do. I’m aiming for a littlebigplanet sort of gameplay with a sandbox mode like gmod/lbp sandbox.

Everything apart from the foundations is subject to change but it will be a puzzle solving game, whether that’s building a tank like you said @Crumble or creating elevators and different contraptions to get from one place to another. I’m aiming for all round educational with many different brain stretching puzzles. I did think it was necessary to get the sandbox done first as that’s the best part, infinite potential with no finite story or level count.

On top of this I plan to make Aedif’s (the player) surroundings more interactive. The problem with this project is there’s so much I can do that I start tripping over myself, I started to make the toolbox for controlling vehicles and when that was sufficient enough to drive the tank I jumped on to revising the player class and movement. It’s ability to be a game isn’t far off, but it being the ‘go to’ ‘hours of fun’ game is far off, almost so far I get scared to look!

Thanks @Luatee! The framerate you get with this huge game is pretty incredible. If you don’t mind me asking, I was wondering how you did the terrain generation? I have tried multiple times, but wasn’t sure how exactly to do it. I have used noise() but was not sure how to then apply that to physics objects(as I can assume you are using, coding your own collision detection I expect would be quite difficult and slower than box2D) or how to then store the data in a table without that table getting too large. If this is a ‘trade secret,’ that’s ok too B-) Thanks again!
-TheSolderKing

@TheSolderKing thanks, it’s just time and effort though! I don’t mind you asking, I worked the terrain generation in to this example which looks pretty cool using Planet Cute sprites. I added a few comments to show what’s what:
http://pastebin.com/ZVRqgSmc

You can use noise on a large or small scale, in this example I use it on a small scale to add a bumpiness to the terrain (to show off some stability) which is generated by a sine curve. In my game I use it on the large scale which is one of the reasons the ground isn’t jagged but it gives a good random set of hills. I can put an example in if you like.

I’m not sure what you mean by store the data in a table, are you referring to the saving and loading of contraptions?

You will laugh at me, but just before you wrote this reply, I worked out how to do it on my own! Still, I appreciate the help and the concept of using noise on a sine wave is quite interesting. By store data in the table, I meant how to store the terrain points in a table-I worked that out as well. Anyways, thanks for sharing the concept. I would be interested to know how you save and load contraptions though, but I expect it is with AABB queries, am I correct? Can the user specify a bounding box for their contraptions, or do you figure out which bodies are attached to other bodies somehow? Either way, some impressive code there :). I can see this being extremely successful on the app store :smiley:

@TheSolderKing Nah no laughing, it’s better to teach yourself than be taught by others definitely. You can get some funky looking hills using noise multiplied or added to a combination of cos and sin.

I won’t give you the code I use for loading/saving contraptions but I will tell how you how to do it because using Lua’s JSON library is not needed for something so trivial. Btw I am going to add in the ability to use a bounding box for selection but at the moment I use joints to tie it all together. Anyway you’ll need this key function:

function split(inputstr, sep)
        local t={} 
        local i=1
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                t[i] = str
                i = i + 1
        end
        return t
end

It’s allows you to split a string in to a table using a separating character, I use the following for certain objects (^ & , *). It’s easier to start from the saving end when creating a structure to save objects.

Say if I have an object Ball, we have its id, its size/position vec2(x,y) and an angle, I can save it like this:

local str = ""
for k,v in pairs(balltbl) do
 str = str "&ball,"..(v.id)..","..(v.body.radius)..","..(v.body.x).."^"..(v.body.y)..","..(v.body.angle)
end

savedstring = str

Assuming you’re ball object is a class or a table with tbl.body = physicsobject and you use your own id system. I find this method easiest.

So now you have that you can see that ‘&’ splits each object in to its own subset, then ‘,’ splits the objects properties in to their separate values. Obviously ‘^’ splits vec2 in to two readable x,y values. Knowing this you should be able to add different properties in the mix such as linearVelocity and angularVelocity.

To load it is where we use our key function, if I want to load my savedstring all I need to do is this:

local tbl = split(savedstring,"&")
for k,v in pairs(tbl) do
 local ti = split(v,",")
 local typ = tonumber(ti[1])
 local id = tonumber(ti[2])
 local size = tonumber(ti[3])
 local pos = split(ti[4],"^")
 local angle = tonumber(ti[5])
 if typ == "ball" then
  local ball = Ball(size)
  ball.body.position = vec2(pos[1],pos[2])
  ball.body.angle = angle
  ball.id = id
  table.insert(globalents,ball)
 end
end

You’ll need to use saveLocalData(name,str) and readLocalData(name) to save and load but other than that it’s quite simple when you get to it.

nice split function @luatee, thanks.

@Jmv38 Can’t take credit for that ancient function but you’re welcome :wink:

@Luatee came across this and thought of your little guy walking!

//vimeo.com/87494655

Edit: could not make the video appear? (need to add https:) in front of the above link

the picture wont show on my ipad. Weird…

@piinthesky my method is no where near as complicated as that! It’s very well done though, I was in awe the first time I saw that video.

fantastic video! Too bad thee is no code…