Isto surgiu de um pedido no fórum do MPAGD e, como já tinha criado a mecânica em Cocoa and the Time Machine e a tinha expandido e melhorado em 24 Hour Parsley People, não foi muito difícil criar uma versão simplificada que podes usar como base e depois adaptar e expandir para os teus jogos MPAGD.
O nosso objetivo é criar um caixote que o jogador possa empurrar para a esquerda e para a direita, e em que possa saltar para chegar a plataformas mais altas.
Além disso, vamos sujeitá-lo à gravidade, de modo que se o jogador o empurrar para fora de uma plataforma, caia para a plataforma de baixo.
No MPAGD padrão existe um script de sprite empurrável, mas não é muito adequado para um jogo de plataformas 2D; originalmente usei-o como ponto de partida, mas no fim reescrevi-o e simplifiquei-o (estava a tentar poupar o máximo de bytes possível!).
Então, é isto que deves obter...
Então, a primeira coisa de que vamos precisar é de um par de variáveis que guardem as coordenadas X e Y do jogador; na minha demo uso V & W, por isso no script do teu jogador adiciona as seguintes linhas:
LET V = X LET W = Y
Agora cria um evento para o teu caixote, é aqui que vai ser feito todo o trabalho. Adiciona o seguinte código (substitui V & W se já tiveres outras variáveis para os valores X e Y do teu jogador)
;======================================PUSHABLE CRATES
IF IMAGE 5 ; image 5 is my pushable crate
SPRITEINK 6
FALL ; let gravity do its thing
IF COLLISION PLAYER ; is the player touching the crate?
IF X < V ; is crate on left of player?
LET SETTINGA = LEFT ; if so we will push it left
ELSE ; if not
LET SETTINGA = RIGHT ; crate is on the right so we'll push it right
ENDIF
IF W > Y ; is player lower than the crate?
IF SETTINGA = LEFT ; and if crate is on the left
OTHER ; push fails so move the player back to the right
UNDOSPRITEMOVE
ENDSPRITE
ELSE
IF SETTINGA = RIGHT ; and if crate is on the right
OTHER ; push fails so move player to the left
UNDOSPRITEMOVE
ENDSPRITE
ENDIF
ENDIF
ENDIF
IF Y > W ; if player is higher than the crate
SUBTRACT W FROM Y ; how much higher is the player?
IF Y >= 9 ; if it is 9 or more pixels
OTHER ; switch to the player
IF CANGOUP ; if there is space
STOPFALL ; stop the player on the crate
SUBTRACT 1 FROM Y ; required to prevent player/crate overlapping
ENDIF
ENDSPRITE
ENDIF
ADD W TO Y ; reset the crates Y value
ELSE ; if player less than 9px above, landing fails
IF SETTINGA = LEFT ; if crate is on left
OTHER ; push has failed so move player to the right
UNDOSPRITEMOVE
ENDSPRITE
ELSE ; else crate is on right
OTHER ; push has failed so move player to the left
UNDOSPRITEMOVE
ENDSPRITE
ENDIF
ENDIF
IF W = Y ; if player is level with the crate push success!
IF SETTINGA = LEFT ; if crate is on the left of player
IF CANGOLEFT ; and there is room to the left
SPRITELEFT ; push the crate left
ELSE ; but if there is no room to push the crate
OTHER ; switch to the player
IF CANGORIGHT ; if there is space to the right
SPRITERIGHT ; move the player right
ENDIF
ENDSPRITE
ENDIF
ENDIF
IF SETTINGA = RIGHT ; if crate is on the right of player
IF CANGORIGHT ; and there is room to the right
SPRITERIGHT ; push the crate right
ELSE ; but if there is no room to push the crate
OTHER ; switch to the player
IF CANGOLEFT ; if there is space to the left
SPRITELEFT ; move the player left
ENDIF
ENDSPRITE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIFEsta é uma versão muito simplificada da que usei nos meus jogos, mas é a mecânica essencial; claro que a podes adaptar ao teu jogo. Coisas com que a podes expandir:
O que deve acontecer se um inimigo colidir com um caixote?
O que deve acontecer se um caixote for empurrado contra um inimigo? (talvez esmagá-lo contra a parede!)
O que acontece se um caixote for empurrado contra outro caixote? (em Cocoa 2: 24 Hour Parsley People tenho caixotes que podem ser empilhados uns sobre os outros)
Espero que esta mecânica base te ajude no desenvolvimento dos teus próprios jogos e te dê ideias para criar mecânicas novas e únicas!
*ATUALIZAÇÃO: alterei o código acima para que agora use o comando UNDOSPRITEMOVE em vez de somar e subtrair ao X do jogador quando um empurrão falha; acho que é uma melhor utilização da linguagem de scripting do MPAGD
