question

Nomestack-4849 avatar image
0 Votes"
Nomestack-4849 asked JanWieldraaijer-1495 answered

A problem in my Game

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
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @Nomestack-4849. Your game seems that using ASWD keys to move the player and CheckCollisions works good on the right and the bttom wall, but doesn't work well on the left and the top wall, right?

0 Votes 0 ·
JanWieldraaijer-1495 avatar image
1 Vote"
JanWieldraaijer-1495 answered

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
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JanWieldraaijer-1495 avatar image
1 Vote"
JanWieldraaijer-1495 answered Nomestack-4849 edited

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

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

11111111111111111111111111111111
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
1000000000000000S000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
10000000000000000000000000000001
11111111111111111111111111111111

1 = block
S = player start position

0 Votes 0 ·
NonkiTakahashi avatar image
0 Votes"
NonkiTakahashi answered

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".

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.