巷で噂のchatGPTを触ってみました。
「pyxelでメガデモを作ってください」とお願いすると、出来上がってきたのがこれ。
charGPTさんの回答
「メガデモ」は、デモシーンの文化に由来する、視覚効果、音楽、そしてプログラミング技術を駆使して作られたアート作品です。
Pyxelを使って簡易的なメガデモを作る場合、以下の要素を組み合わせることができます:
動的な背景効果 (例: ノイズ、波形、グラデーション)
3D風オブジェクトの回転や動き (例: 立方体や球体の擬似3Dアニメーション)
テキストスクロール (例: 左右または上下に流れるテキスト)
サウンドループ (例: シンプルなループ音楽)
以下は、Pyxelで簡易メガデモを作成するサンプルコードです。
import pyxel
import math
import random
class MegaDemo:
def __init__(self):
pyxel.init(160, 120, title="Pyxel Mega Demo", fps=30)
pyxel.sound(0).set(
"c3e3g3c4g3e3c3c3 g3c4e4g4e4c4g3g3", # 音階
"p", # 波形
"7", # 音量
"n", # エフェクト
30, # テンポ
)
pyxel.play(0, 0, loop=True)
self.angle = 0
self.scroll_text = "Pyxel Mega Demo! " * 10
self.text_x = pyxel.width
pyxel.run(self.update, self.draw)
def update(self):
# アニメーション更新
self.angle += 0.02
self.text_x -= 1
if self.text_x < -len(self.scroll_text) * 4:
self.text_x = pyxel.width
# 終了処理
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(0)
self.draw_background_effect()
self.draw_rotating_cube()
self.draw_scrolling_text()
def draw_background_effect(self):
"""動的な背景ノイズ"""
for y in range(pyxel.height):
for x in range(pyxel.width):
color = (x + y + pyxel.frame_count) % 16
pyxel.pset(x, y, color)
def draw_rotating_cube(self):
"""3D風の回転立方体"""
size = 20
half_size = size / 2
vertices = [
[-half_size, -half_size, -half_size],
[half_size, -half_size, -half_size],
[half_size, half_size, -half_size],
[-half_size, half_size, -half_size],
[-half_size, -half_size, half_size],
[half_size, -half_size, half_size],
[half_size, half_size, half_size],
[-half_size, half_size, half_size],
]
# 回転
rotated_vertices = [
self.rotate_vertex(v, self.angle, self.angle / 2, self.angle / 3)
for v in vertices
]
# 投影
projected_vertices = [
self.project_vertex(v) for v in rotated_vertices
]
# 辺のリスト
edges = [
(0, 1), (1, 2), (2, 3), (3, 0), # 前面
(4, 5), (5, 6), (6, 7), (7, 4), # 背面
(0, 4), (1, 5), (2, 6), (3, 7), # 接続
]
# 辺を描画
for edge in edges:
v1, v2 = edge
x1, y1 = projected_vertices[v1]
x2, y2 = projected_vertices[v2]
pyxel.line(int(x1), int(y1), int(x2), int(y2), 7)
def draw_scrolling_text(self):
"""横スクロールするテキスト"""
pyxel.text(self.text_x, 100, self.scroll_text, pyxel.frame_count % 16)
def rotate_vertex(self, vertex, angle_x, angle_y, angle_z):
"""頂点を回転させる"""
x, y, z = vertex
# x軸回転
cos_x, sin_x = math.cos(angle_x), math.sin(angle_x)
y, z = y * cos_x - z * sin_x, y * sin_x + z * cos_x
# y軸回転
cos_y, sin_y = math.cos(angle_y), math.sin(angle_y)
x, z = x * cos_y - z * sin_y, x * sin_y + z * cos_y
# z軸回転
cos_z, sin_z = math.cos(angle_z), math.sin(angle_z)
x, y = x * cos_z - y * sin_z, x * sin_z + y * cos_z
return [x, y, z]
def project_vertex(self, vertex):
"""3D座標を2Dに投影"""
x, y, z = vertex
distance = 100
factor = distance / (distance - z) if (distance - z) != 0 else 1
x = x * factor + pyxel.width / 2
y = y * factor + pyxel.height / 2
return [x, y]
# アプリケーションを実行
MegaDemo()
ちょっと趣向を変えて、
「pyxelとpymunkでメガデモを作ってください」とお願いしてみました。
chatGPTさんの回答
PyxelとPymunkを組み合わせてメガデモ(グラフィックと物理シミュレーションのデモ)を作るのは面白そうですね!以下にそのプロジェクトの概要を説明し、サンプルコードを提供します。
概要
Pyxel はレトロスタイルのゲーム開発に特化したPythonライブラリで、簡単にグラフィックスや音楽を作成できます。
Pymunk は2D物理シミュレーションライブラリで、物理演算や衝突判定を手軽に実装できます。
メガデモの内容:
レトロなピクセルアートで描画される背景とエフェクト。
物理演算で動くオブジェクト(ボールや箱など)。
インタラクティブな要素(クリックでオブジェクトを発射するなど)。
import pyxel
import pymunk
import random
import math
# 画面サイズ
WIDTH, HEIGHT = 256, 256
# Pymunkのスペース設定
space = pymunk.Space()
space.gravity = (0, 900)
# オブジェクトとパーティクルのリスト
objects = []
particles = []
# 境界線の作成
def create_static_boundaries():
static_lines = [
pymunk.Segment(space.static_body, (0, HEIGHT), (WIDTH, HEIGHT), 1), # 底辺
pymunk.Segment(space.static_body, (0, 0), (0, HEIGHT), 1), # 左壁
pymunk.Segment(space.static_body, (WIDTH, 0), (WIDTH, HEIGHT), 1), # 右壁
]
for line in static_lines:
line.elasticity = 0.8
line.friction = 0.5
space.add(*static_lines)
# ボールを生成
def create_ball(x, y):
mass = 1
radius = random.randint(5, 10)
moment = pymunk.moment_for_circle(mass, 0, radius)
body = pymunk.Body(mass, moment)
body.position = x, y
shape = pymunk.Circle(body, radius)
shape.elasticity = 0.8
shape.friction = 0.5
space.add(body, shape)
objects.append((body, shape))
create_particles(x, y, color=pyxel.frame_count % 16 + 1)
# パーティクルを生成
def create_particles(x, y, color):
for _ in range(20):
angle = random.uniform(0, 2 * math.pi)
speed = random.uniform(50, 150)
dx = math.cos(angle) * speed
dy = math.sin(angle) * speed
particles.append({"x": x, "y": y, "dx": dx, "dy": dy, "life": 30, "color": color})
# 動くプラットフォームを生成
def create_moving_platform():
body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
body.position = WIDTH // 2, HEIGHT - 50
shape = pymunk.Segment(body, (-50, 0), (50, 0), 5)
shape.elasticity = 0.9
space.add(body, shape)
return body
# Pyxelアプリ
class App:
def __init__(self):
pyxel.init(WIDTH, HEIGHT, title="Enhanced Pyxel + Pymunk Demo")
pyxel.sound(0).set("c3e3g3c4", "p", "7", "n", 25)
pyxel.sound(1).set("g3c4e4g4", "t", "6", "f", 15)
pyxel.sound(2).set("e3c4g3", "n", "7", "f", 10)
pyxel.play(0, 0, loop=True)
create_static_boundaries()
self.platform = create_moving_platform()
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
create_ball(pyxel.mouse_x, pyxel.mouse_y)
pyxel.play(1, 1)
# パーティクルの更新
for particle in particles[:]:
particle["x"] += particle["dx"] * 1 / 60
particle["y"] += particle["dy"] * 1 / 60
particle["life"] -= 1
if particle["life"] <= 0:
particles.remove(particle)
# プラットフォームの動き
t = pyxel.frame_count / 60
self.platform.position = (WIDTH // 2 + math.sin(t) * 50, HEIGHT - 50)
# Pymunkのステップ
space.step(1 / 60)
def draw(self):
pyxel.cls(0)
# パーティクルの描画
for particle in particles:
pyxel.pset(int(particle["x"]), int(particle["y"]), particle["color"])
# ボールの描画
for body, shape in objects:
if isinstance(shape, pymunk.Circle):
x, y = body.position
pyxel.circ(x, y, shape.radius, pyxel.frame_count % 16 + 1)
# プラットフォームの描画
x, y = self.platform.position
pyxel.rect(x - 50, y - 5, 100, 5, 10)
pyxel.text(5, 5, "Click to spawn balls!", 7)
# アプリの実行
App()
マウス左クリックを連打すると玉を発生させ、発生時にはじけるアニメーションをします。
抽象的な質問でも基本は抑えているようです。
ただ、出力されたpyxelのソースコードのバージョンは古い場合があるのでそこは指摘してあげれば改善してくれます。
もっと細かく指示してあげればそれなりのソースコードを得ることができます。
それなり・・・です。