見出し画像

ジャストフラッシュナックルのタイミング染み込ませ練習ツール※EXE版あり

ルークを使ってみたいけど、フラッシュナックルが難しいイメージがあって敬遠してる人も多いんじゃないでしょうか。
出せなくはないけど、トレモでフレーム確認して練習するのもめんどい。

というわけで、ボタンを離すタイミングを身体に染み込ませる練習ツールを作りました。
Pythonを使用しています。ゲームは起動しなくていいです。

内容はシンプル。キーボードのXボタン、またはコントローラーのXボタン(弱パンチのところ)を押して離すだけ。
18~20フレームで離すとピっと音がして成功です。

コードは下記のとおり。
Pythonをインストールした後、テキストエディタなどを使用してコードをコピペ。
拡張子を.pyとして実行してください。

import tkinter as tk
import time
import pygame
import winsound
from pynput import keyboard

# フレーム設定
FRAMES_PER_SECOND = 60
TARGET_FRAME = 18
SUCCESS_FRAME_END = 20

# Pygame初期化
pygame.init()
pygame.joystick.init()

# コントローラー接続
joystick = None
if pygame.joystick.get_count() > 0:
    joystick = pygame.joystick.Joystick(0)
    joystick.init()

# サウンド(winsoundを使用したビープ音)
def play_success_sound():
    frequency = 440  # Hz (ラの音)
    duration = 100  # ミリ秒
    winsound.Beep(frequency, duration)

class FrameTimer:
    def __init__(self):
        self.start_time = None
        self.timer_active = False

    def start(self):
        self.start_time = time.time()
        self.timer_active = True

    def reset(self):
        self.start_time = None
        self.timer_active = False

    def get_current_frame(self):
        if self.start_time is None:
            return 0
        elapsed_time = time.time() - self.start_time
        return int(elapsed_time * FRAMES_PER_SECOND)

# 過去5回分のリリースタイミングを保存するリスト
release_log = []

def update_log(log_text):
    """リリースタイミングを更新し、ログを表示"""
    if len(release_log) >= 5:
        release_log.pop(0)  # 古いログを削除
    release_log.append(log_text)
    log_text_display = "\n".join(release_log)
    log_label.config(text=log_text_display)

# コントローラーまたはキーボードのXボタンをチェックする関数
def check_controller_and_keyboard():
    global timer_started, current_frame
    pygame.event.pump()  # イベントポーリング

    # コントローラーのXボタンをチェック
    x_button_pressed = False
    if joystick is not None:
        x_button_pressed = joystick.get_button(2)  # Xボタンが押されているかチェック

    if x_button_pressed or x_key_pressed:
        if not timer_started:
            timer.start()
            timer_started = True
            update_ui(True)
        current_frame = timer.get_current_frame()
    else:
        if timer_started:
            current_frame = timer.get_current_frame()
            if TARGET_FRAME <= current_frame <= SUCCESS_FRAME_END:
                result_label.config(text="ジャスト!")
                play_success_sound()  # 成功時に音を再生
                update_log(f"ジャスト: {current_frame}フレーム")
            elif current_frame < TARGET_FRAME:
                result_label.config(text="早い")
                update_log(f"早い: {current_frame}フレーム")
            else:
                result_label.config(text="遅い")
                update_log(f"遅い: {current_frame}フレーム")
            timer_started = False
            timer.reset()  # タイマーをリセット
            update_ui(False)
    
    # 60フレーム毎にチェック
    root.after(1000 // FRAMES_PER_SECOND, check_controller_and_keyboard)

# キーボードのXキーが押されたときの処理
x_key_pressed = False
def on_press(key):
    global x_key_pressed
    try:
        if key.char == 'x':
            x_key_pressed = True
    except AttributeError:
        pass

def on_release(key):
    global x_key_pressed
    if key == keyboard.KeyCode.from_char('x'):
        x_key_pressed = False

# キーボードのリスナーを開始
keyboard_listener = keyboard.Listener(on_press=on_press, on_release=on_release)
keyboard_listener.start()

def update_ui(is_pressed):
    if is_pressed:
        button_status.config(text="●")  # 押された場合は●
    else:
        button_status.config(text="◯")  # 押されていない場合は◯

def update_counter():
    if timer.timer_active:
        current_frame = timer.get_current_frame()
        counter_label.config(text=f"カウント: {current_frame} フレーム")
    else:
        counter_label.config(text="カウント: 0 フレーム")  # タイマーがリセットされたらカウントをリセット
    root.after(1000 // FRAMES_PER_SECOND, update_counter)

# Tkinter UIの設定
root = tk.Tk()
root.title("ジャストナックル染み込ませツール")

# ボタン状態表示 (◯/●)
button_status = tk.Label(root, text="◯", font=("Arial", 36))
button_status.pack(pady=20)

# タイミング結果
result_label = tk.Label(root, text="タイミング: 未検出", font=("Arial", 16))
result_label.pack(pady=10)

# ストップウォッチカウント
counter_label = tk.Label(root, text="カウント: 0 フレーム", font=("Arial", 16))
counter_label.pack(pady=10)

# リリースタイミングのログ表示
log_label = tk.Label(root, text="過去5回のタイミング:\n", font=("Arial", 14))
log_label.pack(pady=10)

# タイマーと状態管理
timer_started = False
timer = FrameTimer()

# コントローラーとキーボードのXボタンの監視
check_controller_and_keyboard()

# カウンター表示
update_counter()

root.mainloop()

コードわからんし面倒くさい人のためにEXE版を作成しました。
2024年いっぱいはダウンロードできると思います。
※サポートはしません。苦情も受け付けません。タイミングが違ってたらごめんなさい。

実は「凄えツール思いついた!」と思って作ったのですが、記事を書いて最後にトレモのスクショを貼った時に「ボタンを離したフレーム表示されとるやんけ」って気づいたんですよね。トレモでやればいいじゃん、と。
でもまあせっかく作ったし、ボタンを押して離すタイミングを掴みやすい気がするのでぜひお試しください。


この記事が気に入ったらサポートをしてみませんか?