Games Doing the sprite works! X2

developer_123

Member
Licensed User
Good day! Since I require my character to change animation according to the events that occur in the game, I stopped setting the graphics files in the tiled, and started loading the sprite arrangements by assigning a name to each animated situation. I followed Mario's example and loaded the the first sequence situation (walking), into the cache using the next structure:


B4X:
Private Sub load_to_cache
Dim all As List = X2.ReadSprites (xui.LoadBitmap (File.DirAssets, "walking_sprite.png"), 1, 7, 1, 1)
    X2.GraphicCache.PutGraphic ("walking", Array (all.Get (0), all.Get (1), all.Get (2), all.Get (3), all.Get (4), all.Get (5), all.Get (6)))
end sub
.
.
.
sub do_some_thing
'any contitional code here
bw.GraphicName = "walking"

end sub
Within the Tiled, an interval of 70 ms between frames is established, the "graphic file" field is empty and the "graphic name" field is "walking", but the image of the character is always the same (does not change-is always the first image of sprite , is say the image corresponding to "all.Get (0)"). I do not know why ...



maybe i'm ignoring something so i appreciate any hints
 
Last edited:

developer_123

Member
Licensed User
Hello ilan, I am not clipping it since the sprite file only comes with the 7 frames. I use the PISKEL program which generated the sprite adjusted and properly distributed each frame in the .png file.
 

developer_123

Member
Licensed User
Is like LoadBugGraphics from Mario, but without squashed part

B4X:
Private Sub LoadBugGraphics
        Dim all As List = X2.ReadSprites(xui.LoadBitmap(File.DirAssets, "enemy1.png"), 1, 3, 1, 1)
        X2.GraphicCache.PutGraphic("bug", Array(all.Get(0), all.Get(1)))
    Dim squashed As X2ScaledBitmap = all.Get(2)
    squashed.Bmp = squashed.Bmp.Crop(0, squashed.Bmp.Height / 2, squashed.Bmp.Width, squashed.Bmp.Height / 2)
    X2.GraphicCache.PutGraphic("bug squashed", Array(squashed))
End Sub
maybe i'm ignoring part of the code to this works
 

developer_123

Member
Licensed User
can you post a sample project so we can test it?
Attached I send the test project. I extracted the essential code that I refer to in this thread. I eliminated what was related to the "GS.ShouldDraw - bw.UpdateGraphic(GS, True)" code (send it from the game class to the character's tick) since the way I did it, it indicated a compilation error, and also it has not worked for me anyway. Two important points. The first, the idea is to observe the animation of the character walking. The second is that when it collides with the rock, both the rock and the character show a single animation cycle, that is to say that the fall of the character is not repeated, and that the rock in turn shows the animation only once. I don't know if this is achieved with "X2.AddFutureTask", because I still don't understand this instruction very well.
 

ilan

Expert
Licensed User

developer_123

Member
Licensed User
class Game is missing. cannot run it
Holle, Just downloaded it from the wetransfer link and it loaded completely. However below I copy the game class. Just having the idea of how is the correct use of "gs.shouldraw" (I think that is my error, when using it it generates a compilation error, something I am indicating wrong) so that the sprite is displayed in an animated way it would be good help!


B4X:
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
Sub Class_Globals
    Public X2 As X2Utils
    Private xui As XUI 'ignore
    Public world As B2World
    Public Ground, resorte, canon As X2BodyWrapper
    Private ivForeground As B4XView
    Private ivBackground As B4XView
    Public lblStats As B4XView
    Public TileMap As X2TileMap
    Public Const ObjectLayer As String = "Object Layer 1"
    Private Label1 As Label
    Dim check_characters As Int
    Dim number_of_characters As Int =15
    Public mCharacter(number_of_characters) As Character
End Sub

Public Sub Initialize (Parent As B4XView)


    Parent.LoadLayout("GameLayout")
    world.Initialize("world", world.CreateVec2(0, -10))
    X2.Initialize(Me, ivForeground, world)
    Dim WorldWidth As Float = 6 'meters
    Dim WorldHeight As Float = WorldWidth / 1.333 'same ratio as in the designer script
    X2.ConfigureDimensions(world.CreateVec2(WorldWidth / 2, WorldHeight / 2), WorldWidth)
    'Load the graphics and add them to the cache.
    'comment to disable debug drawing
    'X2.EnableDebugDraw
    CreateStaticBackground
    'Passing Null for the target view parameter because we are not creating the background with a tile layer.
    TileMap.Initialize(X2, File.DirAssets, "tiled.json", Null)
    TileMap.SetSingleTileDimensionsInMeters(WorldWidth / TileMap.TilesPerRow, WorldHeight / TileMap.TilesPerColumn)
    TileMap.PrepareObjectsDef(ObjectLayer)
    
    Create_elements
    load_images

End Sub
Private Sub CreateStaticBackground
    Dim bc As BitmapCreator
    bc.Initialize(ivBackground.Width / xui.Scale / 2, ivBackground.Height / xui.Scale / 2)
    bc.FillGradient(Array As Int(0xFF006EFF, 0xFF00DAAD), bc.TargetRect, "TOP_BOTTOM")
    X2.SetBitmapWithFitOrFill(ivBackground, bc.Bitmap)
End Sub

Public Sub Resize
    X2.ImageViewResized
    
End Sub

Private Sub load_images
    Dim width As Float = 0.22
    Dim all As List = X2.ReadSprites(xui.LoadBitmap(File.DirAssets, "walking_sprite.png"), 1, 7, width, width*(1.3))
    X2.GraphicCache.PutGraphic("walking", Array(all.Get(0), all.Get(1), all.Get(2), all.Get(3), all.Get(4), all.Get(5), all.Get(6)))
    
    Dim falling As List = X2.ReadSprites(xui.LoadBitmap(File.DirAssets, "falling.png"), 1, 4, width, width*(1.3))
    X2.GraphicCache.PutGraphic("falling", Array(falling.Get(0), falling.Get(1), falling.Get(2), falling.Get(3)))
    
    Dim rock As List = X2.ReadSprites(xui.LoadBitmap(File.DirAssets, "rock.png"), 1, 4, 0.25, 0.25)
    X2.GraphicCache.PutGraphic("rock", Array(rock.Get(0), rock.Get(1), rock.Get(2), rock.Get(3)))
End Sub


Public Sub Tick (GS As X2GameStep)


End Sub

Private Sub Create_elements
    Dim ol As X2ObjectsLayer = TileMap.Layers.Get(ObjectLayer)
    For Each template As X2TileObjectTemplate In ol.ObjectsById.Values
        Select template.Name
            Case "character"
                For check_characters=0 To number_of_characters - 1
                    template.BodyDef.Position.X = X2.RndFloat(X2.ScreenAABB.BottomLeft.X, X2.ScreenAABB.TopRight.X)
                    Dim bw As X2BodyWrapper = TileMap.CreateObject(template)
                    mCharacter(check_characters).Initialize(bw)
                Next
            Case "ground"
                TileMap.CreateObject(template)
            Case "wall"
                TileMap.CreateObject(template)
            Case "rock"
                TileMap.CreateObject(template)
        End Select
    Next
End Sub

Public Sub DrawingComplete
    
End Sub

'Return True to stop the game loop
Public Sub BeforeTimeStep (GS As X2GameStep) As Boolean
    Return False
End Sub

Private Sub World_BeginContact (Contact As B2Contact)
    Dim bodies As X2BodiesFromContact = X2.GetBodiesFromContact(Contact, "character")
    If bodies = Null Then
        For check_characters=0 To number_of_characters - 1
            mCharacter(check_characters).touch=""
        Next
        Return
    End If
    
    Select bodies.OtherBody.Name
    
        Case "ground"
            For check_characters=0 To number_of_characters - 1
                If bodies.ThisBody= mCharacter(check_characters).bw Then 
                    mCharacter(check_characters).touch="ground"
                    mCharacter(check_characters).Tick(bodies.OtherBody)
                End If
            Next
    
        Case "wall"
            For check_characters=0 To number_of_characters - 1
                If bodies.ThisBody= mCharacter(check_characters).bw Then
                    mCharacter(check_characters).touch="wall"
                    mCharacter(check_characters).Tick(bodies.OtherBody)
            
                End If
            Next

        Case "rock"
            For check_characters=0 To number_of_characters - 1
                If bodies.ThisBody= mCharacter(check_characters).bw Then 
                    mCharacter(check_characters).touch="rock"
                    mCharacter(check_characters).Tick(bodies.OtherBody)
            
                End If
            Next
    End Select
    

End Sub

Private Sub World_EndContact(Contact As B2Contact)
    Dim bodies As X2BodiesFromContact = X2.GetBodiesFromContact(Contact, "character")
    If bodies <> Null Then
        For check_characters=0 To number_of_characters - 1
            mCharacter(check_characters).touch=""
        Next
    End If
End Sub
 

ilan

Expert
Licensed User
Holle, Just downloaded it from the wetransfer link and it loaded completely
you are using a shared folder that's why you are able to run it. anyway i add the game class from your code above and what i think is the problem is you don't call

B4X:
bw.UpdateGraphic(GS, True)
i don't understand why you changed the Tick event properties from

B4X:
Public Sub Tick (GS As X2GameStep)
to

B4X:
Public Sub Tick(element As X2BodyWrapper)
i would suggest you stick to the game layout erel did. changing the tick event may cause problems.
i understand that you are getting like this the X2BodyWrapper to detect collision but it is not the right way to do.

have a look at the Mario example and see how to get collision detection and how to update the graphics.
i am pretty sure there needs to be a graphic update call to update the sprites but i have not used x2 to much to be 100% sure.
i use more iSpritekit for b4i and Libgdx for b4a.

anyway try to set back the tick event and update the graphics with

B4X:
bw.UpdateGraphic(GS, True)
forget first the collision detection first concentrate on the animations and that everything first then start the collision detection.
 
Top