Jogo 2d usando unity

Alunos: 

Alex Costa

Danielle Teixeira

Paulo

Professor: Arivan

Esp: Desenvolvimento de aplicações para Dispositivos móveis

Funcionalidades do jogo

  • 3 fases com 30 segundos para serem completada  e se o jogar perder uma vida é reiniciada a fase;
  • Um contador decrescente do tempo;
  • Pontua quantidade de ouros que o jogador coleta na fase.
  • Aplica rotação no eixo

menu do jogo

Cenário do jogo

cameraController.cs

using UnityEngine;
using System.Collections;

/**
 * Componente para fazer a câmera seguir o jogador.
 * Necesário acoplar esse script a camera e definir o objeto follow.
 */
public class CameraController : MonoBehaviour {

	public GameObject follow;

	// LateUpdate é chamado após todo processamento da 
	// física ser realizado.
	void LateUpdate () {

		// Posição do objeto seguido.
		Vector3 followPosition = follow.transform.position;

		// Nova posição da câmera.
		Vector3 cameraPosition = new Vector3 (followPosition.x, followPosition.y, 
transform.position.z);

		// Atualiza a posição da câmera.
		transform.position = cameraPosition;
	}
}

GameManager

  • Controla o fluxo do jogo
  • Definidos número de fases
  • Reinicia a fase após tempo acabar

GameManager

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

/**
 *  Controla o fluxo do jogo (navegação entre fases e menu).
 */
public class GameManager : MonoBehaviour
{

    // Total de fases no jogo.
    const int TOTAL_LEVELS = 3;

    // Fase atual do jogador.
    private int level;

    // Interface de fim de jogo.
    private GameObject endGameMenu = null;

    // Implementa o padrão SINGLETON.
    // Precisamos de apenas uma instância do GameManager acessível
    // em todo o jogo.
    public static GameManager instance = null;
    private int totalPickups = 0;
    private int totalPontos = 0;
    private Text totalPontosText = null;

    int totalLife = 3;

    void Awake ()
    {
        //Check if instance already exists
        if (instance == null) {

            //if not, set instance to this
            instance = this;
        }

        //If instance already exists and it's not this:
        else if (instance != this) {

            //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.
            Destroy (gameObject);    
        }

        //Sets this to not be destroyed when reloading scene
        DontDestroyOnLoad (gameObject);
    }

    // Chamado pela unity sempre que uma cena acaba
    // de ser carregada.
    void OnLevelWasLoaded (int level)
    {

        // Cria o menu de fim de jogo.
        CreateEndGameMenu ();

        // Oculta o  menu de fim de jogo.
        endGameMenu.SetActive (false);
    }

    // Cria dinamicamente o menu de fim de jogo.
    // Um Prefab do menu foi previamente criado e
    // encontra-se na pasta Prefabs.
    private void CreateEndGameMenu ()
    {
        // Recupera uma referência ao modelo do prefab.
        GameObject EndMenu = Resources.Load<GameObject> ("Prefabs/EndMenu");

        // Instancia o modelo (adicionando a cena) e guardando uma referência
        // para ele na variável engGameMenu.
        endGameMenu = Instantiate (EndMenu, new Vector3 (1, 1, 1), Quaternion.identity) as GameObject;

        // Recupera referências aos botões do menu associando as respectivas
        // ações de clique.
        Button nextLevelBtn = GameObject.Find ("NextLevelBtn").GetComponent<Button> ();
        nextLevelBtn.onClick.AddListener (() => NextLevel ());

        Button restartLevelBtn = GameObject.Find ("RestartLevelBtn").GetComponent<Button> ();
        restartLevelBtn.onClick.AddListener (() => RestartLevel ());

        Button menuPrincipalBtn = GameObject.Find ("MenuPrincipalBtn").GetComponent<Button> ();
        menuPrincipalBtn.onClick.AddListener (() => MenuPrincipal ());

        this.totalPontosText = GameObject.Find ("pontosText").GetComponent<Text> ();
        totalPontosText.text = "Total de Pontos : " + totalPontos.ToString ();

    }

    // -----------------------------------------totalPickups

    // Inicia um novo jogo.
    public void NewGame ()
    {
        level = 0;
        NextLevel ();
    }

    // Reinicia a fase atual.
    public void RestartLevel ()
    {
        SceneManager.LoadScene ("mapload");
        this.totalPontos -= totalPickups;
    }

    // Avança para a próxima fase.
    public void NextLevel ()
    {
        level++;

        if (level <= TOTAL_LEVELS) {
            SceneManager.LoadScene ("mapload");
        }
    }

    // Encerra a fase atual, exibindo
    // o menu de fim de jogo.
    public void EndLevel (int timeLeft)
    {
        if (level >= TOTAL_LEVELS)
            SceneManager.LoadScene ("menu");
        else if (endGameMenu != null) {
            totalPontos = (50 * (totalPickups)) + ((30 - timeLeft) * 10);
            this.totalPontosText.text = "Total de Pontos : " + totalPontos.ToString ();
            endGameMenu.SetActive (true);
        }
    }

    public void MenuPrincipal ()
    {
        SceneManager.LoadScene ("menu");
        this.totalLife = 3;
    }

    // Sai do jogo.
    public void QuitGame ()
    {
        Application.Quit ();
    }

    public int CurrentLevel ()
    {
        return this.level;
    }

    public bool OnCollision (Collision2D other, int pickupsCounter)
    {

        // Se todos pickups foram coletados encerra a fase.
        // Isso deve ser removido, visto que a fase deverá 
        // ser encerrada quando o UFO for direcionado para o
        // portal.

        if (pickupsCounter >= totalPickups) {
            return true;
        } else {
            return false;
        }
    }

    public void SetTotalPickups (int length)
    {
        this.totalPickups = length;
    }

    public void decrementLife ()
    {
        this.totalLife--;
    }

    public int lifes ()
    {
        return this.totalLife;
    }
} 

maploader.cs

using UnityEngine;
using System.Collections;
using System.Text.RegularExpressions;

/**
 * Cria um level dinamicamente a partir de um arquivo de texto.
 * O arquivo representa uma matriz onde cada elemento representa
 * um tile que irá compor o cenário.
 */
public class MapLoader : MonoBehaviour
{

	void Start ()
	{
		CreateLevel (GameManager.instance.CurrentLevel ());
		// Identifica quantos pickups a fase tem.
		GameManager.instance.SetTotalPickups (GameObject.FindGameObjectsWithTag ("Pickups").Length);

	}

	// Cria os tiles do level a partir
	// da matriz carregada do arquivo de texto.
	void CreateLevel (int level)
	{
		string[][] data = LoadLevelData (level);

		for (int y = 0; y < data.Length; y++) {
			for (int x = 0; x < data [0].Length; x++) {

				switch (data [y] [x]) {
				case "1":
					CreateTile ("Wall" + Random.Range (0, 3), x, y);
					break;
				case "0":
					CreateTile ("Floor" + Random.Range (0, 3), x, y);
					break;
				case "+":
					CreateTile ("Portal", x, y);
					break;
				case "-":
					CreateTile ("FloorPortal", x, y);
					break;
				case "x":
					CreateTile ("Trap", x, y);
					break;
				case "@":
					CreateTile ("Floor" + Random.Range (0, 3), x, y);
					CreateTile ("Pickup", x, y);
					break;
				}
			}
		}


	}

	// Cria um tile de um dado tipo em uma dada
	// posição.
	// Sugere-se altear o parâmetro "string prefab"
	// para um array de prefabs, e selecionar um
	// prefab aleatório dentro desse array.
	// Assim a fase fica mais diversificada.
	GameObject CreateTile (string prefab, int x, int y)
	{
		GameObject Prefab = Resources.Load<GameObject> ("Prefabs/" + prefab);
		Instantiate (Prefab, new Vector3 (x - 4, y, 0), Quaternion.identity);
		return Prefab;
	}

	// Retorna a matriz que representa o level informado.
	// Por padrão os arquivos de level devem se chamar
	// level1, level2, etc.
	string[][] LoadLevelData (int level)
	{
		// Caminho do arquivo dentro da pasta "Resources".
		string path = "Maps/level" + level;

		// Carrega o arquivo.
		TextAsset textFile = (TextAsset)Resources.Load (path);

		// Recupera o texto do arquivo.
		string text = textFile.text;

		// Realiza splits transformando o texto em
		// uma matriz.
		string[] lines = Regex.Split (text, "\n");
		int rows = lines.Length;
		string[][] data = new string[rows][];
		for (int i = 0; i < rows; i++) {
			string[] lineParts = Regex.Split (lines [i], " ");
			data [(rows - 1) - i] = lineParts;
		}

		return data;
	}


		
}

Player

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

/**
 *  Script de controle do UFO.
 */
public class Player : MonoBehaviour
{

    // Velocidade de movimentação do UFO.
    public float speed;

    // Guarda o total de pickups na fase, para verificar
    // se a fase foi concluída. Na versão final do jogo/
    // isso deve ser removido (a fase será concluída quando
    // o jogador acessar o portal).
    private int totalPickups;

    // Conta quantos pickups o jogador pegou.
    private int pickupsCounter;

    // Guarda uma referência ao componente Rigidbody2d do jogador,
    // utilizado para movimentação.
    private Rigidbody2D rb2d;

    // Guarda uma referência ao componente Animator do jogador,
    // usado para animação.
    // Atenção: o animator funcionará apenas na cena "animation",
    // onde ele foi configurado no UFO!
    private Animator animator;

    // Guarda uma referência ao AudioSOurce que emite o som
    // de coleta de pickups.
    //    public AudioSource collectAudio;
    public AudioSource collectAudio;

    // Guarda uma referência ao componente de interface
    // que exibe a quantidade de pickups coletados.
    public Text countText;

    public Text timerText;
    private float timeLeft = 30;

    bool freezerLevel = false;

    // Use this for initialization
    void Start ()
    {
        // Recupera as referências.
        rb2d = GetComponent<Rigidbody2D> ();
        animator = GetComponent<Animator> ();

        // Inicia com 0 pickups.
        pickupsCounter = 0;

        // Atualiza o texto de exibição da quantidade de pickups.
        updatePickupsText ();

        for (int f = 3; f > GameManager.instance.lifes (); f--) {
            Image manLife = GameObject.Find ("manLife" + f).GetComponent<Image> ();
            manLife.enabled = false;
        }
    }


    void Update ()
    {
        if (!this.freezerLevel) {
            timeLeft -= Time.deltaTime;
            timerText.text = "Tempo: " + Mathf.RoundToInt (timeLeft).ToString ();
            if (timeLeft < 0) {
                this.freezerLevel = true;
                //            GameOver();
                Image manLife = GameObject.Find ("manLife" + GameManager.instance.lifes ()).GetComponent<Image> ();

                GameManager.instance.decrementLife ();
                manLife.enabled = false;
                if (GameManager.instance.lifes () > 0) {
                    GameManager.instance.RestartLevel ();
                } else {
                    GameManager.instance.MenuPrincipal ();
                }

            }
        }
                
    }

    // Chamado em intervalos fixos.
    // Uso: atualizacao física.
    void FixedUpdate ()
    {    
        if (rb2d) {

            // Armazena o vetor direção do movimento do UFO.
            Vector2 movement;

            // Diretivas de compilãção.
            #if UNITY_STANDALONE  || UNITY_WEBPLAYER 

            // Compilação PC/Desktop
                
            // Recupera as direções horizontal/vertical
            // dos dispositivos de entrada.
            float vHorizontal = Input.GetAxis ("Horizontal");
            float vVertical = Input.GetAxis ("Vertical");

            movement = new Vector2 (vHorizontal, vVertical);

            // Bônus!
            // Forma alternativa de mover o UFO.
            // Descomente e teste! Use o mouse!
            /*
                if (Input.GetMouseButtonDown (0)) 
                {
                    Vector3 newPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                    newPosition.z = transform.position.z;
                    MoveTo (newPosition);
                }
                */

            #elif UNITY_IOS || UNITY_ANDROID || UNITY_WP8 || UNITY_IPHONE 
                
                // Compilação Mobile

                // Recupera as direções horizontal/vertical do
                // acelerômetro.
                movement = new Vector2(Input.acceleration.x, Input.acceleration.y);

            #endif

            rb2d.AddForce (movement * speed);
        }
    }



    // Chamado quando o UFO colide com algum objeto
    // que possua um Collider setado como isTrigger.
    void OnTriggerEnter2D (Collider2D other)
    {

        // Verifica se o objeto colidido possui a tag
        // "Pickups".
        if (other.gameObject.CompareTag ("Pickups")) {

            animator.SetTrigger ("damage");

            // Remove o pickup
            other.gameObject.SetActive (false);

            // Incrementa o contado de pickups.
            pickupsCounter++;

            // Reproduz o som de pickups.
            collectAudio.volume = 1;
            collectAudio.Play ();

            // Atualiza o texto com a contagem de pickups
            // coletados.
            updatePickupsText ();

        }

    }


    // Chamado quando o UFO colide com algum objeto
    // que possua um Collider não setado como isTrigger.
    void OnCollisionEnter2D (Collision2D other)
    {
        if (GameManager.instance.OnCollision (other, pickupsCounter) && other.gameObject.CompareTag ("Portal")) {
            {

                // Fim de fase.

                // Remove o rb2d do UFO. Assim
                // ele não se moverá mais.
                Destroy (rb2d);

                // Inicia um método em uma coroutine.
                // Uma coroutine pode ser interrompida e 
                // continuada a partir de condições que determinamos.
                StartCoroutine (EndLevel ());
                this.freezerLevel = true;
            }
        }

        Debug.Log (other.gameObject.tag);
        // Dispara a animação de dano.
        // Assim a animação é disparada sempre
        // que o UFO colide com uma parede.

        // Atenção: o animator funcionará apenas na cena "animation",
        // onde ele foi configurado no UFO!
        animator.SetTrigger ("damage");
    }

    // Coroutine de fim de level.
    IEnumerator EndLevel ()
    {
        // Aguarda 1 segundos.
        yield return new WaitForSeconds (1);

        // Exibe o menu.
        GameManager.instance.EndLevel (Mathf.RoundToInt (timeLeft));
    }

    // Atualiza o texto de interface.
    void updatePickupsText ()
    {
        countText.text = "Ouros: " + pickupsCounter;
    }
        
    // Bônus!
    // Forma alternativa de mover o UFO.
    // Descomente e teste! Use o mouse!
    /*
    void MoveTo(Vector3 position)
    {
        StopCoroutine ("MoveToC");
        StartCoroutine ("MoveToC", position);
    }

    IEnumerator MoveToC(Vector3 target)
    {
        while (Vector3.Distance (transform.position, target) > 0.1f) 
        {
            // Lerp gera uma interpolação baseada na distância 
            // e no tempo passado.
            transform.position = Vector3.Lerp (transform.position, target, Time.deltaTime);

            // Ao retornar null a partir de uma Coroutine, ela será 
            // continuada automaticamente no próximo Game Loop!
            yield return null;
        }
    }
    */
} 

Portal

using UnityEngine;
using System.Collections;

public class Portal : MonoBehaviour
{

    // Use this for initialization
    void Start ()
    {
    
    }
    
    // Update is called once per frame
    void Update ()
    {
    
    }

    void OnCollisionEnter (Collision col)
    {
        Debug.Log (col.gameObject.tag);
    }
}
ROTATor
using UnityEngine;
using System.Collections;

/**
 * Gira um objeto na velocidade informada.
 * Util para pickups do jogo!
 */
public class Rotator : MonoBehaviour {

    public float speed = 45;
    
    // Update is called once per frame
    void Update () 
    {
        // Aplica a rotação apenas no eixo Z.
        // Usa o tempo como referência pois desejamos
        // que a rotação possua a velocidade de 
        // speed graus por segundo!
        transform.Rotate (new Vector3(0,0,speed)*Time.deltaTime);
    }
} 

CameraController

using UnityEngine;
using System.Collections;

/**
 * Componente para fazer a câmera seguir o jogador.
 * Necesário acoplar esse script a camera e definir o objeto follow.
 */
public class CameraController : MonoBehaviour {

    public GameObject follow;

    // LateUpdate é chamado após todo processamento da 
    // física ser realizado.
    void LateUpdate () {

        // Posição do objeto seguido.
        Vector3 followPosition = follow.transform.position;

        // Nova posição da câmera.
        Vector3 cameraPosition = new Vector3 (followPosition.x, followPosition.y, transform.position.z);

        // Atualiza a posição da câmera.
        transform.position = cameraPosition;
    }
} 

GameMenu

GAMEMENU
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

/**
 *  Responde a interações nos botões do menu inicial.
 *  1) Esse componente precisa ser vinculado a algum game object
 *  2) Os métodos desse component devem ser vinculados aos botões através do 
 *  editor. 
 */
public class GameMenu : MonoBehaviour
{

    // Clique em "Novo Jogo".
    public void NewGame ()
    {
        GameManager.instance.NewGame ();
    }

    // Clique em "Sair"
    public void QuitGame ()
    {
        GameManager.instance.QuitGame ();
    }
} 

deck

By Danielle Teixeira

deck

Unity 2d

  • 1,171