Unity3D | 经典小游戏Pacman

Unity3D | 经典小游戏Pacman❥你的关注是博主坚持创作的伟大动力❥☀️项目效果展示目录☀️项目概况⭐️整体布局⭐️地图介绍⭐️玩法介绍⭐️相关知识⭐️版本说明☀️项目源码❀玩家的移动(PacmanMove.cs)❀糖豆设计(Pacdot.cs)❀敌方人机的移动(GhostMove)

大家好,又见面了,我是你们的朋友全栈君。

你的关注是博主坚持创作的伟大动力 

☀️项目效果展示

Unity3D | 经典小游戏Pacman


目录

☀️项目概况

⭐️整体布局

⭐️地图介绍

⭐️玩法介绍

⭐️相关知识

⭐️版本说明

☀️项目源码

❀玩家的移动(PacmanMove.cs)

❀糖豆设计(Pacdot.cs)

❀敌方人机的移动(GhostMove)


☀️项目概况

⭐️整体布局

Unity3D | 经典小游戏Pacman

⭐️地图介绍

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

❀普通糖豆(玩家通过移动,经过的普通糖豆会被吃掉,获得积分) 

❀特殊糖豆(玩家吃到后,可以让所有敌方停止移动,产生幻影效果)

❀隔离墙(相当于迷宫的墙,在两堵墙之间的间隙才能移动) 

❀剩余游戏时间Remain(共设300s,时间一到,游戏结束)

❀截止到现在花费的游戏时间Now(设在0~300之间)

❀截止到目前为止的游戏得分Score(越高越好)

❀敌方人机(分为四种颜色区分,小橙、小粉、小蓝、小红)

❀我方玩家(小黄,游戏的主体之一)

⭐️玩法介绍

玩法(输赢的判断):

  • 尽量在所设时限内吃完所有的糖豆并且未被敌方人机碰到。
  • 如果都吃完了,用时少的更佳;
  • 如果都没吃完,相同时间内得分高者更佳。
  • 吃到特殊糖豆(大糖豆),可以让所有敌方停止移动,产生幻影效果,相当于无敌效果的反作用,使自己在某段时间内不会被攻击,延长了玩家的存活时间,可以通过概率设计更改玩家的存活率。

⭐️相关知识

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

⭐️版本说明

  • 小虾采用的是Unity一个较新的版本-2021.1.16,这里建议小伙伴们下载和教程相同版本的,不然真的会有可能遇到卡点消耗心情哈。
  • 可以和我一样在Unity Hub里面安装,Hub感觉挺好用的。

Unity3D | 经典小游戏Pacman


☀️项目源码

小虾在这里主要介绍部分代码实现,还想知道其他部分实现的小伙伴在下方留言,我再更新哈~

❀玩家的移动(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);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145107.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 泰勒展开式「建议收藏」

    泰勒展开式「建议收藏」数学中,泰勒公式是一个用函数在某点的信息描述其附近取值的公式。如果函数足够平滑的话,在已知函数在某一点的各阶导数值的情况之下,泰勒公式可以用这些导数值做系数构建一个多项式来近似函数在这一点的邻域中的值

  • 激活函数的作用「建议收藏」

    激活函数的作用「建议收藏」激活函数是用来加入非线性因素的,解决线性模型所不能解决的问题首先我们有这个需求,就是二分类问题,如我要将下面的三角形和圆形点进行正确的分类,如下图:利用我们单层的感知机,用它可以划出一条线,把平面分割开:上图直线是由得到,那么该感知器实现预测的功能步骤如下,就是我已经训练好了一个感知器模型,后面对于要预测的样本点,带入模型中,如果y>0,那么就说明是直线的右侧,也就…

  • 后视镜加热按键图标_js点击按钮弹出图片

    后视镜加热按键图标_js点击按钮弹出图片如何给自己的网站添加方便快捷的“返回顶部”小图标按钮呢?如下图:JS源代码:/***JavaScript脚本实现回到页面顶部示例*@paramacceleration速度*@paramstime时间间隔(毫秒)**/functiongotoTop(acceleration,stime){acceleration=acceleration||0.1…

  • PAT乙级题库

    PAT乙级题库1001害死人不偿命的(3n+1)猜想(15分)1002写出这个数(20分)1004成绩排名(20分)1006换个格式输出整数(15分)1007素数对猜想(20分)1008数组元素循环右移问题(20分)1011A+B和C(15分)1012数字分类(20分)1013数素数(20分)1016部分A+B(1…

  • js的 cssText[通俗易懂]

    js的 cssText[通俗易懂]转载自:https://www.cnblogs.com/majingyi/p/6840818.html 很多人用过style.color、style.display等直接设置元素的样式属性,但是style.cssText用过的人就不多了。cssText本质是什么?cssText的本质就是设置HTML元素的sty…

  • 2021 pycharm激活码(最新序列号破解)

    2021 pycharm激活码(最新序列号破解),https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号