“抓住神经猫”的2D游戏创作

news/2025/2/5 5:08:48/

经过一阵子的学习,再次上传一份小游戏,叫“抓住神经猫”的游戏,通过二维数组,实例化出场景并进行游戏,直到围住神经猫或者让它逃脱为止。

首先呢,我把用到的图片上传,然后感兴趣的朋友可以保存图片然后复制代码进行游戏,各种函数都有介绍,希望大家能够喜欢以及支持我,以后会更新更多的自己学会的游戏并上传代码进行解说的,谢谢。

首先,我们打开Unity创建好2D 工程之后,建立一个空物体命名为GameController,然后添加场景,把背景图片拖入GameController中,如下,是一张背景图片:

1.1 游戏背景图片

这是游戏开始、游戏胜利、游戏失败、游戏重新开始的图片,我们把它也作为GameController的子物体拖入:

1.2 游戏开始图片


1.3 游戏胜利图片


1.4 游戏失败图片

1.5 游戏重新开始的图片

把这些图片都拖入GameController之后,我们把上面出背景之外的所有对象全部取消渲染,然后添加两个预设体pot1和pot2,(在2D工程中设置预设体的方法:把图片先从文件夹拖入场景中,然后设置完毕之后再把场景中的图片拖入工程文件夹里,这样就能得到预设体了)。

                                                                                                                                                                            

        1.6  pot1图片               1.7  pot2图片

之后对我们的主角神经猫进行图片的切割,然后制作成动画Animation,然后把神经猫也设置成预设体:


1.8  神经猫图片

之后,我们就可以开始编码啦,首先,编写控制pot的类脚本Item,来控制游戏场景中的位移与pot的被点击事件,代码如下:

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


public class Item : MonoBehaviour
{
    public GameController gameController;


    public int rowIndex;
    public int columnIndex;
    //po1t的偏移量
    public float xoff = -2.65f;
    public float yoff = -3.3f;


    public bool moveAble = true;                //用于检验是否可以移动


    //更新位置
    private void UpdatePosition()
    {
        Vector3 v = new Vector3(0, 0, 0);
        v.x = xoff + 0.6f * columnIndex;
        if (rowIndex % 2 == 0)
            v.x = xoff + 0.6f * columnIndex + 0.25f;
        v.y = yoff + 0.5f * rowIndex;
        transform.position = v;
    }


    //移动的函数,把对象移动到形参设置的位置上
    public void Goto(int rowIndex,int columnIndex)
    {
        this.rowIndex = rowIndex;
        this.columnIndex = columnIndex;
        UpdatePosition();
    }


    //鼠标点击后执行Select函数
    private void OnMouseDown()
    {
        gameController.Select(this);
    }
}

之后,再通过每次的点击事件来执行GameController脚本中的函数来实现游戏效果,脚本中都有注释,如果有问题的朋友可以提出来大家一起探讨,我就不一一解释了。

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


public class GameController : MonoBehaviour
{
    public GameObject pot1;
    public GameObject pot2;
    public GameObject cat;              //神经猫


    public GameObject startScreen;      //开始按钮
    public GameObject victory;          //胜利图标
    public GameObject failed;           //失败图标
    public GameObject replay;           //重玩图标


    //可点击的矩阵大小
    public int rowNum = 9;
    public int columnNum = 9;
    //设置两个储存pot1和pot2的数组
    private ArrayList potArr;
    private ArrayList pot2Arr;
    //两个判断游戏是否开始与结束的bool变量
    private bool started = false;
    private bool gameOver = false;


    // 初始化pot1,建立二维数组
    void Start()
    {
        startScreen.GetComponent<StartGame>().gameControlller = this;
        replay.GetComponent<StartGame>().gameControlller = this;
        //初始化pot2的数组
        pot2Arr = new ArrayList();
        //初始化pot的数组
        potArr = new ArrayList();


        //建立一个pot的二维数组
        for (int columnIndex = 0; columnIndex < columnNum; columnIndex++)
        {
            ArrayList temp = new ArrayList();
            for (int rowIndex = 0; rowIndex < rowNum; rowIndex++)
            {
                Item item = CreatePot(pot1, rowIndex, columnIndex);
                temp.Add(item);
            }
            potArr.Add(temp);
        }
    }


    //游戏开始,设置游戏开始时的所有状态
    public void StartGame()
    {
        //游戏开始的状态
        started = true;
        startScreen.SetActive(false);
        //游戏结束的状态,关闭其他几个可视化窗口
        failed.SetActive(false);
        victory.SetActive(false);
        replay.SetActive(false);
        gameOver = false;
        //初始化猫的位置
        cat.SetActive(true);
        MoveCat(Random.Range(3, rowNum - 3), Random.Range(3, columnNum - 3));       //随机设置神经猫的生成点
        //恢复所有pot1的点
        for(int rowIndex=0;rowIndex<rowNum;rowIndex++)
        {
            for(int columnIndex=0;columnIndex<columnNum;columnIndex++)
            {
                Item item = GetPot(rowIndex, columnIndex);
                item.moveAble = true;
            }
        }
        //移除所有的pot2
        foreach(Item item2 in pot2Arr)
        {
            Destroy(item2.gameObject);
        }
        //清空pot2的所有实例化对象
        pot2Arr.Clear();
    }


    //从potArr数组中获取点的Item信息
    Item GetPot(int rowIndex,int columnIndex)
    {
        //判断pot是否超出了数组的范围,已经离开了游戏场景
        if (rowIndex < 0 || rowIndex > rowNum - 1 || columnIndex < 0 || columnIndex > columnNum - 1)
            return null;


        ArrayList temp = potArr[rowIndex] as ArrayList;
        Item item = temp[columnIndex] as Item;
        return item;
    }


    //移动神经猫
    void MoveCat(int rowIndex ,int columnIndex)
    {
        Item item = cat.GetComponent<Item>();
        item.Goto(rowIndex, columnIndex);
    }


    //判断该坐标是否可以移动
    bool MoveAble(Vector2 vec2)
    {
        Item item = GetPot((int)vec2.x, (int)vec2.y);
        if (item == null)
            return false;
        return item.moveAble;
    }


    //判断神经猫是否逃离至边界
    bool Escaped()
    {
        //获取神经猫的Item并取行列的值
        Item item = cat.GetComponent<Item>();
        int rowIndex = item.rowIndex;
        int columnIndex = item.columnIndex;
        //如果神经猫跑到边界了则返回真
        if (rowIndex == 0 || rowIndex == rowNum - 1 || columnIndex == 0 || columnIndex == columnNum - 1)
            return true;
        return false;
    }


    //设置点击事件发生后的一系列相应事件
    public void Select(Item item)
    {
        if (!started || gameOver) return;       //如果游戏还没开始,则不能进行点击
        if (item.moveAble)
        {
            //获取神经猫的Item并取行列的值
            Item item2 = CreatePot(pot2, item.rowIndex, item.columnIndex);
            pot2Arr.Add(item2);
            item.moveAble = false;
            ArrayList steps = FindSteps();
            //如果神经猫还可以移动
            if (steps.Count > 0)
            {
                //随机移动神经猫
                int index = Random.Range(0, steps.Count);
                Vector2 temp = (Vector2)steps[index];
                MoveCat((int)temp.y, (int)temp.x);
                //如果神经猫已经逃离到了边界
                if (Escaped())
                {
                    gameOver = true;
                    failed.SetActive(true);
                    replay.SetActive(true);
                    print("Escaped");
                }
            }
            //如果神经猫已经没有可移动的pot了
            else
            {
                gameOver = true;
                victory.SetActive(true);
                replay.SetActive(true);
            }
        }
    }


    //寻找神经猫周围的可移动点,并返回可移动的点的数组
    ArrayList FindSteps()
    {
        //获取神经猫的Item并取行列的值
        Item item = cat.GetComponent<Item>();
        int rowIndex = item.rowIndex;
        int columnIndex = item.columnIndex;
        //用steps来储存可移动的pot,用vec2来储存可移动pot的行列值
        ArrayList steps = new ArrayList();
        Vector2 vec2 = new Vector2();


        //left
        vec2.y = rowIndex;
        vec2.x = columnIndex - 1;
        if (MoveAble(vec2))
        {
            steps.Add(vec2);
            //print("LEFT:" + vec2.y + "," + vec2.x);
        }
        //right
        vec2.y = rowIndex;
        vec2.x = columnIndex + 1;
        if (MoveAble(vec2))
        {
            steps.Add(vec2);
            //print("RIGHT:" + vec2.y + "," + vec2.x);
        }
        //top
        vec2.y = rowIndex + 1;
        vec2.x = columnIndex;
        if (MoveAble(vec2))
        {
            steps.Add(vec2);
            //print("TOP:" + vec2.y + "," + vec2.x);
        }
        //bottom
        vec2.y = rowIndex - 1;
        vec2.x = columnIndex;
        if (MoveAble(vec2))
        {
            steps.Add(vec2);
            //print("BOTTOM:" + vec2.y + "," + vec2.x);
        }
        //奇数行 topLeft  偶数行  topRight
        vec2.y = rowIndex + 1;
        if (rowIndex % 2 == 1)
            vec2.x = columnIndex - 1;
        else
            vec2.x = columnIndex + 1;
        if (MoveAble(vec2))
        {
            steps.Add(vec2);
            //print("TOPLEFT OR TOPRIGHT:" + vec2.y + "," + vec2.x);
        }
        //奇数行 bottomLeft  偶数行 bottomRight
        vec2.y = rowIndex - 1;
        if (rowIndex % 2 == 1)
            vec2.x = columnIndex - 1;
        else
            vec2.x = columnIndex + 1;
        if (MoveAble(vec2))
        {
            steps.Add(vec2);
            //print("BOTTOMLEFT OR BOTTOMRIGHT:" + vec2.y + "," + vec2.x);
        }
        
        return steps;
    }


    //创建pot
    Item CreatePot(GameObject pot, int rowIndex, int columnIndex)
    {
        GameObject obj = Instantiate(pot) as GameObject;
        obj.transform.parent = this.transform;                      //放在同一个父物体下,方便管理
        Item item = obj.GetComponent<Item>();                       //获取实例化pot上的Item属性
        item.Goto(rowIndex, columnIndex);                           //设置pot的位置
        item.gameController = this;                                 //令实例化的pot获取gameController属性,方便函数Select的调用
        return item;
    }
}

创作完毕之后我们再给游戏开始的图片和重新开始的图片添加BoxCollider2D来实现可点击效果,并添加下面这个脚本:

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

public class StartGame : MonoBehaviour {
    public GameController gameControlller;

    public void OnMouseDown()
    {
        gameControlller.StartGame();
    }
}

如此,我们的游戏功能就基本上都实现了,为了要让pot1可以被点击,记得给pot1添加碰撞体CircleCollider,并添加Item类脚本,为了让每一次实例化的pot都能够实现想要改变的功能,大家修改的时候可以直接修改预设体的信息。


http://www.ppmy.cn/news/307397.html

相关文章

文本挖掘学习笔记(二):文档信息向量化与主题关键词提取

注&#xff1a;学习笔记基于文彤老师文本挖掘的系列课程 全文基于《射雕英雄传》语料库&#xff0c;下面是读入数据的一个基于Pandas的通用操作框架。 读入为数据框 import pandas as pd from matplotlib import pyplot as plt %matplotlib inline # 有的环境配置下read_tab…

转换接头PL8000V-B 0-70MPa

校验台PL8000-TH 0-70MPa 量程PL8000V-B 转换接头PL8000V-B 0-70MPa 数字压力表PL8000T 0-10MPa 友谊森林奇遇记 小故事网 森林的故事   在一片森林中&#xff0c;有一群小动物快乐地生活着&#xff0c;过得无忧无虑。 有一天&#xff0c;来了一个巨人&#xff0c;他把整…

七夕节赚取徽章啦

*七夕来袭&#xff01;是时候展现专属于程序员的浪漫了&#xff01;你打算怎么给心爱的人表达爱意&#xff1f;鲜花礼物&#xff1f;代码表白&#xff1f;还是创意DIY&#xff1f;或者…无论那种形式&#xff0c;快来秀我们一脸吧&#xff01; 记录一起走过的那些日子 今天是…

Android 安卓益智休闲源码

分享104个益智休闲PHP源码&#xff0c;总有一款适合你 链接&#xff1a;https://pan.baidu.com/s/1ZqvTmaOWBN_t-D8zeL1l5Q?pwdexck 提取码&#xff1a;exck 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c;大家下…

摸鱼,我是认真的

苏生不惑第370 篇原创文章&#xff0c;将本公众号设为星标&#xff0c;第一时间看最新文章。 今天分享几个有趣好玩的摸鱼网站/app &#xff0c;摸鱼&#xff0c;我是认真的。 童年游戏博物馆 这个网站收录了各种童年记忆游戏&#xff08;冒险岛&#xff0c;超级马里奥等&#…

那些经典好玩的在线游戏:魂斗罗,超级马里奥,坦克大战

苏生不惑第156 篇原创文章&#xff0c;将本公众号设为星标&#xff0c;第一时间看最新文章。 前段时间看到一条微博 说出一款可以证明年龄的游戏https://www.weibo.com/3486415705/J5YKsEXMk &#xff0c;目前有近2000条评论&#xff0c;很多耳熟能详的经典游戏&#xff0c;比如…

尴尬了,那个程序员把我QQ给删除了

开心一笑 【几个程序员去吃饭&#xff0c;有人点了一道菜&#xff0c;麻辣牛蛙。然后其中有个人说自己不吃牛蛙&#xff0c;于是负责点菜的直接在麻辣牛蛙前划了两道斜线&#xff0c;就像这样&#xff1a; //麻辣牛蛙 现场没有任何人觉得有哪里不对。】 视频教程 大家好&a…

抓住那只喵(HTML5-神经猫)

1.使用createjs 那只喵需要easeljs-0.7.1.min.js easeljsDemo: <canvas width"800px" height"800px" id"gameView"></canvas><script src"js.js"></script> var stage new createjs.Stage("gameView&qu…