Android Example 3D Interactive Starfield using only the Core library

Discussion in 'Tutorials & Examples' started by wonder, Dec 31, 2014.

  1. wonder

    wonder Expert Licensed User

    Hey guys!!

    I took this HTML5 example and adapted it to B4A.

    I hope the code is self-explanatory, if not, I'll be here to help.
    Once again I'm using panels, but you can use whatever objects you want to represent the stars. I recommend, as always, LibGDX.
    #Region  Project Attributes

    #ApplicationLabel: 3D Starfield Example
    #VersionCode: 1
    'SupportedOrientations possible values: unspecified, landscape or portrait.
        #SupportedOrientations: Landscape
    #CanInstallToExternalStorage: False
    #End Region

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

    Sub Process_Globals
    Dim Main_Engine As Timer
    End Sub

    Sub Globals
            Dim number_of_stars = 64 As Float
    Dim star_speed = 0.4 As Float

    Dim max_depth = 32 As Float
    Dim star_x(number_of_stars) As Float
    Dim star_y(number_of_stars) As Float
    Dim star_z(number_of_stars) As Float
    Dim smin = -25 As Int
    Dim smax =  26 As Int

    Dim star(number_of_stars) As Panel

    Dim centerX = 50%x As Float
    Dim centerY = 50%y As Float

    Private TouchScreen As Panel
    End Sub

    Sub Activity_Create(FirstTime As Boolean)

    For i = 0 To (number_of_stars - 1)
    'Initialize 3D Coordinates
                star_x(i) = Rnd(smin, smax)
                star_y(i) = 
    Rnd(smin, smax)
                star_z(i) = 
    Rnd(1, max_depth)

    'Initialize Panels
    Activity.AddView(star(i), 0000)

        Main_Engine.Enabled = 

        TouchScreen.Left = 
        TouchScreen.Top = 
        TouchScreen.Width = 
        TouchScreen.Height = 

    End Sub

    Sub Activity_Resume
        Main_Engine.Enabled = 
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        Main_Engine.Enabled = 
    End Sub

    Sub Main_Engine_Tick
    10, centerX, centerY, star_speed)
    End Sub

    Sub Starfield(star_size As Float, x_center As Float, y_center As Float, speed As Float)
    For i = 0 To (number_of_stars - 1)

    'Moves the star in the z-axis
                      star_z(i)= star_z(i) - speed

    'Resets the star position once it's offscreen
                      If star_z(i) <= 0 Then
                             star_x(i) = 
    Rnd(smin, smax)
                             star_y(i) = 
    Rnd(smin, smax)
                             star_z(i) = max_depth
    End If

    'Black magic happens here, can't explain this part (3D to 2D conversion), I only know it works
                      Dim k  = 128 / star_z(i) As Float
    Dim px = star_x(i) * k + x_center As Float
    Dim py = star_y(i) * k + y_center As Float

    'Display the star as long as its 2D position is on screen
                      If px >= 0%x AND px <= 100%x AND py >= 0%x AND py <= 100%y Then
    Dim size = (1 - (star_z(i) / 32.0)) * star_size As Float
    Dim shade = (1 - (star_z(i) / 32.0)) * 255 As Float

    'Displaying a single star:
                                'The Aplha level is given by how distant in the z-axis the star is
                                       star(i).Color = Colors.ARGB(shade, 0Rnd(128,192), Rnd(192,255))
    'Set the star size according to the z-axis distance
                                       star(i).Width = size
                                       star(i).Height = size
    'Makes px and py the center of the star
                                       star(i).Left = px - (star(i).Width / 2)
                                       star(i).Top = py - (star(i).Height / 

                        'LibGDX "Sub LG_Render" code example:
                        '    Batch.DrawRegion2(star(i), px - Half_of_the_star_size, py - Half_of_the_star_size, size, size)

    End If
    End Sub

    Sub TouchScreen_Touch (Action As Int, X As Float, Y As Float)
    Select Action
    Case Activity.ACTION_DOWN
                    centerX = X
                    centerY = Y
                    star_speed = star_speed * 

    Case Activity.ACTION_MOVE
                    centerX = X
                    centerY = Y
    Case Activity.ACTION_UP
                    star_speed = star_speed / 
    End Select
    End Sub

    Attached Files:

    Last edited: Dec 31, 2014
  2. Informatix

    Informatix Expert Licensed User

    I didn't examine closely the generated source and I cannot say whether it's really safe to use %x and %y in Globals. But to be sure, I avoid doing it and prefer to use these units only in subs. When the activity has been created and is ready to be used (Activity_Create event), the activity dimensions are not likely to change.
    wonder likes this.
  3. Erel

    Erel Administrator Staff Member Licensed User

    It is safe in Sub Globals.
    Peter Simpson, wonder and Informatix like this.
  4. wonder

    wonder Expert Licensed User

    'Black magic happens here, can't explain this part (3D to 2D conversion), I only know it works
                      Dim k  = 128 / star_z(i) As Float
    Dim px = star_x(i) * k + x_center As Float
    Dim py = star_y(i) * k + y_center As Float
    Any math wizard out there who wants to help me understand this part? :D

    HAPPY NEW YEAR!!!!!!!!!!!!!!!!!!!!!!!!!
  5. sorex

    sorex Expert Licensed User

    k is pseudo depth multiplier.

    it's used as z based offset multiplier multiplied to x & y so you get the depth look.
    (the bigger k gets (positive or negative) the farther from the center it goes thus close to you)

    you can also do it with only sin/cos math and a z counter then it's radial based.
    wonder likes this.
  6. wonder

    wonder Expert Licensed User

    Thanks for the explanation!! But where does the 128 comes from? It's on the original example but I couldn't figure it out.
  7. sorex

    sorex Expert Licensed User

    I bet that source comes from an old 256x256 pixel byte based starfield example.

    that's why you have 128 there, it's half of a byte thus the center value which you divide with the distance so the offset goes from aprox -127 to +127.

    add that to the center value and it's nicely positioned inside the visual area of the 256x256 field.
    RandomCoder and wonder like this.
  8. wonder

    wonder Expert Licensed User

    Sorex, I hearby nominate you my math guru!! :D Thanks!!!
    RandomCoder likes this.
  9. rkwan

    rkwan Member Licensed User


    I am a newbie who is trying to do a 3D scatter plot like this one with matplotlib:-

    I looked into the LibGDX from Informatix before
    but I am curious if it would be easy to add the 3 axis lines into this Starfield example as well please?!

    Thanks in advance!
  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