概要・アイデアのコンセプト
次々に出てくる障害物を避けるゲームを作りたいと思い、ディスプレイを必要としたため、OLEDディスプレイを使用したゲーム開発を行いました。
アイデアの詳細
-
Raspberry Pi 4とOLEDディスプレイを接続
今回はボタンを用いた操作をメインとするため、IoT学習HATキット(市販のキット)をRaspberry Pi 4に接続(IoT学習HATキットには入力端子とボタンが二種類付いているため、今回はIoT学習HATキットのボタンを用いる)
-
ソフトの開発を行い、ゲームに必要な要素を作る
今回作成するゲームでの障害物は、イラストなどを使用するのが困難だと考え『バツ印(x)』を障害物として、その障害物を避けるゲームを作成する
-
開発ツールはRaspberry Piに内蔵されているPythonを用いてソフトウェアの開発をする
使用したもの
今回使用したものです。以下のものを使用しました。
・Raspberry Pi 4
・IoT学習HATキット(秋月電子の市販のキット)
・OLEDディスプレイ
・ラズパイとディスプレイを繋ぐためのケーブル類(ジャンパ線)
プログラム
調べても難しい箇所があったため、一部はChatGPTを使用しプログラムを作成しました。
ゲームのプログラム
import board
import digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306
from random import randint, seed
import time
# スイッチのピン番号
SW1 = digitalio.DigitalInOut(board.D24) # 左移動の白色タクトSW(SW1)
SW2 = digitalio.DigitalInOut(board.D21) # 右移動の黒色タクトSW(SW2)
SW1.direction = digitalio.Direction.INPUT
SW1.pull = digitalio.Pull.DOWN # プルダウン抵抗
SW2.direction = digitalio.Direction.INPUT
SW2.pull = digitalio.Pull.DOWN # プルダウン抵抗
# OLEDディスプレイの設定
oled_reset = digitalio.DigitalInOut(board.D4)
WIDTH = 128
HEIGHT = 64
BORDER = 5
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C, reset=oled_reset)
oled.fill(0)
oled.show()
# 画像と描画オブジェクトを作成
image = Image.new("1", (oled.width, oled.height))
draw_obj = ImageDraw.Draw(image)
font = ImageFont.load_default()
# プレイヤーの初期位置
player_x = WIDTH // 2
player_y = int(HEIGHT * 0.8)
# プレイヤーの移動量
player_move_x = 0
# 障害物リスト
obstacles = []
# ランダムな障害物を生成する関数
def create_obstacles():
seed(time.time()) # 乱数シードを毎回変える
for i in range(5): # 障害物の数
ob_x = randint(0, WIDTH - 10)
ob_y = randint(-HEIGHT, 0) # 画面外から出現
obstacles.append([ob_x, ob_y])
# プレイヤーを描画する関数
def draw_player():
global player_x
# プレーヤーを画面の下部に描画
draw_obj.text((player_x, player_y), 'P', font=font, fill=255)
# 障害物を描画して移動させる関数
def draw_obstacles():
for obstacle in obstacles:
ob_x, ob_y = obstacle
draw_obj.text((ob_x, ob_y), 'X', font=font, fill=255) # 'X'で障害物を描画
obstacle[1] += 2 # 障害物を下に移動させる
# 衝突判定の関数
def check_collision():
for obstacle in obstacles:
ob_x, ob_y = obstacle
if abs(player_x - ob_x) < 10 and abs(player_y - ob_y) < 10:
return True
return False
# 画面を描画する関数
def draw_screen():
oled.fill(0) # 画面をクリア
draw_obj.rectangle((0, 0, WIDTH, HEIGHT), outline=0, fill=0) # 画面をクリア
draw_obstacles() # 障害物を描画
draw_player() # プレーヤーを描画
oled.image(image) # 画像をOLEDに転送
oled.show()
# メインループ
create_obstacles() # 初期の障害物を生成
while True:
# スイッチ入力を確認してプレイヤーの移動量を設定
if SW1.value: # SW1が押されている(HIGH) => 左に移動
player_move_x = -2
elif SW2.value: # SW2が押されている(HIGH) => 右に移動
player_move_x = 2
else:
player_move_x = 0 # 移動しない
# プレイヤーの移動を更新
player_x += player_move_x
if player_x < 0:
player_x = 0
elif player_x > WIDTH - 10:
player_x = WIDTH - 10
# 障害物の更新
for obstacle in obstacles:
obstacle[1] += 2 # 障害物を下に移動
# 障害物が画面外に出たら削除し新しい障害物を追加
obstacles[:] = [ob for ob in obstacles if ob[1] < HEIGHT]
if len(obstacles) < 5:
create_obstacles()
# 衝突判定
if check_collision():
draw_obj.text((player_x, player_y - 10), 'GAME OVER', font=font, fill=255)
oled.image(image)
oled.show()
time.sleep(2)
break
# 画面を更新
draw_screen()
time.sleep(0.1) # アニメーション速度を調整
もしかすると、プログラムのスイッチ部分が外部のボタンを使用していたため、ピン番号がIoT学習HATキットのものと違うかもしれません。
どのようなゲームになったのか
まず、今回作成を目標としていたゲームがGoogle Chromeの「dino runner」というものです。操作が難しくなく、ただ前からくる敵を「spaceキー」を押してジャンプするか、「↑と↓」でジャンプしたりしゃがんだりするゲームです。ですが作成するのが困難だと考え、それに似たようなものを作ろうと考えていたところ、ジャンプなどはモーションを作るのが難しくなると感じ、「上からくる障害物を左右に動き、避ける」というものを作る予定でした。
動作結果
作成予定のゲームに近いものは出来ました。
ソフトウェアの作成は9割ほどは出来ましたが、「IoT学習HATキットのボタン」がダメなのか「プログラム」がダメなのかは分かりませんでしたが、数回ボタンを押すと電源が落ちてしまうため、この問題を解決出来るようにしていきたいと考えています。
改善案
・ソフトウェア面
余計な割り込みが発生していたりする可能性があるため、そういった割り込みを解決する。
・ハードウェア面
ブレッドボードを使用してIoT学習HATキットのボタンを使わないようにする。
参考文献
今回のゲームを作るうえで参考にしたサイトのリンク集です。
・障害物を作る - ぶつからないで! - Python - 子どもやティーン向けのコーディングプロジェクト
https://projects.raspberrypi.org/ja-JP/projects/dont-collide
・Raspberry Pi 4 で小さなSSD1306 OLEDディスプレーに文字を表示させてみた
https://dev.classmethod.jp/articles/raspberry-pi-4-ssd1306-oled-display/
-
oono
さんが
2024/09/20
に
編集
をしました。
(メッセージ: 初版)
-
oono
さんが
2024/09/20
に
編集
をしました。
-
oono
さんが
2024/09/30
に
編集
をしました。
-
oono
さんが
2024/09/30
に
編集
をしました。
-
oono
さんが
2024/10/24
に
編集
をしました。
-
oono
さんが
2024/10/29
に
編集
をしました。
-
oono
さんが
2024/10/30
に
編集
をしました。
-
oono
さんが
2024/10/30
に
編集
をしました。
ログインしてコメントを投稿する