Android Question 3D FPS maze for android

MasterGy

Member
Hello !

How could I draw a texture instead of the lines?

B4A basic to android:
 #Region Activity Attributes
#FullScreen: True
#IncludeTitle: False

  #ApplicationLabel: Tóth Gyula (2024Hungary)
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: landscape
    #CanInstallToExternalStorage: false
#End Region

Sub Process_Globals
    
    Dim CanvasView As B4XCanvas
    Private xui As XUI
    Dim map_dat(19) As Float
    Dim map(99, 99) As Int
    Dim map_p(9999, 9) As Float
    Dim map_pc As Int
    Dim map_s(9999, 9) As Int
    Dim map_sc As Int
    Dim map_l(9999, 9) As Int
    Dim map_lc As Int
    Dim cam(19) As Float
    
    Dim temp As Float
    
    Dim roti(2) As Float
    Dim tp(2,2) As Float
    Dim maze(9) As Int
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)

    maze(0) = 50
    Log("legelejese")
    createtrack (maze(0), maze(0), .1)

    
    Activity.LoadLayout("Layout")


    Dim TouchPanel As Panel
    TouchPanel.Initialize("TouchPanel")
    Activity.AddView(TouchPanel, 0, 0, 100%x, 100%y)
    CanvasView.Initialize(Activity)


    cam(0) = maze(0)/2
    cam(1) = maze(0)/2
    cam(2) = .7
    cam(8) = Activity.Width    / 2
    cam(9) = Activity.Height / 2
    cam(7) = 12 'latohatar
    cam(6) = cam(7) * cam(7)
    cam(5) = 1 / cam(7)


 


    Log ("kezd")
    create_textsq

    Log("kreacio")
    Dim disx As Float
    Dim vastag As Float
    Dim grey As Int

    Dim lepes As Float
    Dim ang As Float
    Dim vx As Float
    Dim vy As Float
    Dim vz As Boolean
    Dim vx2 As Int
    Dim vy2 As Int
    Dim cyclebit As Int
    Dim doles(2) As Float
    cam(3) = 100
    Do While True
        cyclebit = cyclebit +1
    
        tp(1,0) = tp(1,0)*.82
        tp(1,1) = tp(1,1)*.82
        
        cam(3) = cam(3)+tp(1,0)*.004

        'cam(0) = cam(0) + Sin(cam(3)) *  -tp(1,1)*.003
        'cam(1) = cam(1) + Cos(cam(3)) *  -tp(1,1)*.003



        vz = False
        For t1 = 0 To 80
            For t2 = 0 To 1
                ang = cam(3) + t1 * (t2 * 2 - 1) * (3.1415 / 180)
                lepes = -tp(1,1) * .007 / 80 * (80 - t1)
                vx = cam(0) + Sin(ang) * lepes
                vy = cam(1) + Cos(ang) * lepes
            
                
                vx2 = vx+0
                vy2 = vy+0
            
                If map(vx2, vy2) = 0 Then
                    cam(0) = vx
                    cam(1) = vy
                    vz = True
                End If
                
                If vz Then Exit
            
            Next
            
            If vz Then Exit
        Next
        
    

        doles(0) = (doles(0) +tp(1,0)*.005)*.9
        If Abs( doles(0))>1 Then doles(0) = sgna(doles(0))
        cam(4) = doles(0)*.15
        
        doles(1) = (doles(1) +tp(1,1)*.005)*.9
        If Abs( doles(1))>1 Then doles(1) = sgna(doles(1))
        cam(10) = -doles(1)*.2-.2
 
 
 
 
        rot

        For t = 0 To map_lc - 1
            If map_p(map_l(t, 0), 5) = 1 And map_p(map_l(t, 1), 5) =1 Then
                disx = (map_p(map_l(t, 0), 6) + map_p(map_l(t, 1), 6))*.5
                grey = 255-255 * disx
                If grey<0 Then grey =0
                If grey>255 Then grey = 255
    
                vastag = interpolate(.2,11,disx)
                CanvasView.Drawline(map_p(map_l(t, 0), 3),map_p(map_l(t, 0), 4),map_p(map_l(t, 1), 3),map_p(map_l(t, 1), 4),Colors.RGB(grey,grey,grey),vastag)
      
            End If
        Next

    
        CanvasView.Invalidate
        Sleep(10)
        CanvasView.ClearRect(CanvasView.TargetRect)
    

    Loop

    Log("vege")
End Sub

Sub TouchPanel_Touch (Action As Int, X As Float, Y As Float)
    Dim t5(10) As Float
    
    t5(9) = 30 'maximalis tavolsag/sebesseg
    If Action = Activity.ACTION_MOVE  Then
        t5(0) = tp(0,0)-X
        t5(1) = tp(0,1)-Y
        t5(2) = ATan2(t5(0),t5(1))
        t5(3) = Sqrt(t5(0)*t5(0)+t5(1)*t5(1))
        If t5(3) > t5(9) Then t5(3) = t5(9)
        t5(4) = 160 / t5(9) * t5(3)
        tp(1,0) = interpolate(tp(1,0),-Sin(t5(2))*t5(4),.91)
        tp(1,1) = interpolate(tp(1,1),-Cos(t5(2))*t5(4),.91)
    End If

    If Action = Activity.ACTION_DOWN Then
        tp(0,0) = X :tp(0,1) = Y
        
    
        
    
    End If
    tp(0,0) = interpolate(tp(0,0),x,.95)
    tp(0,1) = interpolate(tp(0,1),y,.95)
    
    
    
 
End Sub

Sub interpolate(a As Float, b As Float, x As Float) As Float
    Return a + (b - a) * x
End Sub

Sub rot
    Dim x2 As Float
    Dim y2 As Float
    Dim z2 As Float
    Dim x As Float
    Dim y As Float

    Dim dis As Float
    Dim temp As Float
    For t = 0 To map_pc - 1
        x2 = map_p(t, 0) - cam(0)
        y2 = map_p(t, 1) - cam(1)
        z2 = map_p(t, 2) - cam(2)
        
        rotate_2d (x2, y2, cam(3))
        x2 = roti(0)
        y2 = roti(1)
        
        rotate_2d (z2, y2, cam(10))
        z2 = roti(0)
        y2 = roti(1)
        
        
        
        map_p(t, 5) = 0
        If Abs(y2) < cam(7) Then
            If Abs(x2) < cam(7) Then
                dis = (x2 * x2 + y2 * y2)
                If dis < cam(6) Then
                    If y2 > 0 Then
                        temp = 800 / y2
                        x = x2 * temp
                        y = z2 * temp
                        
                        rotate_2d (x,-y,cam(4))
                        
                        map_p(t, 3) = roti(0) + cam(8)
                        map_p(t, 4) = roti(1) + cam(9)
                        
                        
                        map_p(t, 5) = 1
                        map_p(t, 6) = 1 - cam(5) * Sqrt(dis)
                    End If
                End If
            End If
        End If
    Next

End Sub





Sub rotate_2d (x As Float, y As Float, ang As Float)
    Dim x1 As Float
    Dim y1 As Float
    x1 = x * Cos(ang) - y * Sin(ang)
    y1 = x * Sin(ang) + y * Cos(ang)
    roti(0) = x1: roti(1) = y1
End Sub
    
    



Sub add_sq (a As Int, b As Int, c As Int, d As Int ,plan As Int)
    
    map_s(map_sc, 0) = a
    map_s(map_sc, 1) = b
    map_s(map_sc, 2) = c
    map_s(map_sc, 3) = d
    map_s(map_sc,4) = plan
    map_sc = map_sc + 1
    add_line (a, b)
    add_line (a, c)
    add_line (c, d)
    add_line (b, d)

    If plan = 0 Or plan = 1 Then
        add_line (a,d)
        add_line (b,c)
    End If

End Sub

Sub add_line (a As Int, b As Int)
    Dim find As Int
    find = -1
    If map_lc > 0 Then
        For t = 0 To map_lc - 1
            If (map_l(t, 0) = a And map_l(t, 1) = b) Or (map_l(t, 0) = b And map_l(t, 1) = a) Then find = t
        Next
    End If

    If find = -1 Then
        map_l(map_lc, 0) = a
        map_l(map_lc, 1) = b
        map_lc = map_lc + 1
    End If

End Sub



Sub add_point (x As Float, y As Float, z As Float) As Int
 
    Dim find As Int
    Dim apv As Int
    apv = 0
    find = -1
    If map_pc > 0 Then
        For t = 0 To map_pc - 1
            If map_p(t, 0) = x And map_p(t, 1) = y And map_p(t, 2) = z Then find = t
        Next
    End If
    apv = find

    If find = -1 Then
        map_p(map_pc, 0) = x
        map_p(map_pc, 1) = y
        map_p(map_pc, 2) = z
        apv = map_pc
        map_pc = map_pc + 1
    End If
        
 
    Return apv


End Sub


Sub createtrack (qx As Int, qy As Int, qf As Float)
    Dim rt As Int
    Dim temp1 As Int
    Dim d(5) As Int
    
    map_dat(0) = qx
    map_dat(1) = qy
    map_dat(2) = qf

    For x = 0 To qx - 1: For y = 0 To qy - 1: map(x, y) = 1: Next: Next
        d(0) = map_dat(0) / 2
        d(1) = map_dat(1) / 2
        temp1 = 0
        
        Do While temp1< (qx*qy*qf)
            If map(d(0), d(1)) = 1 Then temp1 = temp1+1
            map(d(0), d(1)) = 0
            rt = Rnd(0,4)
            d(Bit.And(rt,1)) = d(Bit.And(rt, 1)) + (Bit.And(rt,2) - 1)
            
            If d(0) = 1 Or d(0) = map_dat(0)-1 Or d(1) = 1 Or d(1) = map_dat(1)-1 Then
                d(0) = map_dat(0) / 2
                d(1) = map_dat(1) / 2
            End If
            
        Loop
    End Sub


Sub create_textsq
    
    For x = 0 To map_dat(0) - 1
        For y = 0 To map_dat(1) - 1
    
            'roof / floor draw
            add_sq (add_point(x, y, map(x, y)), add_point(x + 1, y, map(x, y)), add_point(x, y + 1, map(x, y)), add_point(x + 1, y + 1, map(x, y)),2)
    
            'wall draw
            If map(x, y) = 0 Then
                If map(x - 1, y) = 1 Then create_textsq2 (x, y, x, y+1, 0)
                If map(x + 1, y) = 1 Then create_textsq2 (x+1, y, x+1, y+1, 0)
                If map(x, y - 1) = 1 Then create_textsq2 (x, y, x+1, y, 0)
                If map(x, y + 1) = 1 Then create_textsq2 (x, y+1, x+1, y+1, 0)
            End If
        Next
    Next
End Sub

Sub create_textsq2 (x1 As Int, y1 As Int, x2 As Int, y2 As Int , plan As Int)
    Dim p(4) As Int
    p(0) = add_point(x1, y1, 0)
    p(1) = add_point(x1, y1, 1)
    p(2) = add_point(x2, y2, 1)
    p(3) = add_point(x2, y2, 0)
    add_sq (p(0), p(1), p(3), p(2),plan )
End Sub

Sub sgna (x As Float) As Int
    Dim y As Int
    y = 0
    If x<0 Then y = -1
    If x>1 Then y = 1
    
    Return y

End Sub
 

William Lancee

Well-Known Member
Licensed User
Longtime User
Thanks for posting the project.
It looks very interesting and it is amazing that you can do that kind of visualization with such a few lines of code.

It would take me quite a while to figure out how it is done.
You have matrices of indexes to matrices of indexes to matrices of points.

There is only one place where you draw anything, and it is a line - but it could be a diagonal or a boundary of a square.
Also when it is drawn, I can't see how to know the 3D square the line belongs to. If I did then I could fill the 3D square with a texture, using the B4XPath object.

In any case, there could be other community members who would know better than me. So please step in.
I'll track future postings.
 
Upvote 0

MasterGy

Member
Thanks for posting the project.
It looks very interesting and it is amazing that you can do that kind of visualization with such a few lines of code.

It would take me quite a while to figure out how it is done.
You have matrices of indexes to matrices of indexes to matrices of points.

There is only one place where you draw anything, and it is a line - but it could be a diagonal or a boundary of a square.
Also when it is drawn, I can't see how to know the 3D square the line belongs to. If I did then I could fill the 3D square with a texture, using the B4XPath object.

In any case, there could be other community members who would know better than me. So please step in.
I'll track future postings.
I'm glad you like it ! I am very curious how to solve texture drawing.
I prepared the program so that the point of the texture can be read later.
map_sc - this variable shows how many squares there are in total

map_sc (index, data)
index - from 0 to map_sc-1
dates:
0: 1st point index
1: 2nd point index
2: 3rd point index
3: point 4 index
4. if 0 or 1, then wall . if 2, then roof or floor

and the point index points to the map_p array, which returns the coordinates of the points
map_p(index,data)
dates:
0,1,2 : original XYZ coordinate points
3,4: coordinate points after rotation XY. this is the position of the flat points on the screen
5: if 1, the dot is visible. If it is 0, then the point is behind us, it is pointless to deal with it
6: location in the horizon. if 0, then it is directly in front of us, if 1, then on the horizon. all visible points will be located between 0 and 1, with this I can proportion the gray scale, thus the spatial effect

so ! for example, the square with index 10 is after rotation

The value of X1
map_p(map_s(10,0),3)

value of y2
map_p(map_s(10,1),4)


Lines are stored in another array. if there is a texture, the line drawing can be turned off.

I trust that it is easy that way, and that the language translation does not make it unintelligible.
 
Last edited:
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
"Easy" is relative.
Let's start with something "simple"

B4X:
    'these are just corners of a 2D square (p is an instance of my Point class) - but they can be corners of a transformed square (trapezoid)
    Dim p0 As Point = p.XY(0, 0)
    Dim p1 As Point = p.XY(100, 0)
    Dim p2 As Point = p.XY(100, 100)
    Dim p3 As Point = p.XY(0, 100)
    Dim cv As B4XCanvas = editCv
    'transformed square you want colored
    Dim path As B4XPath
    path.initialize(p0.X, p0.Y)
    path.LineTo(p1.X, p1.Y)
    path.LineTo(p2.X, p2.Y)
    path.LineTo(p3.X, p3.Y)
    cv.DrawPath(path, xui.Color_Red, True, 0)

This just colors squares (trapezoids) - this color codes the target areas . If you want a random texture, then you can copy the pixels to a BitmapCreator object.
In that object you can scan the pixels for the color code and change them to a texture (for example randomly turn them into another color)
Then use cv to draw the resultant bitmap.

To assign images to the trapezoids more work is needed.
You need a separate BitmapCreator object which holds the image.
Then instead of above random perturbation of colors, transfer the image to the color-coded trapezoid proportionally filling the trapezoid.

Caution: at some point the device's processor might not be able to keep up with the animation.
 
Upvote 0

MasterGy

Member
Disaster! The pixel-by-pixel drawing is unfortunately too slow, but thanks for the idea!
First I tried 'ThreeD', which worked for cubes, but not for surfaces. does not draw a texture on a triangle. After that, I tried to draw triangles from 'Agraham''s opengl patterns, but I feel like I'm slowly going crazy. I'm at a loss for now. I have patience, but little expertise in object-oriented programming. I got used to the basic language in 25 years. I just don't understand it all! :(
Moreover, the b4a debug mode fails when using opengl. the application exits on the phone, there is no message. Where to from here?
 
Upvote 0

MasterGy

Member
Thank you for the suggestions! I was very surprised at how surprisingly fast the pixel rendering is! Unfortunately, this wouldn't have worked because there are so many textures (an amount spanning multiple screens), and even though they overlap each other, I would have had to draw them all point by point, moving forward from the back, and whatever is visible, is visible.

My desire has been fulfilled. I was hesitant about OpenGL, I avoided it as much as possible. But thanks to the great sample programs I found here, I managed to patch together what I needed. It wasn't easy, many times I almost gave up, but in the end, I succeeded. It works beautifully. Fast, and later I can also add lighting effects. I drew a sphere over the labyrinth, filled with a sky texture.

I would like to express my gratitude through this:


Thanks everybody !
 

Attachments

  • opengl_fps_to_forum.zip
    506.2 KB · Views: 27
Upvote 0
Top