在解谜类游戏中,往往有许多需要在鼠标点击过后与玩家互动的物品。这些互动的具体实现过程可能各不相同,但是却有一些公共的方法,例如正确选择物品的互动反馈和错误选择物品的互动反馈。因此我们首先抽象出Interactive作为基类,再根据游戏具体需求继承基类实现不同的互动功能。
一、Interactive
首先,我们需要定义互动所需的基本条件(玩家在拥有什么道具的情况下才能与场景中的物品或人物进行互动)和互动的完成情况。
//Interactive.cs
public ItemName requireItem;//需要互动的物品
public bool isDone;//互动是否结束
其次,我们需要定义正确选择和错误选择物品下的互动反馈方法。在这里我们将函数声明为虚函数,不用做出具体的实现,在使用的时候再在继承类中重写。
//Interactive.cs
/// <summary>
/// 选择正确物品的执行情况
/// </summary>
protected virtual void OnClickedAction()
{
}
public virtual void EmptyClicked()
{
Debug.Log("空点");
}
接下来,我们定义物品点击的反馈函数。由于该方法对于不同物品互动的实现均相同,所以可以在Interactive类中给出具体实现。
//Interactive.cs
public void CheckItem(ItemName itemName)
{
if(itemName == requireItem&&!isDone)//选择了正确的互动物品并且互动没有结束
{
isDone = true;
//对物体进行操作(使用物体或移除物体)
OnClickedAction();
EventHandler.CallItemUsedEvent(itemName);
}
}
二、Cotton Puzzle 案例分析
在这里我们以迷失岛2为例,说明在游戏中如何实现与人物以及邮箱的互动。
2.1 邮箱
当我们获取钥匙以后,可以到达邮箱所在场景去开启邮箱。在此之前我们点击邮箱应该没有任何反应。在这里我们的requireItem就是Key。
当我们点击钥匙后再次点击邮箱,邮箱便会被打开并显示出邮票。此时在背包栏中的钥匙也会相应消失。
接下来我们将定义MailBox继承Interactive类,重写OnClickedAction方法并在打开邮箱后实现邮箱贴图的变化以及背包物品的更新。
//MailBox.cs
public class MailBox : Interactive
{
private SpriteRenderer spriteRenderer;
private BoxCollider2D boxCollider;
public Sprite openSprite;
private void Awake()
{
spriteRenderer = GetComponent<SpriteRenderer>();
boxCollider = GetComponent<BoxCollider2D>();
}
private void OnEnable()
{
EventHandler.AfterSceneLoadedEvent += OnAfterSceneLoadedEvent;
}
private void OnDisable()
{
EventHandler.AfterSceneLoadedEvent -= OnAfterSceneLoadedEvent;
}
private void OnAfterSceneLoadedEvent()
{
if(!isDone)
transform.GetChild(0).gameObject.SetActive(false);
else
{
spriteRenderer.sprite = openSprite;
boxCollider.enabled = false;
}
}
protected override void OnClickedAction()
{
spriteRenderer.sprite= openSprite;
transform.GetChild(0).gameObject.SetActive(true);
}
}
2.2 人物互动
在解谜类游戏中经常会出现和人物的对话,通常在获取指定物品前后与人物的对话内容是不同的。在迷失岛2中船票是和老奶奶对话发生变化的requireItem。
由于要实现点击后与老奶奶的对话,所以该互动脚本搭载的物体需要拥有对话控制组件,在CharacterH2脚本中添加以下代码以确保包含对话控制组件。
//CharacterH2.cs
[RequireComponent(typeof(DialogController))]
接下来根据是否使用了船票对不同的对话内容进行显示。
//CharacterH2.cs
public class CharacterH2 : Interactive
{
DialogController dialogController;
private void Awake()
{
dialogController = GetComponent<DialogController>();
}
/// <summary>
/// 选择正确物品的执行情况
/// </summary>
protected override void OnClickedAction()
{
//对话内容B
dialogController.ShowDialogFinish();
}
public override void EmptyClicked()
{
if (isDone)
//对话内容B
{
dialogController.ShowDialogFinish();
//Debug.Log("对话内容B");
}
else
//对话内容A
{
dialogController.ShowDialogEmpty();
//Debug.Log("对话内容A");
}
}
}