Android Question debug issue: variable growing larger than expected

HowardTheDuck

Member
Licensed User
Hi, I've run into another hiccup with this project that I hope someone might be able to explain for me. Sorry for the length, but this rather simple program might be hard to understand without it.

I've created an app which consists of a randomly generated maze, a ball that one navigates through the maze, and an endpoint that is the target. The ball remains stationary in the middle of the screen, while tilting the phone causes the the background to move. The idea is to navigate through the maze to the endpoint, at which point another level will start with a new, bigger maze.

Most of the functionality seems to be working as intended, however there are some issues with the movement that I haven't been able to figure out. Sometimes the ball gets "stuck" at a point within the maze and won't move at all; other times it will move vertically but not horizontally. The most bizarre bug however, is that sometimes the ball will leave the confines of the maze, which it should not be able to do. I've never seen it leave the maze horizontally, but it will do so vertically; I suppose that is a clue, but it hasn't led me anywhere useful.

Also, because of the ball sometimes being placed outside the maze, when the CurrentTile gets updated with a negative value, it causes a crash. Of course, it shouldn't ever receive a negative value, so this is not the root of the problem, the ball being out of bounds is. That ball is going out of bounds due to LastY growing too large, but I have a hard limit in place to cap it, so I don't understand how it is exceeding that limit.

Each tile of the maze is mapped to MazeMap(x,y) with x and y representing the tile's coordinates, so MazeMap(0,0) would be the upper left tile. This map contains a list with items 0-4 as Boolean, items 0-3 indicating the presence of a boundary wall on the North/East/South/West sides, and item 4 is only used for the maze generation. These boundaries should keep the ball within the maze, but they don't seem to be working right.

There is a second coordinate system in place referred to in the code as LastX and LastY. This keeps track of the ball movement, relative to its starting point. So if those values were 40,-50 it would mean the center of the screen is 40 pixels to the right of, and 50 pixels up from, the center of StartTile.

To help debug this, I've included lines 220 and 221 which should limit the LastY to keep it within the bounds of the maze - but even this is still not working 100%. These lines should not be in the finished app, they are only there to keep the maze within view during debug. The tile boundaries should serve that purpose instead when they are working. There are also some readouts of the orientation sensors displayed for now.

If anyone has any ideas what I'm doing wrong, I'd certainly appreciate the help. The boundaries are being generated correctly or else they wouldn't display correctly, it uses the same MazeMap variables for both.

Thanks in advance, and sorry again for the long post.

B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: aMazeBalls
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
    #BridgeLogger: True
#End Region

'Activity module
Sub Process_Globals
    'This map maps between PhoneSensors and SensorData objects.
    Dim SensorsMap As Map
    Type SensorData (Name As String, ThreeValues As Boolean)
    Public level = 1 As Int
    Public MazeMap(10,10) As List' items in list indicate T/F for presence of wall on current cell 0=N, 1=E, 2=S, 3=W, 4=Visited(T/F)
    Public Timer1 As Timer
    Public FPS = 1000/60 As Long ' set denominator to desired FPS
    Public tiltY, tiltZ As Float
    Public Xdpi,Ydpi, Scale As Float
    Public TileWidth, ScreenHeight, ScreenWidth, BallRadius, WallWidth=1 As Int
    Public LastX = 0, LastY = 0 As Double
    Public StartTile, CurrentTile, EndTile As List
End Sub

Sub Globals
    Private pnlScreen As Panel
    Private cvsScreen As Canvas
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Main")
    If FirstTime Then
        SensorsMap.Initialize
        Dim ps As PhoneSensors 'This object is only used to access the type constants.
        AddSensor(ps.TYPE_ORIENTATION, "ORIENTATION", True)
    End If
    cvsScreen.Initialize(pnlScreen)
    Timer1.Initialize("Timer1",FPS)
    Timer1.Enabled = True
 
    'determine the screen size so it can calculate velocity realistically
    Dim r As Reflector 'requires reflection library
    r.Target = r.GetContext
    r.Target = r.RunMethod("getResources")
    r.Target = r.RunMethod("getDisplayMetrics")
    Xdpi = r.GetField("xdpi")
    Ydpi = r.GetField("ydpi")
    TileWidth = Floor(GetDeviceLayoutValues.Width/10)
    BallRadius = Floor(TileWidth/4)
    ScreenHeight = GetDeviceLayoutValues.Height
    ScreenWidth = GetDeviceLayoutValues.Width
    Scale = GetDeviceLayoutValues.Scale
End Sub

Sub AddSensor(SensorType As Int, Name As String, ThreeValues As Boolean) As SensorData
    Dim sd As SensorData
    sd.Initialize
    sd.Name = Name
    sd.ThreeValues = ThreeValues
    Dim ps As PhoneSensors
    ps.Initialize(SensorType)
    SensorsMap.Put(ps, sd)'ps seems to be an object not a string, why does that work as a key?
End Sub

Sub Activity_Resume
    'Here we start listening for SensorChanged events.
    'By checking the return value we knoe if the sensor is supported.
    For i = 0 To SensorsMap.Size - 1
        Dim ps As PhoneSensors
        Dim sd As SensorData
        ps = SensorsMap.GetKeyAt(i)
        sd = SensorsMap.GetValueAt(i)
        If ps.StartListening("Sensor") = False Then
            Log(sd.Name & " is not supported.")
        End If
    Next
    GameLoop
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    'Stop listening for events.
    For i = 0 To SensorsMap.Size - 1
        Dim ps As PhoneSensors
        ps = SensorsMap.GetKeyAt(i)
        ps.StopListening
    Next
End Sub

Sub Sensor_SensorChanged (Values() As Float)
    tiltY = Values(1)
    tiltZ = Values(2)
    'Z tilt left up to 90, right to -90
    'Y tilt toward me -90, away from me 90
End Sub

Sub GameLoop
    Do While True
        CreateMaze
        'Dim velocX = 0, velocY = 0 As Double
        Dim LastUpdateTime = DateTime.Now As Long
        'Dim LastTiltY = 0, LastTiltZ = 0 As Long
        StartTile.Initialize
        CurrentTile.Initialize
        EndTile.Initialize
        StartTile = DefineStartTile 'origin is midpoint of this tile, which at start is midpoint of screen
        'keep track of movement of ball relative to origin, then calculate what needs displayed based upon those coordinates
        'use precise numbers (not Integers) to track pixel location, then floor for display purposes
        Dim upperYlimit, lowerYlimit As Int 'upper/lower refer to physical location not +/- direction
        upperYlimit = -1*StartTile.Get(1)*TileWidth - TileWidth/2 + WallWidth
        lowerYlimit = (MazeMap.Length - StartTile.Get(1) - 1)*TileWidth + TileWidth/2 - WallWidth
        EndTile = DefineEndTile(StartTile)
        CurrentTile.Add(StartTile.Get(0))
        CurrentTile.Add(StartTile.Get(1))
        Log("initial settings start of gameloop cycle:->" & CurrentTile.Get(0) & " " & CurrentTile.Get(1) & " " & StartTile.Get(0) & " " & StartTile.Get(1))
        'loop while current location <> EndPoint
        Do Until CurrentTile.Get(0) = EndTile.Get(0) And CurrentTile.Get(1) = EndTile.Get(1)
            Sleep(1)
            'there should be a pause button, touching the screen should start/stop the game. it should be paused at the start of a new level
     
            'if tilt Y or Z is not level, calculate where ball would have moved to since last update and place it there
            'for simplification, I am ignoring momentum and friction in calculating ball position
            If tiltY <> 0 Or tiltZ <> 0 Then
                Dim UpdateInterval, deltaX=0, deltaY=0 As Long ', Adjacent=0, Hypotenuse=0
                Dim dirX=1, dirY=1 As Int
                UpdateInterval = DateTime.Now - LastUpdateTime
                'perhaps if UpdateInterval > acceptable, alter it to something reasonable to help shorten distance travelled and smooth motion
                LastUpdateTime = DateTime.Now
                If tiltY <> 0 Then
                    'determine direction of travel
                    If tiltY >0 Then
                        dirY = 1
                    Else
                        dirY = -1
                    End If
                    deltaY = dirY*Floor((tiltY/10)*UpdateInterval)
                End If
                If tiltZ <> 0 Then
                    'determine direction of travel
                    If tiltZ > 0 Then
                        dirX = -1
                    Else
                        dirX = 1
                    End If
                    deltaX = dirX*Floor((tiltZ/10)*UpdateInterval)
                End If
                tiltY = Round(tiltY)
                tiltZ = Round(tiltZ)
'            Log("tiltY: " & tiltY & "tiltZ: " & tiltZ)

                ' *** COLLISION DETECTION ***
                'determine whether ball is capable of moving to desired location and if not, restrict motion as needed
                'to keep this simple, do not allow it to pass more than one tilewidth per loop
                'this will avoid more complex motion calculations and should be sufficient for realism
                'find where ball is currently at, relative to current tile, and how far in each direction it may travel
                Dim OffCenterX, OffCenterY As Int
                OffCenterX = LastX - (TileWidth * (CurrentTile.Get(0) - StartTile.Get(0))) 'X position relative to center of current tile
                OffCenterY = LastY + (TileWidth * (CurrentTile.Get(1) - StartTile.Get(1))) 'note that X & Y are followed by - and +
         
                Log("**************************************")
                Log("CD current tile x,y --> " & CurrentTile.Get(0) & " " & CurrentTile.Get(1))
                Log("tiltZ(x): " & tiltZ & " tiltY: " & tiltY)
                'if no wall, limit is TileWidth, else it is location of wall
                If deltaX > 0 Then
                    'check East wall
                    If MazeMap(CurrentTile.Get(0),CurrentTile.Get(1)).Get(1) = True Then
                        'limit travel in this direction to no further than the wall
                        If OffCenterX + deltaX + BallRadius > TileWidth/2 - (WallWidth+1) Then
                            deltaX = TileWidth/2 - (WallWidth+1) - OffCenterX - BallRadius
                        End If
                    Else
                        'limit travel in this direction to no more than tilewidth
                        If deltaX > TileWidth Then deltaX = TileWidth
                    End If
                Else
                    'check West wall
                    If MazeMap(CurrentTile.Get(0),CurrentTile.Get(1)).Get(3) = True Then
                        'limit travel in this direction to no further than the wall
                        If OffCenterX + deltaX - BallRadius < -1*TileWidth/2 + WallWidth + 1 Then
                            deltaX = WallWidth+1 - TileWidth/2 - OffCenterX + BallRadius
                        End If
                    Else
                        'limit travel in this direction to no more than tilewidth
                        If deltaX < -1*TileWidth Then deltaX = -1*TileWidth
                    End If
                End If
                If deltaY > 0 Then
                    'check South wall
                    If MazeMap(CurrentTile.Get(0),CurrentTile.Get(1)).Get(2) = True Then
                        'limit travel in this direction to no further than the wall
                        If OffCenterY + deltaY + BallRadius > TileWidth/2 - (WallWidth +1) Then
                            deltaY = TileWidth/2 - (WallWidth+1) - OffCenterY - BallRadius
                        End If
                    Else
                        'limit travel in this direction to no more than tilewidth
                        If deltaY > TileWidth Then deltaY = TileWidth
                    End If
                Else
                    'check North wall
                    If MazeMap(CurrentTile.Get(0),CurrentTile.Get(1)).Get(0) = True Then
                        'limit travel in this direction to no further than the wall
                        If OffCenterY + deltaY - BallRadius < -1*TileWidth/2 + WallWidth + 1 Then
                            deltaY = WallWidth + 1 - TileWidth/2 - OffCenterY + BallRadius
                        End If
                    Else
                        'limit travel in this direction to no more than tilewidth
                        If deltaY < -1*TileWidth Then deltaY = -1*TileWidth
                    End If
                End If
                'alter deltaX, deltaY as required
         
         
                'now update the current position of the ball and determine what tile it is in
                LastX = LastX + dirX*deltaX
                LastY = LastY + dirY*deltaY
             
                'remove below after fixing boundary issue
                If LastY > lowerYlimit Then LastY = lowerYlimit
                If LastY < upperYlimit Then LastY = upperYlimit
         
                Dim TileShiftX = 0, TileShiftY = 0 As Int
                TileShiftX = Floor((LastX+(TileWidth/2))/TileWidth)
                TileShiftY = Floor((LastY+(TileWidth/2))/TileWidth)'this is growing too large/small, shifting the CurrentTile out of range and crashing the program
                'this can only happen if LastY is off the maze, meaning I have a North and/or South wall condition incorrect
                CurrentTile.Set(0,StartTile.Get(0)+TileShiftX)
                CurrentTile.Set(1,StartTile.Get(1)+TileShiftY)
                Log("LastX: " & LastX & " deltaX: " & deltaX)
                Log("LastY: " & LastY & " deltaY: " & deltaY)
                Log("StartTile: " & StartTile.Get(0) & " " & StartTile.Get(1))
                Log("TileShiftX,TileShiftY: " & TileShiftX & " " & TileShiftY)
                Log("Reassignment: " & CurrentTile.Get(0) & " " & CurrentTile.Get(1))
            End If
        Loop
        Log("Level up")
        'if current location = EndPoint then increment level and restart GameLoop
        level = level + 1
    Loop
End Sub

Sub CreateMaze
    'define the number of rows and columns
    If level = 1 Then
        'start with a simple 10x10 grid
        Dim Height = 10 As Int
    Else If level = 2 Then
        'now generate a maze big enough to fill the screen vertically, requiring it to scroll horizontally
        Dim Height = 15 As Int
    Else
        'generate a grid of [level 2 height] + (level - 2), square
        Dim Height = 15 + level - 2 As Int
    End If
    Public MazeMap(Height,Height) As List' items in list indicate T/F for presence of wall on current cell 0=N, 1=E, 2=S, 3=W, 4=Visited(T/F)
    Dim visited = 1, currentX = 0, currentY = 0, nextX, nextY As Int
    Dim nextLoc As String
    Dim path As List
    path.Initialize
    path.Add("0,0")
    MazeMap(0,0).Initialize
    MazeMap(0,0).AddAll(Array As Boolean(True,True,True,True,True))
    Do Until visited = Height * Height
        'look up neighboring cells and see which are unvisited
        Dim unvisited As List
        unvisited.Initialize
        For i = -1 To 1
            For j = -1 To 1
                If i + currentX >= 0 And i + currentX < Height Then
                    If j + currentY >= 0 And j + currentY < Height Then
                        'above two lines limit the scope to actual tiles which exist
                        'now further restrict it to only the 4 tiles in the North, East, South, and West directions
                        If i = 0 Or j = 0 Then
                            If MazeMap(i + currentX, j + currentY).IsInitialized Then
                                If MazeMap(i + currentX, j + currentY).Get(4) = False Then
                                    unvisited.Add((i + currentX) & "," & (j + currentY))
                                End If
                            Else
                                unvisited.Add((i + currentX) & "," & (j + currentY))
                            End If
                        End If
                    End If
                End If
            Next
        Next
     
        If unvisited.Size > 0 Then
            'choose one at random
            nextLoc = unvisited.Get(Rnd(0,unvisited.Size))
         
            'make sure there are no walls between current location and nextLoc
            Dim commaLoc As Int
            commaLoc = nextLoc.IndexOf(",")
            nextX = nextLoc.SubString2(0, commaLoc)
            nextY = nextLoc.SubString(commaLoc + 1)
     
            If MazeMap(nextX,nextY).IsInitialized = False Then
                MazeMap(nextX,nextY).Initialize
                MazeMap(nextX,nextY).AddAll(Array As Boolean(True,True,True,True,True))
            End If
            'presence of wall on current cell 0=N, 1=E, 2=S, 3=W, 4=Visited(T/F)
            If nextX = currentX Then
                'remaining in same column, is it up or down?
                If currentY < nextY Then
                    'remove the top wall of current and lower wall of next
                    MazeMap(currentX,currentY).Set(2,False)
                    MazeMap(nextX,nextY).Set(0,False)
                Else
                    'remove the lower wall of current and top wall of next
                    MazeMap(currentX,currentY).Set(0,False)
                    MazeMap(nextX,nextY).Set(2,False)
                End If
            Else
                'remaining in same row, is it to the left or right?
                If currentX > nextX Then
                    'remove the left wall of current and the right wall of next
                    MazeMap(currentX,currentY).Set(3,False)
                    MazeMap(nextX,nextY).Set(1,False)
                Else
                    'remove the right wall of current and the left wall of next
                    MazeMap(currentX,currentY).Set(1,False)
                    MazeMap(nextX,nextY).Set(3,False)
                End If
            End If
     
            'set as visited
            path.Add(nextX & "," & nextY)
            MazeMap(nextX,nextY).Set(4,True)
            visited = visited + 1
        Else
            'There is no where new to go, back up to the previous location and try this again
            path.RemoveAt(path.Size - 1)
            nextLoc = path.Get(path.Size - 1)
            nextX = nextLoc.SubString2(0, commaLoc)
            nextY = nextLoc.SubString(commaLoc + 1)
         
        End If
        currentX = nextX
        currentY = nextY
        nextX = 0'error using Null here
        nextY = 0
    Loop
End Sub

Sub DefineStartTile As List
    'choose a random starting point
    Dim tempList As List
    tempList.Initialize
    tempList.Add(Rnd(0,MazeMap.Length))
    tempList.Add(Rnd(0,MazeMap.Length))
    Return tempList
End Sub

Sub DefineEndTile(x_startpos As List) As List
    'determine what quadrant starting point is in (if any) and place endpoint in a different quadrant
    Dim x1,x2,mid As Int 'this will define the range to select from
    Dim tempList As List
    tempList.Initialize
    mid = Floor(MazeMap.Length/2)
    If x_startpos.Get(0) < mid Then
        x1 = mid
        x2 = MazeMap.Length -1
    Else
        x1 = 0
        x2 = mid
    End If
    tempList.Add(Rnd(x1,x2))
    tempList.Add(Rnd(0, MazeMap.Length))
    Return tempList
End Sub

Sub Timer1_Tick
    'refresh the screen with the current data
    'LastX and LastY tells where the current view is centered relative to the origin
    Private rect1 As Rect
    rect1.Initialize(0dip,0dip,100%x,100%y)
    cvsScreen.DrawRect(rect1,Colors.Black,True,1) 'draw a black background
    'iterate over entire maze cell by cell to determine what is visible and where it should be displayed
    'may wish to put something in here to reduce iteration scope for very large mazes
    For i = 0 To MazeMap.Length - 1
        For j = 0 To MazeMap.Length - 1
            'determine where this tile is relative to starting tile and LastX,LastY
            Dim DistToStartX, DistToStartY As Int
            DistToStartX = (StartTile.Get(0) - i)*TileWidth
            DistToStartY = (StartTile.Get(1) - j)*TileWidth
         
            Dim ULTileX,ULTileY As Double 'x & y coordinates of upper left corner of current tile
            If CurrentTile.Get(0) <> StartTile.Get(0) Then
                ULTileX = 0 - (TileWidth/2) - DistToStartX - LastX'coordinates relative to center of screen
            Else
                ULTileX = 0 - DistToStartX - LastX
            End If
            If CurrentTile.Get(1) <> StartTile.Get(1) Then
                ULTileY = 0 + (TileWidth/2) + DistToStartY - LastY
            Else
                ULTileY = 0 + DistToStartY - LastY
            End If
            'the above may have produced fractional numbers, floor everything so we can use it for pixel display
            ULTileX = Floor(ULTileX)
            ULTileY = Floor(ULTileY)
         
            'Log(ULTileX & " " & ULTileY & " " & LastX  & " " & LastY)
            'the upper left corner of this tile's coordinates are known; check whether any of this tile is visible
            If ULTileX >= (-1*(Floor(ScreenWidth/2))-TileWidth) And ULTileX < Floor(ScreenWidth/2) Then 'if any of the X coordinates are visible
                If ULTileY <= (Floor(ScreenHeight/2) + TileWidth) And ULTileY > -1*(Floor(ScreenHeight/2)) Then 'if any of the Y coordinates are visible
'                    Log("Draw tile")
                    'draw this tile's features
                    'determine the coordinates of the 4 visible corners of this tile
                    Dim ULX, ULY, URX, URY, LLX, LLY, LRX, LRY As Int
                    If ULTileX + Floor(ScreenWidth/2) < 0 Then
                        ULX = 0'truncate, tile begins to the left of the screen
                    Else
                        ULX = ULTileX + Floor(ScreenWidth/2)
                    End If
                 
                    If ULTileY - Floor(ScreenHeight/2) > 0 Then
                        ULY = 0'truncate, tile begins above the screen
                    Else
                        ULY = Floor(ScreenHeight/2) - ULTileY
                    End If
                 
                    If ULTileX + TileWidth + Floor(ScreenWidth/2) > ScreenWidth Then
                        URX = ScreenWidth'truncate, tile extends past the right of the screen
'                        Log("used ScreenWidth: " & ScreenWidth)
                    Else
                        URX = ULTileX + TileWidth + Floor(ScreenWidth/2)
'                        Log("all visible: " & URX)
                    End If
                 
                    If ULTileY - Floor(ScreenHeight/2) > 0 Then
                        URY = 0'truncate, tile begins above the screen
                    Else
                        URY = Floor(ScreenHeight/2) - ULTileY
                    End If
                 
                    If ULTileX + Floor(ScreenWidth/2) < 0 Then
                        LLX = 0 'truncate, tile begins to the left of the screen
                    Else
                        LLX = ULTileX + Floor(ScreenWidth/2)
                    End If
                 
                    If ULTileY - TileWidth < -Floor(ScreenHeight/2) Then
                        LLY = ScreenHeight'truncate, tile lies partially below screen
                    Else
                        LLY = Floor(ScreenHeight/2) - ULTileY + TileWidth
                    End If
                 
                    If ULTileX + TileWidth + Floor(ScreenWidth/2) > ScreenWidth Then
                        LRX = ScreenWidth'truncate, tile extends past the right of the screen
                    Else
                        LRX = ULTileX + TileWidth + Floor(ScreenWidth/2)
                    End If
                 
                    If ULTileY - TileWidth < -1*(Floor(ScreenHeight/2)) Then
                        LRY = ScreenHeight'truncate, tile lies partially below screen
                    Else
                        LRY = Floor(ScreenHeight/2) - ULTileY + TileWidth
                    End If
                 
'                    Log(ULX & " " & ULY & " " & URX & " " & URY & " " & LLX & " " & LLY & " " & LRX & " " & LRY)
                 
                    'coordinates are defined above, draw the tile
                    Private Tile As Rect
                    Tile.Initialize(ULX,ULY,LRX,LRY)
                    cvsScreen.DrawRect(Tile,Colors.White,True,0)
                 
                    'now draw any required boundary lines on this tile
                    'need to test whether these boundaries are supposed to be visible
                    If MazeMap(i,j).Get(0) Then
                        'North wall is True
                        Private North As Rect
                        North.Initialize(ULX,ULY,URX,URY-WallWidth)
                        cvsScreen.DrawRect(North,Colors.Black,True,0)
                    End If
                    If MazeMap(i,j).Get(1) Then
                        'East wall is True
                        Private East As Rect
                        East.Initialize(URX-WallWidth,URY,LRX,LRY)
                        cvsScreen.DrawRect(East,Colors.Black,True,0)
                    End If
                    If MazeMap(i,j).Get(2) Then
                        'South wall is True
                        Private South As Rect
                        South.Initialize(LLX,LLY+WallWidth,LRX,LRY)
                        cvsScreen.DrawRect(South,Colors.Black,True,0)
                    End If
                    If MazeMap(i,j).Get(3) Then
                        'West wall is True
                        Private West As Rect
                        West.Initialize(ULX,ULY,ULX+WallWidth,LLY)
                        cvsScreen.DrawRect(West,Colors.Black,True,0)
                    End If
                    If EndTile.Get(0) = i And EndTile.Get(1) = j Then
                        'draw the goal
                        cvsScreen.DrawCircle(ULX + TileWidth/2, ULY - TileWidth/2, TileWidth/2 - WallWidth, Colors.Green,True,0)
                        cvsScreen.DrawCircle(ULX + TileWidth/2, ULY - TileWidth/2, TileWidth/3 - WallWidth, Colors.Black,True,0)
                    End If
                End If
            End If
        Next
    Next
    'draw a ball in the center of the screen
    cvsScreen.DrawCircle(ScreenWidth/2,ScreenHeight/2,BallRadius,Colors.Red,True,0)
    cvsScreen.DrawText(tiltZ, 50,50,Typeface.DEFAULT,12,Colors.Magenta,"LEFT")
    cvsScreen.DrawText(tiltY, 50,100,Typeface.DEFAULT,12,Colors.Magenta,"LEFT")
 
    pnlScreen.Invalidate
End Sub
 

Attachments

Last edited:

Syd Wright

Well-Known Member
Licensed User
whoops, hope this helps. added a .zip of the project to the first post. thanks Syd!
This game certainly has potential. I recognize the problems you describe. It is not just one problem that needs to be resolved but probably half a dozen (non-related) issues. Also, on my device the whole maze stutters (rapid sideways movements) when the red ball gets close to a wall and also the ball often just seems to ignore the maze walls. I'll take a closer look tomorrow.
 

HowardTheDuck

Member
Licensed User
Thanks Syd, I'm seeing the same issues that you described including the stuttering, although it was doing it vertically for me.
 

Syd Wright

Well-Known Member
Licensed User
Thanks Syd, I'm seeing the same issues that you described including the stuttering, although it was doing it vertically for me.
A couple of initial observations:
1. You initialize Xdpi and Ydpi (using Reflector) but don't use these variables anywhere.
2. Also there is a lot of code inside Timer1. I am wondering whether FPS=1000/60=16.6 msec is enough to complete all this code. At the same time your Gameloop is also doing quite a lot...
3. Isn't it an idea to drop timer1 and do the screen refresh stuff in the gameloop? (I have not yet fully understood how everything works..).
 
Last edited:

HowardTheDuck

Member
Licensed User
A couple of initial observations:
1. You initialize Xdpi and Ydpi (using Reflector) but don't use these variables anywhere.
2. Also there is a lot of code inside Timer1. I am wondering whether FPS=1000/60=16.6 msec is enough to complete all this code. At the same time your Gameloop is also doing quite a lot...
3. Isn't it an idea to drop timer1 and do the screen refresh stuff in the gameloop? (I have not yet fully understood how everything works..).
1. Those should be removed. It is a remnant of old code from when I was doing things differently.
2. I don't think there is any need for the FPS to be that high, it was an arbitrary starting point. Yes, there is a lot there, but it's that Do Until loop which contains the majority of the game play, and that is mostly basic math and if/then statements. The FPS can be lessened if need be.
3. Yes I would have no objection to doing that. I separated the display from the gameloop code mainly because I developed the gameloop first and added the display later. If it needs combined for efficiency, I think that can be done without much trouble.

Any other questions please ask. Thank you!
 

Syd Wright

Well-Known Member
Licensed User
Any other questions please ask. Thank you!
Yes indeed one principle question: Why are you making the entire maze field roll? Wouldn't it be esthetically better to keep the maze fixed (and fill the entire screen with it) and in stead let the red ball roll?
 

HowardTheDuck

Member
Licensed User
Yes indeed one principle question: Why are you making the entire maze field roll? Wouldn't it be esthetically better to keep the maze fixed (and fill the entire screen with it) and in stead let the red ball roll?
The idea is that once the maze begins to grow significantly larger than the screen, it will increase the difficulty of play because much of the maze will be hidden from view. i.e. try solving a large maze while looking through a tiny portal.
 

Syd Wright

Well-Known Member
Licensed User
A couple more observations:
1. Why is the Createmaze sub part of the Gameloop? Surely you only need to generate a maze once.
I would move Createmaze to Activity_Resume, just before calling Gameloop.

2. A crash occurs when the CurrentTile() variables reach the value 10, which is beyond the list array length.
It happens in the "'check West wall" code. A temporary solution could be to use try / catch / end try (surrounding the four wall checks). That works (I tried it).

3. There must be an error in the routine that checks for walls in each tile. It often "sees" walls when there aren't any and also often simply ignores walls. I can't (yet) see where the problem lies.

4. The stutter is probably caused by pushing the maze back to a position whereby the ball is relocated to the middle of a tile (in stead of letting the ball cling to a maze wall).

5. You could still consider keeping the maze fixed and in stead let the ball role. For large mazes, place a panel over the maze with gesture detection such that the user can manually move the maze (when the ball is near the edges or out of sight). Just a thought.

6. The whole Timer1 stuff is not necessary if you place the maze on top of a Panel (which you move over a black Activity background).

7. You might want to take Erel's advice (above), but that probably means that you will have to start almost from scratch.
 
Last edited:

HowardTheDuck

Member
Licensed User
A couple more observations:
1. Why is the Createmaze sub part of the Gameloop? Surely you only need to generate a maze once.
I would move Createmaze to Activity_Resume, just before calling Gameloop.
Actually, it needs to generate a new maze every time a level is completed. Keep in mind GameLoop consists of nested loops; the first loop which contains the call to Createmaze, initializes the start and end points, and the level up at the end. Within that loop is another Do Until loop which contains the collision detection. [EDIT] - the nested loop with collision detection is not exited until the level is complete.

2. A crash occurs when the CurrentTile() variables reach the value 10, which is beyond the list array length.
It happens in the "'check West wall" code. A temporary solution could be to use try / catch / end try (surrounding the four wall checks). That works (I tried it).
Hmm, OK, thank you. Sounds like an indexing problem.

3. There must be an error in the routine that checks for walls in each tile. It often "sees" walls when there aren't any and also often simply ignores walls. I can't (yet) see where the problem lies.
This could be related to the above, if the index is off by 1. Maybe I wrote something expecting it to begin the count at 1 rather than 0.

4. The stutter is probably caused by pushing the maze back to a position whereby the ball is relocated to the middle of a tile (in stead of letting the ball cling to a maze wall).
I don't recall having any code in there which was intended to push the ball to the middle of the tile, except at start. If that's what it is doing, I'm pretty sure it's an error.

5. You could still consider keeping the maze fixed and in stead let the ball role. For large mazes, place a panel over the maze with gesture detection such that the user can manually move the maze (when the ball is near the edges or out of sight). Just a thought.
That's actually a good idea. It would make the game significantly easier, which might be a nice option if this method proves too difficult to play.

6. The whole Timer1 stuff is not necessary if you place the maze on top of a Panel (which you move over a black Activity background).
I'm not sure what you mean, it's already on a Panel, pnlScreen.

7. You might want to take Erel's advice (above), but that probably means that you will have to start almost from scratch.
To be honest I barely glanced at it, I'll give it a more thorough look today. I have a tendency to reinvent the wheel, probably a carryover from when I learned to program in a 3.5k RAM environment on a very different flavor of BASIC :)

Thank you for all the insights & advice Syd. I'll keep this thread updated when I find something relevant.
 
Last edited:
Top