更新履歴
- 2022/08/28 タップイベントの座標の取得/変換方法を変更しました。
ページ一覧
Cocos Creator 3 導入編
Cocos Creator 3 カンタン2Dゲーム制作
- プロジェクト作成と画面の説明
- (1)【トゥイーンの使い方】← 本記事
- (2)【プレハブの使い方】
- (3)【衝突判定(コライダの使い方)】
- (4)【アニメーションクリップの使い方】
- (5)【パーティクルの使い方】
- (6)【ラベルアトラスの使い方】
2Dゲーム制作の開始
これからは実際に2Dゲームを作成していき、具体的なツールの使い方を紹介していきます。
まず「FishGame」という名前で2Dのテンプレートを使い、新規にプロジェクトを作成します。
アセットの登録
以下の画像をローカルに保存します。
ファイル名は左から順にSea.jpg
、Fish.png
、Coin.png
、Syuriken.png
とします。(次の無料素材サイトを利用しました。IllustAC、素材のプチッチ、ストックマテリアル)
CocosCreatorの画面を開き、アセットパネルに4つの素材ファイルをドラッグ&ドロップします。すると、ファイルがAssets
ツリーの直下にコピーされます。Assets
右クリック→Create
→Folder
でフォルダ作成ができるのでファイルが多い場合は任意でフォルダ分けします。ここではImages
というフォルダにすべて入れます。
取り込んだファイルはプロジェクトフォルダ内にコピーされるので、元ファイルは移動/削除しても問題ありません。
次に、Assets
右クリック→Create
→Scene
で新しいシーンを作成します。名前をSeaScene
とします。アセットのファイル名を変更する場合はF2
を押します。
現時点のアセットパネルは次のようになります。
シーンの編集 ~海中のシーン作成~
アセットパネルにあるSeaScene
をダブルクリックします。するとヒエラルキーパネルにSeaScene
が表示され、そのシーンが編集できるようになります。
アセットパネルからSea
、Fish
を選択し、ヒエラルキーパネルのCanvas
の直下にドラッグ&ドロップで入れます。ノードの順番は表示する際に関係しますので、必ず次の図のように配置してください。(他のノードとの入れ子関係にも注意してください。)
配置すると、ヒエラルキーパネルで編集した内容がシーンパネルに表示されます。
ノードの位置の変更 ~魚の場所~
ヒエラルキーパネルにあるFish
を選択します。シーンパネル上の魚に二つの矢印が出ていますので、中心部分のブルーの四角をドラッグすると魚の位置が移動できます。ここではシーンの左下に配置します。
シーンパネルは「右クリック+マウス移動」または「スペースキー+マウス移動」で表示範囲を変えられます。
ノードの位置はインスペクターパネルからも変更可能で、Node
という見出しの下にPosition
があるので、ここではx, y
をそれぞれ-300, -200
とします。ctrl+S
でシーンを保存します。
ノードの基準点について
ノードの位置は、中心点が基準となっています。下の図は現在のキャンバスの位置を示します。
スクリプトの作成 ~魚を動かす~
ここでは、背景をタップ(クリック)するとその方向に向かって魚が一定距離近づく機能を追加します。
アセットパネルから、Assets
右クリック→Create
→TypeScript
→NewComponent
で新しいスクリプトを作成します。名前をTouchFish
とします。ファイルをダブルクリックするとVSCodeが起動しまので、以下のコードを記述します。
スクリプトのクラス名は、作成した際のファイル名が適用されます。後からファイル名を変更した場合、クラス名は自動で変更しないため、スクリプト内のクラス名を手動で書き換えます(4行目、5行目の2か所)。
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
スクリプトが紐付けされました。
ブラウザで動きを確認する
ここまで作成したものを実際に動かしてみます。
画面上の、次に示す赤枠の部分を確認します。
惑星のマークはブラウザの意味、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
だけの指定でしたが、scale
、rotation
も以下のように指定可能です。
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
の内容を確認できます。