I am trying to create a clicker game, and all the basic fundamentals are in; there's a button, you can click it, there's an upgrade, you can infinitely buy it while the price goes up 15%. Now, all of this is fine, but I want to implement a "prestige" for the upgrade; if you buy the upgrade 10 times, you will have to pay a price 5x the cost, but after that the upgrade will give you more rewards. I decided to put a counter in, and whenever you buy the upgrade, it goes up. Now, here is my problem. I put an if statement for when the counter reaches 10 (all of the data for that upgrade is stored in its own dictionary), it will change the text and cost. This does not work at all. Instead, it keeps the same text, and after buying it 1 - 3 more times, it will change the reward given, but nothing else.
Here is my code:
from tkinter import *
from threading import Timer
window = Tk()
window.minsize(1200, 500)
window.title("Clicker Game")
# general setup
default_font = ("Calibri", 15, "normal")
clicks = 0
click_power = 1
# upgrade variables
upgrade1_stats = {
"cost": 15,
"can buy": False,
"times bought": 0,
"click power given": 1,
"prestige": False,
}
# functions
def check_clicks():
global clicks, upgrade1_stats
if clicks >= 10:
upgrade1.place(x=200, y=50)
if clicks >= upgrade1_stats["cost"]:
upgrade1_stats["can buy"] = True
else:
upgrade1_stats["can buy"] = False
def get_upgrade1():
global clicks, upgrade1_stats, click_power
if upgrade1_stats["times bought"] == 10 and upgrade1_stats["can buy"]:
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 5)
update_stats()
upgrade1_stats["prestige"] = False
upgrade1_stats["click power given"] = 1
upgrade1_stats["times bought"] = 1
if upgrade1_stats["can buy"]:
clicks -= upgrade1_stats["cost"]
click_power = upgrade1_stats["click power given"]
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 1.15)
upgrade1_stats["times bought"] = 1
update_stats()
else:
not_enough_clicks()
check_clicks()
if upgrade1_stats["prestige"]:
upgrade1.config(text=f"MAX UPGRADES BOUGHT\nPRESTIGE COST: {upgrade1_stats['cost']}")
else:
upgrade1.config(text=f" {upgrade1_stats['click power given']} Click Power\nCost: {upgrade1_stats['cost']}")
def not_enough_clicks():
new_label = Label(text="NOT ENOUGH CLICKS", font=("Calibri", 80, "bold"))
new_label.place(x=125, y=180)
t = Timer(1, new_label.destroy)
t.start()
def increase_score(*args):
global clicks
if len(args) > 0:
update_amount = args[0]
else:
update_amount = click_power
clicks = update_amount
update_stats()
check_clicks()
def update_stats(**kwargs):
global clicks, click_power
click_display.config(text=f"{clicks} Clicks")
if click_power == 1:
click_power_display.config(text=f"{click_power} Click per Button Click")
else:
click_power_display.config(text=f"{click_power} Clicks per Button Click")
# title text
title_label = Label(text="Clicker Game", font=("Calibri", 30, "bold"))
title_label.grid(column=1, columnspan=2, row=1)
window.grid_columnconfigure(2, weight=1)
window.grid_rowconfigure(1, weight=1)
# click display
click_display = Label(text=f"{clicks} Clicks", font=default_font)
click_display.grid(column=2, row=2)
window.grid_rowconfigure(2, weight=0, pad=70)
# button to click
clicker = Button(text="Click Me", command=increase_score, height=3, width=10, bg="red")
clicker.grid(column=2, row=3)
window.grid_rowconfigure(3, pad=200)
# click power display
click_power_display = Label(text=f"{click_power} Click per Button Click", font=default_font)
click_power_display.place(x=495, y=150)
# upgrades
upgrade1 = Button(text=f" 1 Click Power\nCost: {upgrade1_stats['cost']}", command=get_upgrade1)
window.mainloop()
The expectation is that once buying the upgrade 10 times, it would change the text to "MAX UPGRADES REACHED. PRESTIGE COST: (prestige cost here)". This is not at all what is happening, and I am very confused why. Any and all help would be greatly appreciated by me.
EDIT
With the help of @Alexander, I did update my code to this:
from tkinter import *
from threading import Timer
window = Tk()
window.minsize(1200, 500)
window.title("Clicker Game")
# general setup
default_font = ("Calibri", 15, "normal")
clicks = 0
click_power = 1
# upgrade variables
upgrade1_stats = {
"cost": 15,
"can buy": False,
"times bought": 0,
"click power given": 1,
"prestige": False,
}
# functions
def check_clicks():
global clicks, upgrade1_stats
if clicks >= 10:
upgrade1.place(x=200, y=50)
if clicks >= upgrade1_stats["cost"]:
upgrade1_stats["can buy"] = True
else:
upgrade1_stats["can buy"] = False
def get_upgrade1():
global clicks, upgrade1_stats, click_power
if upgrade1_stats["times bought"] == 10 and upgrade1_stats["can buy"]:
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 5)
update_stats()
upgrade1_stats["prestige"] = True
upgrade1_stats["click power given"] = 1
upgrade1_stats["times bought"] = 1
elif upgrade1_stats["can buy"] and upgrade1_stats["times bought"] != 10:
clicks -= upgrade1_stats["cost"]
click_power = upgrade1_stats["click power given"]
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 1.15)
upgrade1_stats["times bought"] = 1
upgrade1_stats["prestige"] = False
update_stats()
else:
not_enough_clicks()
check_clicks()
if upgrade1_stats["prestige"]:
upgrade1.config(text=f"MAX UPGRADES BOUGHT\nPRESTIGE COST: {upgrade1_stats['cost']}")
else:
upgrade1.config(text=f" {upgrade1_stats['click power given']} Click Power\nCost: {upgrade1_stats['cost']}")
def not_enough_clicks():
new_label = Label(text="NOT ENOUGH CLICKS", font=("Calibri", 80, "bold"))
new_label.place(x=125, y=180)
t = Timer(1, new_label.destroy)
t.start()
def increase_score(*args):
global clicks
if len(args) > 0:
update_amount = args[0]
else:
update_amount = click_power
clicks = update_amount
update_stats()
check_clicks()
def update_stats(**kwargs):
global clicks, click_power
click_display.config(text=f"{clicks} Clicks")
if click_power == 1:
click_power_display.config(text=f"{click_power} Click per Button Click")
else:
click_power_display.config(text=f"{click_power} Clicks per Button Click")
# title text
title_label = Label(text="Clicker Game", font=("Calibri", 30, "bold"))
title_label.grid(column=1, columnspan=2, row=1)
window.grid_columnconfigure(2, weight=1)
window.grid_rowconfigure(1, weight=1)
# click display
click_display = Label(text=f"{clicks} Clicks", font=default_font)
click_display.grid(column=2, row=2)
window.grid_rowconfigure(2, weight=0, pad=70)
# button to click
clicker = Button(text="Click Me", command=increase_score, height=3, width=10, bg="red")
clicker.grid(column=2, row=3)
window.grid_rowconfigure(3, pad=200)
# click power display
click_power_display = Label(text=f"{click_power} Click per Button Click", font=default_font)
click_power_display.place(x=495, y=150)
# upgrades
upgrade1 = Button(text=f" 1 Click Power\nCost: {upgrade1_stats['cost']}", command=get_upgrade1)
window.mainloop()
Now, there is still another problem: The prestige only shows up after "buying" the upgrade 2 or 3 times after you actually bought it 10 times. I want it to show up after EXACTLY 10 times. Could anybody help me with this?
CodePudding user response:
The reason it takes more than 10 clicks for it to appear is because you do not increment the upgrade1_stats["times bought"] until after you have already checked how many times user has previously clicked the bonus. So it takes exactly 11 times.
The solution would be to increment the times bought before checking if it has been bought 10 times, or alternatively you could start the times bought counter at 1 instead of 0.
upgrade1_stats["times bought"] = 1
I would recommend moving the above line and making a few other alterations to reduce some unnecessary code and improve readability. See inline notes in example below.
from tkinter import *
from threading import Timer
window = Tk()
window.minsize(1200, 500)
window.title("Clicker Game")
# general setup
default_font = ("Calibri", 15, "normal")
clicks = 0
click_power = 1
# upgrade variables
upgrade1_stats = {
"cost": 15,
"times bought": 0,
"click power given": 1
}
def get_upgrade1():
global clicks, click_power
if clicks < upgrade1_stats["cost"]: # if there is not enough clicks
return not_enough_clicks() # exit the function early
upgrade1_stats["times bought"] = 1 # increase times bought before check
if upgrade1_stats["times bought"] == 10:
upgrade1_stats["cost"] *= 5 # simplified multiplication
upgrade1_stats["click power given"] = 1
upgrade1.config(text=f" {upgrade1_stats['click power given']} Click Power\nCost: {upgrade1_stats['cost']}")
else:
clicks -= upgrade1_stats["cost"]
click_power = upgrade1_stats["click power given"]
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 1.15)
upgrade1.config(text=f"MAX UPGRADES BOUGHT\nPRESTIGE COST: {upgrade1_stats['cost']}")
update_stats()
def not_enough_clicks():
new_label = Label(text="NOT ENOUGH CLICKS", font=("Calibri", 80, "bold"))
new_label.place(x=125, y=180)
t = Timer(1, new_label.destroy)
t.start()
def increase_score(*_):
global clicks
clicks = click_power
if clicks >= 10:
upgrade1.place(x=200, y=50)
update_stats()
def update_stats(**_):
verb = "Click" if click_power == 1 else "Clicks"
click_display.config(text=f"{clicks} {verb}")
click_power_display.config(text=f"{click_power} {verb} per Button Click")
# title text
title_label = Label(text="Clicker Game", font=("Calibri", 30, "bold"))
title_label.grid(column=1, columnspan=2, row=1)
window.grid_columnconfigure(2, weight=1)
window.grid_rowconfigure(1, weight=1)
# click display
click_display = Label(text=f"{clicks} Clicks", font=default_font)
click_display.grid(column=2, row=2)
window.grid_rowconfigure(2, weight=0, pad=70)
# button to click
clicker = Button(text="Click Me", command=increase_score, height=3, width=10, bg="red")
clicker.grid(column=2, row=3)
window.grid_rowconfigure(3, pad=200)
# click power display
click_power_display = Label(text=f"{click_power} Click per Button Click", font=default_font)
click_power_display.place(x=495, y=150)
# upgrades
upgrade1 = Button(text=f" 1 Click Power\nCost: {upgrade1_stats['cost']}", command=get_upgrade1)
window.mainloop()