前几天上课看见舍友在玩斗兽棋 然后我下来想着也用unity实现一个
首先给大家一个我在网上找到的图片
之后大家可以用unity自带的切割图片的功能 去切割
之前我写的教程地址(给大家参考)
然后我们的思路是使用射线(从摄像头发出)检测点击的物体 当然使用特定的接口通过UGUII也可以实现
同样给出几篇我之前写过的博客给大家参考
然后呢就开始开发阶段了 我们在选择两个相邻的动物之后 我们可以给每个动物写一个单独的脚本
之后获取其中的一个值 通过对比这个值 来判断吃与被吃的关系
预览游戏
我做的这个demo和我们常见的 斗兽棋不一样 我做的这个是默认都为黑色
之后两个玩家交互的翻牌 之后一方为红一方为蓝
所以由于这个特性 我们每次图片必须打乱 从而实现游戏的可玩性(保持随机性)
开发过程
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum PlayerType
{
red,
blue
};
/// <summary>
/// 每个动物身上挂在的脚本(通过这个脚本来判断吃与被吃的关系)
/// </summary>
public class Animal : MonoBehaviour
{
public int Hp;//hp越大 优先级越高(越厉害)
public PlayerType type;//判断是什么玩家
public SpriteRenderer Black;
private BoxCollider collider;
public BoxCollider blackcollider;
float timer = 0;
private void Start()
{
collider = GetComponent<BoxCollider>();
collider.enabled = false;
}
private void Update()
{
if (Black.enabled==false)
{
collider.enabled = true;
blackcollider.enabled = false;
}
}
public void Eated()
{
if (type == PlayerType. red)
{
Arrange.Instance.rednum--;
}
if (type == PlayerType.blue)
{
Arrange.Instance.bluenum--;
}
//被吃掉的方法
gameObject.SetActive(false);
}
/// <summary>
/// 移动到目标位置去
/// </summary>
public void MoveToTargetPosi(Vector3 Targetposi)
{
timer += Time.deltaTime;
if (timer > 1)
{
timer = 0;
}
transform.position = Targetposi;
}
}
之后我们实现一下 点击黑色遮挡退去的效果 以及点击动物的事件和点击空白地方的事件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DisappearLay : MonoBehaviour
{
public Animal a, b;
public float dic;
private Vector3 targetposi;
private void Update()
{
DisappearBlack();
ClickAnimals();
}
/// <summary>
/// 消除黑色阴影
/// </summary>
public void DisappearBlack()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
if (hit.collider.tag == "Layout")
{
hit.collider.gameObject.GetComponent<SpriteRenderer>().enabled = false;
}
}
}
}
public void ClickAnimals()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (a == null && b == null)
{
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.tag == "Animal")
{
a = hit.collider.gameObject.GetComponent<Animal>();
}
}
}
if (a != null && b != null)
{
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.tag == "Animal")
{
a = hit.collider.gameObject.GetComponent<Animal>();
}
}
}
if (a != null && b == null)
{
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.tag == "Animal")
{
b = hit.collider.gameObject.GetComponent<Animal>();
}
if (hit.collider.tag == "NullPosition" && a != null)
{
a.MoveToTargetPosi(hit.collider.gameObject.transform.position);
targetposi = hit.collider.gameObject.transform.position;
Debug.LogError("点住空白部分");
}
}
}
}
if (a != null && b != null)
{
dic = Vector3.Distance(a.transform.position, b.transform.position);
}
if (a != null && b == null)
{
//dic = Vector3.Distance(a.transform.position, b.transform.position);
}
if (a == b)
{
b = null;
}
if (dic <= 2.1f)
{
if (a != null && b != null && a.Hp > b.Hp && a.type != b.type && a.Hp - b.Hp != 7)
{
b.Eated();
a.MoveToTargetPosi(b.transform.position);
a = null;
b = null;
}
if (a != null && b != null && a.Hp < b.Hp && a.type != b.type && b.Hp - a.Hp != 7)
{
a.Eated();
b.MoveToTargetPosi(a.transform.position);
a = null;
b = null;
}
if (a != null && b != null && a.Hp == b.Hp && a.type != b.type)
{
a.Eated();
b.Eated();
a = null;
b = null;
}
if (a != null && b != null && a.Hp - b.Hp==7 && a.type != b.type)//大象和老鼠的处理(a是大象 b是老鼠)
{
b.MoveToTargetPosi(a.transform.position);
a.Eated();
a = null;
b = null;
}
if (a != null && b != null && b.Hp - a.Hp == 7 && a.type != b.type)//大象和老鼠的处理
{
a.MoveToTargetPosi(b.transform.position);
b.Eated();
a = null;
b = null;
}
if (a != null && b != null && a.type == b.type)
{
a = null;
b = null;
}
}
else
{
a = null;
b = null;
}
}
}
其中我们需要创建标签 比如 每个动物都要赋值Aninal的标签
每个空白的地方都要赋值上Layout的标签
因为在开发过程中 遇到很多碰撞体乱检测的问题 所以我代码中 获取了碰撞体等组件
为了避免误触产生bug
在之后就是实现胜利的触发还有所有动物的的位置的排列组合了
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Arrange : MonoBehaviour
{
List<Vector3> posis = new List<Vector3>();
public List<GameObject> Animals;//动物的物体
//检测胜利
public Text redVectory;
public Text blueVectory;
public int rednum = 8;
public int bluenum = 8;
public static Arrange Instance;
private void Awake()
{
Instance = this;
}
private void Start()
{
for(int i=0;i<4; i++)
{
for(int j = 0; j < 4; j++)
{
posis.Add(new Vector3(i*2, j*2, 0));
}
}
for(int i = 0; i < Animals.Count; i++)
{
Vector3 temp= posis[Random.Range(0, posis.Count)];
Animals[i].transform.position = temp;
posis.Remove(temp);
}
redVectory.enabled = false;
blueVectory.enabled = false;
}
private void Update()
{
if (rednum == 0 && bluenum != 0)
{
blueVectory.enabled = true;
}
if (rednum != 0 && bluenum == 0)
{
redVectory.enabled = true;
}
}
}
其中用了单例模式 为了实时更新红方和蓝方剩余的棋子
从而给判断胜利