快乐小鸡游戏

喜欢看小猪佩奇的朋友都知道一款游戏叫做快乐小鸡,于是作者自己动手实现了一款,有需要的朋友也可以下载apk在安卓上运行或者执行码在电脑上玩,下面是程序的运行视频,以及部分实现的代码

GameManager的代码

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }
    private string prefabPath = "Prefabs/ChickenObj";
    public int score = 0;          // 示例参数
    public float moveSpeed = 1f;

    public event Action<int> OnButtonClicked;
    public event Action startGameEvent;

    bool m_isStart = false;
    Player m_player;
    public Vector3 m_transoffset = new Vector3(0.5f,-1,0);

    void Awake()
    {
        // 如果已经有实例了,说明重复了,销毁自己
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }

        Instance = this;

        DontDestroyOnLoad(gameObject); // 可选:切场景不销毁
    }
    private void Start()
    {
        OnButtonClicked?.Invoke(score);
    }

    void Update()
    {
        if(!m_isStart)
        {
            return;
        }
        // 鼠标左键按下
        if (Input.GetMouseButtonDown(0))
        {
            // 1. 获取鼠标屏幕坐标
            Vector3 screenPos = Input.mousePosition;

            // 2. 转成世界坐标
            Vector3 worldPos = ScreenToWorld(screenPos);
            Debug.Log("screenPos = " + screenPos);
            SpawnAtMousePosition(worldPos);
            ++score;
            OnButtonClicked?.Invoke(score);
            return;
        }

        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
            SpawnAtMousePosition(Input.GetTouch(0).position);
            ++score;
            OnButtonClicked?.Invoke(score);
            return;
        }

        if (Input.anyKeyDown && !Input.GetKey(KeyCode.Escape) && !Input.GetMouseButtonDown(0))
        {
            Vector3 randomScreenPos = new Vector3(
            UnityEngine.Random.Range(0f, Screen.width - 50),
            UnityEngine.Random.Range(0f, Screen.height - 200),
            0f);

            Vector3 worldPos = ScreenToWorld(randomScreenPos);

            SpawnAtMousePosition(worldPos);
            ++score;
            OnButtonClicked?.Invoke(score);
            return;
        }
        if (Input.GetKeyDown(KeyCode.Escape))
        {
#if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false; // 编辑器里停止运行
#else
    Application.Quit(); // 打包后退出程序
#endif
        }

    }

    public void startGame()
    {
        m_isStart = true;
        startGameEvent?.Invoke();
        initPlayerChicken();
    }

    void initPlayerChicken()
    {
        GameObject prefab = Resources.Load<GameObject>(prefabPath);
        Debug.Log("prefabPath = " + prefabPath);
        if (prefab == null)
        {
            Debug.LogError($"找不到 Prefab,路径:Resources/{prefabPath}");
            return;
        }
        Vector3 screenCenter = new Vector3(Screen.width / 2f, Screen.height / 2f,0);
        var worldPos = ScreenToWorld(screenCenter);
        // 4. 实例化
        GameObject playerObj = Instantiate(prefab, worldPos, Quaternion.identity);
        m_player = playerObj.GetComponent<Player>();
        m_player.initPlayerInfo();
    }

    void SpawnAtMousePosition(Vector3 worldPos)
    {
        m_player.setPos(worldPos);
        m_player.playJumpAnim();
        // 3. 加载 Resources 下的 Prefab
        GameObject prefab = Resources.Load<GameObject>(prefabPath);
        if (prefab == null)
        {
            Debug.LogError($"找不到 Prefab,路径:Resources/{prefabPath}");
            return;
        }

        worldPos += m_transoffset;
        // 4. 实例化
        GameObject chickenObj = Instantiate(prefab, worldPos, Quaternion.identity);

        // update player postion
        var child = chickenObj.GetComponent<Player>();
        child.initChildInfo();
    }


    // 根据相机类型选择转换方式
    Vector3 ScreenToWorld(Vector3 screenPos)
    {
        Camera cam = Camera.main;
        if (cam == null)
        {
            Debug.LogError("场景里没有 MainCamera 标签的相机");
            return Vector3.zero;
        }

        // 正交相机(2D 常用)
        if (cam.orthographic)
        {
            Vector3 pos = cam.ScreenToWorldPoint(screenPos);
            pos.z = 0f; // 2D 场景一般把 z 归零
            return pos;
        }
        // 透视相机(3D 常用)
        else
        {
            // 方法 A:直接取相机前方某个距离的点
            float distance = 10f; // 距离相机 10 个单位
            Vector3 pos = cam.ScreenToWorldPoint(
                new Vector3(screenPos.x, screenPos.y, distance));
            return pos;

            // 方法 B:如果要精确点到地面/某个平面,用射线检测(见下方说明)
        }
    }


}

player的代码

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
enum playerStateEnum { EGG0, EGG1, CHICKEN,CHILD_CHICKEN };

public class Player : MonoBehaviour
{

    GameObject gameManagerObj;
    GameManager gameManeger;
    float moveSpeed = 0f;
    GameObject m_childChicken;
    GameObject m_firstEggObj;
    GameObject m_secondEggObj;
    GameObject m_curObj;
    List<GameObject> allChildObject;
    private Animator anim;


    public float speed = 1f;
    bool m_isStart = false;
    private bool m_isPlayer = false;
    playerStateEnum _m_state = playerStateEnum.EGG0;
    playerStateEnum m_state
    {
        get { return _m_state; }
        set { 
            _m_state = value;
            refreshState();
        }
    }
    private List<string> allAnimName = new List<string>() { "jump", "move",  "moveAndSpeak" };

    private List<GameObject> allGameObjects = new List<GameObject>();

    private void initObject()
    {
        gameManagerObj = GameObject.Find("GameManager");
        m_firstEggObj = transform.Find("egg0").gameObject;
        m_secondEggObj = transform.Find("egg1").gameObject;
        m_childChicken = transform.Find("chicken_animation").gameObject;
        anim = m_childChicken.GetComponent<Animator>();

        allChildObject = new List<GameObject>() { m_firstEggObj, m_secondEggObj , m_childChicken };
        m_isStart = true;
        foreach (GameObject obj in allChildObject)
        {
            obj.SetActive(false);
        }
        resetAnimState();
        Debug.Log("Start");

    }




    void Update()
    {
       
    }

    public void initPlayerInfo()
    {
        initObject();
        m_isPlayer = true;
        m_state = playerStateEnum.CHICKEN;
    }
    void resetAnimState()
    {
        foreach(var name in allAnimName)
        {
            anim.SetBool(name, false);
        }
    }

    public void playJumpAnim()
    {
        resetAnimState();
        anim.SetBool("jump",true);
    }

    public void playMoveAnim()
    {
        resetAnimState();
        anim.SetBool("move", true);
    }

    public void playmoveAndSpeakAnim()
    {
        resetAnimState();
        anim.SetBool("moveAndSpeak", true);
    }

    public void playIdleAnim()
    {
        resetAnimState();
        anim.SetBool("idle", true);
    }

    public void initChildInfo()
    {

        initObject();
        Debug.Log("initChildInfo");
        m_isPlayer = false;
        m_state = playerStateEnum.EGG0;

        StartCoroutine(egg2HatchState());
    }

    void refreshState()
    {
        Debug.Log("refreshState");
        if (!m_isStart)
        {
            return;
        }
        foreach (GameObject obj in allChildObject)
        {
            obj.SetActive(false);
        }
        switch (m_state)
        {
            case playerStateEnum.EGG0:
                {
                    m_firstEggObj.SetActive(true);
                    m_curObj = m_firstEggObj;
                    break;

                }
            case playerStateEnum.EGG1:
                {
                    m_secondEggObj.SetActive(true);
                    m_curObj = m_secondEggObj;
                    break;
                }
            case playerStateEnum.CHICKEN:
                {
                    m_childChicken.SetActive(true);
                    m_curObj = m_childChicken;
                    break;
                }
            case playerStateEnum.CHILD_CHICKEN:
                {
                    m_childChicken.SetActive(true);
                    m_curObj = m_childChicken;
                    break;
                }

        }
    }

   

    // 孵化流程
    IEnumerator egg2HatchState()
    {
        yield return new WaitForSeconds(2f);
        m_state = playerStateEnum.EGG1;
        StartCoroutine(egg2ChickenState());
    }

    IEnumerator egg2ChickenState()
    {
        yield return new WaitForSeconds(2f);
        m_state = playerStateEnum.CHILD_CHICKEN;
        var curPos = m_curObj.transform.position;
        Vector3 endPos =new Vector3(-20, curPos.y, curPos.z);
        anim.SetBool("idle", false);
        playmoveAndSpeakAnim();
        StartCoroutine(MoveTo(endPos,speed));
    }




    IEnumerator MoveTo( Vector3 endPos, float speed)
    {
        float elapsed = 0f;
        while (transform.position.x > endPos.x)
        {
            var pos = transform.position;
            elapsed = Time.deltaTime * speed;
            transform.position =  new Vector3(pos.x - elapsed, pos.y, pos.z);
            yield return null;   // 等下一帧
        }

        transform.position = endPos; // 保证精确到位
        Destroy(gameObject);
    }

    // 根据相机类型选择转换方式
    Vector3 ScreenToWorld(Vector3 screenPos)
    {
        Camera cam = Camera.main;
        if (cam == null)
        {
            Debug.LogError("场景里没有 MainCamera 标签的相机");
            return Vector3.zero;
        }

        // 正交相机(2D 常用)
        if (cam.orthographic)
        {
            Vector3 pos = cam.ScreenToWorldPoint(screenPos);
            pos.z = 0f; // 2D 场景一般把 z 归零
            return pos;
        }
        // 透视相机(3D 常用)
        else
        {
            // 方法 A:直接取相机前方某个距离的点
            float distance = 10f; // 距离相机 10 个单位
            Vector3 pos = cam.ScreenToWorldPoint(
                new Vector3(screenPos.x, screenPos.y, distance));
            return pos;

            // 方法 B:如果要精确点到地面/某个平面,用射线检测(见下方说明)
        }
    }

    public void setPos(Vector3 pos)
    {
        gameObject.transform.position = pos;
    }


}

UIManager的代码

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    GameObject gameManagerObj;
    GameManager gameManeger;
    public GameObject panel;
    GameObject scoreText;
    Button startBtn;

    // Start is called before the first frame update
    void Start()
    {
        gameManagerObj = GameObject.Find("GameManager");
        if (gameManagerObj != null)
        {
            gameManeger = gameManagerObj.GetComponent<GameManager>();
            if (gameManeger != null)
            {
                Debug.Log("score = " + gameManeger.score);

            }
            else
                Debug.LogError("GameManager 物体上没挂 GameManager 脚本");
            gameManeger.OnButtonClicked += updateScore;
        }
        else
        {
            Debug.LogError("场景里找不到名为 GameManager 的物体");
        }
        initUI();
    }

    void initUI()
    {
        scoreText = panel.transform.Find("scoreText").gameObject;
        startBtn = panel.transform.Find("startBtn").gameObject.GetComponent<Button>();
        startBtn.onClick.AddListener(() =>
        {
            onStartClicked();
        });
    }

    // Update is called once per frame
    void Update()
    {
    }

    void updateScore(int score)
    {
        scoreText.GetComponent<Text>().text = score.ToString();
    }

    void onStartClicked()
    {
        Debug.Log("onStartClicked");
        gameManeger.startGame();
        // hide ui
        startGameUpdate();
    }

    void startGameUpdate()
    {
        startBtn.gameObject.SetActive(false);

    }

    void endGameUpdate()
    {
        startBtn.gameObject.SetActive(true);

    }
}

游戏运行图片

相关推荐
Solange__6 小时前
在线3D预览器、Blender和游戏引擎怎么选?按5类任务比较格式、隐私与编辑性
人工智能·游戏·3d·游戏引擎·blender·1024程序员节·关卡设计
不是万能的豆学长9 小时前
游戏重构生活平衡新方式
游戏·重构·生活
动词ing10 小时前
【题目练习】跳跃游戏
游戏
技术人生0011 天前
DirectX修复工具下载安装教程-Windows系统游戏dll修复工具下载安装修复教程
windows·游戏
郝学胜-神的一滴1 天前
游戏设计:原型与开发 18:Unity入门的第一课
人工智能·程序人生·游戏·ui·unity·游戏引擎
赤生云电竞1 天前
云游戏边缘节点部署:机房选址与网络拓扑优化实践——接入延迟、VXLAN与GPU虚拟化选型
数据库·游戏
呆呆敲代码的小Y1 天前
【实战精选面试题】C# 面试题详细解答,按难易程度排序
android·java·游戏·c#·游戏开发·unity面试题·c#面试题
好想像大佬一样能够ak所有1 天前
LeetCode.55跳跃游戏_python
游戏
2601_957875201 天前
华立科技荣获环球品牌与合作(大中华区)年度“最佳街机游戏合作伙伴”
大数据·科技·游戏