Skip to content

Instantly share code, notes, and snippets.

@roflsunriz
Created May 10, 2025 12:04
Show Gist options
  • Save roflsunriz/2854fb11feed0ae29526710bee90a04a to your computer and use it in GitHub Desktop.
Save roflsunriz/2854fb11feed0ae29526710bee90a04a to your computer and use it in GitHub Desktop.
player_jiggle : Jiggle software for player
import tkinter as tk
from tkinter import ttk
import threading
import time
import importlib
import subprocess
import sys
# 必要なパッケージの自動インストール
def install_package(package):
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
print(f"{package}のインストールが完了しました")
except subprocess.CalledProcessError:
print(f"{package}のインストールに失敗しました")
sys.exit(1)
# 必要なパッケージを確認し、なければインストール
for package in ['pyautogui', 'keyboard']:
try:
importlib.import_module(package)
except ImportError:
print(f"{package}が見つかりません。インストールします...")
install_package(package)
import pyautogui
import keyboard # キーボードショートカット用のモジュール
import random # ランダム選択のためにインポート
class PlayerJiggle:
def __init__(self, root):
self.root = root
self.root.title("Player Jiggle")
self.root.geometry("300x200")
self.root.resizable(False, False)
self.is_running = False
self.thread = None
# グローバルホットキーの設定
keyboard.add_hotkey('k+1', self.start)
keyboard.add_hotkey('k+2', self.stop)
# メインフレーム
main_frame = ttk.Frame(root, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)
# 間隔設定用のフレーム
interval_frame = ttk.Frame(main_frame)
interval_frame.pack(pady=10)
ttk.Label(interval_frame, text="押下間隔(秒):").pack(side=tk.LEFT)
self.interval_var = tk.StringVar(value="5")
self.interval_entry = ttk.Entry(interval_frame, width=10, textvariable=self.interval_var)
self.interval_entry.pack(side=tk.LEFT, padx=5)
# ボタン用のフレーム
button_frame = ttk.Frame(main_frame)
button_frame.pack(pady=20)
self.start_button = ttk.Button(button_frame, text="ON", command=self.start)
self.start_button.pack(side=tk.LEFT, padx=10)
self.stop_button = ttk.Button(button_frame, text="停止", command=self.stop, state=tk.DISABLED)
self.stop_button.pack(side=tk.LEFT, padx=10)
ttk.Button(button_frame, text="終了", command=self.quit).pack(side=tk.LEFT, padx=10)
# ステータス表示
self.status_var = tk.StringVar(value="待機中")
ttk.Label(main_frame, textvariable=self.status_var, font=("", 12)).pack(pady=5)
# ショートカットの説明
shortcut_frame = ttk.Frame(main_frame)
shortcut_frame.pack(pady=5)
ttk.Label(shortcut_frame, text="ショートカット: k+1(開始) / k+2(停止)", font=("", 9)).pack()
def jiggle_loop(self):
"""キー操作を定期的に実行するループ"""
try:
interval = float(self.interval_var.get())
if interval <= 0:
interval = 1.0
except ValueError:
interval = 5.0
self.interval_var.set("5")
self.status_var.set("実行中 - Ctrl+W,S,A,D 間隔: " + str(interval) + "秒")
# 押下可能なキーのリスト
direction_keys = ['w', 's', 'a', 'd']
try:
# 最初にCtrlキーを押す(押しっぱなしにする)
pyautogui.keyDown('ctrl')
while self.is_running:
# ランダムにキーを選択
selected_key = random.choice(direction_keys)
# 選択されたキーを押下(Ctrlは押しっぱなし)
pyautogui.keyDown(selected_key)
time.sleep(0.1) # 短い時間だけキーを押す
pyautogui.keyUp(selected_key)
# 長い待機は小さく分割して、その間にホットキーを確認する
wait_time = 0
check_interval = 0.1 # 0.1秒ごとにショートカットをチェック
while wait_time < interval and self.is_running:
time.sleep(check_interval)
wait_time += check_interval
# k+2が押されたかチェック
if keyboard.is_pressed('k') and keyboard.is_pressed('2'):
# メインスレッドでGUIを更新するようにする
self.root.after(0, self.stop)
return # ループを終了
except Exception as e:
print(f"エラー: {e}")
self.root.after(0, self.stop) # メインスレッドでGUIを更新
def start(self):
"""キー操作シミュレートを開始"""
if self.is_running:
return
self.is_running = True
self.thread = threading.Thread(target=self.jiggle_loop)
self.thread.daemon = True
self.thread.start()
self.start_button.config(state=tk.DISABLED)
self.stop_button.config(state=tk.NORMAL)
self.interval_entry.config(state=tk.DISABLED)
def stop(self):
"""キー操作シミュレートを停止"""
self.is_running = False
if self.thread:
self.thread.join(1.0)
# 必ずCtrlキーを離す
pyautogui.keyUp('ctrl')
# 念のため全てのキーを離す
for key in ['w', 's', 'a', 'd']:
pyautogui.keyUp(key)
self.start_button.config(state=tk.NORMAL)
self.stop_button.config(state=tk.DISABLED)
self.interval_entry.config(state=tk.NORMAL)
self.status_var.set("待機中")
def quit(self):
"""プログラムを終了"""
self.stop()
# ホットキーを解除
keyboard.remove_hotkey('k+1')
keyboard.remove_hotkey('k+2')
self.root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = PlayerJiggle(root)
root.protocol("WM_DELETE_WINDOW", app.quit)
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment