Skip to content

Instantly share code, notes, and snippets.

@gbigwood
Created November 15, 2015 00:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbigwood/0822afaf9b75f7e41ae2 to your computer and use it in GitHub Desktop.
Save gbigwood/0822afaf9b75f7e41ae2 to your computer and use it in GitHub Desktop.
Riven Fast Q-combo click trainer (Python 3.4+)
import tkinter as tk
import time
import statistics
CIRCLE_X=100
CIRCLE_Y=120
CIRCLE_RADIUS=40
PREVIOUS_ACTION=None
CORRECT_MOVE=True
CORRECT_COMBO_COUNT = 0
#Valid click states:
R_CLICK_ON_ENEMY = "R_CLICK_ON_ENEMY"
Q_ON_ENEMY = "Q_ON_ENEMY"
Q_ON_GROUND = "Q_ON_GROUND"
R_CLICK_ON_GROUND = "R_CLICK_ON_GROUND"
comboTimingRecords = []
root = tk.Tk()
canvas = tk.Canvas(root, width=640, height=480, borderwidth=0, highlightthickness=0, bg="black")
canvas.grid()
def _create_circle(self, x, y, r, **kwargs):
return self.create_oval(x-r, y-r, x+r, y+r, **kwargs)
tk.Canvas.create_circle = _create_circle
def in_circle(center_x, center_y, radius, x, y):
square_dist = (center_x - x) ** 2 + (center_y - y) ** 2
return square_dist <= radius ** 2
def setErrorStateIfNecessary(correctMove):
global canvas
if not correctMove:
canvas.configure(background="dark red")
circle_id = canvas.create_circle(x=CIRCLE_X, y=CIRCLE_Y, r=CIRCLE_RADIUS, fill="blue", outline="#DDD", width=4)
counterLabel = tk.Label(root, text="Count: " + str(CORRECT_COMBO_COUNT), fg = "white", bg="green")
def resetEnvironment():
global PREVIOUS_ACTION, CORRECT_MOVE, canvas, counterLabel, CORRECT_COMBO_COUNT
PREVIOUS_ACTION = None
CORRECT_MOVE = True
canvas.configure(background="black")
CORRECT_COMBO_COUNT = 0
counterLabel.config(text="Count: " + str(CORRECT_COMBO_COUNT))
#Reset button:
b1 = tk.Button(root, text="Reset", command=resetEnvironment)
b1.grid(row=0, column = 0)
counterLabel.grid(row=0, column = 1)
#Bind click action
def clickCoords(event):
global PREVIOUS_ACTION, CORRECT_MOVE, CORRECT_COMBO_COUNT, counterLabel, timeAtEndOfCombo, timeAtStartOfCombo, comboTimingRecords
isInCircle = in_circle(CIRCLE_X, CIRCLE_Y, CIRCLE_RADIUS, event.x, event.y)
currentAction = None
if isInCircle:
currentAction = R_CLICK_ON_ENEMY
else:
currentAction = R_CLICK_ON_GROUND
if (currentAction is R_CLICK_ON_ENEMY):
if ((PREVIOUS_ACTION is None) or (PREVIOUS_ACTION is R_CLICK_ON_GROUND)):
if (PREVIOUS_ACTION is R_CLICK_ON_GROUND):
CORRECT_COMBO_COUNT +=1
timeAtEndOfCombo = int(time.time())
comboTimingRecords.append(timeAtEndOfCombo - timeAtStartOfCombo)
meanComboTime = statistics.mean(comboTimingRecords)
combosAndAvg = "Count: " + str(CORRECT_COMBO_COUNT) + "\n" \
"Avg: " + str(meanComboTime)
counterLabel.config(text=combosAndAvg)
else:
timeAtStartOfCombo = int(time.time())
CORRECT_MOVE = True
else:
CORRECT_MOVE = False
else:
if (PREVIOUS_ACTION is Q_ON_ENEMY):
CORRECT_MOVE = True
else:
CORRECT_MOVE = False
PREVIOUS_ACTION = currentAction
setErrorStateIfNecessary(CORRECT_MOVE)
canvas.bind("<Button 3>", clickCoords)
#Bind q action
def qCoords(event):
global PREVIOUS_ACTION, CORRECT_MOVE
isInCircle = in_circle(CIRCLE_X, CIRCLE_Y, CIRCLE_RADIUS, event.x, event.y)
if isInCircle:
currentAction = Q_ON_ENEMY
else:
currentAction = Q_ON_GROUND
if (currentAction is Q_ON_ENEMY) and (PREVIOUS_ACTION is R_CLICK_ON_ENEMY):
CORRECT_MOVE = True
else:
CORRECT_MOVE = False
PREVIOUS_ACTION = currentAction
setErrorStateIfNecessary(CORRECT_MOVE)
canvas.focus_set()
canvas.bind("<q>", qCoords)
#TODO Timing -- check time since previous event
#TODO Timing -- build up speed - time taken since first AA and second.
#TODO High score -- using pickle or shelve or some shit.
#TODO button to reduce enemy size
root.wm_title("Riven Fast Q-Combo Clicker")
root.mainloop()
@codyhan94
Copy link

A small change that makes the program work on a Mac (there's a bug in OSX that causes keypress events to not record event.x and event.y correctly).

def qCoords(event):
    px, py = event.widget.winfo_pointerxy()
    rx, ry = (event.widget.winfo_rootx(), event.widget.winfo_rooty())
    cx, cy = (px - rx, py - ry)

    global PREVIOUS_ACTION, CORRECT_MOVE
    isInCircle = in_circle(CIRCLE_X, CIRCLE_Y, CIRCLE_RADIUS, cx, cy)
    ### etc..

@gbigwood
Copy link
Author

Thanks I will add

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment