Como desenvolver outro jogo de plataformas usando o Unity. Outro tutorial, parte 2

Na continuação do primeiro artigo ( aqui ), continuo desenvolvendo um jogo de plataformas baseado no artigo “Padrões de Design de Nível para Jogos 2D” .

Após o lançamento do primeiro artigo, foi decidido inequivocamente que o controle de botão descrito nele não era completamente conveniente. Portanto, os controles do jogo foram refeitos no joystick. Além disso, infelizmente, o jogo não passou por moderação no mercado de jogos. Na sexta-feira passada recebi uma notificação de que o projeto foi rejeitado devido à coleta de metadados. A propósito, meu primeiro jogo de plataforma, “Knight Kadavar”, também foi rejeitado pela primeira vez por causa de um suposto pedido de permissão para gerenciar chamadas e visualizar SMS (o que era uma total estupidez por parte do bot deles. O jogo não exigia nenhuma permissão). O Google então exigiu de mim um aviso por escrito sobre o motivo de eu precisar. Mas tudo terminou com o fato de eu corrigir alguns erros que notei e enviar o jogo à re-moderação. Ela foi adicionada com sucesso ao mercado de brinquedos. Agora, pretendo fazer exatamente o mesmo com este jogo.

Assim, assim que a segunda cena foi criada, o padrão foi fechado automaticamente

Scene


um fragmento de um nível / mundo baseado em um conceito é geralmente uma dificuldade de superação.

Bônus


item colecionável que tem um efeito positivo nos jogadores

Realizamos 2 tipos de bônus para Lucas:

  • Kit de primeiros socorros que cairá quando você destruir monstros
  • Baús com espadas que Lucas será capaz de lançar em inimigos

Para implementar um bônus com um kit de primeiros socorros, você deve modificar as casas pré-fabricadas com monstros. Mais especificamente, indique o local a partir do qual os bônus aparecerão.



Em seguida, modifique o script Enemy.cs:

Título de spoiler
/* ,        */ [SerializeField] private GameObject bonusPref; //   [SerializeField] private Transform instBonus; //     [SerializeField] private int isBonus; //    ,     /*   */ public void ifDie() { if (Damage(0) <= 0) { isBonus = Random.Range(0,3); if (isBonus == 0) { Instantiate(bonusPref, instBonus.position, instBonus.rotation); } Destroy(this.gameObject); } } 


Chamamos a função com o tipo retornado Damage (0) e verificamos se a Saúde 0. retorna. Nesse caso, chamamos o gerador de números aleatórios. Se o gerador parar escolhendo o número 0, jogamos um bônus no jogador e destruímos o monstro.

A seguir, descrevemos o que você pode fazer com esse bônus. Para fazer isso, crie sua pré-fabricada com os componentes SpriteRenderer, BoxCollider2D e Rigidbody2D. Além disso, crie um script que será responsável pelo que precisa ser feito se a maçã colidir com o player:

Título de spoiler
 public void OnTriggerEnter2D(Collider2D collision) { switch (collision.gameObject.tag) { case "Player": { HeroScript.Health = 100; Destroy(this.gameObject); } break; } } 


Veja o vídeo de visualização .

Em seguida, percebemos o bônus da perda de espadas. Pode ser implementado de acordo com o mesmo princípio da primeira parte, a perda de log foi implementada. A parte interessante será que, quando Lucas pegar as espadas, elas precisarão ser lançadas apenas na faixa de visibilidade dos oponentes, e não quando Lucas recolher as toras. De fato, na forma em que o botão Attack \ item collection agora está implementado, ele faria exatamente isso. Espadas foram jogadas fora em qualquer situação. Para fazer isso, modificamos o código do script de ataque / coleção:

Título de spoiler
  /*      */ [SerializeField] private GameObject swordPref; //    [SerializeField] private Transform instSword; //     [SerializeField] private float swordSpeed; //    private float attackInBoxX, attackInBoxY; //    /*       */ // ED  EnemyDamage Collider2D[] ED = Physics2D.OverlapBoxAll(Hero.position, new Vector2(attackInBoxX, attackInBoxY), 12, lEnemy); { if (ED.Length > 0) { if (InventoryOnHero.swordCount == 0) { Debug.Log(" "); } if (InventoryOnHero.swordCount > 0) { instantiateSword(); InventoryOnHero.swordCount = InventoryOnHero.swordCount - 1; } else { for (int i = 0; i < ED.Length; i++) { ED[i].GetComponent<Enemy>().Damage(1); } } } } 


O que essas linhas de código significam? Primeiro, definimos uma matriz de coletores e verificamos tudo o que caiu em nosso cubo:

 Collider2D[] ED = Physics2D.OverlapBoxAll(Hero.position, new Vector2(attackInBoxX, attackInBoxY), lEnemy); 

Preste atenção aos parâmetros passados, eles são muito diferentes daqueles usados ​​para OvelapCircleAll. Parâmetros principais -

 Vector2(attackInBoxX, attackInBoxY) 

Em seguida, a condição é atendida; se a matriz do colisor for maior que 0, verificaremos o inventário quanto a espadas. Se o número de espadas é 0, não fazemos nada e executamos o método
 ED[i].GetComponent<Enemy>().Damage(1); 
como se fosse um sucesso regular. Se for maior que 0, solte a espada e reduza o número de espadas em 1.

A seguir, a implementação do método instantiateSword ();

Título de spoiler
  private void instantiateSword() { GameObject newArrow = Instantiate(swordPref) as GameObject; newArrow.transform.position = instSword.transform.position; Rigidbody2D rb = newArrow.GetComponent<Rigidbody2D>(); if (GameObject.Find("Hero").GetComponent<HeroScript>().localScale.x > 0) { rb.velocity = new Vector3(swordSpeed, 0, 0); } else { rb.velocity = new Vector3(-swordSpeed, 0, 0); newArrow.transform.Rotate(0,0,-180); } } 


Se você leu bem o artigo anterior, pode ter notado que esse código se parece com uma seção de código responsável por disparar um girassol. Linhas adicionadas a esta seção de código que são responsáveis ​​por determinar a escala de Lucas. Ou seja, ele parece esquerdo ou direito:

 (GameObject.Find("Hero").GetComponent<HeroScript>().localScale.x > 0) 

Se Lucas estiver olhando para a esquerda, então

 rb.velocity = new Vector3(-swordSpeed, 0, 0); newArrow.transform.Rotate(0,0,-180); 

a espada voa para a esquerda e também a gira 180 graus.

Veja o vídeo de visualização .

Executando esta ação, fechamos automaticamente outro 1 padrão:

Object


qualquer entidade que apareça na cena do jogo e possa alterar seu estado. Os objetos incluem perigos, inimigos, bônus, etc.

Embora, muito provavelmente, esse padrão tenha sido implementado anteriormente quando o primeiro monstro foi programado.

Como resultado, no momento, três padrões não são implementados:

  • Área inacessível
  • A mecânica
  • O chefe

A mecânica no momento é de grande interesse para mim. Porque não posso dizer a mim mesma que entendo exatamente o que as pessoas colocam nessa definição.

Além disso, uma área inacessível . Nesta edição, lidarei por algum tempo com problemas de design de nível. Primeiro, porque eu quero escurecer o terceiro nível. Provavelmente uma caverna ou uma masmorra. Com a capacidade de realizar efeitos de iluminação.

Chefe ! Também permanecerá uma cereja no bolo. Quero torná-lo o mais independente possível e com a capacidade de mudar minha aparência.

A primeira parte do artigo
Todos os objetos do jogo foram retirados de https://opengameart.org/ , a saber:



Sinta-se à vontade e escreva comentários sobre Habré ou para mim em worldofonehero@gmail.com.

Obrigado pela leitura, boa sorte.

Source: https://habr.com/ru/post/pt460561/


All Articles