首页 > 其他分享 >Unity破窗游戏制作(简易版)

Unity破窗游戏制作(简易版)

时间:2022-10-08 11:33:16浏览次数:74  
标签:Perfect elements Grids int 破窗 简易版 Unity static public

Unity破窗游戏制作(简易版)

参考:“对不起,我选择摸鱼”—《扫雷》小游戏开发实战,算法、源代码,基于Unity3D开发 - 掘金 (juejin.cn)

到“制作默认方块(4)”均为相同操作

2-1、新建项目

(1)项目开发,从新建项目开始,我使用的Unity版本是Unity 2019.4.7f1,模板就选择2D,项目名称随意,别中文就行:

image.png

(2)创建目录,在Project视图,右击选择Create→Folder,新建几个文件夹:

image.png

(3)目录如下图所示:

image.png

  • Prefabs:预制体资源文件夹
  • Scenes:场景资源文件夹
  • Scripts:脚本资源文件夹
  • Sprites:图片资源文件夹

2-2、导入资源

接下来将需要的资源导入:

default.png null.png mine.png

全部右键另存为图片,然后导入到Project视图的Sprites文件夹内:

选中所有图片,在Inspector视图中,设置Pixels Per Unit为16:

image.png

之所以设置为16,是因为16X16这个单位在游戏世界中是一个比较适合的值。

2-3、设置摄像机属性

在Hierarchy视图中,选中Main Cameras对象,然后在Inspector视图中找到Camera组件,设置属性:

image.png

注意:Clear Flags设置为Skybox,Background按照图中设置,然后Size设置为20。

2-4、制作默认方块

(1)将Project视图的Sprites目录中的default对象拖入Hierarchy视图中:

image.png

(2)选中default对象,在Inspector视图中,选择Add Componet→Physics 2D→Box Collider 2D,添加碰撞器组件:

image.png

注意:勾选Is Trigger

(3)选中default对象,拖回到Projcet视图的Prefabs文件夹内,做成一个预制体,我们将在后面的代码中去实例化生成它:

image.png

(4)Hierarchy视图中的default对象就可以删除了。

(5)新建脚本CreateBg.cs

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

public class CreateBg : MonoBehaviour
{
    public GameObject block;//默认方块
    void Start()
    {
        //创建默认方块
        CreateBlock();
    }

    private void CreateBlock()
    {
        //创建方块父物体
        GameObject blockParent = new GameObject("blockParent");
        //创建10行10列的默认方块
        for (int i = 0; i < 10; i++)
        {
            for (int j = 0; j < 10; j++)
            {
                //Instantiate参数为:预制体 位置 旋转 父物体
                Instantiate(block, new Vector2(i, j), Quaternion.identity, blockParent.transform);
            }
        }
    }
}

将脚本托给Main Camera对象,然后将预制体拖入Block卡槽中:

基本界面就做好了。

2-5、制作窗户类型

(1)新建一个脚本Element.cs,然后在Project视图的Prefabs文件夹中选中default对象,点击Add Componet→Element添加脚本:

 .....
 public bool Lock;//判断是否是锁住
 public bool Perfect;//判断是否是完好
 public bool Broken;
 public Sprite LockTexture;
 public Sprite PerfectTexture;
 public Sprite BrokenTexture;
 void Start()
    {
        //随机锁住
        Lock = Random.value < 0.1;
        Perfect = !Lock;
         // 在Grid注册
        int x = (int)transform.position.x;
        int y = (int)transform.position.y;
        Grids.elements[x, y] = this;
        if (Lock) Grids.elements[x, y].loadTexture(0);

    }
 public void loadTexture(int adjacentCount)
    {
        if (adjacentCount==0)
            GetComponent<SpriteRenderer>().sprite = LockTexture;
        else if(adjacentCount==1)
            GetComponent<SpriteRenderer>().sprite = PerfectTexture;
        else GetComponent<SpriteRenderer>().sprite = BrokenTexture;
    }
    .....

(2)选中default预制体,将对应的资源拖入Element.cs脚本的属性卡槽中:


(3)新建一个Grid.cs脚本,将脚本也添加到预制体default身上,Grid脚本将处理更加复杂的游戏逻辑:

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

public class Grids : MonoBehaviour
{
    public static int w=4; // 网格的长
    public static int h=6; // 网格的高
    public static Element[,] elements = new Element[w, h];
    public static bool isPerfect(int x,int y)
    {
        ....
    }
    public static bool isBroken(int x, int y)
    {
        ....
    }
    public static void brokeWin(int x,int y)
    {
       ....
    }
    public static bool isWin()
    {
      .... 
    }
    public static bool GameOver()
    {
        ....
    }
}

2-6、破坏窗户

Grids.cs:

 public static bool isPerfect(int x,int y)
    {
        if (x >= 0 && y >= 0 && x < w && y < h)
            return elements[x, y].Perfect;
        return false;
    }
    public static bool isBroken(int x, int y)
    {
        if (x >= 0 && y >= 0 && x < w && y < h)
            return elements[x, y].Broken;
        return false;
    }


    public static void brokeWin(int x,int y)
    {
        if (isPerfect(x , y)) { elements[x, y].loadTexture(2);elements[x, y].Broken = true; elements[x, y].Perfect = false; }
        else if (isBroken(x, y)) { elements[x, y].loadTexture(1); elements[x, y].Broken = false; elements[x, y].Perfect = true; }

    }

Elements.cs:

 void onm ouseUpAsButton()
    {
        if (!Lock)	//锁住的窗无法互动
        {
            //反转5格内的非锁住窗户
            int x = (int)transform.position.x;
            int y = (int)transform.position.y;
            Grids.brokeWin(x , y);
            Grids.brokeWin(x-1, y);
            Grids.brokeWin(x+ 1, y);
            Grids.brokeWin(x, y-1);
            Grids.brokeWin(x , y+1);
            //判断是否胜利
            if (Grids.isWin())
            {
                Debug.Log("Game Win");
            }
            if (Grids.GameOver())
            {
                Debug.Log("Game Over");
            }
        }
    }

2-7、判断是否已经破坏所有窗户

接下来,需要判断玩家破坏所有窗户,

接着修改Grid类的代码,添加函数isWin

public static bool isWin()
    {
        foreach (Element elem in elements)
            if (elem.Perfect)
                return false;
        return true;

    }


    public static bool GameOver()
    {
        for(int i = 0; i < w; i++)
        {
            for(int j = 0; j < h; j++)
            {
                if (elements[i, j].Perfect && (i - 1 < 0 || !elements[i - 1, j].Perfect) && (i + 1 >= w || !elements[i + 1, j].Perfect) && (j - 1 < 0 || !elements[i, j - 1].Perfect) && (j + 1 >= h || !elements[i, j + 1].Perfect))
                    return true;
                
            }
        }
        return false;

    }

在这里游戏失败的原因可以有很多:

  • 本就无解
  • 超过了限制步数
  • 超过时间

这些都可以自己写

然后获胜或失败的UI可以自己加

2-8、总结

游戏的大体框架就开发完成了,当然,你也可以添加一些元素让游戏更加有趣:

  • 分成更多难度,比如简单、中等、困难
  • 切换更加漂亮的UI
  • 输赢界面以及重新开始
  • 添加音效

2-9、源码

Grids:

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

public class Grids : MonoBehaviour
{
    public static int w=4; // 网格的长
    public static int h=6; // 网格的高
    public static Element[,] elements = new Element[w, h];

    public static bool isPerfect(int x,int y)
    {
        if (x >= 0 && y >= 0 && x < w && y < h)
            return elements[x, y].Perfect;
        return false;
    }
    public static bool isBroken(int x, int y)
    {
        if (x >= 0 && y >= 0 && x < w && y < h)
            return elements[x, y].Broken;
        return false;
    }


    public static void brokeWin(int x,int y)
    {
        if (isPerfect(x , y)) { elements[x, y].loadTexture(2);elements[x, y].Broken = true; elements[x, y].Perfect = false; }
        else if (isBroken(x, y)) { elements[x, y].loadTexture(1); elements[x, y].Broken = false; elements[x, y].Perfect = true; }

    }

    public static bool isWin()
    {
        foreach (Element elem in elements)
            if (elem.Perfect)
                return false;
        return true;

    }


    public static bool GameOver()
    {
        for(int i = 0; i < w; i++)
        {
            for(int j = 0; j < h; j++)
            {
                if (elements[i, j].Perfect && (i - 1 < 0 || !elements[i - 1, j].Perfect) && (i + 1 >= w || !elements[i + 1, j].Perfect) && (j - 1 < 0 || !elements[i, j - 1].Perfect) && (j + 1 >= h || !elements[i, j + 1].Perfect))
                    return true;
                
            }
        }
        return false;

    }

}

Element:

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

public class Element : MonoBehaviour
{
    public bool Lock;//判断是否是锁住
    public bool Perfect;//判断是否是完好
    public bool Broken;
    public Sprite LockTexture;
    public Sprite PerfectTexture;
    public Sprite BrokenTexture;


    void Start()
    {
        //随机锁住
        Lock = Random.value < 0.1;
        Perfect = !Lock;
        int x = (int)transform.position.x;
        int y = (int)transform.position.y;
        Grids.elements[x, y] = this;
        if (Lock) Grids.elements[x, y].loadTexture(0);

    }

    public void loadTexture(int adjacentCount)
    {
        if (adjacentCount==0)
            GetComponent<SpriteRenderer>().sprite = LockTexture;
        else if(adjacentCount==1)
            GetComponent<SpriteRenderer>().sprite = PerfectTexture;
        else GetComponent<SpriteRenderer>().sprite = BrokenTexture;
    }

    // 判断是否被点击
    public bool isCovered()
    {
        //判断当前纹理的名称是不是默认值
        return GetComponent<SpriteRenderer>().sprite.texture.name == "default";
    }

    // 鼠标点击
    void onm ouseUpAsButton()
    {
        if (!Lock)
        {

            //破坏周围的窗户
            int x = (int)transform.position.x;
            int y = (int)transform.position.y;
            Grids.brokeWin(x , y);
            Grids.brokeWin(x-1, y);
            Grids.brokeWin(x+ 1, y);
            Grids.brokeWin(x, y-1);
            Grids.brokeWin(x , y+1);

            //判断是否胜利
            if (Grids.isWin())
            {
                Debug.Log("Game Win");
            }
            if (Grids.GameOver())
            {
                Debug.Log("Game Over");
            }
        }
    }

}

CreateBg:

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

public class CreateBg : MonoBehaviour
{
    public GameObject block;//默认方块
    void Start()
    {
        //创建默认方块
        CreateBlock();
    }

    public void CreateBlock()
    {
        //创建方块父物体
        GameObject blockParent = new GameObject("blockParent");
        //创建10行10列的默认方块
        for (int i = 0; i <Grids.w; i++)
        {
            for (int j = 0; j < Grids.h; j++)
            {
                //Instantiate参数为:预制体 位置 旋转 父物体
                Instantiate(block, new Vector2(i, j), Quaternion.identity, blockParent.transform);
            }
        }
    }
}

2-10、效果

标签:Perfect,elements,Grids,int,破窗,简易版,Unity,static,public
From: https://www.cnblogs.com/yanyh-robot/p/16768404.html

相关文章

  • unityshader学习笔记4
    顶点/片元着色器的基本结构:Shader"Custom/SimpleShader"{  SubShader{    Pass{      CGPROGRAM      #pragmavertexve......
  • Unity Shader入门精要第七章 基础纹理之遮罩纹理
    Unity系列文章目录文章目录​​Unity系列文章目录​​​​前言​​​​一、实践​​​​参考​​前言遮罩纹理(masktexture)是本章要介绍的最后一种纹理,它非常有用,在很多商业......
  • 关于windows-server-下MySQL Community版本的的安装与配置
    在公司电脑或者服务器上安装软件,都是有要求的,要么购买license(这个需要申请,难度较大),要么安装免费开源的软件笔者最近想要安装mysql服务环境,用于数据存储及开发一些功能程序......
  • Unity同项目导出不同的UnityPackage流程
    Unity3D中的root项目导出为一个package;新建项目并将package导入进来;在新建的项目里更改里面的各种信息(脚本、模型、贴图等等);重命名所有的更改了的资源名称;将所有的prefab都......
  • Unity Editor中模拟HoloLens交互
    下方是在编辑器中模拟HoloLens交互的基本方式按下WSADQE键控制视角的前后左右上下按下鼠标右键移动控制视角按下鼠标右键+滚动鼠标滑轮控制视角的左右旋转按下......
  • 安装mysql-community-server-8.0.30-1.el7.x86_64报错解决办法
    1.错误如下:warning:/usr/local/src/mysql-community-server-8.0.30-1.el7.x86_64.rpm:HeaderV4RSA/SHA256Signature,keyID3a79bd29:NOKEYerror:Faileddepend......
  • 【unity】反射机制
    前言很久之前就听说过反射,但不甚理解,今天看到底层终于领悟,遂记录一下相关内容。C#反射什么是反射借用光学中的反射(Reflection)之名,C#中的反射是从对象外部去获取对象内......
  • Unity中的程序集定义
    Unity项目中,默认我们会出现Assembly-CSharp程序集,编译成Assembly-CSharp.dll文件,在默认情况下我们创建的代码文件均在此程序集中。当我们为Editor添加代码时,只要代码文件放......
  • 【Unity】浅尝xlua热更新插件
    前言之前的学习中了解到了一些热更新的知识,本想系统地学习基于xLua的热更新框架,但时间紧迫,遂浅尝辄止。在此记录一下相关知识。什么是热更新从云端下载资源包,这些新资源......
  • 2022是元宇宙爆发年 最近Unity元宇宙外包和UE4元宇宙外包项目做的比较多 有需要欢迎联
    2022是元宇宙爆发年最近Unity元宇宙和UE4元宇宙相关项目做的比较多有需要欢迎联系我们......