Android Tutorial [B4X] [BitmapCreator] Cross platform Falling Sand game

Discussion in 'Tutorials & Examples' started by Erel, Jun 19, 2018.

  1. Erel

    Erel Administrator Staff Member Licensed User

    [​IMG]

    The main challenge here is the performance. All particles are updated if needed and redrawn every cycle.

    The Particles array stores the state of all "game pixels". A value of 0 means that the pixel is empty. Other values mean that there is a particle on that pixel.
    Sand particles move down or diagonally if they can.

    The RowsState array tracks the rows that are considered dirty. Non-dirty rows are skipped.

    Single dimension arrays of bytes can be accessed in an optimized way in B4i with Bit.FastArrayGet / Set methods (https://www.b4x.com/android/forum/threads/92951/#content). I used these methods in some of the cases.

    All the important code is implemented in the Game class, which is of course shared between the three projects. No sprites are used in this game. The drawings are done in the MoveParticles sub.
    As in the Tetris game the layout is managed with the designer script.

    You need to change the GameUtils module that is included in the zip files with the one attached separately.

    Dependencies:

    - Recent version of XUI.
    - BitmapCreator v3.6 (B4J, B4i)

    The three projects are attached. I've also uploaded an executable jar. Download and double click.
    www.b4x.com/b4j/files/games/FallingSand_ExecutableJar.jar
     

    Attached Files:

    Last edited: Sep 6, 2018
  2. Erel

    Erel Administrator Staff Member Licensed User

     
    Last edited: Jun 19, 2018
  3. LucaMs

    LucaMs Expert Licensed User

    Great !!!

    [on my not-young PC :D:(... 70/71 FPS !]
     
    Toky Olivier likes this.
  4. Jmu5667

    Jmu5667 Well-Known Member Licensed User

    Amazing !
     
  5. mark35at

    mark35at Well-Known Member Licensed User

    Obviously Erel has 36 hours in his day! Otherwise he wouldn't have time for such great things between writing updates and answering questions. Great post! :D
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    Uploaded a new version with an option to switch the gravity.
     
  7. Johan Hormaza

    Johan Hormaza Active Member Licensed User

    It's that simple the best @Erel
     
  8. Alexander Stolte

    Alexander Stolte Well-Known Member Licensed User

    well, that escalated quickly...
    sand.png
     
    KMatle, Erel and Johan Hormaza like this.
  9. Erel

    Erel Administrator Staff Member Licensed User

    Projects in the first post were updated with a fix to a bug that caused the game to crash.

    The cause of this bug might be a bit interesting as it is a pattern that can be used in many cases.

    When the particles move we need to check the status of the nearby pixels. This causes a problem with the pixels near the edge. We can add checks to assure that we don't try to access out of bounds pixels but it can be annoying to always check it when 99.5% of the pixels are known to be inside.
    So instead we are creating ROCK borders when the game starts:
    Code:
    'create the borders
    For y = 0 To Height - 1
       Particles((y + 
    1) * Width - 1) = ROCK
       Particles(y * Width + 
    1) = ROCK
    Next
    For x = 0 To Width - 1
       Particles ((Height - 
    1) * Width + x) = ROCK
       Particles (x) = ROCK
    Next
    This way there are less edge cases to deal with.

    So where was the bug?

    With the Eraser feature. It didn't check for the edges and could have erased the borders themselves. This feature is the only feature that overwrites other types of particles.
    This caused the sand particles to fall outside of the BitmapCreator and even outside of the phone in some cases. The fix is to restrict the erasing position. It was added to AddParticles sub.
     
  10. koaunglay

    koaunglay Member Licensed User

    Please! Why can't I test this project?
    Help

    Code:
    *** Service (starter) Create ***
    ** 
    Service (starter) Start **
    ** 
    Activity (main) Create, isFirst = true **
    java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.DynamicBuilder.build(DynamicBuilder.java:
    21)
        at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayoutHelper(LayoutBuilder.java:
    349)
        at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayoutHelper(LayoutBuilder.java:
    454)
        at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:
    148)
        at anywheresoftware.b4a.objects.PanelWrapper.LoadLayout(PanelWrapper.java:
    134)
        at anywheresoftware.b4a.objects.B4XViewWrapper.LoadLayout(B4XViewWrapper.java:
    247)
        at b4a.example.game._initialize(game.java:
    298)
        at b4a.example.main._activity_create(main.java:
    342)
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    191)
        at b4a.example.main.afterFirstLayout(main.java:
    104)
        at b4a.example.main.access$
    000(main.java:17)
        at b4a.example.main$WaitForLayout.run(main.java:
    82)
        at android.os.Handler.handleCallback(Handler.java:
    754)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    163)
        at android.app.ActivityThread.main(ActivityThread.java:
    6342)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    880)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    770)
    Caused by: java.lang.RuntimeException: 
    Font asset not found b4x_fontawesome.otf
        at android.graphics.Typeface.createFromAsset(
    Typeface.java:206)
        at anywheresoftware.b4a.objects.TextViewWrapper.getTypeface(TextViewWrapper.java:
    155)
        at anywheresoftware.b4a.objects.TextViewWrapper.build(TextViewWrapper.java:
    183)
        at anywheresoftware.b4a.objects.LabelWrapper.build(LabelWrapper.java:
    36)
        ... 
    21 more
    game_initialize (java line: 
    298)
    java.lang.RuntimeException: java.lang.RuntimeException: Object should first be initialized (
    Label).
    Did you forget 
    to call Activity.LoadLayout?
        at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:
    170)
        at anywheresoftware.b4a.objects.PanelWrapper.LoadLayout(PanelWrapper.java:
    134)
        at anywheresoftware.b4a.objects.B4XViewWrapper.LoadLayout(B4XViewWrapper.java:
    247)
        at b4a.example.game._initialize(game.java:
    298)
        at b4a.example.main._activity_create(main.java:
    342)
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    191)
        at b4a.example.main.afterFirstLayout(main.java:
    104)
        at b4a.example.main.access$
    000(main.java:17)
        at b4a.example.main$WaitForLayout.run(main.java:
    82)
        at android.os.Handler.handleCallback(Handler.java:
    754)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    163)
        at android.app.ActivityThread.main(ActivityThread.java:
    6342)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    880)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    770)
    Caused by: java.lang.RuntimeException: Object should first be initialized (
    Label).
    Did you forget 
    to call Activity.LoadLayout?
        at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:
    50)
        at anywheresoftware.b4a.objects.ViewWrapper.innerInitialize(ViewWrapper.java:
    73)
        at anywheresoftware.b4a.objects.LabelWrapper.innerInitialize(LabelWrapper.java:
    28)
        at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayoutHelper(LayoutBuilder.java:
    435)
        at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayoutHelper(LayoutBuilder.java:
    454)
        at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:
    148)
        ... 
    16 more
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    Which version of B4A are you using?
     
  12. koaunglay

    koaunglay Member Licensed User

    V 8.00
    Thanks
     
  13. Erel

    Erel Administrator Staff Member Licensed User

    It should work. Try to uninstall it, clean the project and run again. If it doesn't work then please start a new thread for further discussion.
     
    koaunglay 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