☰
快乐小鸡游戏
2026/11/2 1:53:17 网站建设 项目流程

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

GameManager的代码

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的代码

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的代码

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); } }

游戏运行图片

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询