クリックゲーム
init python:
import random
clicked = False
def random_pos(img_w=0, img_h=0):
"""画像サイズを考慮して画面内に収まるランダム座標を返す"""
screen_w = config.screen_width
screen_h = config.screen_height
max_x = screen_w - img_w
max_y = screen_h - img_h
x = random.randint(0, max_x)
y = random.randint(0, max_y)
return x, y
label start:
# 状態をリセット
$ clicked = False
# 関数呼び出し
$ rx, ry = random_pos(94, 94)
# screen に引数で渡す
call screen click_game(rx, ry)
if _return == "continue":
jump start # 自分に戻ってやり直す
else:
return
screen click_game(xpos, ypos):
if clicked:
add "03.png":
xpos xpos
ypos ypos
vbox:
xalign 0.5
yalign 0.9
spacing 12
textbutton "続ける" action Return("continue")
textbutton "終わり" action Return("end")
else:
imagebutton:
idle "01.png"
hover "02.png"
xpos xpos
ypos ypos
action [
Play("sound", "01.mp3"),
SetVariable("clicked", True)
]
画面内にランダム配置したい
def random_pos(img_w=0, img_h=0):
screen_w = config.screen_width
screen_h = config.screen_height
max_x = screen_w - img_w
max_y = screen_h - img_h
return random.randint(0, max_x), random.randint(0, max_y)
random_pos(幅, 高さ)` でランダム座標を取得できる。
変数を初期化したい
label start:
$ clicked = False
画面を呼び出す前に、状態をリセットできる。
label から screen に値を渡したい
call screen click_game(rx, ry)
click_game
screen に xpos=rx, ypos=ry
として渡る。
クリックしたら画像を変えたい
if clicked:
add "03.png"
else:
imagebutton:
idle "01.png"
hover "02.png"
action SetVariable("clicked", True)
if
分岐と SetVariable
でクリック前/後を切り替える。
クリックで音を鳴らしたい
action Play("sound", "01.mp3")
Play("sound", ファイル名)
で効果音を鳴らせる。
screen から値を返したい
textbutton "続ける" action Return("continue")
textbutton "終わり" action Return("end")
押したボタンの値が _return
に入る。
返り値で処理を分けたい
if _return == "continue":
jump start
else:
return
screen で押されたボタンに応じて次の処理を決められる。
ドラッグ&ドロップ
define config.mouse = {}
default dart_x = 400
default dart_y = 300
default dart_grabbed = False
default dart_offset_x = 0
default dart_offset_y = 0
default dart_shrinking = False
default dart_target_x = 0
default dart_target_y = 0
init python:
import renpy.exports as renpy
# Dart のサイズ(画像サイズに合わせる)
DART_W, DART_H = 188, 188
def grab_dart():
mx, my = renpy.get_mouse_pos()
# マウスが Dart の矩形内か判定
if (store.dart_x <= mx <= store.dart_x + DART_W and
store.dart_y <= my <= store.dart_y + DART_H):
store.dart_offset_x = mx - store.dart_x
store.dart_offset_y = my - store.dart_y
store.dart_grabbed = True
def release_dart():
store.dart_grabbed = False
# ランダムずれを決める
offset_x = random.randint(-10, 10)
offset_y = random.randint(0, 100)
store.dart_target_x = store.dart_x + offset_x
store.dart_target_y = store.dart_y + offset_y
# 中間点を少し横にずらす(カーブ用)
curve_x = (store.dart_x + store.dart_target_x) // 2 + random.randint(-50, 50)
curve_y = (store.dart_y + store.dart_target_y) // 2 + random.randint(-125, 0)
store.dart_mid_x = curve_x
store.dart_mid_y = curve_y
store.dart_shrinking = True
def update_dart_pos():
if store.dart_grabbed:
mx, my = renpy.get_mouse_pos()
store.dart_x = mx - store.dart_offset_x
store.dart_y = my - store.dart_offset_y
label test_drag_like:
call screen drag_like_screen
return
# 縮小用 transform
transform shrink_dart(start_x, start_y, mid_x, mid_y, target_x, target_y):
xpos start_x
ypos start_y
# 前半:中間地点まで
easein 0.5 zoom 0.2 xpos mid_x ypos mid_y
# 後半:的に到達&縮小
easeout 0.25 zoom 0.05 xpos target_x ypos target_y
screen drag_like_screen():
if dart_shrinking:
add "04.png" at shrink_dart(dart_x, dart_y, dart_mid_x, dart_mid_y, dart_target_x, dart_target_y)
else:
add "04.png" xpos dart_x ypos dart_y
timer 0.01 action Function(update_dart_pos) repeat True
key "mousedown_1" action Function(grab_dart)
key "mouseup_1" action Function(release_dart)
vbox:
xalign 0.5
yalign 0.9
text "座標 = [dart_x], [dart_y]"
text "掴んでいる? [dart_grabbed]"
textbutton "戻る" action Return()
変数をゲーム中に保持したい
default dart_x = 400
default dart_y = 300
default dart_grabbed = False
default dart_offset_x = 0
default dart_offset_y = 0
default
は セーブ/ロードにも対応。
ゲーム全体の状態を保存するのに使う。
マウス座標を取得したい
mx, my = renpy.get_mouse_pos()
今のマウス位置 (x, y) を取得できる。
ドラッグ開始(掴んだとき)
def grab_dart():
mx, my = renpy.get_mouse_pos()
if (store.dart_x <= mx <= store.dart_x + DART_W and
store.dart_y <= my <= store.dart_y + DART_H):
store.dart_offset_x = mx - store.dart_x
store.dart_offset_y = my - store.dart_y
store.dart_grabbed = True
クリック位置が Dart の矩形内なら「掴んだ」状態にする。
offset
を保存して画像が瞬間移動しないようにする。
ドラッグ中に追従させたい
def update_dart_pos():
if store.dart_grabbed:
mx, my = renpy.get_mouse_pos()
store.dart_x = mx - store.dart_offset_x
store.dart_y = my - store.dart_offset_y
掴んでいるときだけマウスに追従させる。
timer 0.01 action Function(update_dart_pos) repeat True
timer
で 0.01 秒ごとに更新。
常時「掴んでいるかどうか」を確認できる。
ドラッグ終了(離したとき)
def release_dart():
store.dart_grabbed = False
offset_x = random.randint(-10, 10)
offset_y = random.randint(0, 100)
store.dart_target_x = store.dart_x + offset_x
store.dart_target_y = store.dart_y + offset_y
store.dart_shrinking = True
離したら掴んでいない状態に戻す。
ついでに「着地点(ランダムずれ)」を決める。
キー入力で掴む/離す
key "mousedown_1" action Function(grab_dart)
key "mouseup_1" action Function(release_dart)
左クリック押下で掴み、離したらリリース。
縮小しながら移動させたい
transform shrink_dart(start_x, start_y, mid_x, mid_y, target_x, target_y):
xpos start_x
ypos start_y
easein 0.5 zoom 0.2 xpos mid_x ypos mid_y
easeout 0.25 zoom 0.05 xpos target_x ypos target_y
開始 → 中間点 → 最終位置を通過する。
easein
/ easeout
で加速・減速のニュアンスを調整。
ランダムに中間点をずらしてカーブ移動
curve_x = (store.dart_x + store.dart_target_x) // 2 + random.randint(-50, 50)
curve_y = (store.dart_y + store.dart_target_y) // 2 + random.randint(-125, 0)
store.dart_mid_x = curve_x
store.dart_mid_y = curve_y
最終位置の真ん中を基準に少しズラすことで、直線ではなく「弧を描く」動きになる。
状態を画面で分けたい
if dart_shrinking:
add "04.png" at shrink_dart(dart_x, dart_y, dart_mid_x, dart_mid_y, dart_target_x, dart_target_y)
else:
add "04.png" xpos dart_x ypos dart_y
dart_shrinking
が True のときは transform でアニメーション。
False のときは通常表示。