ぬるーむ

Unity初心者が誰もが知っているゲームの模倣をしています。個人的な備忘録ですが、入門書を読み終えたばかりの初心者の方は「こんなへなちょこでもいいのか!」「俺の方がうまく作れる」と作成意欲がわいたりするかもしれません。

Unityでリバーシを作ってみた 5


スポンサードリンク

Anchor、Pivotの設定

一般的にリバーシの盤は左上が原点のようである。クリックイベントで座標を管理しやすくする為、セルや石などもそれに合わせる。

f:id:Nullsuke:20201122145627p:plain
一般的なリバーシ盤
f:id:Nullsuke:20201122145444p:plain
セルなどのAnchor、Pivot設定
f:id:Nullsuke:20201122151427p:plain
セルの画像のPivot設定
f:id:Nullsuke:20201122150702p:plain
石などの画像のPivot設定

Cellクラス

public class Cell : MonoBehaviour, IPointerClickHandler
{
    [SerializeField] Stone stonePrefab = default;
    [SerializeField] Mark markPrefab = default;
    [SerializeField] RectTransform movedPrefab = default;
    //セルをクリックしたときのイベント
    public event EventHandler<EventArgs> PointerClick;
    private RectTransform rectTransform;
    private SpriteRenderer spriteRenderer;

    public int X { get => (int)rectTransform.anchoredPosition.x; }
    //リバーシ盤に合わせるためY軸は反転させる
    public int Y { get => -(int)rectTransform.anchoredPosition.y; }

    public void Setup(Vector3 vector, Sprite sprite)
    {
        //盤に合わせ左上を原点にする為anchorを使う
        rectTransform.anchoredPosition = vector;
        spriteRenderer.sprite = sprite;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        PointerClick?.Invoke(this, EventArgs.Empty);
    }

    public Stone CreateStone(Stone.ColorType color)
    {
        var stone = Instantiate(stonePrefab, transform, false);
        stone.X = X;
        stone.Y = Y;
        stone.Color = color;

        return stone;
    }
    
    public Mark CreateMark(Stone.ColorType color)
    {
        var mark = Instantiate(markPrefab, transform, false);
        mark.Color = color;

        return mark;
    }

    public RectTransform CreateMoved()
    {
        return Instantiate(movedPrefab, transform, false);
    }

    private void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
        spriteRenderer = GetComponent<SpriteRenderer>();
    }
}

Stoneクラス

public class Stone : Mark
{
    [SerializeField] float reverseAngle = 0f;
    private Vector3 rotatePosition = new Vector3(0.5f, 0.5f, 0);

    public int X { get; set; }
    public int Y { get; set; }
    public bool HasReversed { get; set; }
    
    public static ColorType GetReverseColor(ColorType color)
    {
        int c = (int)color ^ 1;
        return (ColorType)c;
    }

    public void Reverse()
    {
        HasReversed = false;
        StartCoroutine(CoroutineReverse());
    }

    private IEnumerator CoroutineReverse()
    {
        float angle = 0f;
        
        while (angle < 90f)
        {
            transform.RotateAround(transform.TransformPoint(rotatePosition),
                new Vector3(0, 1, 0), reverseAngle);
            angle += reverseAngle;
            
            yield return null;
        }
        
        ChangeColor();

        while (angle < 180f)
        {
            transform.RotateAround(transform.TransformPoint(rotatePosition),
                new Vector3(0, 1, 0), reverseAngle);
            angle += reverseAngle;
            
            yield return null;
        }

        HasReversed = true;
    }

    private void ChangeColor()
    {
        int c = (int)Color ^ 1;
        Color = (ColorType)c;
    }
}