1. 導入:スマホでPythonゲーム開発は可能?
「Pythonでゲームを作りたい。でもパソコンがない…」
そんな風に思ったことはありませんか?
実は、iPhoneやiPadでもPythonでゲームを作る方法があるんです。
その秘密が Pythonista というアプリ。
Pythonistaを使えば、スマホ1台でプログラムを書いて、本格的なミニゲームを開発できます。
この記事では、初心者でもできる「Pythonistaを使ったゲームプログラミング入門」を、サンプルコード付きで解説します。
2. Pythonistaとは?【スマホで使えるPython開発環境】
PythonistaはApp Storeで販売されている有料アプリで、**iOS専用のPython統合開発環境(IDE)**です。
- Pythonのコードを直接書いて実行できる
- コード補完機能・専用キーボード付きでスマホ操作でも快適
- 画像表示やタップ操作ができる
sceneモジュールを標準搭載
つまり、Pythonistaを入れるだけで 「iPhoneがポケットサイズのPython開発PCになる」 のです。
3. ゲーム作りの基本:scene モジュールを理解しよう
Pythonistaのゲーム開発は、scene モジュールを使います。
これはスマホ向けに作られた簡易ゲームエンジンのようなもの。
基本構造は以下の3つを覚えればOKです。
- setup() → 初期化処理(キャラ配置など)
- update() → 毎フレーム処理(動きや当たり判定)
- touch_xxx() → タップやスワイプの入力処理
サンプルコード:
from scene import *
class MyGame(Scene):
def setup(self):
print("ゲーム開始!")
def update(self):
pass
def touch_began(self, touch):
print("画面タップ!")
run(MyGame(), PORTRAIT)
👉 このコードを動かすと、タップするたびに「画面タップ!」と表示され、ゲームループの仕組みが理解できます。
4. Pythonistaで作る簡単ゲーム【サンプル付き】
4-1. タップで猫を動かすミニゲーム
from scene import *
import sound
class CatGame(Scene):
def setup(self):
self.cat = SpriteNode('emj:cat', position=self.size/2, parent=self)
def touch_began(self, touch):
sound.play_effect('arcade:Jump_1')
self.cat.run_action(Action.move_to(touch.location.x, touch.location.y, 0.5))
run(CatGame(), PORTRAIT)
👉 タップした場所に猫がジャンプ!Pythonistaなら数行で作れます。
4-2. ボールをキャッチするゲーム
from scene import *
import random
class CatchBall(Scene):
def setup(self):
self.player = SpriteNode('typb:Alien_Monster', position=(self.size.w/2, 50), parent=self)
self.ball = None
self.score = 0
self.label = LabelNode(f"Score: {self.score}", position=(80, self.size.h-40), parent=self)
def update(self):
if not self.ball:
self.spawn_ball()
else:
self.ball.position = (self.ball.position.x, self.ball.position.y - 5)
if self.ball.position.y < 0:
self.ball.remove_from_parent()
self.ball = None
elif self.player.frame.intersects(self.ball.frame):
self.score += 1
self.label.text = f"Score: {self.score}"
self.ball.remove_from_parent()
self.ball = None
def spawn_ball(self):
x = random.randint(20, int(self.size.w-20))
self.ball = SpriteNode('shp:Circle', position=(x, self.size.h-20), parent=self)
def touch_moved(self, touch):
self.player.position = (touch.location.x, self.player.position.y)
run(CatchBall(), PORTRAIT)
👉 「落ちものをキャッチする」仕組みを学べます。
4-3. 簡易シューティングゲーム
from scene import *
import sound
import random
class Shooting(Scene):
def setup(self):
self.player = SpriteNode('spc:PlayerShip3Green', position=(self.size.w/2, 50), parent=self)
self.bullets = []
self.enemies = []
self.spawn_enemy()
self.score = 0
self.label = LabelNode(f"Score: {self.score}", position=(80, self.size.h-40), parent=self)
def touch_began(self, touch):
bullet = SpriteNode('spc:LaserBlue6', position=self.player.position, parent=self)
self.bullets.append(bullet)
sound.play_effect('arcade:Laser_1')
def update(self):
for bullet in list(self.bullets):
bullet.position = (bullet.position.x, bullet.position.y + 10)
if bullet.position.y > self.size.h:
self.bullets.remove(bullet)
bullet.remove_from_parent()
else:
for enemy in list(self.enemies):
if bullet.frame.intersects(enemy.frame):
enemy.remove_from_parent()
self.enemies.remove(enemy)
bullet.remove_from_parent()
self.bullets.remove(bullet)
sound.play_effect('arcade:Explosion_2')
self.score += 1
self.label.text = f"Score: {self.score}"
if not self.enemies:
self.spawn_enemy()
def spawn_enemy(self):
for _ in range(3):
x = random.randint(50, int(self.size.w-50))
y = random.randint(int(self.size.h/2), int(self.size.h-50))
enemy = SpriteNode('spc:EnemyBlue1', position=(x, y), parent=self)
self.enemies.append(enemy)
def touch_moved(self, touch):
self.player.position = (touch.location.x, self.player.position.y)
run(Shooting(), PORTRAIT)
👉 弾・敵・当たり判定を組み合わせて、遊べるシューティングに。
4-4. おまけ:テトリスもどき
from scene import *
import random, ui
GRID_W, GRID_H = 10, 20
CELL_SIZE = 20
class Tetris(Scene):
def setup(self):
self.grid = [[0]*GRID_W for _ in range(GRID_H)]
self.active = [[1,1],[1,1]]
self.x, self.y = 4, 0
self.drop_timer = 0
self.speed = 0.5
def update(self):
self.drop_timer += self.dt
if self.drop_timer > self.speed:
self.drop_timer = 0
self.y += 1
if self.collide():
self.y -= 1
self.lock_piece()
self.spawn_piece()
self.draw_grid()
self.draw_piece()
def collide(self):
for r in range(len(self.active)):
for c in range(len(self.active[0])):
if self.active[r][c]:
gx, gy = self.x+c, self.y+r
if gy >= GRID_H or gx < 0 or gx >= GRID_W or self.grid[gy][gx]:
return True
return False
def lock_piece(self):
for r in range(len(self.active)):
for c in range(len(self.active[0])):
if self.active[r][c]:
gx, gy = self.x+c, self.y+r
if 0 <= gy < GRID_H:
self.grid[gy][gx] = 1
self.grid = [row for row in self.grid if any(cell == 0 for cell in row)]
while len(self.grid) < GRID_H:
self.grid.insert(0, [0]*GRID_W)
def spawn_piece(self):
self.active = [[1,1],[1,1]]
self.x, self.y = 4, 0
def draw_grid(self):
self.background_color = 'black'
for r in range(GRID_H):
for c in range(GRID_W):
if self.grid[r][c]:
path = ui.Path.rect(c*CELL_SIZE, (GRID_H-r-1)*CELL_SIZE, CELL_SIZE, CELL_SIZE)
ui.set_color('blue')
path.fill()
def draw_piece(self):
for r in range(len(self.active)):
for c in range(len(self.active[0])):
if self.active[r][c]:
path = ui.Path.rect((self.x+c)*CELL_SIZE, (GRID_H-(self.y+r)-1)*CELL_SIZE, CELL_SIZE, CELL_SIZE)
ui.set_color('red')
path.fill()
def touch_began(self, touch):
if touch.location.x < self.size.w/2:
self.x -= 1
if self.collide(): self.x += 1
else:
self.x += 1
if self.collide(): self.x -= 1
run(Tetris(), PORTRAIT)
👉 「落ちる・積む・揃ったら消える」という基本だけ実装した簡易版テトリスです。
5. Pythonistaでゲームを作るメリット
- パソコン不要 → スマホ1台で完結
- 通勤・通学のスキマ時間に練習可能
- Pythonの基礎を遊びながら学べる
- ゲーム開発の仕組みを理解できる
6. まとめ
Pythonistaを使えば、iPhoneひとつでPythonゲーム開発が楽しめます。
- タップで猫を動かす
- ボールキャッチゲーム
- シューティングゲーム
- テトリスもどき
ステップアップ式に学べば、初心者でもゲーム作りの感覚がつかめるはずです。
ぜひ「Pythonista ゲームプログラミング入門」として挑戦してみてください!

コメント