Minilop Retroware

Tutoriais de shoot 'em up · Parte 4 de 12

Shmup vertical - Parte 4 - A arma do jogador

2 de agosto de 2022

Até agora temos uma nave espacial que o jogador pode controlar; agora vamos dar-lhe uma arma que possa disparar. Primeiro, temos de ter em conta que, por defeito, o MPAGD trabalha com sprites de 16 x 16 píxeis, por isso vamos inicialmente criar uma arma de 16 x 16.

Vamos criar o sprite da arma:

MENU: EDITOR > SPRITES

Prime X para acrescentar um novo sprite e cria os teus Torpedos de Fotões (ou o que quiseres que a nave inimiga dispare!). Este é o meu:

Captura de ecrã do tutorial

Agora, antes de começarmos a programar, há duas coisas que temos de ter em conta:

1) O MPAGD só consegue lidar com 12 sprites no ecrã em simultâneo, por isso vamos ter de controlar quantos estão em jogo.

2) Vamos querer verificar que o jogador largou a tecla de disparo de cada vez que dispara, sem disparo automático, por isso vamos ter de verificar o debouncing da tecla (key debouncing).

Cada uma destas coisas resolve-se com bastante facilidade.

Controlar os sprites no ecrã

Vamos usar uma variável, S, para manter a contagem de quantos sprites estão no ecrã em cada momento. Sempre que aparece um inimigo, ou é disparado um torpedo, incrementamos a contagem, garantindo que nunca passa de 12. Da mesma forma, sempre que um é removido, decrementamos a contagem (S).

Para começar, vamos pôr S a 0 no evento RESTART SCREEN e depois fazer ADD 1 a S por cada sprite quando é inicializado:

MENU: EVENTS > RESTART SCREEN

EVENT RESTARTSCREEN

LET S = 0			; initialise the sprite counter

MENU: EVENTS > INITIALISE SPRITES

EVENT INITSPRITE

ADD 1 TO S            ; increment the sprite counter

Assim, quando o ecrã é desenhado, S começa em 0 e é incrementado por cada sprite que é depois colocado no ecrã

A seguir, vamos escrever código para os Torpedos de Fotões (a arma) que defina o que acontece quando o jogador dispara um. Vamos usar o Sprite type 1 para a arma:

MENU: EVENTS > SPRITE TYPE 1

Q

EVENT SPRITETYPE1

							; PHOTON TORPEDOS
							; ====================


IF DIRECTION 1				; Torpedo travel up
	LET IMAGE = 1				; make sure we are on image 1
	REPEAT 6					; torpedos move quick, so do this 6 times
	SPRITEUP					; move up
	ADD 2 TO SETTINGB			; increase the distance counter by 2
	IF SETTINGB > = 88		; when distance travelled = 88
		LET DIRECTION = 99	; run the explode routine
	ENDIF
		IF Y <= 8			; has the torpedo reached the top?	
		LET DIRECTION = 99	; yes, so explode it
		EXIT				; exit this event (as we are in a loop)
	ENDIF
	ENDREPEAT
ENDIF

IF DIRECTION = 99				; explode the torpedo
	REMOVE					; remove the torpedo
	SUBTRACT 1 FROM S			; decrement the sprite counter
ENDIF

Tal como em Arcadia, os torpedos do jogador não percorrem a altura total do ecrã, explodem depois de percorrerem metade dessa altura, por isso vamos fazer o mesmo. Usei a variável local SETTINGB para calcular quando o torpedo percorreu 88 pixels e, nesse momento, mudamos a sua DIRECTION para 99, que é uma sub-rotina que fará explodir o torpedo. Mais tarde vamos desenhar um gráfico de explosão; por agora, vamos apenas remover o sprite e decrementar a variável contadora de sprites (S).

Não te esqueças de atualizar o evento Initialise Sprite para pôr SETTINGB a 0 quando um torpedo é inicializado pela primeira vez.

EVENT INITSPRITE

ADD 1 TO S				; increment the sprite counter

IF TYPE 1				; PHOTON TORPEDO
	LET SETTINGB = 0		; initialise the distance counter
ENDIF

A seguir, vamos voltar ao evento do jogador e acrescentar o código para o botão FIRE:

EVENT PLAYER
AT 0 14 DISPLAY TRIPLEDIGITS S

						; COLOURS
						; =======================
SPRITEINK 69				; Bright Cyan ink

IF KEY UP				; Player presses up (thrust)
	LET FRAME = 1			; switch to the frame that shows jetflame
	IF Y > 92 			; If player is below the 80 y pixel line
		SPRITEUP			; move player up
		SPRITEUP			; and up again (faster movement)
	ENDIF
ELSE						; if player is not pressing thrust
	LET FRAME = 0			; switch to the regular spaceship (no jetflame)
	SPRITEDOWN			; move player down
ENDIF

						; PLAYER MOVEMENT
						; ====================
IF KEY LEFT				; has player pressed LEFT?
	IF CANGOLEFT			; can the player move left?	
		SPRITELEFT		; yes, move player left
		SPRITELEFT		; and again (moves faster)
	ENDIF 
ENDIF

IF KEY RIGHT				; has the player pressed RIGHT?			
	IF CANGORIGHT			; yes, can the player move right?				
		SPRITERIGHT		; yes, move player right
		SPRITERIGHT		; and again (moves faster)
	ENDIF									
ENDIF

								; FIRE PHOTON TORPEDOS
								; ====================
IF KEY FIRE						; if player presses fire key
	IF SETTINGA = 0				; if firekey is debounced
		IF S < 12				; and if less than 12 on screen
			SPAWN 1 1			; spawn a bullet
			LET SETTINGA = 1		; bounce the fire key
			SPAWNED				; switch to the Photon Torpedo
			LET DIRECTION = 1		; set its direction to 1 (up)
			ENDSPRITE			; return to this sprite
		ENDIF
	ENDIF
ELSE								; fire key not pressed
	LET SETTINGA = 0				; debounce it
ENDIF				


						; BOUNDARY CHECK
						; ====================
IF Y >= BOTTOMEDGE		; has player gone beyond the bottom edge?
	LET Y = BOTTOMEDGE	; yes, keep them at the bottom edge
ENDIF

Vamos testá-lo, compilando o jogo

Está a funcionar como esperado. Agora vamos melhorá-lo criando uma explosão, para o que vamos acrescentar mais alguns fotogramas ao nosso sprite do torpedo:

Captura de ecrã do tutorialCaptura de ecrã do tutorialCaptura de ecrã do tutorialCaptura de ecrã do tutorial

Agora vamos atualizar a nossa sub-rotina de explosão no evento do torpedo (SPRITE TYPE 1). Destaquei o código novo abaixo:

EVENT SPRITETYPE1

						; PHOTON TORPEDOS
						; ====================


IF DIRECTION 1			; Torpedo travel up
	LET IMAGE = 1			; make sure we are on image 1
	REPEAT 6				; torpedos move quick, so do this 6 times
	SPRITEUP				; move up
	ADD 2 TO SETTINGB		; increase the distance travelled counter by 2
	IF SETTINGB > = 88	; when distance travelled = 88
		LET DIRECTION = 99; run the explode routine
	ENDIF
	IF Y <= 8			; has torpedo reached the top?
		LET DIRECTION = 99; yes, so explode it
		EXIT				; quit this event as we are in a loop
	ENDIF	
	ENDREPEAT
ENDIF

IF DIRECTION = 99			; explode the torpedo
	ADD 1 TO FRAME		; increment the frame
	IF FRAME = 5			; when we reach the last frame
		REMOVE			; remove the torpedo
		SUBTRACT 1 FROM S	; decrement the sprite counter
	ENDIF
ENDIF

Muito bem, já temos a nossa nave espacial, que se pode mover e disparar torpedos... acho que vamos precisar de um inimigo!

SEGUINTE: PARTE 4: O NOSSO PRIMEIRO INIMIGO EXTRATERRESTRE

Todos os tutoriais de shoot 'em up