Android Tutorial How to make games

Discussion in 'Tutorials & Examples' started by Informatix, Sep 12, 2013.

  1. Informatix

    Informatix Expert Licensed User

    In fact, you can. The Touch event of AcSf returns an event object that you can pass to the GestureDetector library to get all touch details or, better, you can bind a GestureDetector instance to the AcSf.

    There are plenty. For example:
    http://www.rengelbert.com/tutorial.php?id=176
    http://theinvader360.blogspot.fr/2013/05/street-race-swipe-libgdx-scene2d.html
    http://steigert.blogspot.fr/2012/06/12-libgdx-tutorial-2d-animations.html

    Yes, it's a dead project and I've never been able to make it work properly, so I should remove it definitely from the suggested game engines.

    If you find AcSf too limited, then GameSprite is even more limited (and slower).

    To make games, my advice is to use libGDX. Especially if you want to make a Civilization-like game that requires a tile system. The learning curve is not as steep as you think.
     
    StefanoAccorsi likes this.
  2. Informatix

    Informatix Expert Licensed User

    It depends on the kind of games of course, but I agree that, without basic math skills, doing games can become quickly a complicated task.
     
    StefanoAccorsi likes this.
  3. StefanoAccorsi

    StefanoAccorsi Member Licensed User

    Thank you so much Informatix and wonder. I'm trying but without success. For example, I'm following the gamefromscratch tutorial on Scene2D but it doesn't work. I created a simple class for the actor:

    Code:
    Sub Class_Globals
        
    Dim MyActor As lgScn2DActor
        
    Private Texture As lgTexture
    End Sub

    'Initializes the object. You can add parameters to this method if needed.
    Public Sub Initialize
        
    'Initializes the actor
        Texture.Initialize("sprites/mario.png")
        MyActor.Initialize(
    "Mario")
        MyActor.Name=
    "Mario"
    End Sub

    public Sub MyActor_Draw(batch As lgSpriteBatch, alpha As Float)
        batch.DrawTex(Texture, 
    20%x20%y)
    End Sub
    and used it in the main:

    Code:
    Sub Globals
        
    Dim lGdx As LibGDX
        
    Dim GL As lgGL
        
    Dim Stage As lgScn2DStage
        
    Dim Mario As Actor
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    'Initializes libGDX
        lGdx.Initialize("LG")
    End Sub

    Sub Activity_Resume
        
    'Informs libGDX of Resume events
        If lGdx.IsInitialized Then lGdx.Resume
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        
    'Informs libGDX of Pause events
        If lGdx.IsInitialized Then lGdx.Pause
    End Sub

    Sub LG_Create   
        
    'Initializes the stage
        Stage.Initialize2(lGdx.Graphics.Width, lGdx.Graphics.Height, True"ST")
       
        
    'Initialize the actor in the dedicated class
        Mario.Initialize(lGdx)
       
        Stage.AddActor(Mario.MyActor)
    End Sub

    Sub LG_Resize(Width As Int, Height As Int)
        
    'Sets the stage viewport
        Stage.SetViewport(Width, Height, True)
    End Sub

    Sub LG_Render
        
    'Clears the screen
        GL.glClearColor(0001)
        GL.glClear(GL.GL10_COLOR_BUFFER_BIT)

        
    'Draws the actors
        Stage.Draw
    End Sub

    Sub LG_Pause
    End Sub

    Sub LG_Resume
    End Sub

    Sub LG_Dispose
        
    'Disposes all resources
        Stage.dispose
    End Sub
    It works without any error but nothing is shown on the screen ... mario.png is a simple "Mario bros" file found on internet.

    What's wrong with it? It seemed so simple ...
     
  4. Informatix

    Informatix Expert Licensed User

    You don't load an image, so the result is not very surprising. Anyway, you should not begin with Scene2D, but with the basic things: you load a texture, you create a sprite or a texture region from it and you display that in a SpriteBatch. Don't skip the tutorial pages too quickly. Start here: http://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspx
     
    wonder likes this.
  5. StefanoAccorsi

    StefanoAccorsi Member Licensed User

    The original was:

    Code:
    public class MyActor extends Actor {
       Texture texture = new Texture(Gdx.files.internal(
    "data/jet.png"));
       @Override
       
    public void draw(Batch batch, float alpha){
          batch.draw(texture,
    0,0);
       
    }
    }
    So I supposed that:

    Code:
    Public Sub Initialize
        
    'Initializes the actor
        Texture.Initialize("sprites/mario.png")
        MyActor.Initialize(
    "Mario")
        MyActor.Name=
    "Mario"
    End Sub

    public Sub MyActor_Draw(batch As lgSpriteBatch, alpha As Float)
        batch.DrawTex(Texture, 
    00)
    End Sub
    was a good translation ...

    Anyway, as I wrote in the first post I started from the beginning. The "Hello world" tutorial was easy, and so were the next two but I got stuck in the 3b one (TextureAtlas and Animation). As I wrote I can't translate it, same error I obviously made with the previous example.
    In this one the problem seems to lie in this line:
    Code:
    textureAtlas = new TextureAtlas(Gdx.files.internal("data/spritesheet.atlas"));
    animation = new Animation(1/15f, textureAtlas.getRegions());
    that I translated with:
    Code:
    ...
    atlas.InitializeWithFile2(lGdx.Files.internal(
    "atlas/spritesheet.atlas"))
    animation.Initialize((1.0/15.0), atlas.GetAllRegions)
    ...
    but a List<Object> (returned by atlas.GetAllRegions) can't be casted to an array of lgTextureRegion. I transformed the list in an array but the program crashes at runtime.

    But, since about the example at top you wrote that I didn't load any image, while I supposed to load it with the line
    Code:
    Texture.Initialize("sprites/mario.png")
    then probably I made a similar mistake here that, anyway, I still can't find...
     
  6. wonder

    wonder Expert Licensed User

    If you really want to know your way around LibGDX, you have to take baby steps, at least for the next two-weeks.

    Here's something you can start with. I've tried to comment as much as I could. :)
    Code:
    '==================================================================================================
        #Region  Project Attributes
            
    #ApplicationLabel: LibGDX Test
            
    #VersionCode: 1
            
    #VersionName: 1
            
    'SupportedOrientations possible values: unspecified, landscape or portrait.
            #SupportedOrientations: Landscape
            
    #CanInstallToExternalStorage: True
        
    #End Region

        
    #Region  Activity Attributes
            
    #FullScreen: True
            
    #IncludeTitle: False
        
    #End Region
    '==================================================================================================

    '==================================================================================================
        Sub Process_Globals
            
    Type Sprite( _
                Texture 
    As lgTexture, _
                TextureRegion 
    As lgTextureRegion, _
                ActiveFrame 
    As Int, _
                ActiveFrameX 
    As Int, _
                ActiveFrameY 
    As Int, _
                FramesPerRow 
    As Int, _
                FrameSizeX 
    As Int, _
                FrameSizeY 
    As Int, _
                FPS 
    As Int, _
                TimeStamp 
    As Long _
            )
        
    End Sub
    '==================================================================================================

    '==================================================================================================
        Sub Globals
            
    'Required LibGDX stuff
            Dim GLView          As View
            
    Dim lGdx            As LibGDX
            
    Dim Gl              As lgGL
            
    Dim Camera          As lgOrthographicCamera
            
    Dim Batch           As lgSpriteBatch

            
    'Our custom sprite object
            Dim Ryu             As Sprite
        
    End Sub

        
    Sub Activity_Create(FirstTime As Boolean)
            
    'Initialize the LibGDX layer
                GLView = lGdx.InitializeView("LG")
                
    Activity.AddView(GLView, 0%x0%y100%x100%y)
        
    End Sub

        
    Sub Activity_Resume
            
    If lGdx.IsInitialized Then lGdx.Resume
        
    End Sub

        
    Sub Activity_Pause(UserClosed As Boolean)
            
    If lGdx.IsInitialized Then lGdx.Pause
        
    End Sub
    '==================================================================================================

    '==================================================================================================
    Sub LG_Create
            Batch.Initialize
            
    Dim Texture As lgTexture 'Initializes the texture object, meaning our source bitmap (PNG)
            Dim TextureRegion As lgTextureRegion 'Initializes what will be our animated sprite

            Texture.Initialize(
    "ryu.png"'ryu.png is located in the files folder
            TextureRegion.InitializeWithTexture(Texture) 'The texture "Texture" we just initialized is assigned to our animated sprite "TextureRegion"

            
    'If you look above, we've started by creating a custom type named "Sprite".
            'LibGDX has its own Sprite object, by you can also create something similar, as seen in this example.
            'Since Java passes objects by reference (and B4A is Java), "Ryu.Texture" is nothing but a pointer (like a shortcut)
            'to the original texture object "Texture" the same goes for "Ryu.TextureRegion".
            Ryu.Texture       = Texture
            Ryu.TextureRegion = TextureRegion

            
    'The animation will run at 24 frames per second, independent from the engine (LG_Render)
            'which should ALWAYS, I repeat, ALWAYS run non-less than 60 frames per second.
            Ryu.FPS = 24
            Ryu.FramesPerRow = 
    8
            Ryu.ActiveFrame = -
    1 'Why -1 and not 0? Explained in the Sub Animation
            Ryu.FrameSizeX = 178
            Ryu.FrameSizeY = 
    178
    End Sub

    Sub LG_Resize(Width As Int, Height As Int)
        
    'Sets the camera viewport
            Camera.Initialize

            
    'The reason I'm using SetToOrtho2(True) is because I want my x.y origin
            'to be located at the upper-left corner of the screen.
            Camera.SetToOrtho2(True, lGdx.Graphics.Width, lGdx.Graphics.Height)
    End Sub

    Sub LG_Render
        
    'Clears the screen
            Gl.glClear(Gl.GL10_COLOR_BUFFER_BIT)

        
    'Updates the matrices of the camera
            Camera.Update

        
    'Uses the coordinate system specified by the camera
            Batch.ProjectionMatrix = Camera.Combined

        
    'Sprite Animator
            Animation

        
    'Renderer
            Batch.Begin
                
    'Ryu's Texture Region is drawn here, sized 300x300 pixels on-screen.
                'Remember, this size is independent of it's original frame size (178x178).
                Batch.DrawRegion2(Ryu.TextureRegion, 00300300)
            Batch.End
    End Sub

    'The Dispose event is EXTREMELY IMPORTANT, if neglected you'll have memory leaks
    'You don't have to dispose TextureRegions, only Textures. <-- FOR OUR SPECIFIC CASE
    Sub LG_Dispose
        Batch.dispose
        Ryu.Texture.dispose
    End Sub

    Sub LG_Pause
        LG_Resume
    End Sub

    Sub LG_Resume
    End Sub
    '==================================================================================================

    '==================================================================================================
    'This is my custom-made sprite animator. Like I said, you may use LibGDX own Sprite object for this purpose,
    'but I think this is a good opportunity to understand the basis of sprite animation.
    Sub Animation
        
    'Every 1/24 of a second, a new frame will be displayed.
        If DateTime.Now - Ryu.TimeStamp > (1 / Ryu.FPS * 1000Then
            
    'Advances ONE frame. Since Ryu.ActiveFrame was initialized to -1, the first frame to be displayed will be FRAME 0.
            Ryu.ActiveFrame = Ryu.ActiveFrame + 1
            
    If Ryu.ActiveFrame > 9 Then Ryu.ActiveFrame = 0

            
    'Timestamps the new frame
            Ryu.TimeStamp = DateTime.Now

            
    'This formula gets the X, Y texture coordinates based on the ActiveFrame index.
            Ryu.ActiveFrameX = Ryu.ActiveFrame Mod Ryu.FramesPerRow
            Ryu.ActiveFrameY = 
    Floor(Ryu.ActiveFrame / Ryu.FramesPerRow)

            
    'This is where the magic happens.
            'Ryu's sprite (Texture Region) will be section of it's own texture (Ryu.Texture) sized 178x178 pixels.
            Ryu.TextureRegion.SetRegion(Ryu.ActiveFrameX * Ryu.FrameSizeX, _
                                        Ryu.ActiveFrameY * Ryu.FrameSizeY, _
                                        Ryu.FrameSizeX, Ryu.FrameSizeY)
            
    'OPTIONAL
            'Because I like to have the x,y origin (0,0) at the upper-left corner, I have to flip the texture region.
            Ryu.TextureRegion.Flip(FalseTrue)

            
    '################################################################
            'The Texture Region is now ready to be displayed in a Batch.Draw!
            '################################################################

        
    End If
    End Sub
    '==================================================================================================
    If you're interested in a more advanced sprite animation, click below. :)
    This small project will display Ryu's "idle" animation, which is comprised of the first 10 frames (left-to-right, to the bottom) of the texture file.
    Notice this line of code in the Animation sub:
    Code:
    If Ryu.ActiveFrame > 9 Then Ryu.ActiveFrame = 0
    If you wanted to display a punch, you only need to remember that the corresponding frames are [10 to 13]. You could create an array to store the animation size of each character move. For example:
    Code:
    Type Sprite(..., ..., ..., Moves(,) As Int, ActiveMove As Int)

    ...

    'Constants
    '------------------------------------------------------
    Dim numberOfMoves = 2 As Int
    Dim numberOfColumns = 2 As Int
    Dim firstFrameColumn = 0 As Int
    Dim animationSizeColumn = 1 As Int
    '------------------------------------------------------

    Dim Moves(numberOfMoves, numberOfColumns) As Int

    'Suggestion: Read the following from a text file (or SQLite database)
    '------------------------------------------------------
    Dim IdleIndex = 0 As Int
    Dim PunchIndex = 1 As Int

    Dim IdleFirstFrame = 0 As Int
    Dim IdleSize = 10 As Int

    Dim PunchFirstFrame = 10 As Int
    Dim PunchSize = 4 As Int
    '------------------------------------------------------

    Moves(IdleIndex, firstFrameColumn) = IdleFirstFrame
    Moves(IdleIndex, animationSizeColumn) = IdleFirstFrame

    Moves(PunchIndex, firstFrameColumn) = PunchFirstFrame
    Moves(PunchIndex, animationSizeColumn) = PunchFirstFrame

    Ryu.Moves = Moves
    Now we could replace:
    Code:
    If Ryu.ActiveFrame > 9 Then Ryu.ActiveFrame = 0
    With:
    Code:
    Sub MainGameCycle
        ...
        ...
        
    'punch = punchIndex = 1 (for example)
        ...
        
    If playerAction.PunchBtn Then
            SetMove_Ryu(punch)
        
    End If
        Animate_Ryu(Ryu.ActiveMove)
    End Sub

    Sub SetMove_Ryu(moveIndex As Int)
        Ryu.ActiveMove = moveIndex
        Ryu.ActiveFrame = Ryu.Moves(Ryu.ActiveMove, firstFrameColumn)
    End Sub

    Sub Animate_Ryu(moveIndex As Int)
        Ryu.ActiveMove = moveIndex
        
    Dim lastFrame = _
            Ryu.Moves(Ryu.ActiveMove, firstFrameColumn) + _
            (Ryu.Moves(Ryu.ActiveMove, animationSizeColumn) - 
    1) _
        
    As Int

        
    If Ryu.ActiveFrame > Ryu.Moves(Ryu.ActiveMove, lastFrame) Then
            Ryu.ActiveFrame = Ryu.Moves(Ryu.ActiveMove, firstFrameColumn)
        
    End If
        ...
        ...
        ...
    End Sub
     

    Attached Files:

    • ryu.png
      ryu.png
      File size:
      141 KB
      Views:
      179
    Last edited: Feb 3, 2016
  7. wonder

    wonder Expert Licensed User

    Another piece of advice:
    - Don't be tempted to use Lists, Maps or any other fancy objects. They will slow your game down.
    - Use Arrays.
     
  8. melonZgz

    melonZgz Active Member Licensed User

    I was in your situation a few months ago, so I understand you perfectly.
    In short: Go for LibGDX. Even if your game is simple, the performance will be better.
    Some months ago I made a big mistake, I started to write my first game (very simple game, a flappy clone with cute graphics, a shop, multiple modes...), and as it was rather simple I started using gameSpriteView library. It was OK in my phone (a MotoG), but when it was almost finished, I realized that the performance was very different depending on which device I was testing it, and stuttering a lot in some devices. So I had to start again, and start learning GDX.
    What I did was studying the examples provided. First just learn how to draw an image in the screen. then you can try to animate it (example animation). Also the flappy game example was so usefull for me.
    Once you understand some concepts like textures, regions, sprites, spritebatch, camera, you can work very fast.
    And you can try box2d, it's great! It opens you a new world of games, where you can let the physics engine do the work. You'll "only" have to check collisions and sensors to see what happens in your world. My first game is going to be a libGDX+Box2D game.
    About the math background, for a 2D game you don't have to be an engineer, but you need to have some knowledge about vectors. The more the better.

    Is this true?? is really noticeable? Because in my game is based on lists, sometimes with more than 50 elements.
    What I do in each step is something like


    Code:
    For Each knight As cKnight In lstKnights
        knight.draw(DeltaTime)
    Next
    Which I read somewhere it was the fastest way to get the elements from a list. If using arrays is faster I think I'll get better performance for my game.

    PS: First post in these forums after years just watching. I'll be more active since now.
    PS2: Sorry for my english!
     
    StefanoAccorsi and wonder like this.
  9. wonder

    wonder Expert Licensed User

    Well, depends. On a fighting game (two-characters + background), I would probably be fine, but on a RTS game, where you can have hundreds of characters on screen and/or the same amount of A.I. agents, favoring arrays is a must. The performance gap between the two will be noticeable. (@Informatix, correct me if I'm wrong).

    Of course, you can use lists/maps/databases to organize and load your assets (textures, sound, music, maps), though. Just not in-game.
     
    melonZgz likes this.
  10. Informatix

    Informatix Expert Licensed User

    The operations that you perform on a collection can be independent from the number of elements in the collection or very dependent according to the type of collection, and some collections have known limitations due to the way they are implemented or the lack of some functions: extending or shrinking an array is very expensive (arrays are usually of fixed size; they are not supposed to have a dynamic size), sorting a map or an array is a bit complicated in B4A... That's why there's no generic answer. Depending on the operations to perform and on their frequency, you will choose a collection or another. If performance is not at stake, you will choose the most convenient collection.
    That being said, the fact is that many collections are based on an array (List, for example, is in Java an ArrayList). So, all the overhead can be removed by using directly arrays. To remove its main limitation, an array can be sized big enough to hold all possible elements created by your game, and a simple index variable will keep track of the last cell filled. When you add an element, you increment the index and fill the available cell. There's still a problem with the sorts and removals but there are solutions for these cases too. The question is: do you really need that? If a List does the job, use a List.
     
    Last edited: Feb 2, 2016
    melonZgz likes this.
  11. wonder

    wonder Expert Licensed User

    How about creating a large array with a fixed MAX_VALUE?
    Code:
    '=== main cycle ===
    Dim MAX_ENEMIES_ONSCREEN = 256 As Int
    Dim Enemy(MAX_ENEMIES_ONSCREEN) as Whatever

    If Enemy(i).Active = TRUE Then
        ...
        ...
    End If
    '=== main cycle ===
    Is it a bad practice?
     
    Last edited: Feb 2, 2016
  12. StefanoAccorsi

    StefanoAccorsi Member Licensed User

    This will be very very useful! Thank you @wonder I'll let you know.
     
    wonder likes this.
  13. wonder

    wonder Expert Licensed User

    I'm happy to help! :)

    By the way, I'm not sure, but just to be safe dispose "Texture" as well.
    Code:
    Sub LG_Dispose
        Batch.dispose
        Ryu.Texture.dispose
        Texture.dispose 
    '<-- add this line
    End Sub
     
  14. StefanoAccorsi

    StefanoAccorsi Member Licensed User

    Ok, big steps ahead from the last post, thank to your hints.

    But still I have a big problem: debugging. When I started to work with libGDX I understood that I have to compile & run in "release" mode, since libGDX works in a different thread and that, as written in the great @Informatix tutorial, "You have to use the Log() function to debug your game."

    But does Log() work in release run? Since I can't see any of my logs in the right window, as I see in not-libGDX programming.

    And if I try to run the program in debug mode, it crashes as soon as it starts, while in release it doesn't: it can't find resources files ...

    As usual thank you.
     
    Last edited: Feb 17, 2016
    wonder likes this.
  15. ilan

    ilan Expert Licensed User

    hi

    i am not sure if i post this question in the right thread but since it is about box2d i am asking it here.

    i am working now on a libgdx - box2d game and i have created a world with some physic bodies and a car (that is connected with prismatic joints + revolute joints, bla bla bla.)

    i set 0 to the wheels friction. the value should be between 0 - 1. according to box2d manuals (Chapter 7.2 http://box2d.org/manual.pdf)

    friction 0 means NO FRICTION, friction 1 means a very high friction but what i get is a opposite behavior (by a circle body!)

    is it a bug or am i doing something wrong :confused:?

    EDIT: the same for lgBox2DEdgeShape and lgBox2DPolygonShape
     
    Last edited: Mar 5, 2016
  16. Informatix

    Informatix Expert Licensed User

    You should post in the libGDX thread instead.
    Did you try the friction demo? Do you have strange results with it?
     
  17. ilan

    ilan Expert Licensed User

    sorry

    YES! the same behavior.
    i just tried your example "Varing Friction"
    and changed this line:

    Code:
    Dim friction(5As Float = Array As Float (0.750.50.350.10)
    to

    Code:
    Dim friction(5As Float = Array As Float (00000)
    and all box are sliding but they shouldnot slide because friction is 0
    when i set to 1 all stay at place
     
  18. Informatix

    Informatix Expert Licensed User

    That seems normal. If there's no friction (=0), objects should slide at full speed. And it's exactly what the manual says.
     
  19. ilan

    ilan Expert Licensed User

    you are right, sorry.
    i misunderstood the manual. friction strong means NO sliding, i tought strong friction means a very strong sliding. :confused:
    (result of my weak english)
     
  20. Hilen

    Hilen New Member Licensed User

    I have been playing are writing games since Pong. Very good points to consider here. As you mention, there is much more to making a great game than just coding. Games take a ton of thought and planning and as a wise man once said...

    ..."Imagination is more important than knowledge." - A. E.

    One small thing to add...Things like Play-ability and Shelf-life must always trump fancy graphics.
     
    Informatix likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice