1. 程式人生 > 其它 >跳一跳Unity版(一)——基本功能實現

跳一跳Unity版(一)——基本功能實現

Unity製作跳一跳小遊戲

主要內容:1、最終呈現效果 2、程式碼大概邏輯 3、程式碼塊


1、目前效果:

2、程式碼大概邏輯

3、程式碼塊

(1)掛在主攝像機

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Axes
{
    public static LandState landState = LandState.None;
    public static int direction = 0;
    public const int axisX = 0;
    
public const int axisY = 1; } public class Cubes { public static Transform current; public static Transform target; public static int id = 0; } public class InitCube : MonoBehaviour { int direction = 0; int index = 0; float randomColor = 0; List<GameObject> cubeList = new
List<GameObject>(); GameObject cubePrefab;

private void OnDisable() { //事件登出 JumpLeap.AfterJump -= RandInitCube; } private void Start() { //事件註冊 JumpLeap.AfterJump += RandInitCube; Axes.direction = direction; //盒子池 cubePrefab = Resources.Load<GameObject>("
Cube"); for (int i = 0; i < 6; i++) { cubeList.Add(GameObject.Instantiate(cubePrefab)); cubeList[i].SetActive(false); } SetCubePosAndActive(Vector3.zero); SetCubePosAndActive(new Vector3(2,0,0)); } //重新開始遊戲 public void RestartGame() { index = 0; Cubes.id = 0; Axes.direction = 0; for (int i = 0; i < 6; i++) { cubeList[i].SetActive(false); } SetCubePosAndActive(Vector3.zero); SetCubePosAndActive(new Vector3(2, 0, 0)); GameObject.FindGameObjectWithTag("Player").transform.position = new Vector3(0, 3, 0); GameObject.FindGameObjectWithTag("Player").transform.rotation = Quaternion.identity; } //設定cube 位置和狀態 public void SetCubePosAndActive(Vector3 pos) { cubeList[index].SetActive(true); cubeList[index].transform.position = pos; cubeList[index].GetComponent<MeshRenderer>().material.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f), 1); int ii = index - 1; if (ii < 0) { ii = cubeList.Count - 1; } Cubes.current = cubeList[ii].transform; Cubes.target = cubeList[index].transform; for (int i = 0; i < cubeList.Count; i++) { cubeList[i].tag = "Untagged"; if (i == ii) { Cubes.current.tag = "Current"; } if (i == index) { Cubes.target.tag = "Target"; } } index++; if (index == cubeList.Count) { index = 0; } } //隨機生成cube public void RandInitCube() { if (Cubes.current == JumpLeap._instance.colliderTrans) { return; } Axes.direction = Random.Range(0, 2); direction = Axes.direction; float distance = Random.Range(1.5f, 2.5f); if (Axes.direction == Axes.axisX) { SetCubePosAndActive(new Vector3(Cubes.target.position.x + distance, Cubes.target.position.y, Cubes.target.position.z)); } if (Axes.direction == Axes.axisY) { SetCubePosAndActive(new Vector3(Cubes.target.position.x, Cubes.target.position.y, Cubes.target.position.z + distance)); } } }

(2)掛在棋子上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;



public enum Status
{
    BeforeJump,
    PrepareJump,
    JumpMoment,
    Jumping,
    AfterJump,
    Die,
    None
}
public class JumpLeap : MonoBehaviour
{
    public static JumpLeap _instance;
    GameObject effect;
    AudioSource audioDu;

    private void Awake()
    {
        _instance = this;
    }

    public delegate void MainDelegate();
    public static MainDelegate AfterJump;
    public static MainDelegate Die;


    int direction = 0;

    public Status jumpStatus = Status.None;
    Rigidbody rigidBody;

    float distance = 0;   //跳多遠
    public float speed = 3;      //跳的速度
    
    CameraMove cameraMove;
    Vector3 endPos;

    bool isDefeatted = false;
    bool isTouching = false;

    public Transform colliderTrans { get; set; }

    //判斷遊戲失敗
    Status JudgeDefeat(Vector3 playerLandPos)
    {
        if (colliderTrans.tag == "Plane")
        {
            return Status.Die;
        }
        if (colliderTrans == Cubes.current)
        {
            if (Mathf.Abs(playerLandPos.x - Cubes.current.position.x) > 0.5f * Cubes.current.localScale.x)
            {
                isDefeatted = true;
            }
            if (Mathf.Abs(playerLandPos.z - Cubes.current.position.z) > 0.5f * Cubes.current.localScale.z)
            {
                isDefeatted = true;
            }
        }

        if (colliderTrans == Cubes.target)
        {
            //若失敗
            if (Mathf.Abs(playerLandPos.x - Cubes.target.position.x) > 0.5f * Cubes.target.localScale.x)
            {
                isDefeatted = true;
            }
            if (Mathf.Abs(playerLandPos.z - Cubes.target.position.z) > 0.5f * Cubes.target.localScale.z)
            {
                isDefeatted = true;
            }
        }
        //若沒有失敗
        return Status.AfterJump;
    }

    //接觸判定
    private void OnCollisionEnter(Collision collision)
    {
        isTouching = true;
        colliderTrans = collision.transform;
        jumpStatus = JudgeDefeat(transform.position);
        Cubes.id++;
    }
    
    void Start()
    {
        rigidBody = GetComponent<Rigidbody>();
        cameraMove = GameObject.Find("Main Camera").GetComponent<CameraMove>();
        effect = Resources.Load<GameObject>("LandCenterPointEffect");
        audioDu = this.GetComponent<AudioSource>();
    }

    //翻跟斗
    void RotateSelf(int dir)
    {

        if (dir == 0)
        {
            transform.rotation = Quaternion.identity;
            transform.DORotate(new Vector3(0, 0, -360), 0.6f, RotateMode.FastBeyond360);
        }

        if (dir == 1)
        {
            transform.rotation = Quaternion.identity;
            transform.DORotate(new Vector3(360, 0, 0), 0.6f, RotateMode.FastBeyond360);
        }
    }



    void Update()
    {
        
        //滑鼠按下
        if (isTouching && Input.GetMouseButtonDown(0) && jumpStatus == Status.BeforeJump)
        {
            jumpStatus = Status.PrepareJump;
            audioDu.UnPause();
            audioDu.Play();
        }
        //滑鼠抬起
        if (isTouching && Input.GetMouseButtonUp(0) && jumpStatus == Status.PrepareJump)
        {
            jumpStatus = Status.JumpMoment;
            audioDu.Pause();
        }
        

        //狀態判定
        switch (jumpStatus)
        {
            //跳前狀態
            case Status.BeforeJump:
                distance = 0;
                cameraMove.Move();
                rigidBody.constraints = RigidbodyConstraints.FreezeRotation;
                break;
            //預備狀態
            case Status.PrepareJump:
                distance += Time.deltaTime * speed;
                if (Cubes.current.position.y < -0.5f)
                {
                    break;
                }
                float tim = Time.deltaTime;
                Cubes.current.Translate(0, -tim, 0);
                transform.Translate(0, -tim, 0);
                break;
            //起跳瞬間狀態
            case Status.JumpMoment:
                direction = Axes.direction;
                RotateSelf(direction);
                if (Axes.direction == 0)
                {
                    endPos = new Vector3(transform.position.x + distance, Cubes.target.position.y + 0.5f, transform.position.z);
                    //transform.DORotate(new Vector3(0, 0, -360), 0.6f, RotateMode.FastBeyond360);
                    jumpStatus = Status.Jumping;
                }
                if (Axes.direction == 1)
                {
                    endPos = new Vector3(transform.position.x, Cubes.target.position.y + 0.5f, transform.position.z + distance);
                    //transform.DORotate(new Vector3(360, 0, 0), 0.6f, RotateMode.FastBeyond360);
                    jumpStatus = Status.Jumping;
                }
                Axes.landState = LandState.Edge;
                if ((direction == 0 ? Mathf.Abs(endPos.x - Cubes.target.position.x) : Mathf.Abs(endPos.z - Cubes.target.position.z)) < 0.15f)
                {
                    endPos = new Vector3(Cubes.target.position.x, Cubes.target.position.y + 0.5f, Cubes.target.position.z);
                    Axes.landState = LandState.Center;
                }
                transform.DOJump(endPos, 2, 1, 0.8f);
                isTouching = false;
                break;
            //騰空狀態
            case Status.Jumping:
                if (Vector3.Distance(transform.position, endPos) < 0.2f)
                {
                    transform.position = endPos;
                }
                if (Cubes.current.position.y > 0)
                {
                    Cubes.current.position = new Vector3(Cubes.current.position.x, 0, Cubes.current.position.z);
                    break;
                }
                Cubes.current.Translate(0, Time.deltaTime, 0);
                break;
            //落地狀態
            case Status.AfterJump:
                if (Axes.landState == LandState.Center)
                {
                    Instantiate(effect,endPos,Quaternion.identity);
                }
                transform.rotation = Quaternion.identity;
                rigidBody.constraints = RigidbodyConstraints.None;
                AfterJump();
                if (isDefeatted == true)
                {
                    jumpStatus = Status.None;
                    isDefeatted = false;
                }
                else
                {
                    jumpStatus = Status.BeforeJump;
                }
                break;
            case Status.Die:
                jumpStatus = Status.None;
                Die();
                break;
            case Status.None:
                
                break;
            default:
                break;
        }
    }

}

(3)掛在Canvas上

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

public enum LandState
{
    Edge,
    Center,
    None
}

public class Const1
{
    public const string bestGrades = "bestGrades";
}

public class Scores : MonoBehaviour
{

    Text scroeText;
    public int grades = 0;
    int bestGrades = 0;
    public Transform defeatPanel;
    Button restartBtn;
    InitCube initCube;
    Text scoreDP;
    Text bestscoreDP;
    JumpLeap jumpLeap;

    private void OnEnable()
    {
        JumpLeap.AfterJump += AddGrades;
        JumpLeap.Die += ShowDefeatPanel;
    }
    private void OnDisable()
    {
        JumpLeap.AfterJump -= AddGrades;
        JumpLeap.Die -= ShowDefeatPanel;
    }

    private void Start()
    {
        bestGrades = PlayerPrefs.GetInt(Const1.bestGrades);
        scoreDP = transform.Find("DefeatPanel/Score").GetComponent<Text>();
        bestscoreDP = transform.Find("DefeatPanel/BestScore").GetComponent<Text>();
        initCube = GameObject.Find("Main Camera").GetComponent<InitCube>();
        scroeText = transform.Find("Image/Score").GetComponent<Text>();
        defeatPanel = transform.Find("DefeatPanel");
        defeatPanel.gameObject.SetActive(false);
        restartBtn = transform.Find("DefeatPanel/RestartButton").transform.GetComponent<Button>();
        restartBtn.onClick.AddListener(() => 
        {
            initCube.RestartGame();
            defeatPanel.gameObject.SetActive(false);
            JumpLeap._instance.jumpStatus = Status.None;
            scroeText.text = "分數:" + grades;
        });
        scroeText.text = "分數:" + grades;
    }

    //加分
    public void AddGrades()
    {
        if (Cubes.current == JumpLeap._instance.colliderTrans)
        {
            return;
        }
        switch (Axes.landState)
        {
            case LandState.Edge:
                grades += 1;
                break;
            case LandState.Center:
                grades += 3;
                break;
        }
        scroeText.text = "分數:" + grades;
    }
    

    //顯示失敗介面
    public void ShowDefeatPanel()
    {
        //分數清零
        if (bestGrades < grades)
        {
            bestGrades = grades;
            PlayerPrefs.SetInt(Const1.bestGrades, bestGrades);
        }
        scroeText.text = "分數:" + grades;
        
        defeatPanel.gameObject.SetActive(true);
        scoreDP.text = grades + "";
        bestscoreDP.text = "歷史最高分:" + bestGrades;
        grades = 0;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMove : MonoBehaviour
{


    Vector3 originalPos;
    public void InitCamera()
    {
        transform.position = originalPos;
    }
    private void Awake()
    {
        originalPos = transform.position;
    }
    //移動攝像頭
    public void Move()
    {
        transform.position = Vector3.Lerp(transform.position, new Vector3(Cubes.current.position.x - 3, Cubes.current.position.y + 5, Cubes.current.position.z - 3), 0.08f);
    }
}