## Block- Man Script

The place for any Hollywood tutorials
Bugala
Posts: 1132
Joined: Sun Feb 14, 2010 7:11 pm

### Re: Block- Man Script

I think what you after with this one:

Code: Select all

``````elseif Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Xpos >= BL_Xpos
BM_XPos, BM_YPos = BM_XPos, BL_YPos - 16 ; Handle collision with top side of obstacle
DebugPrint("Hit The Top Side")
EndIf``````
Is actually:

Code: Select all

``elseif Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Ypos >= BL_Ypos + 32``

For in original version you were checking X-postition instead of Y-position
ocean77
Posts: 111
Joined: Mon Jan 28, 2019 8:34 pm

### Re: Block- Man Script

As far as I can tell each of the conditions do what they are supposed to, I just can't get them all to be considered. Just two at a time. I tested this by commenting out first the top two and then the bottom two.
Bugala
Posts: 1132
Joined: Sun Feb 14, 2010 7:11 pm

### Re: Block- Man Script

I think I can take tomorrow a better look. But didnt realise it yesterday yet, but seeing this again now I think I know what is likely the problem.

Thing is, you are assuming there are four different possibilities to collide. Left, Right, Top, Bottom.

But in reality you have only Two collisions happening, the first two: Left and Right.

For thing is, when you have collision that would fulfill TOP or BOTTOM, it will also at same time fulfill one of the LEFT or RIGHT conditions.

Thing is,

Code: Select all

``````IF Condition 1
ELSEIF Condition 2
ELSEIF Condition 3
ENDIF``````
Work in such way that if Condition 1 is fulfilled, then it doesnt even check Condition 2 and 3 at all.

So in this case you could have that Condition 2 (LEFT) and Condition 3 (BOTTOM) are both fulfilled, and in this case, only Condition 2 is executed, since it happens first in the list.

Since Collision in your code in practice always happens from two different sides at same time.

As an example:

Code: Select all

``````AAAAA
A   A
A   A
XXXXX
XAAAX
B   B
B   B
BBBBB
``````

You might think that Box B is hitting Box A from Bottom, which is true, but, B is also touching A from LEFT side, since they both have same X.

Therefore in your IF-ELSEIF-ELSEIF, it notices that condition of hitting from LEFT side is already true before it checks the BOTTOM, and hence the BOTTOM check is never checked or executed.
Bugala
Posts: 1132
Joined: Sun Feb 14, 2010 7:11 pm

### Re: Block- Man Script

Actually, to test this, try running this code:

Code: Select all

``````if Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Xpos =< BL_Xpos
BM_XPos, BM_YPos = BL_XPos - 16, BM_YPos ; Handle collision with left side of obstacle
DebugPrint("Hit The Left Side")
endif

if Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Xpos =< BL_Xpos + 32
BM_XPos, BM_YPos = BL_XPos + 32, BM_YPos ; Handle collision with right side of obstacle
DebugPrint("Hit The Right Side")
endif

if Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Ypos >= BL_Ypos
BM_XPos, BM_YPos = BM_XPos, BL_YPos + 32 ; Handle collision with bottom side of obstacle
DebugPrint("Hit The Bottom Side")
endif

if Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Xpos >= BL_Xpos
BM_XPos, BM_YPos = BM_XPos, BL_YPos - 16 ; Handle collision with top side of obstacle
DebugPrint("Hit The Top Side")
EndIf``````
Now it will check every condition and run those codes.

Basically I expect it to result in printing two conditions each time. One of LEFT-RIGHT and one of TOP-BOTTOM. Since every time there is a collision, two of those conditions will always be true if I checked right.
ocean77
Posts: 111
Joined: Mon Jan 28, 2019 8:34 pm

### Re: Block- Man Script

That doesn't work as intended.

If I reorganize them as follows:

Code: Select all

`````` if Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Xpos =< BL_Xpos
BM_XPos, BM_YPos = BL_XPos - 16, BM_YPos ; Handle collision with left side of obstacle
DebugPrint("Hit The Left Side")

elseif Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Ypos >= BL_Ypos
BM_XPos, BM_YPos = BM_XPos, BL_YPos + 32 ; Handle collision with bottom side of obstacle
DebugPrint("Hit The Bottom Side")

elseif Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Xpos >= BL_Xpos
BM_XPos, BM_YPos = BM_XPos, BL_YPos - 16 ; Handle collision with top side of obstacle
DebugPrint("Hit The Top Side")

elseif Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) = True and BM_Xpos =< BL_Xpos + 32
BM_XPos, BM_YPos = BL_XPos + 32, BM_YPos ; Handle collision with right side of obstacle
DebugPrint("Hit The Right Side")

EndIf``````
Then all sides except the right one works... Well almost. The player still slips along the sides of the obstacle if it's too close to the corner.

I kind of want each of the obstacle's sides to trigger a separate event.
amyren
Posts: 344
Joined: Thu May 02, 2019 11:53 am

### Re: Block- Man Script

This seem to work

Code: Select all

``````@DISPLAY{WIDTH = 800, HEIGHT = 600, MODE = "WINDOWED"} ;Create the window

CreateBrush(1, 16, 16, #GREEN)  ; CREATE BLOCK-MAN
CreateBrush(2, 32, 32, #GRAY)   ; CREATE OBSTICLE

BM_Xpos = #CENTER ; Set initial X-position
BM_Ypos = #CENTER ; Set initial Y-position
SPEED = 3 ; Set the movement speed
SPEED45=Sqrt(SPEED^2/2)

BL_Xpos = 400 ; Obstacle position
BL_Ypos = 300

/*
speed as vector, Pythagoras:
SPEEDX^2+SPEEDY^2 =      SPEED^2
SPEEDX^2          =      SPEED^2-SPEEDY^2
SPEEDX            = Sqrt(SPEED^2-SPEEDY^2)
SPEEDY            = Sqrt(SPEED^2-SPEEDX^2)
*/

;Check Key-presses and move Block-Man:
;SPEEDX=Sqrt(SPEED^2/2)
SPEEDX=SPEED45 ; calculate this only one time
SPEEDY=SPEEDX ; (because 45°)

If Not IsKeyDown("LEFT") And Not IsKeyDown("RIGHT")
SPEEDX=0
SPEEDY=SPEED
EndIf

If Not IsKeyDown("UP") And Not IsKeyDown("DOWN")
SPEEDY=0
SPEEDX=SPEED
EndIf

If IsKeyDown("LEFT") = True Then BM_XPos = BM_XPos - SPEEDX
If IsKeyDown("RIGHT") = True Then BM_XPos = BM_XPos + SPEEDX
If IsKeyDown("UP") = True Then BM_YPos = BM_YPos - SPEEDY
If IsKeyDown("DOWN") = True Then BM_Ypos = BM_Ypos + SPEEDY

;Check if Block-Man leaves the screen and reposition if he does:
If BM_XPos < 0 Then BM_XPos = 0
If BM_XPos > 784 Then BM_XPos = 784
If BM_Ypos < 0 Then BM_Ypos = 0
If BM_Ypos > 584 Then BM_Ypos = 584

;Check if we're colliding with obstacle:

; Can only get two of these conditions to work:

If Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Xpos =< BL_Xpos And BM_Xpos+12 < BL_Xpos
BM_XPos, BM_YPos = BL_XPos - 16, BM_YPos ; Handle collision with left side of obstacle
DebugPrint("Hit The Left Side")

ElseIf Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Ypos >= BL_Ypos-31 And BM_Ypos > BL_Ypos+28
BM_XPos, BM_YPos = BM_XPos, BL_YPos + 32 ; Handle collision with bottom side of obstacle
DebugPrint("Hit The Bottom Side")

ElseIf Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Ypos =< BL_Ypos And BM_Ypos+12 < BL_Ypos
BM_XPos, BM_YPos = BM_XPos, BL_YPos - 16 ; Handle collision with top side of obstacle
DebugPrint("Hit The Top Side")

ElseIf Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Xpos =< BL_Xpos+31 And BM_Xpos > BL_Xpos+28
BM_XPos, BM_YPos = BL_XPos + 32, BM_YPos ; Handle collision with right side of obstacle
DebugPrint("Hit The Right Side")
EndIf

;Display our elements at their respective positions:
DisplayBrush(1, BM_Xpos, BM_Ypos)
DisplayBrush(2, BL_XPos, BL_Ypos)
EndFunction

BeginDoubleBuffer()
EscapeQuit(True)
Repeat
Cls()
Flip()
Forever
EndDoubleBuffer()
``````
amyren
Posts: 344
Joined: Thu May 02, 2019 11:53 am

### Re: Block- Man Script

Removed some redundant conditions.
The reason for using +12 and +28 for the conditions is the size of the boxes. Both BM an BX coordinates are the upper left corner of the box. So when collision apears at the left and top side you must consider the width/height of BM for the comparisation, for the right/bottom the width/height of the BL box. And then there is the movement speed, which is 3. Meaning it moves 3 steps at the time. You could also use +15-SPEED and +31-SPEED like in the example below.

The #CENTER alignment argument for the BM positions can not be used here, so better use an actual values for the startposition.

Code: Select all

``````@DISPLAY{WIDTH = 800, HEIGHT = 600, MODE = "WINDOWED"} ;Create the window

CreateBrush(1, 16, 16, #GREEN)  ; CREATE BLOCK-MAN
CreateBrush(2, 32, 32, #GRAY)   ; CREATE OBSTICLE

BM_Xpos = 380 ; Set initial X-position
BM_Ypos = 300 ; Set initial Y-position
SPEED = 4 ; Set the movement speed
SPEED45=Sqrt(SPEED^2/2)

BL_Xpos = 400 ; Obstacle position
BL_Ypos = 300

/*
speed as vector, Pythagoras:
SPEEDX^2+SPEEDY^2 =      SPEED^2
SPEEDX^2          =      SPEED^2-SPEEDY^2
SPEEDX            = Sqrt(SPEED^2-SPEEDY^2)
SPEEDY            = Sqrt(SPEED^2-SPEEDX^2)
*/

;Check Key-presses and move Block-Man:
;SPEEDX=Sqrt(SPEED^2/2)
SPEEDX=SPEED45 ; calculate this only one time
SPEEDY=SPEEDX ; (because 45°)

If Not IsKeyDown("LEFT") And Not IsKeyDown("RIGHT")
SPEEDX=0
SPEEDY=SPEED
EndIf

If Not IsKeyDown("UP") And Not IsKeyDown("DOWN")
SPEEDY=0
SPEEDX=SPEED
EndIf

If IsKeyDown("LEFT") = True Then BM_XPos = BM_XPos - SPEEDX
If IsKeyDown("RIGHT") = True Then BM_XPos = BM_XPos + SPEEDX
If IsKeyDown("UP") = True Then BM_YPos = BM_YPos - SPEEDY
If IsKeyDown("DOWN") = True Then BM_Ypos = BM_Ypos + SPEEDY

;Check if Block-Man leaves the screen and reposition if he does:
If BM_XPos < 0 Then BM_XPos = 0
If BM_XPos > 784 Then BM_XPos = 784
If BM_Ypos < 0 Then BM_Ypos = 0
If BM_Ypos > 584 Then BM_Ypos = 584

;Check if we're colliding with obstacle:

; Can only get two of these conditions to work:

If Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Xpos+15-SPEED < BL_Xpos
BM_XPos, BM_YPos = BL_XPos - 16, BM_YPos ; Handle collision with left side of obstacle
DebugPrint("Hit The Left Side")

ElseIf Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Ypos > BL_Ypos+31-SPEED
BM_XPos, BM_YPos = BM_XPos, BL_YPos + 32 ; Handle collision with bottom side of obstacle
DebugPrint("Hit The Bottom Side")

ElseIf Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Ypos+15-SPEED < BL_Ypos
BM_XPos, BM_YPos = BM_XPos, BL_YPos - 16 ; Handle collision with top side of obstacle
DebugPrint("Hit The Top Side")

ElseIf Collision(#BRUSH, 1, BM_XPos, BM_YPos, 2, BL_Xpos, BL_Ypos ) And BM_Xpos > BL_Xpos+31-SPEED
BM_XPos, BM_YPos = BL_XPos + 32, BM_YPos ; Handle collision with right side of obstacle
DebugPrint("Hit The Right Side")
EndIf

;Display our elements at their respective positions:
DisplayBrush(1, BM_Xpos, BM_Ypos)
DisplayBrush(2, BL_XPos, BL_Ypos)
EndFunction

BeginDoubleBuffer()
EscapeQuit(True)
Repeat
Cls()