Games Platformer game

melonZgz

Active Member
Licensed User
Longtime User
Hello there!
While I finish my UFO game I've started to work again in my platformer game. So with you...
UPDATE: GAME LAUNCHED!

https://play.google.com/store/apps/details?id=com.ninjagames.platformer

main.png

EDIT: Made a little trailer:
It allready looks like a game! with main menu and level selection screen allready there, dialogs, effects...
The main mechanics are there (it's made with LibGDX + Box2D). This is going fast, as I'm importing a lot of stuff from my UFO game.
The concept is simple, go and find the chest, get the treasure, the door will open and you can leave the level.
There will be some exploration, puzzles, secrets... I'll also add different worlds, more enemies...
When I was a child, platformer games where my favourites, so I'm so excited while making this game. I only wish I had more time to do game programming!
 
Last edited:

melonZgz

Active Member
Licensed User
Longtime User
Yeah, I have a regular job, and family, friends, other hobbies... I try to dedicate 2 hours a day to game programming (it's some kind of arrangement with my wife :p)
In my dreams I'd quit my job and dedicate full time to game programming :rolleyes:, but it's not a realistic scenario
 

ilan

Expert
Licensed User
Longtime User
In my dreams I'd quit my job and dedicate full time to game programming :rolleyes:, but it's not a realistic scenario

this is something i am planning too.
i would like to take a break from job for 1 year. create new high quality games + apps and if after 1 year i will see that i cannot make a living from them i will get back a job.

i am working on a box2d libgdx game. i am using tiled and its really a great tool. the problem is that you have to invest a lot time to finish a complete nice game with levels and nice UI. i believe in my situation a complete game would take about 3 month but if i would do it full time i believe it would take 1 month.

i think that i will stop making simple small games and concentrate on big ones.

i have at least 4 box2d games in mind that i want to release 2017 (really nice games) i already purchased the graphics for them now i just need to find the time to finish them.

are you planning to release also apps? or you would like to make only games?
 

ilan

Expert
Licensed User
Longtime User
btw i just created a codemodule to load a complete level from tiled and create the bodies from it.

for now to module is creating only bodies from a rectangle tiled body so its more for the ground and wall objects.
i will improve the code so it will load all objects and create box2d bodies from it like (coins, ground, rocks,...)

this is the code module i created today:

B4X:
Sub Process_Globals
Private scalex, scaley, vpW, vpH As Float
End Sub

Sub CreateLevel(world As lgBox2DWorld, tiledmap As lgMapTiledMap, scalexfactor As Float, scaleyfactor As Float, LgWidth As Float, LgHeight As Float)
    vpW = LgWidth
    vpH = LgHeight
    scalex = scalexfactor
    scaley = scaleyfactor
   
    Dim layerint As Int = -1
   
    For i = 0 To tiledmap.Layers.GetAllLayers.Size-1
        Dim layer As lgMapLayer = tiledmap.Layers.GetAllLayers.Get(i)
        If layer.Name = "objectlayer1" Then
            layerint = i
            Exit
        End If
    Next
   
    If layerint < 0 Then Return
   
    For Each obj As lgMapRectangleMapObject In tiledmap.Layers.Get(layerint).Objects.GetAllObjects
        Dim Box As lgBox2DPolygonShape
        Box.SetAsBox2((obj.Rectangle.width/2)/scalex,(obj.Rectangle.height/2)/scaley,world2box2d(obj.Rectangle.x,obj.Rectangle.y,obj.Rectangle.width,obj.Rectangle.height),0)
        Dim fd As lgBox2DFixtureDef
        fd.shape = Box
        fd.restitution = 0.2
        fd.Density = 1
        fd.friction = 1
        Dim bd_def As lgBox2DBodyDef
        bd_def.type = world.BODYTYPE_Static
        bd_def.position.set(0,0)
        Dim box2dbody As lgBox2DBody
        box2dbody = world.createBody(bd_def)
        box2dbody.createFixture(fd)
        box2dbody.UserData = obj.Name
        Box.dispose
    Next
End Sub

private Sub world2box2d (posx As Float, posy As Float, width As Float, height As Float) As lgMathVector2
    Dim vector As lgMathVector2
    vector.x = ((posx + (width/2)) - (vpW/2)) / scalex
    vector.y = ((posy + (height/2)) - (vpH/2) ) / scaley
    Return vector
End Sub

this is how i load it to my project (with a single line)

B4X:
    Dim tilemap As lgMapTmxMapLoader
    tilemap.Initialize
    tiledmap = tilemap.Load("test.tmx")
    tmr.Initialize(tiledmap)
   
    LoadLevelTiled.CreateLevel(World,tiledmap,scaleX,scaleY,vpW,vpH)

i have several layers in my tmx file so everything is rendered and the objectlayer is converted to box2d bodies.
 

sorex

Expert
Licensed User
Longtime User
cool, that's Rick Dangerous like.

are that elephant legs coming out of the ceiling? ;)
 

melonZgz

Active Member
Licensed User
Longtime User
I load the map in a similar way. In my collision layer (object layer in tiled) I have rectangles and polygons that I create as box2d bodies. For polygons, they need to be convex, because if they're concave some triangulation is needed (I just read all the vertices and then I create the lgBox2dPolygonShape). This way I make all the levels in my UFO game. I'd like to add also a polyline object, for more complex shapes...
 

ilan

Expert
Licensed User
Longtime User
ok now the module also supports Polygon shapes

B4X:
'Code module
Sub Process_Globals
Private scalex, scaley, vpW, vpH As Float
End Sub

Sub CreateLevel(world As lgBox2DWorld, tiledmap As lgMapTiledMap, scalexfactor As Float, scaleyfactor As Float, LgWidth As Float, LgHeight As Float)
    vpW = LgWidth
    vpH = LgHeight
    scalex = scalexfactor
    scaley = scaleyfactor

    Dim layerint As Int = -1

    For i = 0 To tiledmap.Layers.GetAllLayers.Size-1
        Dim layer As lgMapLayer = tiledmap.Layers.GetAllLayers.Get(i)
        If layer.Name = "objectlayer1" Then
            layerint = i
            Exit
        End If
    Next

    If layerint < 0 Then Return

    For Each obj As lgMapObject In tiledmap.Layers.Get(layerint).Objects.GetAllObjects
        If obj Is lgMapPolygonMapObject Then
            Dim polygonobj As lgMapPolygonMapObject = obj
            Dim polygon As lgBox2DPolygonShape
            Dim newVertices(polygonobj.Polygon.Vertices.Length) As Float
            For i = 0 To polygonobj.Polygon.Vertices.Length - 1
                Dim ver As Float = polygonobj.Polygon.Vertices(i)
                newVertices(i) = ver / scalex
            Next
            polygon.Set2(newVertices)
            Dim polygonShapeDef As lgBox2DFixtureDef
            polygonShapeDef.shape = polygon
            polygonShapeDef.restitution=0.2
            polygonShapeDef.Density = 0.5
            Dim polygonBodyDef As lgBox2DBodyDef
            polygonBodyDef.Type = world.BODYTYPE_Static
            polygonBodyDef.position.set(world2box2d(polygonobj.Polygon.X,polygonobj.Polygon.Y,0,0).x,world2box2d(polygonobj.Polygon.X,polygonobj.Polygon.Y,0,0).y)
            Dim polygonbody As lgBox2DBody
            polygonbody = world.createBody(polygonBodyDef)
            polygonbody.createFixture(polygonShapeDef)
            polygonbody.UserData = polygonobj.Name   
            polygon.dispose
            Log("polygon created")
        else if obj Is lgMapRectangleMapObject Then
            Dim rectobj As lgMapRectangleMapObject = obj
            Dim Box As lgBox2DPolygonShape
            Box.SetAsBox2((rectobj.Rectangle.width/2)/scalex,(rectobj.Rectangle.height/2)/scaley,world2box2d(rectobj.Rectangle.x,rectobj.Rectangle.y,rectobj.Rectangle.width,rectobj.Rectangle.height),0)
            Dim fd As lgBox2DFixtureDef
            fd.shape = Box
            fd.restitution = 0.2
            fd.Density = 1
            fd.friction = 1
            Dim bd_def As lgBox2DBodyDef
            bd_def.type = world.BODYTYPE_Static
            bd_def.position.set(0,0)
            Dim box2dbody As lgBox2DBody
            box2dbody = world.createBody(bd_def)
            box2dbody.createFixture(fd)
            box2dbody.UserData = obj.Name
            Box.dispose
            Log("box created")
        End If
    Next
End Sub

private Sub world2box2d (posx As Float, posy As Float, width As Float, height As Float) As lgMathVector2
    Dim vector As lgMathVector2
    vector.x = ((posx + (width/2)) - (vpW/2)) / scalex
    vector.y = ((posy + (height/2)) - (vpH/2) ) / scaley
    Return vector
End Sub

EDIT: this is how it looks like:

Screenshot_2016-10-28-15-27-06.jpeg


i must say it is a lot of fun working with tiled and box2d (if everything works as you expect :p)

TILED VIEW:

tiled1.jpeg
 
Last edited:

ilan

Expert
Licensed User
Longtime User
really sad that tiled dont have CIRCLE obj and only ELLIPSE because box2d dont have an ellipse body :(
 

melonZgz

Active Member
Licensed User
Longtime User
For more complex objects you can use the physics body editor tool.
And for other objects (enemies, traps, mechanisms...) i just draw a little rectangle in an object layer and add some custom properties (ie: type of platform, speed, stop time...). And when loading I just read the x and y values and then init the object with the parameters.
 

ilan

Expert
Licensed User
Longtime User
For more complex objects you can use the physics body editor tool.
And for other objects (enemies, traps, mechanisms...) i just draw a little rectangle in an object layer and add some custom properties (ie: type of platform, speed, stop time...). And when loading I just read the x and y values and then init the object with the parameters.

this is exactly what i was thinking to do. i thought to add some small objects just to get their x/y so i can locate all dynamic bodies (like player, enemies,...)

i have already used the body editor tool and joints in other projects (like my Moped game) so for complex bodies i will use it.
what i still need to learn is how to use lgviews like buttons, panels,..

the thing is that the lgInputProcessor or lgGestureDetector cannot recognize a touch and hold event like a simple android panel view.
they can recognize a touch down and touch up but not when i hold the down. i needed that for my moped game where i touch the Gas Pedal and could not figure it out.

i dont want to stop only when touch up was fired i would like to have a touch and hold event.
i also need to investigate the how to make menus and animate them like you did in your games. can i have panels and add views in it and move only that panel around instead of moving each button?
 

ilan

Expert
Licensed User
Longtime User
I'd like to add also a polyline object, for more complex shapes...

B4X:
'Code module
Sub Process_Globals
End Sub

Sub CreateLevel(world As lgBox2DWorld, tiledmap As lgMapTiledMap)
    Private scalex As Float = Main.scaleX
    Private scaley As Float = Main.scaleY
  
    Dim layerint As Int = -1
  
    For i = 0 To tiledmap.Layers.GetAllLayers.Size-1
        Dim layer As lgMapLayer = tiledmap.Layers.GetAllLayers.Get(i)
        If layer.Name = "objectlayer1" Then
            layerint = i
            Exit
        End If
    Next
  
    If layerint < 0 Then Return
  
    For Each obj As lgMapObject In tiledmap.Layers.Get(layerint).Objects.GetAllObjects
        If obj Is lgMapPolygonMapObject Then   
            Dim polygonobj As lgMapPolygonMapObject = obj
            Dim polygon As lgBox2DPolygonShape
            Dim newVertices(polygonobj.Polygon.Vertices.Length) As Float
            For i = 0 To polygonobj.Polygon.Vertices.Length - 1
                Dim ver As Float = polygonobj.Polygon.Vertices(i)
                newVertices(i) = ver / scalex
            Next
            polygon.Set2(newVertices)
            Dim polygonShapeDef As lgBox2DFixtureDef
            polygonShapeDef.shape = polygon
            polygonShapeDef.restitution=0.2
            polygonShapeDef.Density = 0.5
            Dim polygonBodyDef As lgBox2DBodyDef
            polygonBodyDef.Type = world.BODYTYPE_Static
            polygonBodyDef.position.set(PosCon.world2box2d(polygonobj.Polygon.X,polygonobj.Polygon.Y,0,0).x,PosCon.world2box2d(polygonobj.Polygon.X,polygonobj.Polygon.Y,0,0).y)
            Dim polygonbody As lgBox2DBody
            polygonbody = world.createBody(polygonBodyDef)
            polygonbody.createFixture(polygonShapeDef)
            polygonbody.UserData = polygonobj.Name      
            polygon.dispose
            Log("polygon created")
        else if obj Is lgMapRectangleMapObject Then
            Dim rectobj As lgMapRectangleMapObject = obj
            Dim Box As lgBox2DPolygonShape
            Box.SetAsBox2((rectobj.Rectangle.width/2)/scalex,(rectobj.Rectangle.height/2)/scaley,PosCon.world2box2d(rectobj.Rectangle.x,rectobj.Rectangle.y,rectobj.Rectangle.width,rectobj.Rectangle.height),0)
            Dim fd As lgBox2DFixtureDef
            fd.shape = Box
            fd.restitution = 0.2
            fd.Density = 1
            fd.friction = 1
            Dim bd_def As lgBox2DBodyDef
            bd_def.type = world.BODYTYPE_Static
            bd_def.position.set(0,0)
            Dim box2dbody As lgBox2DBody
            box2dbody = world.createBody(bd_def)
            box2dbody.createFixture(fd)
            box2dbody.UserData = obj.Name
            Box.dispose
            Log("box created")
        else if obj Is lgMapEllipseMapObject Then
            Dim circleobj As lgMapEllipseMapObject = obj
            Dim Circle As lgBox2DCircleShape
            Circle.Radius = (circleobj.Ellipse.width/scalex)/2
            Dim circlefd As lgBox2DFixtureDef
            circlefd.shape = Circle
            circlefd.density = 1
            circlefd.restitution = 0.2
            circlefd.friction = 1
            circlefd.isSensor = True
            Dim circledef As lgBox2DBodyDef
            circledef.type = world.BODYTYPE_Static
            circledef.position.Set(PosCon.world2box2d(circleobj.Ellipse.x,circleobj.Ellipse.Y,0,0).x+Circle.Radius,PosCon.world2box2d(circleobj.Ellipse.x,circleobj.Ellipse.Y,0,0).y+Circle.Radius)
            Dim circlebody As lgBox2DBody
            circlebody = world.CreateBody(circledef)
            circlebody.createFixture(circlefd)
            circlebody.UserData = obj.Name
            Circle.dispose
        else if obj Is lgMapPolylineMapObject Then
            Dim polylineobj As lgMapPolylineMapObject = obj
            Dim chain As lgBox2DChainShape
            Dim newVertices(polylineobj.Polyline.Vertices.Length) As Float
            For i = 0 To polylineobj.Polyline.Vertices.Length - 1
                Dim ver As Float = polylineobj.Polyline.Vertices(i)
                newVertices(i) = ver / scalex
            Next
            chain.createChain(newVertices)
            Dim chainShapeDef As lgBox2DFixtureDef
            chainShapeDef.shape = chain
            chainShapeDef.restitution=0.2
            chainShapeDef.Density = 0.5
            Dim chainBodyDef As lgBox2DBodyDef
            chainBodyDef.Type = world.BODYTYPE_Static
            chainBodyDef.position.set(PosCon.world2box2d(polylineobj.Polyline.X,polylineobj.Polyline.Y,0,0).x,PosCon.world2box2d(polylineobj.Polyline.X,polylineobj.Polyline.Y,0,0).y)
            Dim chainbody As lgBox2DBody
            chainbody = world.createBody(chainBodyDef)
            chainbody.createFixture(chainShapeDef)
            chainbody.UserData = polylineobj.Name      
            chain.dispose
            Log("polyline created")
        End If
    Next
End Sub

Now i can create in Tiled very complex object without any problems (also concave Polygons! like i used to create in BodyEditor)

Screenshot_2016-10-30-01-18-08.png




tiled2.png
 

andymc

Well-Known Member
Licensed User
Longtime User
Wow! I really need to learn box2d. I've not touched it at all yet. I write my own physics into my games, but this means they're always quite simple and my collisions are always square shaped or circle shaped.
I too try to fit in my games programming around my family, my main time I have is on my train to work, which gives me nearly two hours per day to work on games. the other option is I could spend an hour every other night at home after my wife goes to bed working, but this means I'll be too tired to work on the train in the morning. My dream too is to quit my day job and be a fulltime games developer.
 

melonZgz

Active Member
Licensed User
Longtime User
the thing is that the lgInputProcessor or lgGestureDetector cannot recognize a touch and hold event like a simple android panel view.
they can recognize a touch down and touch up but not when i hold the down. i needed that for my moped game where i touch the Gas Pedal and could not figure it out.

i dont want to stop only when touch up was fired i would like to have a touch and hold event.
i also need to investigate the how to make menus and animate them like you did in your games. can i have panels and add views in it and move only that panel around instead of moving each button?

Hello there!
In my games I'm not using scene2D, just textureRegions and sprites. For the GUI I use textureregions and I animate them via interpolators. Maybe a lot of work without using scene2D... but it works!
And for the touch events, this is what I have in my car game, where IP is inputProcessor, and cameraGUI is a camera I have only to show the GUI:

B4X:
Private Sub FromScreenToWorld(ScreenX As Int, ScreenY As Int) As lgMathVector2
   'Translates the screen coordinates into viewport/world coordinates
   Dim Coord As lgMathVector2
   Coord.set(ScreenX, ScreenY)
   cameraGUI.Unproject(Coord)
   Return Coord
End Sub

Public Sub touchLeft(x As Float, y As Float) As Boolean
    Dim where As lgMathVector2 = FromScreenToWorld(x,y)   
    Return     (where.x < cameraGUI.ViewportWidth/2)
End Sub

Public Sub touchRight(x As Float, y As Float) As Boolean
    Dim where As lgMathVector2 = FromScreenToWorld(x,y)   
    Return     (where.x >= cameraGUI.ViewportWidth/2)
End Sub

Sub IP_TouchDown(screenX As Int, screenY As Int, Pointer As Int) As Boolean
    If touchLeft(screenX, screenY) Then
        leftPointer = Pointer
    End If   
    If touchRight(screenX, screenY) Then
        rightPointer = Pointer
    End If
End Sub

Sub IP_touchup(screenX As Int, screenY As Int, pointer As Int)
    Select Case pointer
        Case leftPointer
            leftPointer = -1
        Case rightPointer
            rightPointer = -1
    End Select
End Sub

And somewhere in the render event I have

B4X:
car.handleInputs(leftPointer, rightPointer)
 

ilan

Expert
Licensed User
Longtime User
Hello there!
In my games I'm not using scene2D, just textureRegions and sprites. For the GUI I use textureregions and I animate them via interpolators. Maybe a lot of work without using scene2D... but it works!
And for the touch events, this is what I have in my car game, where IP is inputProcessor, and cameraGUI is a camera I have only to show the GUI:

hi, i am using stage and actors for my buttons and menu. @Informatix told me once that i should handle my touches on an actor level and not on screen coordinates.

On my old games i used only screen touches but the game i am working on now i would like not only to make a game i want to increase my knowledge in libgdx and box2d so i am trying a lot new stuff.

I have still not figure out how to add interpolation to a texture. what i do is adding interpolation to actors but how is it possible to add it to a texture? can u please post an example? thanx @melonZgz :)
 

melonZgz

Active Member
Licensed User
Longtime User
Well, I have a "sceneObject" class. It has the position, the textureRegion and more things (oversimplified example):
B4X:
'Class module
Sub Class_Globals
    ...
    Dim interpolator As lgMathInterpolation
    Dim finalPosition As lgMathVector2
    Dim initialPosition As lgMathVector2
    Dim actualPosition As lgMathVector2  
    Dim duracionAnim As Float
    Dim interpolator As lgMathInterpolation
    Dim time As Float
    Dim texture As lgTextureRegion
    ...
End Sub

And the draw event:

B4X:
Public Sub draw (batch As lgSpriteBatch, delta As Float)
Dim progress As Float
Dim a As Float
...
        time = time + delta
        progress = time / duracionAnim
        a = interpolator.apply (progress)
        If progress >=1 Then
            progress = 1
            animating = False
            inPlace = True
        End If
        actualPosition.x = initialPosition.x + a * (finalPosition.x - initialPosition.x)
        actualPosition.y = initialPosition.y + a * (finalPosition.y - initialPosition.y)
...
        'Draw
        batch.DrawRegion (texture,actualPosition.x-texture.RegionWidth/2,actualPosition.y-texture.RegionHeight/2)
 

ilan

Expert
Licensed User
Longtime User
Thanks for the tips and snipped. Nice to learn from each other on this forum.
Anyway i will stay with scene2d since it is working fine.

I build a function where i animate my actors with a single line.
I make very good progress with my new game.
Btw i implemented your camera update in my game @melonZgz and it is working great.

First i just updated the camera to my player x/y but then i tried to use a mousejoint so i connected a body to my player with a mousejoint and camera x/y was updated according to the connected body but u may guess what result i was getting :D

Then i tried with a revolute joint. It was better then the mousejoint but not what i wanted so in the end i used your camera update sub. And i like the result.

Thanx for sharing :)
 
Top