Jeg elsker clicker- og idle-spil – spil der ofte involverer en masse klikkeri med musen. Og sådan noget kan automatiseres. Der findes allerede et hav af forskellige småprogrammer, der løser “problemet”, men jeg synes det kunne være sjovt at se om Gemini kunne spytte en autoclicker-app up.
Første prompt til Gemini 3 i Pro indstilling:
Jeg vil gerne lave en autoclicker-app til windows 11. Hjælp mig med at gøre det.
Det resulterede i lidt Python-kode, og med udviklerens vigtigste værktøj (CTRL-C + CTRL-V) fik jeg smidt koden i Visual Studio Code for en testkørsel. Allerede første version er faktisk ganske anstændig:

Meeeeen, den måde at indstille intervallet mellem klikkene er ikke lige min kop te, så det skal på plads:
Lad mig indstille intervallet mere nøjagtigt. Timer, minutter, sekunder og millisekunder mellem hvert klik.
Lav en "start" og "stop" knap.
Efter den rettelse ser app’en sådan ud:

Gemini foreslog at lave en “Pick Location”-funktion:
Would you like me to add the "Pick location" feature next, so you can tell the mouse exactly where to click on the screen?
Interessant og god idé, men så kan vi ligeså godt gøre det endnu sjovere:
Ja tak, jeg vil gerne have en pick location, men den skal være mere avanceret.
Det skal være muligt at tilføje flere locations, som så klikkes i rækkefølge i løkke med det valgte interval.
Det var faktisk nok til at lave en brugbar app, der gør lige præcis hvad jeg har brug for:
[autoclicker.py]
import tkinter as tk
from tkinter import ttk
import threading
import time
import pyautogui
import keyboard
class AutoClickerApp:
def __init__(self, root):
self.root = root
self.root.title("Advanced Auto Clicker")
self.root.geometry("600x350") # Gjort bredere for at gøre plads til listen
self.root.resizable(False, False)
# State variables
self.running = False
self.interval = 0.1
self.coordinates = [] # Liste over (x, y) punkter
self.coord_index = 0 # Hvilket punkt er vi nået til?
# Variabel til Radiobuttons (0 = Current Location, 1 = Coordinate List)
self.click_mode = tk.IntVar(value=0)
# UI Setup
self.setup_ui()
# Start background thread
self.click_thread = threading.Thread(target=self.clicker_logic)
self.click_thread.daemon = True
self.click_thread.start()
# Hotkeys
keyboard.add_hotkey('F6', self.toggle_clicking)
keyboard.add_hotkey('F7', self.add_current_location) # Ny hotkey til at gemme punkt
def setup_ui(self):
# --- Left Side: Settings ---
left_frame = ttk.Frame(self.root)
left_frame.pack(side="left", fill="both", expand=True, padx=10, pady=10)
# 1. Click Interval
interval_frame = ttk.LabelFrame(left_frame, text="Click interval")
interval_frame.pack(fill="x", pady=5)
input_container = ttk.Frame(interval_frame)
input_container.pack(padx=5, pady=10)
self.ent_hours = self.create_time_input(input_container, "hours", "0")
self.ent_mins = self.create_time_input(input_container, "mins", "0")
self.ent_secs = self.create_time_input(input_container, "secs", "0")
self.ent_ms = self.create_time_input(input_container, "ms", "100")
# 2. Click Options / Mode
mode_frame = ttk.LabelFrame(left_frame, text="Cursor position")
mode_frame.pack(fill="x", pady=10)
rb_current = ttk.Radiobutton(mode_frame, text="Current location", variable=self.click_mode, value=0)
rb_current.pack(anchor="w", padx=10, pady=2)
rb_list = ttk.Radiobutton(mode_frame, text="Coordinate List (Sequence)", variable=self.click_mode, value=1)
rb_list.pack(anchor="w", padx=10, pady=2)
# 3. Status & Start/Stop
control_frame = ttk.Frame(left_frame)
control_frame.pack(pady=20)
self.status_label = ttk.Label(control_frame, text="Status: STOPPED", foreground="red", font=("Segoe UI", 10, "bold"))
self.status_label.pack(pady=5)
btn_frame = ttk.Frame(left_frame)
btn_frame.pack()
self.btn_start = ttk.Button(btn_frame, text="Start (F6)", command=self.start_clicking)
self.btn_start.pack(side="left", padx=5, ipadx=5)
self.btn_stop = ttk.Button(btn_frame, text="Stop (F6)", command=self.stop_clicking)
self.btn_stop.pack(side="left", padx=5, ipadx=5)
self.btn_stop.state(['disabled'])
# --- Right Side: Coordinate List ---
right_frame = ttk.LabelFrame(self.root, text="Location List")
right_frame.pack(side="right", fill="both", padx=10, pady=10, expand=True)
# Listbox with Scrollbar
list_scroll = ttk.Scrollbar(right_frame)
list_scroll.pack(side="right", fill="y")
self.lst_coords = tk.Listbox(right_frame, yscrollcommand=list_scroll.set, height=10)
self.lst_coords.pack(side="left", fill="both", expand=True, padx=5, pady=5)
list_scroll.config(command=self.lst_coords.yview)
# List Controls
lbl_instr = ttk.Label(right_frame, text="Hover & Press F7 to add", foreground="gray", font=("Segoe UI", 8))
lbl_instr.pack(side="bottom", pady=2)
btn_clear = ttk.Button(right_frame, text="Clear List", command=self.clear_locations)
btn_clear.pack(side="bottom", fill="x", padx=5, pady=5)
def create_time_input(self, parent, label_text, default_val):
frame = ttk.Frame(parent)
frame.pack(side="left", padx=2)
entry = ttk.Entry(frame, width=4, justify='right')
entry.insert(0, default_val)
entry.pack(side="left")
lbl = ttk.Label(frame, text=label_text)
lbl.pack(side="left")
return entry
def get_total_seconds(self):
try:
h = int(self.ent_hours.get() or 0)
m = int(self.ent_mins.get() or 0)
s = int(self.ent_secs.get() or 0)
ms = int(self.ent_ms.get() or 0)
return (h * 3600) + (m * 60) + s + (ms / 1000.0)
except ValueError:
return 0.1
def add_current_location(self):
"""Adds the current mouse x,y to the list"""
x, y = pyautogui.position()
self.coordinates.append((x, y))
self.lst_coords.insert(tk.END, f"Point {len(self.coordinates)}: X={x}, Y={y}")
# Auto-select the radio button for list mode if user starts adding points
self.click_mode.set(1)
def clear_locations(self):
self.coordinates = []
self.lst_coords.delete(0, tk.END)
self.coord_index = 0
def start_clicking(self):
if not self.running:
self.interval = self.get_total_seconds()
self.running = True
self.status_label.config(text="Status: RUNNING", foreground="green")
self.btn_start.state(['disabled'])
self.btn_stop.state(['!disabled'])
def stop_clicking(self):
if self.running:
self.running = False
self.status_label.config(text="Status: STOPPED", foreground="red")
self.btn_start.state(['!disabled'])
self.btn_stop.state(['disabled'])
def toggle_clicking(self):
if self.running:
self.stop_clicking()
else:
self.start_clicking()
def clicker_logic(self):
while True:
if self.running:
# Mode 1: Coordinate List
if self.click_mode.get() == 1 and self.coordinates:
# Get current target
target_x, target_y = self.coordinates[self.coord_index]
pyautogui.click(target_x, target_y)
# Move to next point in list, loop back to 0 if at end
self.coord_index = (self.coord_index + 1) % len(self.coordinates)
# Mode 0: Current Location (or List is empty)
else:
pyautogui.click()
time.sleep(self.interval)
else:
time.sleep(0.01)
if __name__ == "__main__":
root = tk.Tk()
try:
from ctypes import windll
windll.shcore.SetProcessDpiAwareness(1)
except:
pass
app = AutoClickerApp(root)
root.mainloop()
[### Sådan bruger du den nye "Pick Location" funktion:
Start scriptet.
Bevæg musen hen over det sted på skærmen, du vil klikke på.
Tryk på F7. Du vil se koordinaterne (f.eks. X=500, Y=300) dukke op i listen til højre.
Gentag for så mange punkter, du vil.
Sørg for, at "Coordinate List" er valgt (det sker automatisk, når du tilføjer punkter).
Tryk Start (F6).
Nu vil musen hoppe til Punkt 1, klikke, vente tiden ud, hoppe til Punkt 2, klikke, osv. Når den når bunden af listen, starter den forfra ved Punkt 1.]

Den “færdige” app (den kan jo stadig forbedres) skrevet på 5 minutter i Google Gemini 3 Pro. Og nu skal jeg lige finde et spil frem, og snyde som en gris!
