I’m trying to make a silly game but though everything works perfectly during the first game, the catcher speed (both when button is pressed once and when it’s held down) go haywire and way over the max limit of 40 (and in the case of press once button goes higher than the default of 15) for some reason. I’ve tried resetting the incremental variables when the game ends and when a new game starts and it still doesn’t work. What am I doing wrong and how can I solve it?
from itertools import cycle from random import randrange from tkinter import Canvas, Tk, messagebox, Button moving_left = False moving_right = False game_active = False # Track if the game is active canvas_width = 1000 canvas_height = 800 root = Tk() root.title("Egg Catcher") c = Canvas(root, width=canvas_width, height=canvas_height, background="deep sky blue") c.create_rectangle(-5, canvas_height - 100, canvas_width + 5, canvas_height + 5, fill="sea green", width=0) c.create_oval(80, 80, 120, 120, fill='orange', width=0) c.pack() # Play button with increased size and font play_button = Button(root, text="Play", command=lambda: start_game(), width=20, height=2, font=("Arial", 16)) play_button.place(relx=0.5, rely=0.5, anchor="center") best_score = 0 # Variable to track the best score color_cycle = cycle(["light blue", "light green", "light pink", "light yellow", "light cyan"]) egg_width = 45 egg_height = 55 egg_score = 10 egg_speed = 35 # Timing for how often move_eggs is called (in milliseconds) # Falling speed for eggs base_fall_speed = 12 # Default speed at which the eggs fall (in pixels) fall_speed = base_fall_speed # Initialize fall_speed to the base value catcher_color = "blue" catcher_width = 100 catcher_height = 100 catcher = None # Initialize catcher globally score = 0 lives_remaining = 5 eggs = [] # This will hold tuples of (egg_id, is_red) score_text = None lives_text = None best_score_text = None # Best score display variable # Speed variables for the catcher catcher_move_speed = 15 # Base speed when key is pressed once max_move_speed = 40 # Maximum speed for the catcher acceleration = 5 # Speed increment when holding down the key current_catcher_speed = catcher_move_speed # Current speed of the catcher def reset_game(): global catcher, score_text, lives_text, best_score_text global current_catcher_speed, fall_speed c.delete("all") # Clear all items from the canvas c.create_rectangle(-5, canvas_height - 100, canvas_width + 5, canvas_height + 5, fill="sea green", width=0) # Recreate ground c.create_oval(80, 80, 120, 120, fill='orange', width=0) # Recreate egg basket # Reset catcher catcher_startx = canvas_width / 2 - catcher_width / 2 catcher_starty = canvas_height - catcher_height - 100 catcher_startx2 = catcher_startx + catcher_width catcher_starty2 = catcher_starty + catcher_height catcher = c.create_arc(catcher_startx, catcher_starty, catcher_startx2, catcher_starty2, start=200, extent=140, style="arc", outline=catcher_color, width=3) # Reset score and lives display global score, lives_remaining, best_score_text score = 0 lives_remaining = 5 score_text = c.create_text(10, 10, anchor="nw", font=("Arial", 18), fill="darkblue", text="Score: " + str(score)) lives_text = c.create_text(canvas_width - 10, 10, anchor="ne", font=("Arial", 18), fill="darkblue", text="Lives: " + str(lives_remaining)) best_score_text = c.create_text(10, 40, anchor="nw", font=("Arial", 18), fill="darkblue", text="Best Score: " + str(best_score)) # Reset current catcher speed current_catcher_speed = catcher_move_speed # Reset catcher speed for a new game def start_game(): global moving_left, moving_right, score, lives_remaining, eggs, game_active global fall_speed, current_catcher_speed # Reset game state moving_left = False moving_right = False score = 0 lives_remaining = 5 eggs = [] fall_speed = base_fall_speed # Reset egg fall speed to the base value current_catcher_speed = catcher_move_speed # Reset current speed to base speed game_active = True # Set game active to True reset_game() # Reset the game canvas play_button.place_forget() # Hide the play button root.after(1000, create_egg) root.after(1000, move_eggs) root.after(1000, check_catch) move_catcher() reset_difficulty() # Start with the default difficulty def create_egg(): if not game_active: # Check if the game is active return x = randrange(10, canvas_width - egg_width) y = 40 is_red = randrange(0, 10) < 2 # 20% chance to be red fill_color = 'red' if is_red else next(color_cycle) new_egg = c.create_oval(x, y, x + egg_width, y + egg_height, fill=fill_color, width=0) eggs.append((new_egg, is_red)) # Store egg ID and its color info root.after(randrange(370, 900), create_egg) def move_eggs(): if not game_active: # Check if the game is active return for egg_tuple in eggs: egg, _ = egg_tuple (eggx, eggy, eggx2, eggy2) = c.coords(egg) c.move(egg, 0, fall_speed) # Move by the constant fall speed if eggy2 > canvas_height: egg_dropped(egg) root.after(egg_speed, move_eggs) # Timing for moving eggs def egg_dropped(egg): for egg_tuple in eggs[:]: # Iterate over a copy of the list if egg_tuple[0] == egg: eggs.remove(egg_tuple) break c.delete(egg) # Check if the egg is red or not is_red = egg_tuple[1] # Get the is_red status from the tuple if not is_red: lose_a_life() # Only lose a life if it is not red if lives_remaining == 0: global game_active, best_score game_active = False # Set game active to False if score > best_score: best_score = score # Update best score c.itemconfigure(best_score_text, text="Best Score: " + str(best_score)) # Update best score display messagebox.showinfo("Game Over!", f"Final Score: {score}") play_button.place(relx=0.5, rely=0.5, anchor="center") # Show play button again return def lose_a_life(): global lives_remaining lives_remaining -= 1 c.itemconfigure(lives_text, text="Lives: " + str(lives_remaining)) def check_catch(): (catcherx, catchery, catcherx2, catchery2) = c.coords(catcher) for egg_tuple in eggs[:]: # Iterate over a copy of the list egg, is_red = egg_tuple (eggx, eggy, eggx2, eggy2) = c.coords(egg) if (catcherx < eggx2 and catcherx2 > eggx and catchery < eggy2 and catchery2 > eggy): eggs.remove(egg_tuple) # Remove the egg from the list c.delete(egg) if is_red: increase_score(-egg_score) # Subtract points for red eggs else: increase_score(egg_score) # Add points for non-red eggs root.after(100, check_catch) def increase_score(points): global score, egg_speed score += points egg_speed = max(50, int(egg_speed * 0.95)) # Adjust the speed (keep minimum limit) c.itemconfigure(score_text, text="Score: " + str(score)) def move_left(event): global moving_left moving_left = True def move_right(event): global moving_right moving_right = True def stop_left(event): global moving_left moving_left = False def stop_right(event): global moving_right moving_right = False def move_catcher(): global current_catcher_speed (x1, y1, x2, y2) = c.coords(catcher) # Reset speed if no keys are pressed if not moving_left and not moving_right: current_catcher_speed = catcher_move_speed # Reset to base speed if moving_left and x1 > 0: current_catcher_speed += acceleration # Increase speed c.move(catcher, -current_catcher_speed, 0) elif moving_right and x2 < canvas_width: current_catcher_speed += acceleration # Increase speed c.move(catcher, current_catcher_speed, 0) # Ensure current speed never exceeds max_move_speed current_catcher_speed = min(current_catcher_speed, max_move_speed) root.after(20, move_catcher) # Call again every 20 ms def reset_difficulty(): global fall_speed fall_speed = base_fall_speed # Reset to the base fall speed increase_difficulty() # Start the difficulty increase loop def increase_difficulty(): global fall_speed fall_speed += 3 # Increase fall speed root.after(5000 - (fall_speed * 8), increase_difficulty) # Bindings for movement c.bind("<Left>", move_left) c.bind("<Right>", move_right) c.bind("<KeyRelease-Left>", stop_left) c.bind("<KeyRelease-Right>", stop_right) c.focus_set() root.mainloop()
submitted by /u/Plastic-Bee4052
[link] [comments]
r/learnpython I’m trying to make a silly game but though everything works perfectly during the first game, the catcher speed (both when button is pressed once and when it’s held down) go haywire and way over the max limit of 40 (and in the case of press once button goes higher than the default of 15) for some reason. I’ve tried resetting the incremental variables when the game ends and when a new game starts and it still doesn’t work. What am I doing wrong and how can I solve it? from itertools import cycle from random import randrange from tkinter import Canvas, Tk, messagebox, Button moving_left = False moving_right = False game_active = False # Track if the game is active canvas_width = 1000 canvas_height = 800 root = Tk() root.title(“Egg Catcher”) c = Canvas(root, width=canvas_width, height=canvas_height, background=”deep sky blue”) c.create_rectangle(-5, canvas_height – 100, canvas_width + 5, canvas_height + 5, fill=”sea green”, width=0) c.create_oval(80, 80, 120, 120, fill=’orange’, width=0) c.pack() # Play button with increased size and font play_button = Button(root, text=”Play”, command=lambda: start_game(), width=20, height=2, font=(“Arial”, 16)) play_button.place(relx=0.5, rely=0.5, anchor=”center”) best_score = 0 # Variable to track the best score color_cycle = cycle([“light blue”, “light green”, “light pink”, “light yellow”, “light cyan”]) egg_width = 45 egg_height = 55 egg_score = 10 egg_speed = 35 # Timing for how often move_eggs is called (in milliseconds) # Falling speed for eggs base_fall_speed = 12 # Default speed at which the eggs fall (in pixels) fall_speed = base_fall_speed # Initialize fall_speed to the base value catcher_color = “blue” catcher_width = 100 catcher_height = 100 catcher = None # Initialize catcher globally score = 0 lives_remaining = 5 eggs = [] # This will hold tuples of (egg_id, is_red) score_text = None lives_text = None best_score_text = None # Best score display variable # Speed variables for the catcher catcher_move_speed = 15 # Base speed when key is pressed once max_move_speed = 40 # Maximum speed for the catcher acceleration = 5 # Speed increment when holding down the key current_catcher_speed = catcher_move_speed # Current speed of the catcher def reset_game(): global catcher, score_text, lives_text, best_score_text global current_catcher_speed, fall_speed c.delete(“all”) # Clear all items from the canvas c.create_rectangle(-5, canvas_height – 100, canvas_width + 5, canvas_height + 5, fill=”sea green”, width=0) # Recreate ground c.create_oval(80, 80, 120, 120, fill=’orange’, width=0) # Recreate egg basket # Reset catcher catcher_startx = canvas_width / 2 – catcher_width / 2 catcher_starty = canvas_height – catcher_height – 100 catcher_startx2 = catcher_startx + catcher_width catcher_starty2 = catcher_starty + catcher_height catcher = c.create_arc(catcher_startx, catcher_starty, catcher_startx2, catcher_starty2, start=200, extent=140, style=”arc”, outline=catcher_color, width=3) # Reset score and lives display global score, lives_remaining, best_score_text score = 0 lives_remaining = 5 score_text = c.create_text(10, 10, anchor=”nw”, font=(“Arial”, 18), fill=”darkblue”, text=”Score: ” + str(score)) lives_text = c.create_text(canvas_width – 10, 10, anchor=”ne”, font=(“Arial”, 18), fill=”darkblue”, text=”Lives: ” + str(lives_remaining)) best_score_text = c.create_text(10, 40, anchor=”nw”, font=(“Arial”, 18), fill=”darkblue”, text=”Best Score: ” + str(best_score)) # Reset current catcher speed current_catcher_speed = catcher_move_speed # Reset catcher speed for a new game def start_game(): global moving_left, moving_right, score, lives_remaining, eggs, game_active global fall_speed, current_catcher_speed # Reset game state moving_left = False moving_right = False score = 0 lives_remaining = 5 eggs = [] fall_speed = base_fall_speed # Reset egg fall speed to the base value current_catcher_speed = catcher_move_speed # Reset current speed to base speed game_active = True # Set game active to True reset_game() # Reset the game canvas play_button.place_forget() # Hide the play button root.after(1000, create_egg) root.after(1000, move_eggs) root.after(1000, check_catch) move_catcher() reset_difficulty() # Start with the default difficulty def create_egg(): if not game_active: # Check if the game is active return x = randrange(10, canvas_width – egg_width) y = 40 is_red = randrange(0, 10) < 2 # 20% chance to be red fill_color = ‘red’ if is_red else next(color_cycle) new_egg = c.create_oval(x, y, x + egg_width, y + egg_height, fill=fill_color, width=0) eggs.append((new_egg, is_red)) # Store egg ID and its color info root.after(randrange(370, 900), create_egg) def move_eggs(): if not game_active: # Check if the game is active return for egg_tuple in eggs: egg, _ = egg_tuple (eggx, eggy, eggx2, eggy2) = c.coords(egg) c.move(egg, 0, fall_speed) # Move by the constant fall speed if eggy2 > canvas_height: egg_dropped(egg) root.after(egg_speed, move_eggs) # Timing for moving eggs def egg_dropped(egg): for egg_tuple in eggs[:]: # Iterate over a copy of the list if egg_tuple[0] == egg: eggs.remove(egg_tuple) break c.delete(egg) # Check if the egg is red or not is_red = egg_tuple[1] # Get the is_red status from the tuple if not is_red: lose_a_life() # Only lose a life if it is not red if lives_remaining == 0: global game_active, best_score game_active = False # Set game active to False if score > best_score: best_score = score # Update best score c.itemconfigure(best_score_text, text=”Best Score: ” + str(best_score)) # Update best score display messagebox.showinfo(“Game Over!”, f”Final Score: {score}”) play_button.place(relx=0.5, rely=0.5, anchor=”center”) # Show play button again return def lose_a_life(): global lives_remaining lives_remaining -= 1 c.itemconfigure(lives_text, text=”Lives: ” + str(lives_remaining)) def check_catch(): (catcherx, catchery, catcherx2, catchery2) = c.coords(catcher) for egg_tuple in eggs[:]: # Iterate over a copy of the list egg, is_red = egg_tuple (eggx, eggy, eggx2, eggy2) = c.coords(egg) if (catcherx < eggx2 and catcherx2 > eggx and catchery < eggy2 and catchery2 > eggy): eggs.remove(egg_tuple) # Remove the egg from the list c.delete(egg) if is_red: increase_score(-egg_score) # Subtract points for red eggs else: increase_score(egg_score) # Add points for non-red eggs root.after(100, check_catch) def increase_score(points): global score, egg_speed score += points egg_speed = max(50, int(egg_speed * 0.95)) # Adjust the speed (keep minimum limit) c.itemconfigure(score_text, text=”Score: ” + str(score)) def move_left(event): global moving_left moving_left = True def move_right(event): global moving_right moving_right = True def stop_left(event): global moving_left moving_left = False def stop_right(event): global moving_right moving_right = False def move_catcher(): global current_catcher_speed (x1, y1, x2, y2) = c.coords(catcher) # Reset speed if no keys are pressed if not moving_left and not moving_right: current_catcher_speed = catcher_move_speed # Reset to base speed if moving_left and x1 > 0: current_catcher_speed += acceleration # Increase speed c.move(catcher, -current_catcher_speed, 0) elif moving_right and x2 < canvas_width: current_catcher_speed += acceleration # Increase speed c.move(catcher, current_catcher_speed, 0) # Ensure current speed never exceeds max_move_speed current_catcher_speed = min(current_catcher_speed, max_move_speed) root.after(20, move_catcher) # Call again every 20 ms def reset_difficulty(): global fall_speed fall_speed = base_fall_speed # Reset to the base fall speed increase_difficulty() # Start the difficulty increase loop def increase_difficulty(): global fall_speed fall_speed += 3 # Increase fall speed root.after(5000 – (fall_speed * 8), increase_difficulty) # Bindings for movement c.bind(“<Left>”, move_left) c.bind(“<Right>”, move_right) c.bind(“<KeyRelease-Left>”, stop_left) c.bind(“<KeyRelease-Right>”, stop_right) c.focus_set() root.mainloop() submitted by /u/Plastic-Bee4052 [link] [comments]
I’m trying to make a silly game but though everything works perfectly during the first game, the catcher speed (both when button is pressed once and when it’s held down) go haywire and way over the max limit of 40 (and in the case of press once button goes higher than the default of 15) for some reason. I’ve tried resetting the incremental variables when the game ends and when a new game starts and it still doesn’t work. What am I doing wrong and how can I solve it?
from itertools import cycle from random import randrange from tkinter import Canvas, Tk, messagebox, Button moving_left = False moving_right = False game_active = False # Track if the game is active canvas_width = 1000 canvas_height = 800 root = Tk() root.title("Egg Catcher") c = Canvas(root, width=canvas_width, height=canvas_height, background="deep sky blue") c.create_rectangle(-5, canvas_height - 100, canvas_width + 5, canvas_height + 5, fill="sea green", width=0) c.create_oval(80, 80, 120, 120, fill='orange', width=0) c.pack() # Play button with increased size and font play_button = Button(root, text="Play", command=lambda: start_game(), width=20, height=2, font=("Arial", 16)) play_button.place(relx=0.5, rely=0.5, anchor="center") best_score = 0 # Variable to track the best score color_cycle = cycle(["light blue", "light green", "light pink", "light yellow", "light cyan"]) egg_width = 45 egg_height = 55 egg_score = 10 egg_speed = 35 # Timing for how often move_eggs is called (in milliseconds) # Falling speed for eggs base_fall_speed = 12 # Default speed at which the eggs fall (in pixels) fall_speed = base_fall_speed # Initialize fall_speed to the base value catcher_color = "blue" catcher_width = 100 catcher_height = 100 catcher = None # Initialize catcher globally score = 0 lives_remaining = 5 eggs = [] # This will hold tuples of (egg_id, is_red) score_text = None lives_text = None best_score_text = None # Best score display variable # Speed variables for the catcher catcher_move_speed = 15 # Base speed when key is pressed once max_move_speed = 40 # Maximum speed for the catcher acceleration = 5 # Speed increment when holding down the key current_catcher_speed = catcher_move_speed # Current speed of the catcher def reset_game(): global catcher, score_text, lives_text, best_score_text global current_catcher_speed, fall_speed c.delete("all") # Clear all items from the canvas c.create_rectangle(-5, canvas_height - 100, canvas_width + 5, canvas_height + 5, fill="sea green", width=0) # Recreate ground c.create_oval(80, 80, 120, 120, fill='orange', width=0) # Recreate egg basket # Reset catcher catcher_startx = canvas_width / 2 - catcher_width / 2 catcher_starty = canvas_height - catcher_height - 100 catcher_startx2 = catcher_startx + catcher_width catcher_starty2 = catcher_starty + catcher_height catcher = c.create_arc(catcher_startx, catcher_starty, catcher_startx2, catcher_starty2, start=200, extent=140, style="arc", outline=catcher_color, width=3) # Reset score and lives display global score, lives_remaining, best_score_text score = 0 lives_remaining = 5 score_text = c.create_text(10, 10, anchor="nw", font=("Arial", 18), fill="darkblue", text="Score: " + str(score)) lives_text = c.create_text(canvas_width - 10, 10, anchor="ne", font=("Arial", 18), fill="darkblue", text="Lives: " + str(lives_remaining)) best_score_text = c.create_text(10, 40, anchor="nw", font=("Arial", 18), fill="darkblue", text="Best Score: " + str(best_score)) # Reset current catcher speed current_catcher_speed = catcher_move_speed # Reset catcher speed for a new game def start_game(): global moving_left, moving_right, score, lives_remaining, eggs, game_active global fall_speed, current_catcher_speed # Reset game state moving_left = False moving_right = False score = 0 lives_remaining = 5 eggs = [] fall_speed = base_fall_speed # Reset egg fall speed to the base value current_catcher_speed = catcher_move_speed # Reset current speed to base speed game_active = True # Set game active to True reset_game() # Reset the game canvas play_button.place_forget() # Hide the play button root.after(1000, create_egg) root.after(1000, move_eggs) root.after(1000, check_catch) move_catcher() reset_difficulty() # Start with the default difficulty def create_egg(): if not game_active: # Check if the game is active return x = randrange(10, canvas_width - egg_width) y = 40 is_red = randrange(0, 10) < 2 # 20% chance to be red fill_color = 'red' if is_red else next(color_cycle) new_egg = c.create_oval(x, y, x + egg_width, y + egg_height, fill=fill_color, width=0) eggs.append((new_egg, is_red)) # Store egg ID and its color info root.after(randrange(370, 900), create_egg) def move_eggs(): if not game_active: # Check if the game is active return for egg_tuple in eggs: egg, _ = egg_tuple (eggx, eggy, eggx2, eggy2) = c.coords(egg) c.move(egg, 0, fall_speed) # Move by the constant fall speed if eggy2 > canvas_height: egg_dropped(egg) root.after(egg_speed, move_eggs) # Timing for moving eggs def egg_dropped(egg): for egg_tuple in eggs[:]: # Iterate over a copy of the list if egg_tuple[0] == egg: eggs.remove(egg_tuple) break c.delete(egg) # Check if the egg is red or not is_red = egg_tuple[1] # Get the is_red status from the tuple if not is_red: lose_a_life() # Only lose a life if it is not red if lives_remaining == 0: global game_active, best_score game_active = False # Set game active to False if score > best_score: best_score = score # Update best score c.itemconfigure(best_score_text, text="Best Score: " + str(best_score)) # Update best score display messagebox.showinfo("Game Over!", f"Final Score: {score}") play_button.place(relx=0.5, rely=0.5, anchor="center") # Show play button again return def lose_a_life(): global lives_remaining lives_remaining -= 1 c.itemconfigure(lives_text, text="Lives: " + str(lives_remaining)) def check_catch(): (catcherx, catchery, catcherx2, catchery2) = c.coords(catcher) for egg_tuple in eggs[:]: # Iterate over a copy of the list egg, is_red = egg_tuple (eggx, eggy, eggx2, eggy2) = c.coords(egg) if (catcherx < eggx2 and catcherx2 > eggx and catchery < eggy2 and catchery2 > eggy): eggs.remove(egg_tuple) # Remove the egg from the list c.delete(egg) if is_red: increase_score(-egg_score) # Subtract points for red eggs else: increase_score(egg_score) # Add points for non-red eggs root.after(100, check_catch) def increase_score(points): global score, egg_speed score += points egg_speed = max(50, int(egg_speed * 0.95)) # Adjust the speed (keep minimum limit) c.itemconfigure(score_text, text="Score: " + str(score)) def move_left(event): global moving_left moving_left = True def move_right(event): global moving_right moving_right = True def stop_left(event): global moving_left moving_left = False def stop_right(event): global moving_right moving_right = False def move_catcher(): global current_catcher_speed (x1, y1, x2, y2) = c.coords(catcher) # Reset speed if no keys are pressed if not moving_left and not moving_right: current_catcher_speed = catcher_move_speed # Reset to base speed if moving_left and x1 > 0: current_catcher_speed += acceleration # Increase speed c.move(catcher, -current_catcher_speed, 0) elif moving_right and x2 < canvas_width: current_catcher_speed += acceleration # Increase speed c.move(catcher, current_catcher_speed, 0) # Ensure current speed never exceeds max_move_speed current_catcher_speed = min(current_catcher_speed, max_move_speed) root.after(20, move_catcher) # Call again every 20 ms def reset_difficulty(): global fall_speed fall_speed = base_fall_speed # Reset to the base fall speed increase_difficulty() # Start the difficulty increase loop def increase_difficulty(): global fall_speed fall_speed += 3 # Increase fall speed root.after(5000 - (fall_speed * 8), increase_difficulty) # Bindings for movement c.bind("<Left>", move_left) c.bind("<Right>", move_right) c.bind("<KeyRelease-Left>", stop_left) c.bind("<KeyRelease-Right>", stop_right) c.focus_set() root.mainloop()
submitted by /u/Plastic-Bee4052
[link] [comments]