turns-00053.parquet:12359
b17ea020f065fd036ac38c99
turn 1/1o1-preview-2024-09-12EnglishUnited Kingdom6091 words
degenerate_repetitionAbsentFinal dense release
USER
Option Explicit On
Option Strict On
Imports System.IO
Imports System.Text.Json
Imports System.Text.Json.Serialization
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Media
Imports System.ComponentModel
Imports NAudio.Wave
Imports NAudio.Wave.SampleProviders
Public Class frmGame
#Region " Variables "
Private Const MoveTimerInterval As Integer = 100 ' milliseconds (0.5 seconds)
Private movingBalls As New List(Of MovingBall)()
Private CollectedCoins As Integer = 0
Private playerX As Integer
Private playerY As Integer
Private hasKey As Boolean = False ' To track if the player has collected a key
Private justWarped As Boolean = False ' To prevent immediate re-warping
Public Property RoomFilePath As String
Private SelectedMusic As String
' Constants for grid layout
Private Const INDENT As Integer = 20
Private Const WALL_THICKNESS As Integer = 10
' Variables for grid size
Private SQCOUNTX As Integer
Private SQCOUNTY As Integer
' Variables for square sizes
Private SQSizeX As Integer
Private SQSizeY As Integer
' Variables for wall and floor styles
Private wallsHatchStyle As HatchStyle
Private wallsColor1 As Color
Private wallsColor2 As Color
Private floorsHatchStyle As HatchStyle
Private floorsColor1 As Color
Private floorsColor2 As Color
' Arrays to store walls and items
Private verticalWalls()() As Boolean
Private horizontalWalls()() As Boolean
Private placedItems()() As String
Private verticalWallItems()() As String
Private horizontalWallItems()() As String
Private floorsUseEdgeStyle()() As Boolean
' Image resources
Private imageDictionary As New Dictionary(Of String, Image)
Private animatedImages As New List(Of Image)
' Animation timer
Private animationTimer As Timer
' Flag to indicate when the room data is loaded
Private isRoomDataLoaded As Boolean = False
Private musicPlayer As SoundPlayer
' Paths
Private ReadOnly projectDir As String = GetProjectDirectory()
Private ReadOnly ImagesFolder As String = Path.Combine(projectDir, "Data", "Images")
Private ReadOnly musicFolder As String = Path.Combine(projectDir, "Data", "Music")
Private ReadOnly SFXFolder As String = Path.Combine(projectDir, "Data", "Sound Effects")
' Sound effect files
Private soundEffectFiles As New Dictionary(Of String, String)
' NAudio mixer
Private mixer As MixingSampleProvider
Private waveOut As WaveOutEvent
' Class to represent the simple room data
Public Class SimpleRoomData
Public Property GridSizeX As Integer
Public Property GridSizeY As Integer
' Properties to save colors and styles
Public Property wallsHatchStyleValue As Integer
Public Property wallsColor1Argb As Integer
Public Property wallsColor2Argb As Integer
Public Property floorsHatchStyleValue As Integer
Public Property floorsColor1Argb As Integer
Public Property floorsColor2Argb As Integer
' Arrays to save wall states
Public Property verticalWalls As Boolean()()
Public Property horizontalWalls As Boolean()()
' Arrays to save placed items
Public Property placedItems As PlacedItemData()()
Public Property verticalWallItems As PlacedItemData()()
Public Property horizontalWallItems As PlacedItemData()()
' Arrays to save floor edge styles
Public Property floorsUseEdgeStyle As Boolean()()
' Property to save the selected music
Public Property SelectedMusic As String
' Property to save the level name
Public Property LevelName As String
End Class
' Class to represent a moving ball
Private Class MovingBall
Public Property X As Integer
Public Property Y As Integer
Public Property DeltaX As Integer
Public Property DeltaY As Integer
Public Property Timer As Timer
End Class
#End Region
#Region " Movement "
Private Sub FindPlayerStartPosition()
For x As Integer = 0 To placedItems.Length - 1
If placedItems(x) IsNot Nothing Then
For y As Integer = 0 To placedItems(x).Length - 1
Dim imageKey As String = placedItems(x)(y)
If imageKey = "picStart" Then
playerX = x
playerY = y
' Remove the "picStart" from placedItems
placedItems(x)(y) = Nothing
Exit Sub
End If
Next
End If
Next
End Sub
Private Sub frmGame_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
' Handle movement keys
Dim moved As Boolean = False
Select Case e.KeyCode
Case Keys.Up, Keys.P
moved = AttemptMove("Up")
Case Keys.Down, Keys.L
moved = AttemptMove("Down")
Case Keys.Left, Keys.Z
moved = AttemptMove("Left")
Case Keys.Right, Keys.X
moved = AttemptMove("Right")
End Select
If moved Then
picTest.Invalidate()
End If
End Sub
Private Function AttemptMove(direction As String) As Boolean
Dim deltaX As Integer = 0
Dim deltaY As Integer = 0
Select Case direction
Case "Up"
deltaY = -1
Case "Down"
deltaY = 1
Case "Left"
deltaX = -1
Case "Right"
deltaX = 1
End Select
Dim newX As Integer = playerX + deltaX
Dim newY As Integer = playerY + deltaY
' Check boundaries
If newX < 0 OrElse newX >= SQCOUNTX OrElse newY < 0 OrElse newY >= SQCOUNTY Then
Return False
End If
' Check walls between current and new position
If Not CanMoveTo(newX, newY, deltaX, deltaY) Then
Return False
End If
' Check what's at the new position
Dim targetItem As String = placedItems(newX)(newY)
If String.IsNullOrEmpty(targetItem) Then
' The cell is empty, move the player
playerX = newX
playerY = newY
' Play move sound
PlaySoundEffect("Move")
' After moving, check for warp
CheckForWarp()
Return True
ElseIf targetItem = "picBlock1" Then
' There's a block, attempt to push it
Dim blockMoved As Boolean = AttemptPushBlock(newX, newY, deltaX, deltaY)
If blockMoved Then
' Move the player
playerX = newX
playerY = newY
' Play move sound
PlaySoundEffect("Move")
' After moving, check for warp
CheckForWarp()
Return True
Else
Return False
End If
ElseIf targetItem = "picBlockStopper1" Then
' Player can move onto block stopper, which remains in place
playerX = newX
playerY = newY
' Play move sound
PlaySoundEffect("Move")
' After moving, check for warp
CheckForWarp()
Return True
ElseIf targetItem = "picBall" Then
' Attempt to push the ball
Dim ballMoved As Boolean = AttemptPushBall(newX, newY, deltaX, deltaY)
If ballMoved Then
' Move the player into the ball's original position
playerX = newX
playerY = newY
' Play move sound
PlaySoundEffect("Move")
' After moving, check for warp
CheckForWarp()
Return True
Else
Return False
End If
ElseIf targetItem = "picCoin" Then
' Collect the coin
CollectedCoins += 1
placedItems(newX)(newY) = Nothing
playerX = newX
playerY = newY
' Play coin sound
PlaySoundEffect("Coin")
' Play move sound
PlaySoundEffect("Move")
' After moving, check for warp
CheckForWarp()
Return True
ElseIf targetItem = "picKey" Then
' Collect the key
hasKey = True
placedItems(newX)(newY) = Nothing
playerX = newX
playerY = newY
' Play key pickup sound
PlaySoundEffect("Key") ' Assuming you have a 'Key.wav' sound effect
' Play move sound
PlaySoundEffect("Move")
' After moving, check for warp
CheckForWarp()
Return True
ElseIf targetItem = "picGate" Then
If hasKey Then
' Remove the gate and allow player to move
placedItems(newX)(newY) = Nothing
playerX = newX
playerY = newY
' Play door open sound (assuming you have 'Door Open.wav')
PlaySoundEffect("Door Open")
' Play move sound
PlaySoundEffect("Move")
' Optionally, reset hasKey if the key is one-time use
' hasKey = False
' After moving, check for warp
CheckForWarp()
Return True
Else
' Cannot move onto the gate without the key
Return False
End If
ElseIf targetItem = "picFinish" Then
' Player reaches finish point
playerX = newX
playerY = newY
' Play move sound
PlaySoundEffect("Move")
GameWon()
Return True
ElseIf targetItem = "picWarp" Then
' Move the player onto the warp tile first
playerX = newX
playerY = newY
' Play move sound
PlaySoundEffect("Move")
' Handle warp
HandleWarp()
Return True
Else
' Other items, prevent movement for now
Return False
End If
End Function
Private Sub CheckForWarp()
If placedItems(playerX)(playerY) = "picWarp" AndAlso Not justWarped Then
HandleWarp()
ElseIf placedItems(playerX)(playerY) <> "picWarp" Then
justWarped = False
End If
End Sub
Private Sub HandleWarp()
If Not justWarped Then
' Find the other warp tile
Dim warpPositions As New List(Of Point)
For x As Integer = 0 To placedItems.Length - 1
If placedItems(x) IsNot Nothing Then
For y As Integer = 0 To placedItems(x).Length - 1
If placedItems(x)(y) = "picWarp" Then
warpPositions.Add(New Point(x, y))
End If
Next
End If
Next
' Remove the current warp position from the list
warpPositions.Remove(New Point(playerX, playerY))
If warpPositions.Count = 1 Then
' Set justWarped to True to prevent immediate re-warping
justWarped = True
' Play warp sound
PlaySoundEffect("Warp")
' Move player to the other warp position
playerX = warpPositions(0).X
playerY = warpPositions(0).Y
' After warping, check if the destination is also a warp (to prevent double warp)
CheckForWarp()
Else
' There are not exactly two warps. Handle error.
' MessageBox.Show("Warp error: Exactly two warp tiles are required.")
' You can comment out the error message if desired
End If
End If
End Sub
' Modify the AttemptPushBall function
Private Function AttemptPushBall(ballX As Integer, ballY As Integer, deltaX As Integer, deltaY As Integer) As Boolean
' Check if the ball is already moving
For Each movingBall In movingBalls
If movingBall.X = ballX AndAlso movingBall.Y = ballY Then
' The ball is already moving
Return False
End If
Next
Dim nextX As Integer = ballX + deltaX
Dim nextY As Integer = ballY + deltaY
' Check boundaries for the first move
If nextX < 0 OrElse nextX >= SQCOUNTX OrElse nextY < 0 OrElse nextY >= SQCOUNTY Then
Return False
End If
' Check walls between ball's current position and new position
If Not CanBallMoveTo(ballX, ballY, deltaX, deltaY) Then
Return False
End If
' Check what's at ball's new position
Dim blockTargetItem As String = placedItems(nextX)(nextY)
Dim occupied As Boolean = False
If Not String.IsNullOrEmpty(blockTargetItem) Then
If IsLaser(nextX, nextY) Then
' Destroy laser and continue
placedItems(nextX)(nextY) = Nothing
PlaySoundEffect("Break Lazer")
Else
' Cannot move into occupied cell
Return False
End If
End If
' Remove the ball from its initial position
placedItems(ballX)(ballY) = Nothing
' Place the ball at the next position
placedItems(nextX)(nextY) = "picBall"
' Create and start the moving ball
Dim mb As New MovingBall With {
.X = nextX,
.Y = nextY,
.DeltaX = deltaX,
.DeltaY = deltaY,
.Timer = New Timer() With {.Interval = MoveTimerInterval}
}
' Add handler for timer tick
AddHandler mb.Timer.Tick, AddressOf BallMovementTimerTick
mb.Timer.Start()
movingBalls.Add(mb)
' Redraw the game area
picTest.Invalidate()
Return True
End Function
' Ball movement timer tick handler
Private Sub BallMovementTimerTick(sender As Object, e As EventArgs)
Dim t As Timer = CType(sender, Timer)
' Find the moving ball associated with this timer
Dim mb As MovingBall = movingBalls.FirstOrDefault(Function(b) b.Timer Is t)
If mb Is Nothing Then
' Should not happen
t.Stop()
t.Dispose()
Return
End If
Dim currentX As Integer = mb.X
Dim currentY As Integer = mb.Y
Dim nextX As Integer = currentX + mb.DeltaX
Dim nextY As Integer = currentY + mb.DeltaY
' Check boundaries
If nextX < 0 OrElse nextX >= SQCOUNTX OrElse nextY < 0 OrElse nextY >= SQCOUNTY Then
' Ball cannot move further, stop
StopMovingBall(mb)
Return
End If
' Initialize wallBlocks as False
Dim wallBlocks As Boolean = False
If mb.DeltaX = 1 Then
' Moving right
If verticalWalls(currentX + 1)(currentY) Then
If IsLaserOnVerticalWall(currentX + 1, currentY) Then
' Destroy the laser
verticalWallItems(currentX + 1)(currentY) = Nothing
' Remove the wall
verticalWalls(currentX + 1)(currentY) = False
PlaySoundEffect("Break Lazer")
wallBlocks = False ' Allow passage after destroying laser
Else
wallBlocks = True ' Solid wall blocks movement
End If
End If
ElseIf mb.DeltaX = -1 Then
' Moving left
If verticalWalls(currentX)(currentY) Then
If IsLaserOnVerticalWall(currentX, currentY) Then
verticalWallItems(currentX)(currentY) = Nothing
verticalWalls(currentX)(currentY) = False
PlaySoundEffect("Break Lazer")
wallBlocks = False
Else
wallBlocks = True
End If
End If
ElseIf mb.DeltaY = 1 Then
' Moving down
If horizontalWalls(currentX)(currentY + 1) Then
If IsLaserOnHorizontalWall(currentX, currentY + 1) Then
horizontalWallItems(currentX)(currentY + 1) = Nothing
horizontalWalls(currentX)(currentY + 1) = False
PlaySoundEffect("Break Lazer")
wallBlocks = False
Else
wallBlocks = True
End If
End If
ElseIf mb.DeltaY = -1 Then
' Moving up
If horizontalWalls(currentX)(currentY) Then
If IsLaserOnHorizontalWall(currentX, currentY) Then
horizontalWallItems(currentX)(currentY) = Nothing
horizontalWalls(currentX)(currentY) = False
PlaySoundEffect("Break Lazer")
wallBlocks = False
Else
wallBlocks = True
End If
End If
End If
If wallBlocks Then
' Ball is blocked by wall
StopMovingBall(mb)
Return
End If
' Check what's at the next position
Dim occupied As Boolean = False
Dim nextItem As String = placedItems(nextX)(nextY)
If Not String.IsNullOrEmpty(nextItem) Then
If IsLaser(nextX, nextY) Then
' Destroy laser and continue
placedItems(nextX)(nextY) = Nothing
PlaySoundEffect("Break Lazer")
Else
' Cannot move into occupied cell
occupied = True
End If
End If
' Check for moving balls in next position
For Each otherBall In movingBalls
If otherBall IsNot mb AndAlso otherBall.X = nextX AndAlso otherBall.Y = nextY Then
occupied = True
Exit For
End If
Next
' Check if player is in the next position
If playerX = nextX AndAlso playerY = nextY Then
occupied = True
End If
If occupied Then
StopMovingBall(mb)
Return
End If
' Remove the ball from current position
placedItems(currentX)(currentY) = Nothing
' Move the ball into next position
mb.X = nextX
mb.Y = nextY
placedItems(mb.X)(mb.Y) = "picBall"
' Redraw game area
picTest.Invalidate()
End Sub
' Helper method to stop a moving ball
Private Sub StopMovingBall(mb As MovingBall)
' Stop and dispose the timer
mb.Timer.Stop()
RemoveHandler mb.Timer.Tick, AddressOf BallMovementTimerTick
mb.Timer.Dispose()
' Remove from the list
movingBalls.Remove(mb)
' The ball remains in its current position
placedItems(mb.X)(mb.Y) = "picBall"
' Redraw the game area
picTest.Invalidate()
End Sub
Private Function CanBallMoveTo(currentX As Integer, currentY As Integer, deltaX As Integer, deltaY As Integer) As Boolean
' Check walls between current and next position
Dim nextX As Integer = currentX + deltaX
Dim nextY As Integer = currentY + deltaY
If deltaX = 1 Then
' Moving right
If verticalWalls(currentX + 1)(currentY) Then Return False
ElseIf deltaX = -1 Then
' Moving left
If verticalWalls(currentX)(currentY) Then Return False
ElseIf deltaY = 1 Then
' Moving down
If horizontalWalls(currentX)(currentY + 1) Then Return False
ElseIf deltaY = -1 Then
' Moving up
If horizontalWalls(currentX)(currentY) Then Return False
End If
Return True ' Move is allowed
End Function
Private Function IsLaserOnVerticalWall(x As Integer, y As Integer) As Boolean
If x >= 0 AndAlso x < verticalWallItems.Length AndAlso
verticalWallItems(x) IsNot Nothing AndAlso
y >= 0 AndAlso y < verticalWallItems(x).Length Then
Dim item As String = verticalWallItems(x)(y)
Return item = "picLazer1" OrElse item = "picLazer2"
End If
Return False
End Function
Private Function IsLaserOnHorizontalWall(x As Integer, y As Integer) As Boolean
If x >= 0 AndAlso x < horizontalWallItems.Length AndAlso
horizontalWallItems(x) IsNot Nothing AndAlso
y >= 0 AndAlso y < horizontalWallItems(x).Length Then
Dim item As String = horizontalWallItems(x)(y)
Return item = "picLazer1" OrElse item = "picLazer2"
End If
Return False
End Function
Private Function AttemptPushBlock(blockX As Integer, blockY As Integer, deltaX As Integer, deltaY As Integer) As Boolean
Dim blockNewX As Integer = blockX + deltaX
Dim blockNewY As Integer = blockY + deltaY
' Check boundaries
If blockNewX < 0 OrElse blockNewX >= SQCOUNTX OrElse blockNewY < 0 OrElse blockNewY >= SQCOUNTY Then
Return False
End If
' Check walls between block's current position and new position
Dim wallExists As Boolean = False
Dim laserExists As Boolean = False
If deltaX = 1 Then
' Pushing block right
wallExists = verticalWalls(blockX + 1)(blockY)
laserExists = IsLaserOnVerticalWall(blockX + 1, blockY)
If laserExists Then
verticalWallItems(blockX + 1)(blockY) = Nothing
verticalWalls(blockX + 1)(blockY) = False ' Remove the wall
PlaySoundEffect("Break Lazer")
End If
ElseIf deltaX = -1 Then
' Pushing block left
wallExists = verticalWalls(blockX)(blockY)
laserExists = IsLaserOnVerticalWall(blockX, blockY)
If laserExists Then
verticalWallItems(blockX)(blockY) = Nothing
verticalWalls(blockX)(blockY) = False ' Remove the wall
PlaySoundEffect("Break Lazer")
End If
ElseIf deltaY = 1 Then
' Pushing block down
wallExists = horizontalWalls(blockX)(blockY + 1)
laserExists = IsLaserOnHorizontalWall(blockX, blockY + 1)
If laserExists Then
horizontalWallItems(blockX)(blockY + 1) = Nothing
horizontalWalls(blockX)(blockY + 1) = False ' Remove the wall
PlaySoundEffect("Break Lazer")
End If
ElseIf deltaY = -1 Then
' Pushing block up
wallExists = horizontalWalls(blockX)(blockY)
laserExists = IsLaserOnHorizontalWall(blockX, blockY)
If laserExists Then
horizontalWallItems(blockX)(blockY) = Nothing
horizontalWalls(blockX)(blockY) = False ' Remove the wall
PlaySoundEffect("Break Lazer")
End If
End If
If wallExists Then
If laserExists Then
' Block can move through laser, laser will be destroyed
' Wall is already removed above
Else
' Solid wall, block cannot move
Return False
End If
End If
' Check what's at block's new position
Dim blockTargetItem As String = placedItems(blockNewX)(blockNewY)
If String.IsNullOrEmpty(blockTargetItem) Then
' The block can be moved
' Move the block
placedItems(blockNewX)(blockNewY) = "picBlock1"
placedItems(blockX)(blockY) = Nothing
' Play Push Block.wav sound
PlaySoundEffect("Push Block")
Return True
Else
' Block cannot be moved
Return False
End If
End Function
Private Function CanBlockMoveTo(blockX As Integer, blockY As Integer, deltaX As Integer, deltaY As Integer) As Boolean
Dim wallExists As Boolean = False
Dim laserExists As Boolean = False
If deltaX = 1 Then
' Pushing block right
wallExists = verticalWalls(blockX + 1)(blockY)
laserExists = IsLaserOnVerticalWall(blockX + 1, blockY)
ElseIf deltaX = -1 Then
' Pushing block left
wallExists = verticalWalls(blockX)(blockY)
laserExists = IsLaserOnVerticalWall(blockX, blockY)
ElseIf deltaY = 1 Then
' Pushing block down
wallExists = horizontalWalls(blockX)(blockY + 1)
laserExists = IsLaserOnHorizontalWall(blockX, blockY + 1)
ElseIf deltaY = -1 Then
' Pushing block up
wallExists = horizontalWalls(blockX)(blockY)
laserExists = IsLaserOnHorizontalWall(blockX, blockY)
End If
If wallExists Then
If laserExists Then
' Block can move through laser, laser will be destroyed
Return True
Else
' Solid wall, block cannot move
Return False
End If
Else
' No wall, block can move
Return True
End If
End Function
Private Function IsLaser(x As Integer, y As Integer) As Boolean
Dim item As String = placedItems(x)(y)
If item IsNot Nothing Then
Return item = "picLazer1" OrElse item = "picLazer2"
End If
Return False
End Function
Private Function CanMoveTo(newX As Integer, newY As Integer, deltaX As Integer, deltaY As Integer) As Boolean
' Check walls between current and new position
If deltaX = 1 Then
' Moving right
If verticalWalls(playerX + 1)(playerY) Then Return False
' Check for lasers on the vertical wall
If IsLaserOnVerticalWall(playerX + 1, playerY) Then Return False
ElseIf deltaX = -1 Then
' Moving left
If verticalWalls(playerX)(playerY) Then Return False
If IsLaserOnVerticalWall(playerX, playerY) Then Return False
ElseIf deltaY = 1 Then
' Moving down
If horizontalWalls(playerX)(playerY + 1) Then Return False
If IsLaserOnHorizontalWall(playerX, playerY + 1) Then Return False
ElseIf deltaY = -1 Then
' Moving up
If horizontalWalls(playerX)(playerY) Then Return False
If IsLaserOnHorizontalWall(playerX, playerY) Then Return False
End If
' Prevent moving onto moving balls
For Each mb In movingBalls
If mb.X = newX AndAlso mb.Y = newY Then
Return False
End If
Next
Return True ' Move is allowed
End Function
Private Sub GameWon()
' Play Finish.wav sound
PlaySoundEffect("Finish")
MessageBox.Show($"Congratulations! You have completed the level.{Environment.NewLine}Coins Collected: {CollectedCoins}")
' Optionally, stop the game or reset the level
' For example, close the game form
Me.Close()
End Sub
#End Region
#Region " Load "
' Event handler for form load
Private Sub frmGame_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Load the room data from file
If Not String.IsNullOrEmpty(RoomFilePath) AndAlso File.Exists(RoomFilePath) Then
LoadRoomFromFile(RoomFilePath)
Else
MessageBox.Show("Room file not found.")
Me.Close()
Return
End If
' Initialize images and animations
InitializeImages()
' Initialize sound effects
InitializeSoundEffects()
' Start the animation timer
animationTimer = New Timer() With {.Interval = 100}
AddHandler animationTimer.Tick, AddressOf OnAnimationTick
animationTimer.Start()
' Force picTest to repaint
picTest.Invalidate()
Me.KeyPreview = True
Me.Focus()
End Sub
Private Sub LoadRoomFromFile(filePath As String)
Try
Dim options As New JsonSerializerOptions With {
.IncludeFields = True,
.PropertyNameCaseInsensitive = True
}
Dim jsonString As String = File.ReadAllText(filePath)
Dim roomData As RoomData = JsonSerializer.Deserialize(Of RoomData)(jsonString, options)
If roomData Is Nothing Then
MessageBox.Show("Error: Failed to deserialize room data.")
Return
End If
' Ensure images are loaded before restoring state
InitializeImages()
' Restore room data
RestoreRoomData(roomData)
Catch ex As Exception
MessageBox.Show("Error loading room: " & ex.ToString())
End Try
End Sub
Private Sub RestoreRoomData(roomData As RoomData)
Try
' Restore grid sizes
SQCOUNTX = roomData.GridSizeX
SQCOUNTY = roomData.GridSizeY
' Restore colors and styles
wallsHatchStyle = CType(roomData.wallsHatchStyleValue, HatchStyle)
wallsColor1 = Color.FromArgb(roomData.wallsColor1Argb)
wallsColor2 = Color.FromArgb(roomData.wallsColor2Argb)
floorsHatchStyle = CType(roomData.floorsHatchStyleValue, HatchStyle)
floorsColor1 = Color.FromArgb(roomData.floorsColor1Argb)
floorsColor2 = Color.FromArgb(roomData.floorsColor2Argb)
' Restore walls and items
verticalWalls = roomData.verticalWalls
horizontalWalls = roomData.horizontalWalls
floorsUseEdgeStyle = roomData.floorsUseEdgeStyle
' Restore placed items
placedItems = RestorePlacedItems(roomData.placedItems)
verticalWallItems = RestorePlacedItems(roomData.verticalWallItems)
horizontalWallItems = RestorePlacedItems(roomData.horizontalWallItems)
' Restore level name and selected music
SelectedMusic = roomData.SelectedMusic
lblName.Text = roomData.LevelName
PlaySelectedMusic()
' Set flag indicating room data is loaded
isRoomDataLoaded = True
' Refresh the game picture
picTest.Invalidate()
Catch ex As Exception
MessageBox.Show("Error restoring room data: " & ex.ToString())
End Try
FindPlayerStartPosition()
End Sub
Private Function RestorePlacedItems(data As PlacedItemData()()) As String()()
If data Is Nothing Then
Return Nothing
End If
Dim lengthOuter As Integer = data.Length
Dim restoredItems As String()() = New String(lengthOuter - 1)() {}
For x As Integer = 0 To lengthOuter - 1
If data(x) IsNot Nothing Then
Dim lengthInner As Integer = data(x).Length
restoredItems(x) = New String(lengthInner - 1) {}
For y As Integer = 0 To lengthInner - 1
If data(x)(y) IsNot Nothing Then
restoredItems(x)(y) = data(x)(y).ImageKey
Else
restoredItems(x)(y) = Nothing
End If
Next
Else
restoredItems(x) = Nothing
End If
Next
Return restoredItems
End Function
Private Sub InitializeVerticalWalls()
verticalWalls = New Boolean(SQCOUNTX)() {}
For x As Integer = 0 To SQCOUNTX
verticalWalls(x) = New Boolean(SQCOUNTY - 1) {}
For y As Integer = 0 To SQCOUNTY - 1
verticalWalls(x)(y) = True ' Default to True for walls
Next
Next
End Sub
Private Sub InitializeHorizontalWalls()
horizontalWalls = New Boolean(SQCOUNTX - 1)() {}
For x As Integer = 0 To SQCOUNTX - 1
horizontalWalls(x) = New Boolean(SQCOUNTY) {}
For y As Integer = 0 To SQCOUNTY
horizontalWalls(x)(y) = True ' Default to True for walls
Next
Next
End Sub
Private Sub InitializePlacedItems()
placedItems = New String(SQCOUNTX - 1)() {}
For x As Integer = 0 To SQCOUNTX - 1
placedItems(x) = New String(SQCOUNTY - 1) {}
For y As Integer = 0 To SQCOUNTY - 1
placedItems(x)(y) = Nothing
Next
Next
End Sub
Private Sub InitializeVerticalWallItems()
verticalWallItems = New String(SQCOUNTX)() {}
For x As Integer = 0 To SQCOUNTX
verticalWallItems(x) = New String(SQCOUNTY - 1) {}
For y As Integer = 0 To SQCOUNTY - 1
verticalWallItems(x)(y) = Nothing
Next
Next
End Sub
Private Sub InitializeHorizontalWallItems()
horizontalWallItems = New String(SQCOUNTX - 1)() {}
For x As Integer = 0 To SQCOUNTX - 1
horizontalWallItems(x) = New String(SQCOUNTY) {}
For y As Integer = 0 To SQCOUNTY
horizontalWallItems(x)(y) = Nothing
Next
Next
End Sub
Private Sub InitializeFloorsUseEdgeStyle()
floorsUseEdgeStyle = New Boolean(SQCOUNTX - 1)() {}
For x As Integer = 0 To SQCOUNTX - 1
floorsUseEdgeStyle(x) = New Boolean(SQCOUNTY - 1) {}
For y As Integer = 0 To SQCOUNTY - 1
floorsUseEdgeStyle(x)(y) = False
Next
Next
End Sub
' Method to initialize images and animations
Private Sub InitializeImages()
Try
imageDictionary("picBlock1") = Image.FromFile(Path.Combine(ImagesFolder, "Block.png"))
imageDictionary("picBaddy1") = Image.FromFile(Path.Combine(ImagesFolder, "Baddy 1 anim.gif"))
imageDictionary("picBaddy2") = Image.FromFile(Path.Combine(ImagesFolder, "Baddy 2 anim.gif"))
imageDictionary("picBaddy3") = Image.FromFile(Path.Combine(ImagesFolder, "Baddy3.gif"))
imageDictionary("picBaddy4") = Image.FromFile(Path.Combine(ImagesFolder, "Baddy4.gif"))
imageDictionary("picBall") = Image.FromFile(Path.Combine(ImagesFolder, "Ball.gif"))
imageDictionary("picBlockSwitch") = Image.FromFile(Path.Combine(ImagesFolder, "BlockSwitch.png"))
imageDictionary("picBomb") = Image.FromFile(Path.Combine(ImagesFolder, "Bomb.gif"))
imageDictionary("picCoin") = Image.FromFile(Path.Combine(ImagesFolder, "Coin.gif"))
imageDictionary("picFinish") = Image.FromFile(Path.Combine(ImagesFolder, "Finish.gif"))
imageDictionary("picFlipper1") = Image.FromFile(Path.Combine(ImagesFolder, "Flipper1.gif"))
imageDictionary("picFlipper2") = Image.FromFile(Path.Combine(ImagesFolder, "Flipper2.gif"))
imageDictionary("picFlipper3") = Image.FromFile(Path.Combine(ImagesFolder, "Flipper3.gif"))
imageDictionary("picFlipper4") = Image.FromFile(Path.Combine(ImagesFolder, "Flipper4.gif"))
imageDictionary("picGate") = Image.FromFile(Path.Combine(ImagesFolder, "Gate.gif"))
imageDictionary("picKey") = Image.FromFile(Path.Combine(ImagesFolder, "Key.gif"))
imageDictionary("picLazer1") = Image.FromFile(Path.Combine(ImagesFolder, "Lazer1.gif"))
imageDictionary("picLazer2") = Image.FromFile(Path.Combine(ImagesFolder, "Lazer2.gif"))
imageDictionary("picWarp") = Image.FromFile(Path.Combine(ImagesFolder, "Warp.gif"))
imageDictionary("picWarp2") = Image.FromFile(Path.Combine(ImagesFolder, "Warp2.gif"))
imageDictionary("picStart") = Image.FromFile(Path.Combine(ImagesFolder, "Guy.gif"))
imageDictionary("picBlockStopper1") = Image.FromFile(Path.Combine(ImagesFolder, "Debris1.png"))
' Add other images similarly...
' List of image keys that are animated
Dim animatedImageKeys As String() = {
"picBaddy1", "picBaddy2", "picBaddy3", "picBaddy4",
"picLazer1", "picLazer2", "picFlipper1", "picFlipper2",
"picFlipper3", "picFlipper4", "picCoin", "picGate",
"picKey", "picFinish", "picBall", "picBomb",
"picWarp", "picWarp2", "picStart"
}
' Add images that require animation to the animatedImages list
For Each imgKey In animatedImageKeys
If imageDictionary.ContainsKey(imgKey) Then
Dim img As Image = imageDictionary(imgKey)
animatedImages.Add(img)
ImageAnimator.Animate(img, AddressOf OnFrameChanged)
End If
Next
Catch ex As Exception
MessageBox.Show("Error loading images: " & ex.Message)
End Try
End Sub
' Method to initialize sound effects
Private Sub InitializeSoundEffects()
Try
soundEffectFiles("Break Lazer") = Path.Combine(SFXFolder, "Break Lazer.wav")
soundEffectFiles("Coin") = Path.Combine(SFXFolder, "Coin.wav")
soundEffectFiles("Finish") = Path.Combine(SFXFolder, "Finish.wav")
soundEffectFiles("Move") = Path.Combine(SFXFolder, "Move.wav")
soundEffectFiles("Push Block") = Path.Combine(SFXFolder, "Push Block.wav")
soundEffectFiles("Warp") = Path.Combine(SFXFolder, "Warp.wav")
' Add sound effect for key pickup and door open
soundEffectFiles("Key") = Path.Combine(SFXFolder, "Key.wav") ' Ensure Key.wav exists
soundEffectFiles("Door Open") = Path.Combine(SFXFolder, "Door Open.wav") ' Ensure Door Open.wav exists
' Ensure all files exist
For Each kvp In soundEffectFiles
' If Not File.Exists(kvp.Value) Then
' MessageBox.Show("Sound effect file not found: " & kvp.Value)
' End If
' Commented out error messages as per your request
Next
' Initialize NAudio mixer for sound effects
mixer = New MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100, 2))
mixer.ReadFully = True ' To prevent stream closing unexpectedly
waveOut = New WaveOutEvent()
waveOut.Init(mixer)
waveOut.Play()
Catch ex As Exception
MessageBox.Show("Error initializing sound effects: " & ex.Message)
End Try
End Sub
' Helper method to play a sound effect using NAudio
Private Sub PlaySoundEffect(soundKey As String)
If soundEffectFiles.ContainsKey(soundKey) Then
Dim soundFilePath As String = soundEffectFiles(soundKey)
If File.Exists(soundFilePath) Then
Try
Dim reader As New AudioFileReader(soundFilePath)
' Adjust volume if necessary
reader.Volume = 1.0F
' Explicitly cast to ISampleProvider to resolve overload
mixer.AddMixerInput(DirectCast(reader, ISampleProvider))
Catch ex As Exception
' MessageBox.Show("Error playing sound effect: " & soundKey & vbCrLf & ex.Message)
' Commented out error messages as per your request
End Try
End If
End If
End Sub
' Helper method to get the project directory
Private Function GetProjectDirectory() As String
Dim dir As DirectoryInfo = New DirectoryInfo(Application.StartupPath)
For i As Integer = 1 To 4 ' Adjust this number based on your directory structure
If dir.Parent IsNot Nothing Then
dir = dir.Parent
End If
Next
Return dir.FullName
End Function
#End Region
#Region " Sound "
Private Sub PlaySelectedMusic()
If musicPlayer IsNot Nothing Then
' Stop any currently playing music
musicPlayer.Stop()
musicPlayer.Dispose()
musicPlayer = Nothing
End If
If Not String.IsNullOrEmpty(SelectedMusic) Then
Dim musicFilePath As String = Path.Combine(musicFolder, SelectedMusic & ".wav")
If File.Exists(musicFilePath) Then
Try
musicPlayer = New SoundPlayer(musicFilePath)
' Set LoadCompleted event handler to play music on repeat
AddHandler musicPlayer.LoadCompleted, AddressOf MusicLoadCompleted
musicPlayer.LoadAsync()
Catch ex As Exception
MessageBox.Show("Error playing music: " & ex.Message)
End Try
Else
' MessageBox.Show("Selected music file not found: " & SelectedMusic)
' Commented out error messages as per your request
End If
End If
End Sub
Private Sub MusicLoadCompleted(sender As Object, e As AsyncCompletedEventArgs)
If musicPlayer IsNot Nothing Then
musicPlayer.PlayLooping()
End If
End Sub
#End Region
#Region " Draw "
' Event handler for animation timer tick
Private Sub OnAnimationTick(sender As Object, e As EventArgs)
For Each img In animatedImages
ImageAnimator.UpdateFrames(img)
Next
picTest.Invalidate()
End Sub
' Event handler for image frame change (required by ImageAnimator)
Private Sub OnFrameChanged(o As Object, e As EventArgs)
' Required but can be left empty
End Sub
Private Sub picTest_Paint(sender As Object, e As PaintEventArgs) Handles picTest.Paint
If Not isRoomDataLoaded Then
Return
End If
' Fill the entire background with the walls' hatch style and colors
Using backgroundBrush As New HatchBrush(wallsHatchStyle, wallsColor1, wallsColor2)
e.Graphics.FillRectangle(backgroundBrush, picTest.ClientRectangle)
End Using
' Calculate square sizes based on the current size of picTest
CalculateSquareSizes(picTest.ClientSize.Width, picTest.ClientSize.Height)
e.Graphics.SmoothingMode = SmoothingMode.None
' Draw the game grid, walls, and items
DrawGrid(e.Graphics)
End Sub
' Method to calculate square sizes based on control size
Private Sub CalculateSquareSizes(clientWidth As Integer, clientHeight As Integer)
SQSizeX = (clientWidth - 2 * INDENT - (SQCOUNTX + 1) * WALL_THICKNESS) \ SQCOUNTX
SQSizeY = (clientHeight - 2 * INDENT - (SQCOUNTY + 1) * WALL_THICKNESS) \ SQCOUNTY
End Sub
' Method to draw the grid, walls, and items
Private Sub DrawGrid(g As Graphics)
Dim xOrigin As Integer = INDENT
Dim yOrigin As Integer = INDENT
' Draw floor squares
For x As Integer = 0 To SQCOUNTX - 1
For y As Integer = 0 To SQCOUNTY - 1
Dim floorRect As New Rectangle(
xOrigin + x * (SQSizeX + WALL_THICKNESS) + WALL_THICKNESS \ 2,
yOrigin + y * (SQSizeY + WALL_THICKNESS) + WALL_THICKNESS \ 2,
SQSizeX,
SQSizeY
)
If floorsUseEdgeStyle IsNot Nothing AndAlso floorsUseEdgeStyle.Length > x AndAlso
floorsUseEdgeStyle(x) IsNot Nothing AndAlso floorsUseEdgeStyle(x).Length > y AndAlso
floorsUseEdgeStyle(x)(y) Then
' Draw with wall's hatch style and colors (edge style)
Using floorBrush As New HatchBrush(wallsHatchStyle, wallsColor1, wallsColor2)
g.FillRectangle(floorBrush, floorRect)
End Using
Else
' Draw with floor's hatch style and colors
Using floorBrush As New HatchBrush(floorsHatchStyle, floorsColor1, floorsColor2)
g.FillRectangle(floorBrush, floorRect)
End Using
End If
Next
Next
' Draw wall intersections
For x As Integer = 0 To SQCOUNTX
For y As Integer = 0 To SQCOUNTY
Dim intersectionRect As New Rectangle(
xOrigin + x * (SQSizeX + WALL_THICKNESS) - WALL_THICKNESS \ 2,
yOrigin + y * (SQSizeY + WALL_THICKNESS) - WALL_THICKNESS \ 2,
WALL_THICKNESS,
WALL_THICKNESS
)
Using wallBrush As New HatchBrush(wallsHatchStyle, wallsColor1, wallsColor2)
g.FillRectangle(wallBrush, intersectionRect)
End Using
Next
Next
' Draw vertical walls or floor
For x As Integer = 0 To SQCOUNTX
For y As Integer = 0 To SQCOUNTY - 1
Dim wallRect As New Rectangle(
xOrigin + x * (SQSizeX + WALL_THICKNESS) - WALL_THICKNESS \ 2,
yOrigin + y * (SQSizeY + WALL_THICKNESS) + WALL_THICKNESS \ 2,
WALL_THICKNESS,
SQSizeY
)
If x >= 0 AndAlso x < verticalWalls.Length AndAlso
verticalWalls(x) IsNot Nothing AndAlso
y >= 0 AndAlso y < verticalWalls(x).Length Then
If verticalWalls(x)(y) Then
' Draw wall
Using wallBrush As New HatchBrush(wallsHatchStyle, wallsColor1, wallsColor2)
g.FillRectangle(wallBrush, wallRect)
End Using
Else
' Draw floor
Using floorBrush As New HatchBrush(floorsHatchStyle, floorsColor1, floorsColor2)
g.FillRectangle(floorBrush, wallRect)
End Using
End If
End If
Next
Next
' Draw horizontal walls or floor
For x As Integer = 0 To SQCOUNTX - 1
For y As Integer = 0 To SQCOUNTY
Dim wallRect As New Rectangle(
xOrigin + x * (SQSizeX + WALL_THICKNESS) + WALL_THICKNESS \ 2,
yOrigin + y * (SQSizeY + WALL_THICKNESS) - WALL_THICKNESS \ 2,
SQSizeX,
WALL_THICKNESS
)
If x >= 0 AndAlso x < horizontalWalls.Length AndAlso
horizontalWalls(x) IsNot Nothing AndAlso
y >= 0 AndAlso y < horizontalWalls(x).Length Then
If horizontalWalls(x)(y) Then
' Draw wall
Using wallBrush As New HatchBrush(wallsHatchStyle, wallsColor1, wallsColor2)
g.FillRectangle(wallBrush, wallRect)
End Using
Else
' Draw floor
Using floorBrush As New HatchBrush(floorsHatchStyle, floorsColor1, floorsColor2)
g.FillRectangle(floorBrush, wallRect)
End Using
End If
End If
Next
Next
' Draw items on the floor squares
DrawItems(g)
' Draw items on the walls
DrawWallItems(g)
End Sub
Private Sub DrawItems(g As Graphics)
If placedItems Is Nothing Then Return
For x As Integer = 0 To placedItems.Length - 1
If placedItems(x) IsNot Nothing Then
For y As Integer = 0 To placedItems(x).Length - 1
Dim imageKey As String = placedItems(x)(y)
If Not String.IsNullOrEmpty(imageKey) AndAlso imageDictionary.ContainsKey(imageKey) Then
If imageKey = "picStart" Then
' Skip drawing the player here
Continue For
End If
Dim img As Image = imageDictionary(imageKey)
Dim xPos As Integer = INDENT + x * (SQSizeX + WALL_THICKNESS) + WALL_THICKNESS \ 2
Dim yPos As Integer = INDENT + y * (SQSizeY + WALL_THICKNESS) + WALL_THICKNESS \ 2
Dim destRect As New Rectangle(xPos, yPos, SQSizeX, SQSizeY)
' Draw the item
g.DrawImage(img, destRect)
End If
Next
End If
Next
' Now draw the player at its current position
DrawPlayer(g)
End Sub
Private Sub DrawPlayer(g As Graphics)
Dim img As Image = imageDictionary("picStart")
Dim xPos As Integer = INDENT + playerX * (SQSizeX + WALL_THICKNESS) + WALL_THICKNESS \ 2
Dim yPos As Integer = INDENT + playerY * (SQSizeY + WALL_THICKNESS) + WALL_THICKNESS \ 2
Dim destRect As New Rectangle(xPos, yPos, SQSizeX, SQSizeY)
' Draw the player
g.DrawImage(img, destRect)
End Sub
' Method to draw items on walls
Private Sub DrawWallItems(g As Graphics)
' Draw vertical wall items
If verticalWallItems IsNot Nothing Then
For x As Integer = 0 To verticalWallItems.Length - 1
If verticalWallItems(x) IsNot Nothing Then
For y As Integer = 0 To verticalWallItems(x).Length - 1
Dim imageKey As String = verticalWallItems(x)(y)
If Not String.IsNullOrEmpty(imageKey) AndAlso imageDictionary.ContainsKey(imageKey) Then
Dim img As Image = imageDictionary(imageKey)
ImageAnimator.UpdateFrames(img)
Dim wallX As Integer = INDENT + x * (SQSizeX + WALL_THICKNESS) - (WALL_THICKNESS \ 2)
Dim wallY As Integer = INDENT + y * (SQSizeY + WALL_THICKNESS) + (WALL_THICKNESS \ 2)
Dim wallWidth As Integer = WALL_THICKNESS
Dim wallHeight As Integer = SQSizeY
' Keep original image width, stretch height
Dim newWidth As Integer = img.Width
Dim newHeight As Integer = wallHeight
' Center horizontally
Dim centeredX As Integer = wallX + (wallWidth - newWidth) \ 2
Dim drawRect As New Rectangle(centeredX, wallY, newWidth, newHeight)
g.DrawImage(img, drawRect)
End If
Next
End If
Next
End If
' Draw horizontal wall items
If horizontalWallItems IsNot Nothing Then
For x As Integer = 0 To horizontalWallItems.Length - 1
If horizontalWallItems(x) IsNot Nothing Then
For y As Integer = 0 To horizontalWallItems(x).Length - 1
Dim imageKey As String = horizontalWallItems(x)(y)
If Not String.IsNullOrEmpty(imageKey) AndAlso imageDictionary.ContainsKey(imageKey) Then
Dim img As Image = imageDictionary(imageKey)
ImageAnimator.UpdateFrames(img)
Dim wallX As Integer = INDENT + x * (SQSizeX + WALL_THICKNESS) + (WALL_THICKNESS \ 2)
Dim wallY As Integer = INDENT + y * (SQSizeY + WALL_THICKNESS) - (WALL_THICKNESS \ 2)
Dim wallWidth As Integer = SQSizeX
Dim wallHeight As Integer = WALL_THICKNESS
' Stretch width, keep original image height
Dim newWidth As Integer = wallWidth
Dim newHeight As Integer = img.Height
' Center vertically
Dim centeredY As Integer = wallY + (wallHeight - newHeight) \ 2
Dim drawRect As New Rectangle(wallX, centeredY, newWidth, newHeight)
g.DrawImage(img, drawRect)
End If
Next
End If
Next
End If
End Sub
#End Region
#Region " Closing "
' Ensure that the animation timer is disposed when the form closes
Private Sub frmGame_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
If animationTimer IsNot Nothing Then
animationTimer.Stop()
animationTimer.Dispose()
animationTimer = Nothing
End If
If musicPlayer IsNot Nothing Then
musicPlayer.Stop()
musicPlayer.Dispose()
musicPlayer = Nothing
End If
If waveOut IsNot Nothing Then
waveOut.Stop()
waveOut.Dispose()
waveOut = Nothing
End If
If mixer IsNot Nothing Then
mixer = Nothing
End If
' Stop and dispose any remaining moving ball timers
For Each mb In movingBalls
mb.Timer.Stop()
RemoveHandler mb.Timer.Tick, AddressOf BallMovementTimerTick
mb.Timer.Dispose()
Next
movingBalls.Clear()
End Sub
Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
Me.Close()
End Sub
#End Region
End Class
Can you see why the ball won't destroy the laser when it goes through it? What it should do is just remove the laser from the game. Remember the Lazer is a wall item.
ASSISTANT
Yes, the issue lies in the way the code is checking for lasers on walls. The ball does not destroy the laser because it's checking the wrong index for the laser's presence on the wall. Specifically, when the ball moves, it's checking for lasers on walls using the incorrect indices for `verticalWallItems` and `horizontalWallItems`.
In the `BallMovementTimerTick` function, when the ball moves to the right (`DeltaX = 1`), it should check the wall between the current cell and the cell to the right. The vertical wall between these two cells is indexed at `verticalWalls(currentX + 1)(currentY)`, which is correct. However, the laser on that wall is actually stored at `verticalWallItems(currentX)(currentY)`, not `verticalWallItems(currentX + 1)(currentY)`.
**Here's how to fix the issue:**
1. **Adjust the Indices When Checking for Lasers:**
In the `BallMovementTimerTick` method, modify the indices used to check for the laser on the wall. Replace all instances where you're checking `IsLaserOnVerticalWall(currentX + 1, currentY)` with `IsLaserOnVerticalWall(currentX, currentY)` when moving right, and similarly adjust the indices when moving in other directions.
2. **Update the Code in `BallMovementTimerTick`:**
**Before:**
```vb
If mb.DeltaX = 1 Then
' Moving right
If verticalWalls(currentX + 1)(currentY) Then
If IsLaserOnVerticalWall(currentX + 1, currentY) Then
' Destroy the laser
verticalWallItems(currentX + 1)(currentY) = Nothing
' Remove the wall
verticalWalls(currentX + 1)(currentY) = False
PlaySoundEffect("Break Lazer")
wallBlocks = False ' Allow passage after destroying laser
Else
wallBlocks = True ' Solid wall blocks movement
End If
End If
```
**After Adjustment:**
```vb
If mb.DeltaX = 1 Then
' Moving right
If verticalWalls(currentX + 1)(currentY) Then
If IsLaserOnVerticalWall(currentX, currentY) Then
' Destroy the laser
verticalWallItems(currentX)(currentY) = Nothing
' Remove the wall
verticalWalls(currentX + 1)(currentY) = False
PlaySoundEffect("Break Lazer")
wallBlocks = False ' Allow passage after destroying laser
Else
wallBlocks = True ' Solid wall blocks movement
End If
End If
```
3. **Similarly, Adjust Other Directions:**
For moving left (`DeltaX = -1`), up (`DeltaY = -1`), and down (`DeltaY = 1`), adjust the indices accordingly.
**Example for Moving Left:**
**Before:**
```vb
If mb.DeltaX = -1 Then
' Moving left
If verticalWalls(currentX)(currentY) Then
If IsLaserOnVerticalWall(currentX, currentY) Then
verticalWallItems(currentX)(currentY) = Nothing
verticalWalls(currentX)(currentY) = False
PlaySoundEffect("Break Lazer")
wallBlocks = False
Else
wallBlocks = True
End If
End If
```
**After Adjustment (indices remain the same as they are already correct in this case):**
```vb
' No change needed for moving left, as indices are correct
```
4. **Review and Adjust the `IsLaserOnVerticalWall` and `IsLaserOnHorizontalWall` Functions:**
Ensure that these functions are correctly indexing the wall items.
**Example Adjusted `IsLaserOnVerticalWall` Function:**
```vb
Private Function IsLaserOnVerticalWall(x As Integer, y As Integer) As Boolean
If x >= 0 AndAlso x < verticalWallItems.Length AndAlso
verticalWallItems(x) IsNot Nothing AndAlso
y >= 0 AndAlso y < verticalWallItems(x).Length Then
Dim item As String = verticalWallItems(x)(y)
Return item = "picLazer1" OrElse item = "picLazer2"
End If
Return False
End Function
```
5. **Ensure Consistency in Wall Item Storage:**
Verify that when lasers are placed on walls in your level data, they are stored in `verticalWallItems` and `horizontalWallItems` using the same indexing scheme that is expected when checking for lasers during ball movement.
By aligning the indices correctly, the ball will now properly detect and destroy lasers on walls as it moves through them. It's crucial that the indices used when placing lasers on walls and the indices used when checking for them during movement are consistent. This ensures that the game logic correctly identifies and interacts with lasers, allowing the ball to destroy them as intended.
---
In summary, the ball wasn't destroying the laser because the game was checking the wrong location for the laser on the wall due to inconsistent indexing. By adjusting the indices used in the collision detection logic to match where the lasers are stored, you can resolve the issue and ensure the ball interacts with lasers correctly.