Unity3D实现经典小游戏Pacman

 更新时间:2021年12月16日 11:22:27   作者:米莱虾  
这篇文章主要介绍了基于Unity3D制作一做个经典小游戏Pacman,文中的示例代码讲解详细,对我们学习Unity3D有一定的帮助,感兴趣的小伙伴可以了解一下

项目概况

整体布局

地图介绍

除了音效,游戏地图上的元素有:

  • 普通糖豆(玩家通过移动,经过的普通糖豆会被吃掉,获得积分) 
  • 特殊糖豆(玩家吃到后,可以让所有敌方停止移动,产生幻影效果)
  • 隔离墙(相当于迷宫的墙,在两堵墙之间的间隙才能移动) 
  • 剩余游戏时间Remain(共设300s,时间一到,游戏结束)
  • 截止到现在花费的游戏时间Now(设在0~300之间)
  • 截止到目前为止的游戏得分Score(越高越好)
  • 敌方人机(分为四种颜色区分,小橙、小粉、小蓝、小红)
  • 我方玩家(小黄,游戏的主体之一)

玩法介绍

玩法(输赢的判断):

尽量在所设时限内吃完所有的糖豆并且未被敌方人机碰到。

如果都吃完了,用时少的更佳;

如果都没吃完,相同时间内得分高者更佳。

吃到特殊糖豆(大糖豆),可以让所有敌方停止移动,产生幻影效果,相当于无敌效果的反作用,使自己在某段时间内不会被攻击,延长了玩家的存活时间,可以通过概率设计更改玩家的存活率。

相关知识

在学习的过程中,几个比较重要的知识点就是:预制体、克隆体、精灵渲染器、渲染层级、脚本、碰撞检测、触发检测、AI设计、UI设计、固定物理帧...

版本说明

小虾采用的是Unity一个较新的版本-2021.1.16,这里建议小伙伴们下载和教程相同版本的,不然真的会有可能遇到卡点消耗心情哈。

可以和我一样在Unity Hub里面安装,Hub感觉挺好用的。

项目源码

玩家的移动(PacmanMove.cs)

using UnityEngine;
 
public class PacmanMove : MonoBehaviour
{
    //吃豆人的移动速度
    public float speed = 0.35f;
    //吃豆人下一次移动将要去的目的地
    private Vector2 dest = Vector2.zero;
 
    private void Start()
    {
        //保证吃豆人在游戏刚开始的时候不会动
        dest = transform.position;
    }
 
    private void FixedUpdate()
    {
        //插值得到要移动到dest位置的下一次移动坐标
        Vector2 temp = Vector2.MoveTowards(transform.position, dest, speed); //随着帧的每次调用,不断向右移动取中间值
        //通过刚体来设置物体的位置
        GetComponent<Rigidbody2D>().MovePosition(temp);
        //必须先达到上一个dest的位置才可以发出新的目的地设置指令
        if ((Vector2)transform.position == dest)
        {
            if ((Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W)) && Valid(Vector2.up))
            {
                dest = (Vector2)transform.position + Vector2.up;
            }
            if ((Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S)) && Valid(Vector2.down))
            {
                dest = (Vector2)transform.position + Vector2.down;
            }
            if ((Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A)) && Valid(Vector2.left))
            {
                dest = (Vector2)transform.position + Vector2.left;
            }
            if ((Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D)) && Valid(Vector2.right))
            {
                dest = (Vector2)transform.position + Vector2.right;
            }
            //获取移动方向
            Vector2 dir = dest - (Vector2)transform.position;
            //把获取到的移动方向设置给动画状态机
            GetComponent<Animator>().SetFloat("DirX", dir.x);
            GetComponent<Animator>().SetFloat("DirY", dir.y);
        }
    }
 
    //检测将要去的位置是否可以到达
    private bool Valid(Vector2 dir)
    {
        //记录下当前位置
        Vector2 pos = transform.position;
        //从将要到达的位置向当前位置发射一条射线,并储存下射线信息
        RaycastHit2D hit = Physics2D.Linecast(pos + dir, pos);
        //返回此射线是否打到了吃豆人自身上的碰撞器
        return (hit.collider == GetComponent<Collider2D>());
    }
}

糖豆设计(Pacdot.cs)

using UnityEngine;
 
public class Pacdot : MonoBehaviour
{
    public bool isSuperPacdot = false;
 
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.name == "Pacman")
        {
            if (isSuperPacdot)
            {
                GameManager.Instance.OnEatPacdot(gameObject);
                GameManager.Instance.OnEatSuperPacdot();
                Destroy(gameObject);
            }
            else
            {
                GameManager.Instance.OnEatPacdot(gameObject);
                Destroy(gameObject);
            }
        }
    }
}

敌方人机的移动(GhostMove) 

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class GhostMove : MonoBehaviour
{
    public GameObject[] wayPointsGos;
    public float speed = 0.2f;
    private List<Vector3> wayPoints = new List<Vector3>();
    private int index = 0;
    private Vector3 startPos;
 
    private void Start()
    {
        startPos = transform.position + new Vector3(0, 3, 0);
        LoadAPath(wayPointsGos[GameManager.Instance.usingIndex[GetComponent<SpriteRenderer>().sortingOrder - 2]]);
    }
 
    private void FixedUpdate()
    {
        if (transform.position != wayPoints[index])
        {
            Vector2 temp = Vector2.MoveTowards(transform.position, wayPoints[index], speed);
            GetComponent<Rigidbody2D>().MovePosition(temp);
        }
        else
        {
            index++;
            if (index >= wayPoints.Count)
            {
                index = 0;
                LoadAPath(wayPointsGos[Random.Range(0, wayPointsGos.Length)]);
            }
        }
        Vector2 dir = wayPoints[index] - transform.position;
        GetComponent<Animator>().SetFloat("DirX", dir.x);
        GetComponent<Animator>().SetFloat("DirY", dir.y);
    }
 
    private void LoadAPath(GameObject go)
    {
        wayPoints.Clear();
        foreach (Transform t in go.transform)
        {
            wayPoints.Add(t.position);
        }
        wayPoints.Insert(0, startPos);
        wayPoints.Add(startPos);
    }
 
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.name == "Pacman")
        {
            if (GameManager.Instance.isSuperPacman)
            {
                transform.position = startPos - new Vector3(0, 3, 0);
                index = 0;
                GameManager.Instance.score += 500;
            }
            else
            {
                collision.gameObject.SetActive(false);
                GameManager.Instance.gamePanel.SetActive(false);
                Instantiate(GameManager.Instance.gameoverPrefab);
                Invoke("ReStart", 3f);
            }
        }
    }
 
    private void ReStart()
    {
        SceneManager.LoadScene(0);
    }
}

到此这篇关于Unity3D实现经典小游戏Pacman的文章就介绍到这了,更多相关Unity3D Pacman游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言学习之函数知识总结

    C语言学习之函数知识总结

    函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。本文就为大家详细讲讲C语言中函数的相关知识点,希望有所帮助
    2022-07-07
  • VisualStudio2019解决scanf函数报错问题

    VisualStudio2019解决scanf函数报错问题

    在 Visual Studio 2019 编辑代码时,前期刚刚接触到VS编译器时存在的困惑,当用scanf()函数,进行输入时,在运行的时候编译器会出现警告报错,本文就来介绍一下解决方法
    2023-08-08
  • c++特殊构造函数详解

    c++特殊构造函数详解

    大家好,本篇文章主要讲的是c++特殊构造函数详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • 通过GDB学习C语言的讲解

    通过GDB学习C语言的讲解

    今天小编就为大家分享一篇关于通过GDB学习C语言的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • C语言简明讲解单引号与双引号的使用

    C语言简明讲解单引号与双引号的使用

    这篇文章主要介绍了在C语言里单引号和双引号的使用,本文通过实例代码说明了单引号和双引号的概念与各自的用法,以下就是详细内容,需要的朋友可以参考下
    2022-04-04
  • C++适用入门同学的模板讲解

    C++适用入门同学的模板讲解

    人们需要编写多个形式和功能都相似的函数,因此有了函数模板来减少重复劳动;人们也需要编写多个形式和功能都相似的类,于是 C++ 引人了类模板的概念,编译器从类模板可以自动生成多个类,避免了程序员的重复劳动
    2022-07-07
  • C语言深入探究函数的溯源

    C语言深入探究函数的溯源

    函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数
    2022-04-04
  • C++ 获取URL内容的实例

    C++ 获取URL内容的实例

    这篇文章主要介绍了C++ 获取URL内容的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 详解C语言中的符号常量、变量与算术表达式

    详解C语言中的符号常量、变量与算术表达式

    这篇文章主要介绍了C语言中的符号常量、变量与算术表达式,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • 从C语言过渡到C++之const

    从C语言过渡到C++之const

    C++中最早引入const是为了替代#define,后来又衍生出了其它用法。这一篇中我们来详细介绍const的各种常见用法。希望对大家学习C++有所帮助。
    2017-07-07

最新评论