5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Cocos Creator 3 カンタン2Dゲーム制作(1)【トゥイーンの使い方】

Last updated at Posted at 2022-08-23

更新履歴

  • 2022/08/28 タップイベントの座標の取得/変換方法を変更しました。

ページ一覧

Cocos Creator 3 導入編

Cocos Creator 3 カンタン2Dゲーム制作

2Dゲーム制作の開始

これからは実際に2Dゲームを作成していき、具体的なツールの使い方を紹介していきます。

まず「FishGame」という名前で2Dのテンプレートを使い、新規にプロジェクトを作成します。

アセットの登録

以下の画像をローカルに保存します。
ファイル名は左から順にSea.jpgFish.pngCoin.pngSyuriken.pngとします。(次の無料素材サイトを利用しました。IllustAC素材のプチッチストックマテリアル

CocosCreatorの画面を開き、アセットパネルに4つの素材ファイルをドラッグ&ドロップします。すると、ファイルがAssetsツリーの直下にコピーされます。Assets右クリック→CreateFolderでフォルダ作成ができるのでファイルが多い場合は任意でフォルダ分けします。ここではImagesというフォルダにすべて入れます。

取り込んだファイルはプロジェクトフォルダ内にコピーされるので、元ファイルは移動/削除しても問題ありません。

次に、Assets右クリック→CreateSceneで新しいシーンを作成します。名前をSeaSceneとします。アセットのファイル名を変更する場合はF2を押します。
現時点のアセットパネルは次のようになります。
image.png

シーンの編集 ~海中のシーン作成~

アセットパネルにあるSeaSceneをダブルクリックします。するとヒエラルキーパネルにSeaSceneが表示され、そのシーンが編集できるようになります。
アセットパネルからSeaFishを選択し、ヒエラルキーパネルのCanvasの直下にドラッグ&ドロップで入れます。ノードの順番は表示する際に関係しますので、必ず次の図のように配置してください。(他のノードとの入れ子関係にも注意してください。)
配置すると、ヒエラルキーパネルで編集した内容がシーンパネルに表示されます。
SeaScene01.png

ノードの位置の変更 ~魚の場所~

ヒエラルキーパネルにあるFishを選択します。シーンパネル上の魚に二つの矢印が出ていますので、中心部分のブルーの四角をドラッグすると魚の位置が移動できます。ここではシーンの左下に配置します。

シーンパネルは「右クリック+マウス移動」または「スペースキー+マウス移動」で表示範囲を変えられます。

ノードの位置はインスペクターパネルからも変更可能で、Nodeという見出しの下にPositionがあるので、ここではx, yをそれぞれ-300, -200とします。ctrl+Sでシーンを保存します。

ノードの基準点について

ノードの位置は、中心点が基準となっています。下の図は現在のキャンバスの位置を示します。

スクリプトの作成 ~魚を動かす~

ここでは、背景をタップ(クリック)するとその方向に向かって魚が一定距離近づく機能を追加します。

アセットパネルから、Assets右クリック→CreateTypeScriptNewComponentで新しいスクリプトを作成します。名前をTouchFishとします。ファイルをダブルクリックするとVSCodeが起動しまので、以下のコードを記述します。

スクリプトのクラス名は、作成した際のファイル名が適用されます。後からファイル名を変更した場合、クラス名は自動で変更しないため、スクリプト内のクラス名を手動で書き換えます(4行目、5行目の2か所)。

TouchFish.ts
import { _decorator, Component, Node, tween, Vec3, Vec2, view, EventTouch, log, Rect, UITransform } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('TouchFish')
export class TouchFish extends Component {
    @property
    moveDuration: number = 0.6; // 魚の一回の移動時間(秒)。

    _isMoveing: boolean = false; // 移動中かどうかのフラグ。

    start() {
        log('TouchFish - Start');
        this.enableTouch(true);
    }

    onDestroy() {
        this.enableTouch(false);
    }

    // タッチイベントの有効/無効切り替え
    enableTouch(enable: boolean) {
        if (enable) {
            this.node.on(Node.EventType.TOUCH_START, (event: EventTouch) => {
                this.moveFish(event);
            }, this);
        } else {
            this.node.off(Node.EventType.TOUCH_START);
        }
    }

    // 魚の移動処理
    moveFish(event: EventTouch) {
        log('TouchFish - moveFish');
        if (this._isMoveing) {
            // 移動中は処理をしない
            return;
        }
        this._isMoveing = true;

        // 魚のノード取得
        let fishNode = this.node.parent.getChildByName("Fish");

        // タップした座標を取得
        let loc: Vec2 = event.getUILocation();
        let uitf = this.node.getComponent(UITransform);
        let eveLoc = uitf.convertToNodeSpaceAR(new Vec3(loc.x, loc.y));

        // 魚の向きを決定
        let fishDirection = fishNode.position.x < eveLoc.x ? 1 : -1;
        fishNode.setScale(new Vec3(fishDirection, 1, 1));

        // トゥイーン
        tween(fishNode)
            .to(this.moveDuration, { position: eveLoc }, {
                easing: "quadOut",
            })
            .call(() => {
                //  トゥイーン後の処理
                log('TouchFish - has finished tween');
                this._isMoveing = false;
            })
            .start();
    }
}

外部ソフトでの編集後は必ずCocosCreaterの画面を開きアクティブにします。アクティブにすることで、外部ソフトの編集がCocosCreater側に反映されます。

CocosCreatorに戻り、ヒエラルキーパネルにあるseaを選択します。インスペクターパネルの一番下の、Add Componentボタンを押します。別の小窓が出るので、Search Nameと書かれたエリアにtouchと入力します。登録済みのスクリプトがCustom Scriptの下に表示されるので、TouchFishを選択します。ctrl+Sでシーンを保存します。

インスペクターパネルの一番下にSeaScriptが追加されました。これによりシーン上のseaノードとTouchFishスクリプトが紐付けされました。

ブラウザで動きを確認する

ここまで作成したものを実際に動かしてみます。
画面上の、次に示す赤枠の部分を確認します。
image.png

惑星のマークはブラウザの意味、Current sceneは今シーンパネルで開いているシーンを対象としています。
▶マークを押すと(またはctrl+P)、ブラウザが立ち上がりゲームが実行します。

正しく作成されていれば、画面をクリックすると、魚がクリックした場所に移動します。

スクリプトの解説

startメソッド/onDestroyメソッド

startメソッドは、初めに一度だけ実行されるメソッドです。初期設定などをここに書きます。
ここでは、enableTouch(true)メソッドを呼び出し、イベントを有効にしています。
一方、onDestroyメソッドはインスタンスが破棄されるときに呼び出されるメソッドです。
enableTouch(false)メソッドを呼び出し、イベントを無効化します。

イベントの有効化

enableTouch()メソッド内では、背景のノードのタッチイベントに対してmoveFishメソッドを呼び出すよう設定しています。そのとき、タッチされた時の情報が入っているenent変数を渡しています。

let self = this;
this.node.on(Node.EventType.TOUCH_START, (event: EventTouch) => {
    self.moveFish(event);
}, this);

EventType.TOUCH_STARTであってもパソコンのマウスボタンクリックでイベントを捕捉します。
一方、EventType.MOUSE_DOWNではスマホ等のマウスのないデバイスではイベントが捕捉できません。

イベントのon/offはEventTypeの単位で切り替えができます。

魚の移動処理

moveFish()メソッドの内容を見ていきます。

まず、Seaの親ノード、つまりCanvasノードを取得して、その子ノードであるFishノードを名前を指定して取得します。

// 魚のノード取得
let fishNode = this.node.parent.getChildByName("Fish");

event.getUILocation()によりイベント発生時に渡された、タップされた位置を取得します。
UITransformコンポーネントを取得し、そこからconvertToNodeSpaceARメソッドにより、ゲーム内で扱っている座標の体系に変換します。

// タップした座標を取得
let loc: Vec2 = event.getUILocation();
let uitf = this.node.getComponent(UITransform);
let eveLoc = uitf.convertToNodeSpaceAR(new Vec3(loc.x, loc.y));

タップされた位置が、魚より右が、左かによって魚の向きを変えるため、両座標のxの値を比較します。
魚のノードに対しsetScale()xにマイナス値を入れると画像が左右逆になります。

// 魚の向きを決定
let fishDirection = fishNode.position.x < eveLoc.x ? 1 : -1;
fishNode.setScale(new Vec3(fishDirection, 1, 1));

tween(トゥイーン)について

tweenという機能を使って魚をタップされた位置まで移動します。tweenは移動先と秒数を指定すると自動でアニメーションを作ってくれる機能です。
toで、時間とtweenの条件を指定します。
callに終了後の処理を記述します。startはすぐに実行するという指示です。

// トゥイーン
tween(fishNode)
    .to(this.moveDuration, { position: eveLoc }, {
        easing: "quadOut",
    })
    .call(() => {
        //  トゥイーン後の処理
        log('TouchFish - has finished tween');
        this._isMoveing = false;
    })
    .start();

easingについて

移動の際の効果を指定します。ここでは「初速が早く、停止位置に近づくと減速する」ようにするため、quadOutとしましたが、linearとすると緩急をつけづに等速で移動します。
それ以外の効果についてはこちらを参照ください。
https://docs.cocos.com/creator/manual/en/tween/tween-function.html

position以外の設定

今回はpositionだけの指定でしたが、scalerotationも以下のように指定可能です。

let quat: Quat = new Quat();
Quat.fromEuler(quat, 0, 0, 45);
tween(fishNode)
    .to(this.moveDuration, {
        position: new Vec3(eveLoc.x, eveLoc.y),
        scale: new Vec3(1.2, 1.2, 1),
        rotation: quat,
    }, //以降省略

toとby

toは画面の座標を指定します。このゲームではタップされた位置にノードを移動させるゲームなのでtoを使います。
一方byは今ある位置からの差分を指定します。例えば、キャラクターの位置を右に200pxだけ動かすという場合は、移動先の座標を計算しなくても200pxの指定だけですみます。

logについて

各所に書かれているlogではその文字列をconsoleに出力します。ブラウザでの実行時にはF12の開発者モードでconsoleの内容を確認できます。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?