カイジのEカード風カードゲームの作成。Part7.カード削除・繰り返し実行【Unityゲーム制作】

簡単なゲーム作成の第7回目を進めていきます。今回は「カード勝敗判定」を繰り返すために、利用したカードを消していきます。とりあえず、今回で一旦はカードゲーム作成は終了です。

はじめに

今回は第7回目です。第1回目は下記から。

ゲーム作成開始

前回までで、とりあえずの形が出来ました。現状だと一回カードを出して判定したら終わりなので、何度も繰り返しできるように変更していきます。

カードを削除

まずは「場に出して判定が終了したカードを消します」。OperatorのOpenCard内、カードの勝敗判定後にDestCardを追加。

DestCard内で場に出ているカードオブジェクトを削除するのですが、敵の場に出ている対象のカードオブジェクトが分からないので、どのカードが選択されているのかEnemyクラスを下記のように変更。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Enemy : MonoBehaviour
{
    public int intEnemyCardNumber;

    public int intRamNumber;
    public List<GameObject> EmCardlist = new List<GameObject>();

    public void EnemyCardSelect()
    {
        EmCardlist.Clear();

        foreach (Transform child in transform)
        {
            EmCardlist.Add(child.gameObject);
        }
        intRamNumber = Random.Range(0, EmCardlist.Count - 1);

        EmCardlist[intRamNumber].transform.localPosition = new Vector3(400, -400, 0);
        intEnemyCardNumber = EmCardlist[intRamNumber].GetComponent<CardScript>().iCardNumber;
    }
}

DestCardを下記のように作成。自分が選んだカードと敵の選んだカード(場に出ているカード)をDestroyしています。

    private void DestCard()
    {
        GameObject playercardObject = Cards.GetComponent<Cards>().SelectCard;

        int emlistNum = EmCards.GetComponent<Enemy>().intRamNumber;
        GameObject enemycardObject = EmCards.GetComponent<Enemy>().EmCardlist[emlistNum];

        Destroy(playercardObject);
        Destroy(enemycardObject);

        Text txtResult = Result.GetComponent<Text>();
        txtResult.text = "";

    }

実行してみます。当然ですが、カードが直ぐに消えてしまいます。

DestCardをInvokeで遅延させて実行します。秒数は適当で良いかと。

これで実行。判定結果が出た後に場に出たカードが消えればOK。これで一応、何度か実行できるようになります。

バグ修正:例.カードリストのクリア

とりあえずのゲームの形となりましたが、現状ではバグを含め修正する箇所が山のようにあります。

例えば、敵カードのリストをクリアしていないので、動きがおかしくなる場合があります。下記のようにカードをランダムで選ぶ前にリストクリアを追加。

まだまだ直す部分は多いですが、ここからはゲームの根幹部分というよりはバグ修正や機能追加になるので一旦カードゲーム作成はここまで。最後にここまでのソースをのせておきます。

ソースのまとめ

まずは「カードを配る、判定する」などの役目を持つオペレーター。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Operator : MonoBehaviour
{
    public GameObject CardPrefab;
    public GameObject Cards;
    public GameObject EmCards;
    public GameObject Result;

    public Sprite[] m_Sprite;

    private void Start()
    {
        //Player
        dealCards(1, -700, Cards);
        dealCards(2, -350, Cards);
        dealCards(2, 0, Cards);
        dealCards(2, 350, Cards);
        dealCards(3, 700, Cards);

        //Enemy
        dealCards(1, -700, EmCards);
        dealCards(2, -350, EmCards);
        dealCards(2, 0, EmCards);
        dealCards(2, 350, EmCards);
        dealCards(3, 700, EmCards);

    }
    void dealCards(int iNumber,float fPosition,GameObject objParent)
    {
        GameObject prefab = (GameObject)Instantiate(CardPrefab);
        prefab.GetComponent<CardScript>().iCardNumber = iNumber;
        prefab.transform.SetParent(objParent.transform, false);
        prefab.transform.localPosition = new Vector3(fPosition, 0, 0);

        SpriteRenderer m_SpriteRenderer;
        m_SpriteRenderer = prefab.GetComponent<SpriteRenderer>();
        m_SpriteRenderer.sprite = m_Sprite[iNumber - 1];
    }

    public void OpenCard()
    {
        EmCards.GetComponent<Enemy>().EnemyCardSelect();
        JugeCard();
        Invoke("DestCard", 2f);

    }

    private void JugeCard()
    {
        int myCardNm = Cards.GetComponent<Cards>().intCardNumer;
        int enCardNm = EmCards.GetComponent<Enemy>().intEnemyCardNumber;

        Text txtResult = Result.GetComponent<Text>();
        //1がグー、2がチョキ、3がパー
        if ((myCardNm - enCardNm + 3) % 3 == 0)
        {
            //引き分け
            txtResult.text = "DRAW";
        }
        else if ((myCardNm - enCardNm + 3) % 3 == 1)
        {
            //負け
            txtResult.text = "LOSE";
        }
        else
        {
            //勝ち
            txtResult.text = "WIN";
        }
    }

    private void DestCard()
    {
        GameObject playercardObject = Cards.GetComponent<Cards>().SelectCard;

        int emlistNum = EmCards.GetComponent<Enemy>().intRamNumber;
        GameObject enemycardObject = EmCards.GetComponent<Enemy>().EmCardlist[emlistNum];

        Destroy(playercardObject);
        Destroy(enemycardObject);

        Text txtResult = Result.GetComponent<Text>();
        txtResult.text = "";

    }
}

ここで直す必要があるのは、プレイヤーがカードを選択せずにOPENボタンを押した時に「カード選択を促すメッセージを表示」したり、初めのカードを配る部分はループを使ったりでもう少し綺麗にまとめたり。途中の勝敗状況や最終結果なども表示するべきですね。

次が「カードが選択されたとき」のスクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CardScript : MonoBehaviour
{
    public int iCardNumber;
    public void ChoiceCard()
    {

        GameObject objCards = this.transform.parent.gameObject;

        if (objCards.GetComponent<Cards>().SelectCard != null)
        {
            objCards.GetComponent<Cards>().SelectCard.GetComponent<Transform>().localPosition = objCards.GetComponent<Cards>().InitPosition;
        }
        objCards.GetComponent<Cards>().SelectCard = this.gameObject;
        objCards.GetComponent<Cards>().InitPosition = this.transform.localPosition;
        objCards.GetComponent<Cards>().intCardNumer = iCardNumber;

        this.transform.localPosition = new Vector3(-400, 400, 0);

    }
}

次が「敵のカードを自動で選択する」スクリプト。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Enemy : MonoBehaviour
{
    public int intEnemyCardNumber;

    public int intRamNumber;
    public List<GameObject> EmCardlist = new List<GameObject>();

    public void EnemyCardSelect()
    {
        EmCardlist.Clear();

        foreach (Transform child in transform)
        {
            EmCardlist.Add(child.gameObject);
        }
        intRamNumber = Random.Range(0, EmCardlist.Count - 1);

        EmCardlist[intRamNumber].transform.localPosition = new Vector3(400, -400, 0);
        intEnemyCardNumber = EmCardlist[intRamNumber].GetComponent<CardScript>().iCardNumber;
    }
}

次が「プレイヤーのカードを管理」しているCardsクラス。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Cards : MonoBehaviour
{
    public GameObject SelectCard;
    public Vector3 InitPosition;
    public int intCardNumer;

}

こうしてみると計画性ゼロで作ったので、ぐちゃぐちゃですね。

ゲームを作る前には簡単なクラス図的なのを作って、どこにどんな役割を持たせるのか、どんな感じに切るのか、ある程度考えてから進めた方が良いですね。当たり前ですが(笑)

次にカードゲームを作る機会があればもっと綺麗に分かりやすく、かつ面白いのが作れたら理想だけど、素人なのでいきなりは難しいですかね。

タイトルとURLをコピーしました