Skip to content

Instantly share code, notes, and snippets.

@vestige
Created December 27, 2025 07:21
Show Gist options
  • Select an option

  • Save vestige/d767a1705b49f74c33ff7f4eb3b9dfbe to your computer and use it in GitHub Desktop.

Select an option

Save vestige/d767a1705b49f74c33ff7f4eb3b9dfbe to your computer and use it in GitHub Desktop.
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import time
import random
import math
# OLEDディスプレイのサイズ設定
width = 128
height = 64
# Raspberry Pi PicoのI2C設定
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)
# 塗りつぶされた円を描画する関数(目と鼻のハイライト)
def draw_filled_circle(x0, y0, radius, color=1):
for y in range(y0 - radius, y0 + radius):
for x in range(x0 - radius, x0 + radius):
if (x - x0) ** 2 + (y - y0) ** 2 <= radius ** 2:
oled.pixel(x, y, color)
# 楕円を描画する関数(目の形)
def draw_ellipse(x0, y0, width, height, color=1):
for y in range(y0 - height, y0 + height):
for x in range(x0 - width, x0 + width):
if ((x - x0) / width) ** 2 + ((y - y0) / height) ** 2 <= 1:
oled.pixel(x, y, color)
# 鼻の外側の円
def draw_circle_hana(x0, y0, radius, color=1):
for theta in range(0, 360):
x = int(x0 + radius * math.cos(math.radians(theta)))
y = int(y0 + radius * math.sin(math.radians(theta)))
oled.pixel(x, y, color)
# 円を描画する関数(瞳のエッジのぼかし効果)
def draw_circle(x0, y0, radius, color=1, dithering=False):
for theta in range(0, 360):
x = int(x0 + radius * math.cos(math.radians(theta)))
y = int(y0 + radius * math.sin(math.radians(theta)))
if dithering and theta % 10 < 5:
oled.pixel(x, y, color)
# 目を開いた状態を描画する関数
def draw_eye_open(eye_center_x, eye_center_y, pupil_x, pupil_y):
# 目の形を描画
draw_ellipse(eye_center_x, eye_center_y, 20, 17)
# 瞳の描画
draw_filled_circle(pupil_x, pupil_y, 15, 0)
# 瞳のエッジにソフトなぼかし効果を追加
draw_circle(pupil_x, pupil_y, 15, 0, dithering=True)
# 瞳のハイライトを描画
draw_filled_circle(pupil_x - 3, pupil_y - 3, 2, 1)
# 鼻を描画する関数
def draw_nose():
# 外側の円を描画
draw_circle_hana(64, 42, 8)
# ハイライトを描画
draw_filled_circle(62, 40, 2)
while True:
# ランダムにルールを選択
rule_choice = random.choice([1, 2, 3])
if rule_choice == 1:
# ランダムに瞳の座標を生成
pupil_dx = random.randint(2, 5)
pupil_dy = random.randint(-3, 0)
pupil_x_left = 25 + pupil_dx
pupil_y_left = 30 + pupil_dy
pupil_x_right = 103 - pupil_dx
pupil_y_right = 30 + pupil_dy
# 両目と鼻を描画する前に画面を黒で塗りつぶす
oled.fill(0)
draw_eye_open(24, 32, pupil_x_left, pupil_y_left)
draw_eye_open(104, 32, pupil_x_right, pupil_y_right)
draw_nose()
oled.show() # 画面を更新
time.sleep(random.uniform(0.01, 0.1))
pupil_dx = random.randint(2, 5)
pupil_dy = random.randint(-3, 0)
pupil_x_left = 25 + pupil_dx
pupil_y_left = 30 + pupil_dy
pupil_x_right = 103 - pupil_dx
pupil_y_right = 30 + pupil_dy
# 両目と鼻を描画する前に画面を黒で塗りつぶす
oled.fill(0)
draw_eye_open(24, 32, pupil_x_left, pupil_y_left)
draw_eye_open(104, 32, pupil_x_right, pupil_y_right)
draw_nose()
oled.show() # 画面を更新
time.sleep(random.uniform(0.1, 0.5))
elif rule_choice == 2:
pupil_x_left = 21
pupil_y_left = 29
pupil_x_right = 94
pupil_y_right = 29
# 両目と鼻を描画する前に画面を黒で塗りつぶす
oled.fill(0)
draw_eye_open(24, 32, pupil_x_left, pupil_y_left)
draw_eye_open(104, 32, pupil_x_right, pupil_y_right)
draw_nose()
oled.show() # 画面を更新
time.sleep(random.uniform(1, 1.5))
else:
pupil_x_left = 32
pupil_y_left = 29
pupil_x_right = 108
pupil_y_right = 29
# 両目と鼻を描画する前に画面を黒で塗りつぶす
oled.fill(0)
draw_eye_open(24, 32, pupil_x_left, pupil_y_left)
draw_eye_open(104, 32, pupil_x_right, pupil_y_right)
draw_nose()
oled.show() # 画面を更新
time.sleep(random.uniform(1, 1.5))
# 一定の確率で目を閉じるようにする
if random.randint(1, 10) > 8:
oled.fill(0)
draw_nose()
oled.show()
time.sleep(random.uniform(0.05, 0.15))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment