Google Driveにはプログラムから色々な操作を行うためのAPIが用意され、またそのAPIを簡単に呼び出せる各言語用の公式SDKが用意されている。公式SDKが使いにくいということはないが、実際に使いたい場面ではAPIの呼び出しのチェインやエラーハンドリング、パラメータの指定方法の都合などで少しばかり冗長なコードを書かざるを得ない部分がある。過去数年いくつかのシステムでGoogle Driveに関する機能の実装をしてきたが、振り返ってみると同じような冗長なコードをそれぞれのプロジェクトで書いてきていたので、このタイミングでコードを共通化して使いまわせるようにライブラリを作った。
そこで、公式ドキュメントの「Active Development Considerations」の項では、XcodeプロジェクトからGodotのプロジェクトをフォルダ参照することで、変更のたびに毎回Exportし直さなくても常に最新の内容でiOSアプリをビルド・実行可能にする方法が説明されている。(※プラグインの追加時など、Xcodeプロジェクトの構造変更が必要な時はプロジェクトの出力し直しが必要になる)これは実に便利で、特にアプリ内課金の機能などiOSのネイティブ機能を使う部分の開発・デバッグには不可欠な手順になっている。
func _input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
for enemy in get_tree().get_nodes_in_group("enemies"):
var distance = event.position.distance_to(enemy.position)
if distance <= ENEMY_RADIUS:
enemy.position = Vector2(rng.randf_range(-STAGE_MARGIN, get_viewport().size.x + STAGE_MARGIN), -STAGE_MARGIN)
score += 1
get_node("HitSound").play(0)
各標的から軌跡のパーティクルが放出されるようにしたいので、Hae.tscnにパーティクルシステムを導入する。Godotのパーティクルシステムには2種類のパーティクルシステムが用意されているが、Open GL ES 3系のプロジェクトでは、より高度でGPUで処理可能なParticles2Dノードを使うことができるので、今回はParticle2Dを追加。
最後に、Particles2DノードのDrawing / Local CoordsプロパティをOffにする。これをOnにしていると、放出されたパーティクルは親のNodeの移動に合わせて一緒に移動してしまう。今回は軌跡として表示をしたいので、標的(親ノード)が移動したとしても放出されたパーティクルは放出された場所にとどまって欲しいので、Offにする。
func _process(delta):
var children = get_tree().get_nodes_in_group("mygroup")
for child in children:
if child.position.x >= get_viewport_rect().size.x:
child.position = Vector2(-100, child.position.y)
extends Node2D
const HaeScene = preload("res://Hae.tscn")
var rng = RandomNumberGenerator.new()
# Called when the node enters the scene tree for the first time.
func _ready():
rng.randomize()
for n in 10:
var anInstance = HaeScene.instance()
anInstance.name = "Hae" + str(n)
anInstance.position = Vector2(rng.randf_range(0.0, get_viewport_rect().size.x), rng.randf_range(0.0, get_viewport_rect().size.y))
anInstance.add_to_group("enemies")
self.add_child(anInstance)
extends Node2D
const HaeScene = preload("res://Hae.tscn")
var rng = RandomNumberGenerator.new()
const STAGE_MARGIN = 100
# Called when the node enters the scene tree for the first time.
func _ready():
...
func _process(delta):
var stageEdgeLeft = -STAGE_MARGIN
var stageEdgeRight = get_viewport_rect().size.x + STAGE_MARGIN
var stageEdgeTop = -STAGE_MARGIN
var stageEdgeBottom = get_viewport_rect().size.y + STAGE_MARGIN
for enemy in get_tree().get_nodes_in_group("enemies"):
if enemy.position.x < stageEdgeLeft:
enemy.position = Vector2(stageEdgeRight, enemy.position.y)
if enemy.position.x > stageEdgeRight:
enemy.position = Vector2(stageEdgeLeft, enemy.position.y)
if enemy.position.y < stageEdgeTop:
enemy.position = Vector2(enemy.position.x, stageEdgeBottom)
if enemy.position.y > stageEdgeBottom:
enemy.position = Vector2(enemy.position.x, stageEdgeTop)
Project ManagerのNew Projectから新しいプロジェクトを作る。RendererにはOpenGL ES 3.0とOpenGL ES 2.0のいずれかを選択できる。今回は特に古いデバイスで動かしたいとかブラウザ上で動かしたいというような目的はないので、OpenGL ES 3.0を選んだ。