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

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

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

2-1、新建项目

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

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

(3)目录如下图所示:

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

2-2、导入资源

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

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

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

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

2-3、设置摄像机属性

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

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

2-4、制作默认方块

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

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

注意:勾选Is Trigger

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

(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 OnMouseUpAsButton()
{
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 OnMouseUpAsButton()
{
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、效果

Unity破窗游戏制作(简易版)的更多相关文章

  1. Unity 进度条3D制作(3D版)

    昨天我们一起学习了2D进度跳的制作,那么趁着我们脑海中还残存昨日的记忆,今天继续学习另一种方法: 实现思路:当鼠标悬浮Start按钮->实例化物体并显示进度->100/100->进入 ...

  2. 简易2D横版RPG游戏制作

    Unity学习笔记1 简易2D横版RPG游戏制作 http://m.blog.csdn.net/article/details?id=24601905

  3. html5 canvas简易版捕鱼达人游戏源码

    插件描述:html5利用canvas写的一个js版本的捕鱼,有积分统计,鱼可以全方位移动,炮会跟着鼠标移动,第一次打开需要鼠标移出背景图,再移入的时候就可以控制炮的转动,因为是用的mouseover触 ...

  4. unity入门—五分钟制作一个理论上的游戏

    unity入门 前言:这可不是标题党,虽然都是基础的操作,不过含括了基本的流程,比起脑海中的五花八门的画面,入门还是这个现实一点. 这里插两句,unity国外官网下载会推荐你看一个简短的视频,国内官网 ...

  5. 自定义View4-塔防小游戏第一篇:一个防御塔+多个野怪(简易版)*

    塔防小游戏 第一篇:一个防御塔+多个野怪(简易版)    1.canvas画防御塔,妖怪大道,妖怪行走路线    2.防御塔攻击范围是按照妖怪与防御塔中心距离计算的,大于防御塔半径则不攻击,小于则攻击 ...

  6. 利用Unity3D制作简易2D计算器

    利用Unity3D制作简易2D计算器 标签(空格分隔): uiniy3D 1. 操作流程 在unity3DD中创建一个新项目 注意选择是2D的(因为默认3D) 在Assets框右键新建C#脚本 在新建 ...

  7. MVC 验证码实现( 简易版)

    现在网站上越来越多的验证码,使用场景也是越来越多,登陆.注册.上传.下载...等等地方,都有可能大量使用到验证码,那么制作验证码到底有多简单呢?我们一起来看下最简易版的验证码实现过程- 验证码的基本步 ...

  8. C+命令行+方向键=简易版扫雷

    前言: 想起来做这个是因为那时候某天知道了原来黑框框里面的光标是可以控制的,而且又经常听人说起这个,就锻炼一下好了. 之前就完成了那1.0的版本,现在想放上来分享却发现有蛮多问题的,而且最重要的是没什 ...

  9. 游戏制作之路:一个对我来说可实现的High-end的Mac/iOS游戏制作大概计划

    对于学习一些东西,我比较习惯任务驱动式的学习,也就是说,要事先订好一个目标,要做什么东西,达到什么效果,然后根据自己了解的知识作一个可以实现这个目标的计划. 现在要学的是游戏制作,而且是High-en ...

随机推荐

  1. Java面试题(六)--Redis

    1 Redis基础篇 1.简单介绍一下Redis优点和缺点? 优点: 1.本质上是一个 Key-Value 类型的内存数据库,很像memcached 2.整个数据库统统加载在内存当中进行操作,定期通过 ...

  2. Linux环境监控工具汇总

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. Linux 操作系统有诸多自带和第三方的监控工具,以下从不同维度来整理常用的一些监控工具. CPU top(经典的Linu ...

  3. 最新MongoDB安装,学习笔记

    MongoDB 导读 作者还在陆续更新中,如果喜欢作者的笔记,觉得可以学习到有帮助,后面会不断学习新内容,就点个关注吧,如果觉得文章有关注可以点个赞,谢谢: 官网:https://www.mongod ...

  4. 利用 SonarScanner 静态扫描 Rainbond 上的 Maven 项目

    对代码进行静态扫描是一种非常常见的代码质量保证手段,这种扫描不仅仅可以检查到代码中的缺陷,应用各种业界最佳实践,也可以检查出安全方面的漏洞,给予项目代码全方位的提升.在各种代码扫描方案之中,Sonar ...

  5. Docker与GU 安装管理配置

    Linux 下的 Docker 安装与使用 一.安装与配置 1.安装依赖包 1 sudo yum install -y yum-utils device-mapper-persistent-data ...

  6. Word 脚注和尾注是什么?怎么设置?

    描述 脚注一般位于页面的底部,作为文档某处内容的注释.尾注一般位于文档的末尾,列出引文的出处等. 设置脚注和尾注 将光标移动到要插入脚注或尾注的地方,然后点击"引用"选项卡. 左边 ...

  7. 微软Azure配置中心 App Configuration (二):Feature Flag 功能开关特性

    写在前面 Web服务开发过程中我们经常有这样的需求: 某些功能我必须我修改了配置才启用,比如新用户注册送券等: 某个功能需到特定的时间才启用,过后就失效,比如春节活动等: 某些功能,我想先对10%的用 ...

  8. Github文件在线加速下载

    众所周知,GitHub是一个巨大的开源宝库,以及程序员和编程爱好者的聚集地,诸多优秀的开源项目全部都是位于GitHub上.但是每当我们看到优秀的开源项目,准备去下(bai)载(piao)时,会发现速度 ...

  9. ansible 002 连接被控端 inventory ansible.cfg ansible-adhoc ansible原理

    ssh用普通用户连接被控端 配置主机清单 (/etc/hosts域名解析为前提) [root@workstation ansible]# cat hosts servera serverb [root ...

  10. npm 和 maven 使用 Nexus3 私服 | 前后端一起学

    前文<Docker 搭建 Nexus3 私服 >介绍了在 docker 环境下安装 nexus3 以及 nexus3 的基本操作和管理,本文分别介绍 npm(前端)和 maven(后端)如 ...