楼主学习Unity的时间有限,每天最多能抽出1小时看看,主要还是周末的时间了。
最近打算开发几个小游戏练练手。最简单的水果忍者就被我相中了,来吧,骚年,一起来一发。
先分析下切水果的几个要点:
1)手指滑过时的刀光、拖尾等:这个我打算用TrailRenderer来实现。效率先不考虑,能做出来再说。
2)水果的刷新:每隔一段时间,比如2s,刷新若干个水果向上抛物运动。这个用协同程序来完成刷新。抛出的时候向上加一个初速度即可。
3)水果的切割:从刀开始触发碰撞到碰撞结束之后,水果才算被切开。然后水果消失,copy出水果的左右两瓣,各自做水平抛物运动。
先完成这几点吧。虽然和大作有点实现上的出入,但是先做出来再细化吧。
1、刀光、拖尾
我的思路是:创建一个空的obj,给他加上Rigidbody2D、CircleCollider2D、TrailRenderer,然后在脚本中实现当鼠标滑到哪的时候,就把这个obj移动到哪。
设置如下:
代码编写如下:
using UnityEngine;
using System.Collections;
public class Knife : MonoBehaviour {
private Vector3 m_VecMouse = new Vector3(0,0,0);
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (!Input.GetMouseButton (0)) {
return;
}
Vector3 ptScreen = Camera.main.WorldToScreenPoint (transform.position);
m_VecMouse.x = Input.mousePosition.x;
m_VecMouse.y = Input.mousePosition.y;
m_VecMouse.z = ptScreen.z;
transform.position = Camera.main.ScreenToWorldPoint (m_VecMouse);
}
void OnTriggerEnter2D(Collider2D other) {
if (!Input.GetMouseButton (0)) {
return;
}
}
void OnTriggerExit2D(Collider2D other) {
if (!Input.GetMouseButton (0)) {
return;
}
audio.Play ();
}
}
游戏效果如下:
感觉还是能接受的。关键是刀光是我自己ps的,技术有限。
2、水果的刷新
先准备下资源:
楼主到处抠图,找到了一个菠萝的psd,再将2dtk里面的箱子copy过来,修改下。
先准备几个预制体,如下:
预制体放到Resources目录下,主要是方便在脚本中加载。我上一篇博客介绍过。
每个水果准备4个预制体:box是完整的水果的,需要附加刚体、碰撞器、脚本等,box_a和box_b是两瓣水果,只需要刚体就行,box_mark是污渍,就是个贴图。
全部准备完毕,开始编写刷新的脚本,如下:
using UnityEngine;
using System.Collections;
public class GameControl : MonoBehaviour {
private GameObject[] m_Prefabs;
public static readonly string[] FRUIT_DATA = {"box", "pineapple",};
// Use this for initialization
void Start () {
m_Prefabs = new GameObject[FRUIT_DATA.Length];
for (int i=0; i<FRUIT_DATA.Length; i++) {
m_Prefabs[i] = Resources.Load ("Prefabs/"+FRUIT_DATA[i]) as GameObject;
}
StartCoroutine ("FlushFruit");
}
// Update is called once per frame
void Update () {
}
//刷新水果
IEnumerator FlushFruit() {
yield return new WaitForSeconds (3);
while (true) {
int iCount = Random.Range(1, 3);
for (var i=0; i<iCount; i++) {
int iIndex = Random.Range(0,FRUIT_DATA.Length);
GameObject fruit = Instantiate(m_Prefabs[iIndex]) as GameObject;
float fPosX = Random.Range(-4.0f, 4.0f);
fruit.transform.position = new Vector3(fPosX, -4.0f, 0);
float fAngle = Random.Range(-180.0f, 180.0f);
fruit.transform.Rotate(Vector3.forward * fAngle);
float fForce = Random.Range(7.0f, 12.0f);
if (fPosX > 0.0f) {
fruit.rigidbody2D.velocity = new Vector3(-1.0f, fForce, 0);
} else {
fruit.rigidbody2D.velocity = new Vector3(1.0f, fForce, 0);
}
}
yield return new WaitForSeconds(1);
}
}
}
我是先暂停了3秒,才开始刷新水果的。毕竟从菜单场景进入本场景,先准备3s比较好。最后,这里还是可以加入3秒的倒计时显示的。比较人性化。
3、水果的切割效果
其实具体思路,最上面就写清楚了。很简单。被碰撞后,发现是刀,就销毁自己,然后创建两瓣水果,分别抛物+自由落体。
using UnityEngine;
using System.Collections;
public class Fruit : MonoBehaviour {
private GameObject m_PrefabFruitA;
private GameObject m_PrefabFruitB;
private GameObject m_PrefabFruitMark;
// Use this for initialization
void Start () {
int i = name.IndexOf("(");
string sName = name;
if (i > 0) {
sName = name.Substring (0, i);
}
m_PrefabFruitA = Resources.Load ("Prefabs/"+sName+"_a") as GameObject;
m_PrefabFruitB = Resources.Load ("Prefabs/"+sName+"_b") as GameObject;
m_PrefabFruitMark = Resources.Load ("Prefabs/"+sName+"_mark") as GameObject;
}
// Update is called once per frame
void Update () {
transform.Rotate (Vector3.forward * Time.deltaTime * 20);
}
void OnTriggerExit2D(Collider2D other) {
if (other.name == "LeftWall" || other.name == "RightWall" || other.name == "BottomWall") {
Destroy (gameObject);
return;
} else if (other.name != "Knife") {
return;
}
if (!Input.GetMouseButton (0)) {
return;
}
Vector3 ptCur = transform.position;
//删除完整的水果
Destroy (gameObject);
//创建污渍
GameObject oFruitMark = Instantiate (m_PrefabFruitMark) as GameObject;
oFruitMark.transform.position = ptCur;
//给污渍随机一个旋转角度
float fAngle = Random.Range (-180.0f, 180.0f);
oFruitMark.transform.Rotate (Vector3.forward * fAngle);
Destroy (oFruitMark, 5.0f);
//左侧水果
GameObject oHalfA = Instantiate (m_PrefabFruitA) as GameObject;
oHalfA.transform.position = ptCur;
fAngle = Random.Range (-180.0f, 180.0f);
oHalfA.transform.Rotate (Vector3.forward * fAngle);
oHalfA.rigidbody2D.velocity = Vector3.left * 3;
Destroy (oHalfA, 3.0f);
//右侧水果
GameObject oHalfB = Instantiate (m_PrefabFruitB) as GameObject;
oHalfB.transform.position = ptCur;
fAngle = Random.Range (-180.0f, 180.0f);
oHalfB.transform.Rotate (Vector3.forward * fAngle);
oHalfB.rigidbody2D.velocity = Vector3.right * 3;
Destroy (oHalfB, 3.0f);
}
}
不过,好像原版里面,污渍不是这么显示的,是显示在其中一半水果的地方,也可能完全不显示污渍。不过这些是细节了。也不难处理。
还像那么回事吧。
现在还缺的就是界面和计分了。打算先用原生的做下试试。
等做的差不多了,再给来第二发。
最后,源码和资源: http://download.csdn.net/detail/leecrest/7084779。