使用Unity制作经典2D游戏之贪吃蛇(上)
这篇文章将讲解怎么使用Unity制作简单的贪吃蛇游戏。贪吃蛇是一种街机游戏,最早的原型诞生于1976年。正如大多数街机游戏一样,它开发简单,且娱乐性强(至少克森的童年时玩它玩过来的)。
知识
我们的文章不需要什么特别的技巧,只需知道Unity的基本操作,例如:GameObject和Transform的概念等等。即使你不了解也没关系,只要你跟着我的思路来即可。
Unity版本
在本章教程中,我们将使用Unity5.0.04版本来制作。对于旧的版本也可以正常运行,不过建议大家还是使用Unity5.0以上的版本。
让我们开始吧。首先先创建一个项目:
将该工程命名为“snake”,路径由你们来设置,这里我设置的是C盘根目录下,选择2D开发,然后点击创建项目按钮:
我选择场景中的Main Camera(主相机),然后再Inspector面板中修改相机的Background为黑色背景,最后调整Size和Position,如下图所示(注意参数要一样,方便后续跟进):
我们将使用下面两张图片来制作我们的边框:
border_horizontal.png
border_vertical.png
我们再一次在Assets下选择这两张图片,如下所示:
之后,我们可以在Inspector面板中改变他们的导入设置,改变参数如下图所示:
现在,我们可以制作我们的边框了。首先把Assets下的两张图片拖拽到Hierarchy面板下,拖拽两次(你也可以通过复制的方式实现),如下图所示:
让我们为它们重命名一下,方便查找。如下图所示(Top是顶部,Bottom是底部,Left是左边,right是右边):
现在,它们在游戏中只是一张一张的图片,毫无卵用,现在就让我们为这些图片添加Colliders(碰撞器)组件,让这些图片变为一堵堵墙吧。
首先先在Hierarchy面板中选择那四张图片,如下图所示;
好,把它们都选中之后,在Inspector面板中找到Add Component按钮,点击它,然后找到Physics2D,最后点击Box Collider2D即可,如下图所示:
刚刚我们所做的操作,不用写任何一行代码,便能让一张毫无卵用的图片编程了一堵墙,太感谢Unity这个强大的游戏引擎了。
food.png
还是老样子,将它的导入设置修改一下,如下图所示:
好吧,让我们把food拖到场景中,Unity会自动的帮我们在Hierarchy面板中创建一个相对应的游戏物体,如下所示(你的位置也许跟下图不一样,这根据你拖拽的位置而定):
每当贪吃蛇碰到food(也就是食物)的时候,应当获得一些相应的信息。因此我们也要给
food(食物)添加Collider(碰撞器)组件。
一个游戏物体没有Collider(碰撞器)组件,那么它只是一个可视化物体(就是没有交互功能的物体),它不是物理世界的一部分。一旦我们为游戏物体添加了Collider(碰撞器)组件,它如一堵墙,任何物体都不能穿透它,且能通过碰撞检测事件来进行交互,如:OnCollisionEnter2D、OnCollisionStay2D等等。假如我们勾选了Is Trigger,它便如水一般,可以穿透它,且能通过触发检测事件来进行交互,如:OnTriggerEnter2D、OnTriggerStay等等。
当贪吃蛇穿过food(食物)时,贪吃蛇应该得到一些通知(就是所谓的响应事件)。然而食物不能像墙一样不能穿过它,因此我们现在要做的就是为food(食物)添加Collider(碰撞器),并且勾上Is Trigger:
好了,现在我们不想让food(食物)在游戏一开始就出现。因此我们把它做成一个预制体,以便我们使用Instantiate函数来生成它,每当我们需要它的时候。现在,让我们把food(食物)重命名为“FoodPrefab”,然后把它拖到Assets文件夹下:
现在我们可以删除Hierarchy面板中的FoodPrefad了,因为我们暂时不需要它了。
让我们在游戏开始之后,间隔几秒就在随机的地方生成一个food(食物)。那么,就让我们创建一个脚本来控制食物的生成吧。我们将把脚本放置在Main Camera下(因为Main Camera始终在游戏场景中)。首先,在Hierarchy中选择Main Camera,然后再Inspector面板中招到Add Component按钮,点击New Script,在Name的输入框中输入SpawnFood,脚本类型选择C Sharp,如下所示:
然后打开该脚本(双击即可):
using UnityEngine;
using System.Collections;
public class SpawnFood : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
我们不需要Update()函数,把它删除了:
using UnityEngine;
using System.Collections;
public class SpawnFood : MonoBehaviour {
// Use this for initialization
void Start () {
}
}
这个脚本需要获取食物预制体,因此,我们将添加一个类型为GameObject类型的公开变量:
using UnityEngine;
using System.Collections;
public class SpawnFood : MonoBehaviour {
// Food Prefab
public GameObject foodPrefab;
// Use this for initialization
void Start () {
}
}
食物应该是在边界内生成的。因此,我们也需要在我们的脚本中通过一些变量获得边框位置的相应信息,如下所示:
using UnityEngine;
using System.Collections;
public class SpawnFood : MonoBehaviour {
// Food Prefab
public GameObject foodPrefab;
// Borders
public Transform borderTop;
public Transform borderBottom;
public Transform borderLeft;
public Transform borderRight;
// Use this for initialization
void Start () {
}
}
让我们创建Spawn()函数在边界内生成food(食物)。首先我们通过x变量来获取左边界和右边界之间的随机位置信息,然后通过y变量来获取上边界和下边界之间的随机位置信息。然后我们便在该位置生成food(食物):
// Spawn one piece of food
void Spawn() {
// x position between left & right border
int x = (int)Random.Range(borderLeft.position.x,
borderRight.position.x);
// y position between top & bottom border
int y = (int)Random.Range(borderBottom.position.y,
borderTop.position.y);
// Instantiate the food at (x, y)
Instantiate(foodPrefab,
new Vector2(x, y),
Quaternion.identity); // default rotation
}
现在,让我们的脚本在每几秒后调用Spawn()函数,我们可以通过使用InvokeRepeating()函数来做:
// Use this for initialization
void Start () {
// Spawn food every 4 seconds, starting in 3
InvokeRepeating("Spawn", 3, 4);
}
下面是SpawnFood函数的完整代码:
using UnityEngine;
using System.Collections;
public class SpawnFood : MonoBehaviour {
// Food Prefab
public GameObject foodPrefab;
// Borders
public Transform borderTop;
public Transform borderBottom;
public Transform borderLeft;
public Transform borderRight;
// Use this for initialization
void Start () {
// Spawn food every 4 seconds, starting in 3
InvokeRepeating("Spawn", 3, 4);
}
// Spawn one piece of food
void Spawn() {
// x position between left & right border
int x = (int)Random.Range(borderLeft.position.x,
borderRight.position.x);
// y position between top & bottom border
int y = (int)Random.Range(borderBottom.position.y,
borderTop.position.y);
// Instantiate the food at (x, y)
Instantiate(foodPrefab,
new Vector2(x, y),
Quaternion.identity); // default rotation
}
}
现在让我们保存脚本,然后回到Inspector面板中,你将会发现SpawnFood脚本下多了几个卡槽,现在我们要做的就是找到对应的预制体,将其拖进卡槽中,如下图所示:
好吧,现在让我们点击Play按钮,然后等待几秒钟,我们将能看到游戏场景中有了一些小点点(食物):
好了,今天就只能到这里了。看了下表23点55分,明天再把它更完吧。