很多游戏的养成系统中会有利用芯片或者碎片来合成特定道具的功能,或者来给玩家以额外的属性提升等,先截个图以便更好说明:
如上图,我们有各种各样形状迥异的碎片,上面只不过列举了其中一部分,现在,我们需要利用这些碎片非常恰好和完整的将左边这个棋盘格填满;当然了,这里并不是要让计算机来计算所有的填充办法,也不是要让计算机来自动的完成填充,而是要让玩家来选择这些碎片的具体放法,最终的目的都是要让这个棋盘格全部填满以解锁新的游戏道具或给游戏中的单位提升尽可能多的属性。这样玩家可以有充分的自由,好去思考和权衡自己当前碎片的库存情况,每个碎片带给玩家的属性提升情况,最终来确定自己应该如何去放。
我们先假设一下玩家放碎片的整个流程,例如,他先选中其中一个碎片,然后点击棋盘格中的一个空白的位置,最后这个碎片就会填充到他所指定的位置。听上去似乎没有任何的问题,但实际上,有很多细节我们都没有思考清楚。
1.他所选中的那个碎片到底能不能在点击的棋盘格位置放下呢?例如,现在只剩两格空格点了,而选择的确是一个三格的碎片,则无论如何点击也是不可能放下此碎片的,即使可能剩下五格,也不一定能保证放下特殊形状的三格碎片。
2.如何能放下碎片,那应该以碎片的哪个格子为基准点进行放置呢?观察下面几张图:
我选中的是同一个碎片,点击的都是棋盘格的中间哪个格子,理论上就会有3种可能的放法,会根据你的碎片定义的基准点放置结果不同,如果碎片本身的格子数更多的话,放置的方式也会和碎片占有的格子数一样多。这本身不会产生任何问题,只要给碎片定义一个原点(基准点)不就好了,但有时候又会有这样的情况发生:
假如图上已经有两个碎片了,你还是像之前一样选中那个折角点击最中心那个格子,这是你发现只剩唯一一种放法,如果你之前定义的碎片的原点并不是折角的那个格子,那么你怎么样都放不上去了,但只要是个人都知道点击中间那个格子是有放法的。那这个时候就会有矛盾产生了,有多种放法的时候应该怎么放,如何定义原点的话只有唯一一种放法的时候很可能就放不上去了,那应该如何处理呢?
我的处理方式是:还是先给每一个碎片定义一个默认原点,但也不一定就要按这个原点的顺序去放置,只有当默认原点放置的方式失效时,才考虑其他的格子作为原点的放法。
基于以上的想法,就可以定义出碎片的基类了:
1 using System.Collections.Generic; 2 using UnityEngine; 3 4 public class Fragment : MonoBehaviour 5 { 6 public int TypeID; 7 //默认原点 8 public List<Vector2Int> Pos; 9 //其他可能的原点组合 10 public List<List<Vector2Int>> ExPos; 11 public bool bSelected { get; set; } 12 public virtual void Init() { } 13 }