アットウィキロゴ

Luaでオブジェクト指向プログラミングをする方法

Luaでオブジェクト指向プログラミングをする場合は通常 metatable を使った実装となりますが、Playdate SDKでは "CoreLibs/object" というライブラリが提供されており、Luaで手軽にオブジェクト指向プログラミング(OOP)を行うことができます。

このページでは "CoreLibs/object" を使用したクラスの定義、継承、インスタンス化の記述方法をまとめます。


基本的な使い方

項目 記述例
import文 import "CoreLibs/object"
クラス定義 class('Name').extends(Parent)
初期化 function Name:init(...)
メソッド定義 function Name:methodName(...) (コロンを使う)
親の呼び出し Name.super.methodName(self, ...) (ドットとselfを使う)
生成 (インスタンス化) local obj = Name(...)
1. ライブラリのインポート
まず、スクリプトの先頭でライブラリをインポートします。
import "CoreLibs/object"

2. クラスの定義とコンストラクタ
class('クラス名').extends()を使用してクラスを定義します。初期化処理(コンストラクタ)は init メソッド内に記述します。
(※Luaの文法上、シングルクォートとダブルクォートのどちらでも問題ないですが、Playdate SDKの記述に合わせて、ここではシングルクォートでクラス定義を行います)
注意:
class('ClassName') を実行すると、ClassName という名前のグローバル変数としてクラスが登録されます。
-- MyClassというクラスを定義(デフォルトでObjectクラスを継承します)
class('MyClass').extends()
 
-- コンストラクタ(インスタンス生成時に自動で呼ばれる)
function MyClass:init(x, y)
    self.x = x
    self.y = y
end
 
-- メソッドの定義(必ずコロン ':' を使って定義します)
function MyClass:printPosition()
    print("Position: " .. self.x .. ", " .. self.y)
end
 

3. インスタンス化
クラス名を関数のように呼び出すことで、新しいインスタンスを生成できます。このとき渡した引数は、そのまま init メソッドに渡されます。

-- インスタンスの生成(newなどのキーワードは不要です)
local myObject = MyClass(10, 20)
 
-- メソッドの呼び出し
myObject:printPosition() -- 出力: Position: 10, 20
 

4. 継承 (Inheritance)
既存のクラスを継承して新しいクラスを作る場合は、`.extends()` の引数に親クラスを指定します。Playdate開発では、`playdate.graphics.sprite` を継承してカスタムスプライトを作ることが最も多いユースケースです。

-- MyClassを継承したPlayerクラスを定義
class('Player').extends(MyClass)
 
function Player:init(x, y, name)
    -- 親クラスのコンストラクタを呼び出す(必須)
    Player.super.init(self, x, y)
 
    self.name = name
    self.hp = 100
end
 
function Player:printStatus()
    print(self.name .. " (HP: " .. self.hp .. ")")
    self:printPosition() -- 親クラスのメソッドも使用可能
end
 
  • 親メソッドの呼び出し: クラス名.super.メソッド名(self, 引数) という構文を使います。コロン ":" ではなくドット "." と "self" を明示的に渡す必要がある点に注意してください。

5. Playdate特有の実践的な例(Spriteの継承)
実際のゲーム開発では、画面に描画されるオブジェクトは playdate.graphics.sprite (スプライト) を継承して作るのが一般的です。

import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
 
local gfx = playdate.graphics
 
-- スプライトを継承
class('Enemy').extends(gfx.sprite)
 
function Enemy:init(x, y)
    -- 親クラス(sprite)のinitを呼ぶ
    Enemy.super.init(self)
 
    -- スプライトの初期設定
    local image = gfx.image.new(32, 32, gfx.kColorBlack)
    self:setImage(image)
    self:moveTo(x, y)
    self:add() -- 画面の描画リストに追加
end
 
-- 毎フレーム呼ばれる更新処理をオーバーライド
function Enemy:update()
    self:moveBy(1, 0) -- 右へ移動
end
 

その他のTips

カプセル化(private変数・private関数)の実装方法
Luaでは、オブジェクト指向に対応している言語ではないため、アクセス指定子を指定してカプセル化することはできません。
そのため、変数や関数名の先頭に「_」をつけるなどして運用で対処するのがベターです。

なおクロージャーを使って完全に隠蔽することはできますが、インスタンスごとに関数が作られてしまってメモリを圧迫する可能性があるので、シングルトンでない限りクロージャーで隠蔽するのは避けた方が良さそうです。

関連ページ

最終更新:2026年04月27日 07:20