A problem in my Game

Nomestack 61 Reputation points
2021-03-28T14:42:53.9+00:00

I'm creating a game in small basic but the player can get through the walls and I don't understand why this happens, can someone help me?

GraphicsWindow.BackgroundColor = "Black"
GraphicsWindow.BrushColor = "White"
GraphicsWindow.PenWidth = 0
GraphicsWindow.Title = "Maze"
GraphicsWindow.Width = 640
GraphicsWindow.Height = 480
dir = Program.Directory
data = dir + "\maze_data.txt" ' this is an external file that stores the game levels

GraphicsWindow.KeyDown = KeyDown

SetGameVariables()

Sub SetGameVariables
  TileWidth = 20
  TileHeight = 20
  PlayerSpeed = 20
  PlayerWidth = 20
  PlayerHeight = 20
  LevelWidth = 32
  LevelHeight = 24
  CurrentLevel = 1
EndSub

Level1()

Sub Level1

  IsPlaying = "True"

  For i = 1 To 24
    Row[i] = File.ReadLine(data,i)
  EndFor

  GraphicsWindow.BrushColor = "Blue"
  Player = Shapes.AddRectangle(PlayerWidth,PlayerHeight)
  GraphicsWindow.BrushColor = "Red"
  HitboxUp = Shapes.AddRectangle(PlayerWidth,PlayerHeight)
  Shapes.SetOpacity(HitboxUp,50)
  HitboxLeft = Shapes.AddRectangle(PlayerWidth,PlayerHeight)
  Shapes.SetOpacity(HitboxLeft,50)
  HitboxRight = Shapes.AddRectangle(PlayerWidth,PlayerHeight)
  Shapes.SetOpacity(HitboxRight,50)
  HitboxDown = Shapes.AddRectangle(PlayerWidth,PlayerHeight)
  Shapes.SetOpacity(HitboxDown,50)

  For y = 1 To 24
    For x = 1 To 32
      If Text.GetSubText(Row[y],x,1) = "1" Then
        GraphicsWindow.BrushColor = "White"
        Build_Block()
      EndIf
      If Text.GetSubText(Row[y],x,1) = "S" Then
        PlayerX = x * TileWidth - TileWidth
        PlayerY = y * TileHeight - TileHeight
        Shapes.Move(Player,x * TileWidth - TileWidth, y * TileHeight - TileHeight)
      EndIf
    EndFor
  EndFor
EndSub

Sub Build_Block
  TextWindow.WriteLine("[Build a block]")
  BlockCount = BlockCount + 1
  TextWindow.WriteLine(" -> Block Index: " + BlockCount)
  Block[BlockCount] = Shapes.AddRectangle(20,20)
  Shapes.Move(Block[BlockCount],x * TileWidth - TileWidth, y * TileHeight - TileHeight)
  BlockPosX[BlockCount] = x * TileWidth - TileWidth
  BlockPosY[BlockCount] = y * TileHeight - TileHeight
  TextWindow.WriteLine(" -> BlockPosX: " + BlockPosX[BlockCount])
  TextWindow.WriteLine(" -> BlockPosY: " + BlockPosY[BlockCount])
EndSub

Sub CheckCollisions
  For i = 1 To Array.GetItemCount(BlockPosX)
    If Shapes.GetLeft(HitboxLeft) = BlockPosX[i] Then
      CanMoveLeft = "False"
    Else
      CanMoveLeft = "True"
    EndIf
  EndFor
  For i = 1 To Array.GetItemCount(BlockPosX)
    If Shapes.GetLeft(HitboxRight) = BlockPosX[i] Then
      CanMoveRight = "False"
    Else
      CanMoveRight = "True"
    EndIf
  EndFor
  For i = 1 To Array.GetItemCount(BlockPosY)
    If Shapes.GetTop(HitboxUp) = BlockPosY[i] Then
      CanMoveUp = "False"
    Else
      CanMoveUp = "True"
    EndIf
  EndFor
  For i = 1 To Array.GetItemCount(BlockPosY)
    If Shapes.GetTop(HitboxDown) = BlockPosY[i] Then
      CanMoveDown = "False"
    Else
      CanMoveDown = "True"
    EndIf
  EndFor
  TextWindow.WriteLine("Down: " + CanMoveDown)
  TextWindow.WriteLine("Left: " + CanMoveLeft)
  TextWindow.WriteLine("Up: " + CanMoveUp)
  TextWindow.WriteLine("Right: " + CanMoveRight)
EndSub

Sub KeyDown
  Key = GraphicsWindow.LastKey
  If Key = "W" And CanMoveUp Then
    PlayerY = PlayerY - PlayerSpeed
    Shapes.Move(Player,PlayerX,PlayerY)
  ElseIf Key = "A" And CanMoveLeft Then
    PlayerX = PlayerX - PlayerSpeed
    Shapes.Move(Player,PlayerX,PlayerY)
  ElseIf Key = "S" And CanMoveDown Then
    PlayerY = PlayerY + PlayerSpeed
    Shapes.Move(Player,PlayerX,PlayerY)
  ElseIf Key = "D" And CanMoveRight Then
    PlayerX = PlayerX + PlayerSpeed
    Shapes.Move(Player,PlayerX,PlayerY)
  EndIf
  Shapes.Move(HitboxLeft,PlayerX-PlayerWidth,PlayerY)
  Shapes.Move(HitboxUp,PlayerX,PlayerY-PlayerHeight)
  Shapes.Move(HitboxDown,PlayerX,PlayerY+PlayerHeight)
  Shapes.Move(HitboxRight,PlayerX+PlayerWidth,PlayerY)
  CheckCollisions()
EndSub
Small BASIC
Small BASIC
A programming language created by Microsoft that serves a stepping stone for beginners from block-based coding languages to more complex text-based languages.
277 questions
{count} votes

Accepted answer
  1. WhTurner 1,611 Reputation points
    2021-03-30T15:23:48.747+00:00

    I made some changes to the Sub CheckCollisions, and now I think it works as you want, even for some blocks in the middle of the playfield. You can move around them, but not aross them.

    Sub CheckCollisions
      CanMoveLeft = "True"
      CanMoveRight = "True"
      CanMoveUp = "True"
      CanMoveDown = "True"
      For i = 1 To Array.GetItemCount(BlockPosX)
        If BlockPosY[I]=PlayerY Then
          If Shapes.GetLeft(HitboxLeft) = BlockPosX[i] Then
            CanMoveLeft = "False"
          EndIf
          If Shapes.GetLeft(HitboxRight) = BlockPosX[i] Then
            CanMoveRight = "False"
          EndIf
        EndIf
      EndFor
      For i = 1 To Array.GetItemCount(BlockPosY)
        If BlockPosX[i]=PlayerX Then
          If Shapes.GetTop(HitboxUp) = BlockPosY[i] Then
            CanMoveUp = "False"
          EndIf
          If Shapes.GetTop(HitboxDown) = BlockPosY[i] Then
            CanMoveDown = "False"
          EndIf
        EndIf
      EndFor
      TextWindow.WriteLine(" Down: " + CanMoveDown)
      TextWindow.WriteLine(" Left: " + CanMoveLeft)
      TextWindow.WriteLine("   Up: " + CanMoveUp)
      TextWindow.WriteLine("Right: " + CanMoveRight)
    EndSub
    
    1 person found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. WhTurner 1,611 Reputation points
    2021-03-28T17:22:50.217+00:00

    Can tou publish the maze_data.txt file?
    Testing without these file is difficult ;-)

    1 person found this answer helpful.

  2. Nonki Takahashi 676 Reputation points
    2021-03-30T12:22:12.27+00:00

    We have four flags CanMoveLeft/Right/Up/Down. Let's start to check the conditions to set CanMoveLeft flag.

      For i = 1 To Array.GetItemCount(BlockPosX)
        If Shapes.GetLeft(HitboxLeft) = BlockPosX[i] Then
          CanMoveLeft = "False"
        Else
          CanMoveLeft = "True"
        EndIf
      EndFor
    

    But this code is equivalent as:

      i = Array.GetItemCount(BlockPosX)
      If Shapes.GetLeft(HitboxLeft) = BlockPosX[i] Then
        CanMoveLeft = "False"
      Else
        CanMoveLeft = "True"
      EndIf
    

    If the player's position is (2, 13), HitboxLeft's position is (1, 13). And i is 32, so BlockPosX[i] is 620.
    Shapes.GetLeft(HitboxLeft) is 0. So CanMoveLeft becomes "True".

    0 comments No comments