Um tutorial um pouco diferente hoje: em vez de me concentrar nos eventos de sprites inimigos, aqui está um método para adicionar quedas aleatórias de itens de bónus...e mensagens de faixa chamativas nos teus jogos MPAGD.
É algo que escrevi pela primeira vez para Cocoa and the Time Machine e que depois melhorei em 24 Hour Parsley People.
O que eu queria conseguir era...
O jogador derrota um inimigo
Cai aleatoriamente um item de bónus (escolhido entre 4 possíveis, ponderados de modo a que os mais potentes caiam com menos frequência)
O jogador apanha o item de bónus
O item de bónus concede energia/pontos/o que for
Aparece uma faixa a piscar no ecrã
Aqui está um exemplo em ação num ecrã de demonstração, usando parte do código do meu último jogo, em que o nosso herói Cocoa consegue desviar as balas dos Agentes com o Tesla Device...e quando um Agente é derrotado, largamos um item de bónus para o Cocoa apanhar.
Neste exemplo tenho quatro possíveis itens de bónus:
Standard Parsley (restaura 1/3 da saúde): 40% de probabilidade de cair
Mega Parsley (restaura toda a saúde): 12% de probabilidade de cair
Device fuel cell (restaura 1/3 da energia do dispositivo): 30% de probabilidade de cair
One Up (uma vida extra): 8% de probabilidade de cair
O que nos deixa com 10% de probabilidade de não cair nada
Aqui está em ação:
Primeiro vamos precisar de desenhar alguns OBJECTS que serão usados como os itens colecionáveis que caem; criei 4 objetos e defini-os todos como 'Hidden' (porque não serão posicionados num ecrã específico nem estarão automaticamente no inventário do jogador)
Também vamos precisar de algum texto para a nossa faixa intermitente. Vou manter o código o mais eficiente possível, por isso será boa ideia que cada número de MESSAGE corresponda ao respetivo número de OBJECT.
i.e
OBJECT 0 (Standard Parsley ) MESSAGE 0
OBJECT 1 (Ultra Parsley) MESSAGE 1
OBJECT 2 (Standard Parsley ) MESSAGE 2
OBJECT 3 (Ultra Parsley) MESSAGE 3
Por isso, abre o teu ficheiro de TEXT MESSAGES, certifica-te de que começa com DEFINEMESSAGES e adiciona as tuas mensagens. Acrescentei alguns espaços no início de algumas delas porque vamos imprimi-las no mesmo sítio do ecrã e quero que fiquem o mais centradas possível:

A seguir, vamos escrever um pouco de código que irá ativar a nossa rotina de bónus. Vou usar a variável B para a própria rotina de bónus, e em concreto o valor 2 será usado para chamar a rotina.
Vou ativar a rotina de bónus quando o inimigo for morto por uma bala ressaltada. (Por isso, poderia pô-lo no evento do sprite da bala ou no do Agente.) Neste caso coloquei-o no evento do Agente, e o sprite da bala é do Tipo 2,
IF COLLISION 2 ; has the bullet hit the agent?
LET N = X ; if so, remember the agents X & Y co-ords
LET O = Y ; store them in N & O
LET B = 2 ; start the bonus routine
REMOVE ; remove the agent
ENDIFA seguir, vamos criar a própria rotina de bónus, que selecionará um item de bónus aleatório com base nas ponderações que preferirmos; tens de a colocar num script MAIN LOOP:
IF B = 2 ; BONUS ROUTINE
GETRANDOM 50 ; get a random number from 0 to 49
IF RND <= 19 ; is it less than 20? (i.e. 40%)
PUT N O 0 ; if so, put the PARSLEY object at N O
ELSE ; if not
IF RND <= 34 ; is it less than 35 (i.e. is it 20-34 30%)
PUT N O 3 ; if so, put the DEVICE FUEL CELL object at N O
ELSE ; if not
IF RND <= 40 ; is it less than 40? (i.e 35-40 or 12%)
PUT N O 1 ; if so, put the ULTRA PARSLEY object at N O
ELSE ; if not
IF RND <= 44 ; is it less than 45? (i.e 41-44 or 8%)
PUT N O 2 ; if so, put the ONE UP object at NO
ENDIF
ENDIF
ENDIF
ENDIF
LET B = 3 ; we've slected the bonus so we change B to stop it running again
ENDIFAssim, agora, quando o jogador derrota o inimigo, há 90% de probabilidade de ser recompensado com um item de bónus para apanhar. O bónus aparecerá em N,O (que eram as coordenadas x e y do AGENTE quando foi neutralizado).
Agora vamos adicionar algum código ao evento do jogador que tratará do que acontece quando o jogador apanha o seu bónus:
DETECTOBJ ; has the player touched an object?
IF OBJ <> 255 ; is it valid?
BEEP 25 ; make a sound
GET OBJ ; collect the object
IF OBJ = 0 ; is it the standard parsley?
ADD 33 TO L ; if so, increase health by 33
ENDIF
IF OBJ = 1 ; is it the mega parsley?
LET L = 99 ; if so, max the health
ENDIF
IF OBJ = 2 ; is it the one-up?
ADD 1 TO LIVES ; add an extra life
ENDIF
IF OBJ = 3 ; is it the device fuel cell?
ADD 33 TO V ; increase the device power by 33
ENDIF
IF OBJ > 0 ; if it was a Bonus drop object collectded
IF OBJ <= 3
LET B = 5 ; trigger the banner
LET N = OBJ ; we'll store the object number in N so that we can call the correct message in the banner
ENDIF
ENDIF
ENDIFBem, isso tratará da recompensa do jogador quando apanhar o bónus; agora queremos imprimir no ecrã uma faixa chamativa, só por diversão
Voltemos ao script MAIN LOOP e, por baixo do nosso IF B=2 ...ENDIF, vamos acrescentar o código da faixa:
IF B = 5 ; the banner routine
PRINTMODE 1 ; let's use big text!
GETRANDOM 8 ; get a random number from 0 to 7
INK RND ; make the ink that colour
AT 9 9 ; this is where the banner will appear on screen
MESSAGE N ; display the objects corresponding message
ADD 1 TO C ; we'll use C as a counter
IF C = 30 ; has the banner flashed 30 times?
LET C = 0 ; reset the counter
LET B = 0 ; end the bonus
REDRAW ; remove the banner from the screen
PRINTMODE 0 ; go back to normal text size
ENDIF
ENDIFComo podes ver no código acima, uso a variável C como contador para que a faixa pisque 30 vezes. Escolhi este método em vez de um ciclo REPEAT porque queria que o jogo continuasse enquanto a faixa está ativa, em vez de ter de esperar que a faixa termine antes de avançar.
E é isto na sua forma mais simples.
Obviamente, podes personalizá-lo ao teu gosto. Uso a rotina da faixa para várias outras coisas nos meus jogos, mas, no essencial, é assim que o faço.
Espero que isto ajude!
