Block- Man Script

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

Re: Block- Man Script

Post by Bugala »

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

Post by ocean77 »

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: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Re: Block- Man Script

Post by Bugala »

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: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Re: Block- Man Script

Post by Bugala »

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

Post by ocean77 »

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: 352
Joined: Thu May 02, 2019 11:53 am

Re: Block- Man Script

Post by amyren »

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)
*/

Function p_UpdateScreen()
    
    ;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()
	p_UpdateScreen()
	Flip()
Forever
EndDoubleBuffer()
amyren
Posts: 352
Joined: Thu May 02, 2019 11:53 am

Re: Block- Man Script

Post by amyren »

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)
*/

Function p_UpdateScreen()
    
    ;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()
	p_UpdateScreen()
	Flip()
Forever
EndDoubleBuffer()
Post Reply