Minilop Retroware

MPAGD Advanced

Horizontal moving platforms in MPAGD

14 November 2020

Platforms that move are a staple of most platform games, a genre that MPAGD is ideally suited for coding smooth 8 bit retro games. However the tool does not come with an 'off the shelf' script for horizontally moving platforms.

This is something I tried to tackle in my first game, Cocoa and the Time Machine. First, I had in mind an idea of how I wanted them to work. I had seen some attempts in other AGD games that were close, but not quite what I wanted. Predominantly these required the player to press the direction key to remain on the platform, so if the platform were moving right...the player needs to press the right key to remain on it.

But that's not what I wanted. I wanted the player to land on the platform and transported automatically, but also be able to move left and right on top of the platform to adjust their position, and jump on and off.

After many, many attempts, I got an effect that worked, although was not visually as good as it could have been, in Cocoa and the Time Machine

As you can see, Cocoa can walk or jump onto and off the platform, he can also adjust his position on the platform. The problem is more the aesthetics...the Cocoa sprite is, well, a bit jerky.

The code for this involved using a few variables so that I could tell whether the player was currently on the platform or not, and the platforms current direction of travel and so on.

In 24 Hour Parsley People I set out to improve this....and here's the new code applied to the original game:

Much nicer.

So here's how its done.

First in the Event for the platform sprite:

EVENT SPRITETYPE1


IF COLLISION 0                          	; first check if the player is colliding with the platform, if so:
	LET P = Y                              	; store the Y value of the platform in P
	OTHER					; now switch to the player sprite    
	IF P > Y				; is player above the platform?
		SUBTRACT Y FROM P		; if so, by how much?
		IF P <= 4			; if less than 4 px  landing is unsuccessful!
			ENDSPRITE						
			EXIT
		ELSE                                 
			ADD Y TO P		; reset P (the platforms Y co-ord)
			LET Y = P		; make the players Y = the platforms Y
			SUBTRACT 16 FROM Y	; now put the  player on top of the platform
			STOPFALL		; and keep the player on top
			IF KEY LEFT		; lets add in some controls for movement on the platform
				IF CANGOLEFT
					SPRITELEFT
				ENDIF
			ENDIF
			IF KEY RIGHT
				IF CANGORIGHT
					SPRITERIGHT	
				ENDIF
			ENDIF
			ENDSPRITE
		ENDIF

		IF DIRECTION = 0		; 0 means the platform is moving left but isnt carrying a player
			LET DIRECTION = 2 	; so if it was 0 when the player landed use 2 to denote CARRYING LEFT
		ELSE				; if not 0 it must be going right
			LET DIRECTION = 3	; so we'll use 3 to denote the platform is CARRYING RIGHT
		ENDIF
		IF DIRECTION = 2		; now that the platform is carrying left
			IF CANGOLEFT		; check it can still go left
				SPRITELEFT	; in which case continue
				OTHER 		; and set the players Direction to 5 (which we use in the player event)
				IF CANGOLEFT
					LET DIRECTION = 5
				ENDIF
				ENDSPRITE	; switch back to the platform
			ELSE                     
				LET DIRECTION = 3	; if platfrom cant go left anymore, switch to carrying right
			ENDIF
		ENDIF
		IF DIRECTION = 3			; now that the platform is carrying right
			IF CANGORIGHT			; check it can still go right
				SPRITERIGHT		; in which case continue
				OTHER
				IF CANGORIGHT
					LET DIRECTION = 6	; and set the players Direction to 6 (which we use in the player event)
				ENDIF
				ENDSPRITE			; switch back to the platform
			ELSE
				LET DIRECTION = 2		; if platfrom cant go right anymore, switch to carrying left
			ENDIF
		ENDIF
		EXIT
	ELSE
		ENDSPRITE
	ENDIF
ENDIF
								; if the player and platform are not colliding any more
IF DIRECTION = 2						; if it was set to CARRYING LEFT
	LET DIRECTION = 0					; switch to normal left movement (not carrying the player)
ENDIF

IF DIRECTION = 3						; if it was set to CARRYING RIGHT
	LET DIRECTION = 1					; switch to normal right movement (not carrying the player)
ENDIF

IF DIRECTION = 0						; normal left movement of the platform (not carrying the player)
	IF CANGOLEFT
		SPRITELEFT
	ELSE
		LET DIRECTION = 1
	ENDIF
ENDIF
IF DIRECTION = 1 						; normal right movement of the platform (not carrying the player)
	IF CANGORIGHT
		SPRITERIGHT
	ELSE
		LET DIRECTION = 0
	ENDIF
ENDIF

OK, so that will control how the platform will operate, check if the player is on the platform, if so keep them there and move them, but still allow them to adjust their position.

Now we're going to need some code for the player event:

IF DIRECTION = 5                          ; is the players direction set to being carried left?
   IF CANGOLEFT                           ; if so, can the player go left?
      SPRITELEFT                          ; if so, move them left
   ELSE                                   ; if not
      LET DIRECTION = 0                   ; set the players direction to normal left
   ENDIF
   ADD 16 TO Y                            ; check ahead to see if the platform is about to reach a wall block
   SUBTRACT 2 FROM X
   GETBLOCK X Y
   SUBTRACT 16 FROM Y
   ADD 2 TO X
   IF BLOCK = WALLBLOCK                   ; if it is about to reach a wallblock
      LET DIRECTION = 0                   ; change the player direction to normal left
   ENDIF
  
ENDIF


IF DIRECTION = 6                          ; is the players direction set to being carried right?
   IF CANGORIGHT                          ; if so can the player go right?
      SPRITERIGHT                         ; if so, move them right
   ELSE                                   ; if not
      LET DIRECTION =1                    ; set the players direction to normal right
   ENDIF   
   ADD 16 TO Y                            ; check ahead to see if the platform is about to reach a wall block 
   ADD 16 TO X
   GETBLOCK X Y
   SUBTRACT 16 FROM Y
   SUBTRACT 16 FROM X
   IF BLOCK = WALLBLOCK                   ; if it is about to reach a wallblock
      LET DIRECTION = 1                   ; change the player direction to normal left
   ENDIF
ENDIF

Note that in the above code I am also checking ahead to see if the platform is going to hit a wall block, this is useful for keeping the player moving in the correct direction when the platform itself changes direction...the lag between the two events also has an accidental benefit of simulating inertia as the player changes direction which you can see in the video above...bonus!

This code, also lends itself nicely to putting obstacles in the way that the player has to jump over like these ones in 24 Hour Parsley People...

I'm sure people far cleverer than me will be able to improve these, I'm just pleased that I've been able to improve them from my first game to my second :)

I also used this in the third episode of 24 Parsley People, but in a slightly different way. This time I used my Pushables code (I'll blog about that another day) but when a certain pushable item gets pushed into water it becomes a horizontal moving platform....here's what I mean...

This would have been better if I hadn't run out of memory, as I had another frame for the log so that you see it side on when it is floating in the water...ah well, such is 8bit code in 39K of available memory :)

Hope this helps!

All MPAGD Advanced