如何无重复更新函数返回变量?Cookie Clicker游戏开发问题
问题概述
开发Cookie Clicker类游戏时,为避免重复代码编写了defamountx函数,但遇到变量更新问题:点击按钮时,函数返回的amount、price、cps无法同步更新全局变量。目前只能通过单独定义赋值函数实现,但这会引入重复代码,违背减少冗余的初衷。
原代码片段
import tkinter as tk root = tk.Tk() def printt(): print(amountc, amountg, amountt) def defamountx(amount, priceconstant, cpsconstant, Name, Button, refresh): global cpsall old_price = round(priceconstant * 1.15 ** amount) if refresh is False: amount += 1 price = round(priceconstant * 1.15 ** amount) cps = amount * cpsconstant Button["text"] = f"{Name}\n🍪{price}" shoptxt["text"] = f"↓Shop↓, {cpsall} c/s" print(amount) return amount, price, cps amountc=0 amountg=0 amountt=0 cpsall = 0 shoptxt = tk.Label(root, height=1, width=40) shoptxt.pack() clickerbn = tk.Button(root, command=lambda: defamountx(amountc, 5, 0.1, "Clicker", clickerbn, False), width=30, height=2) amountc, pricec, cpsc = defamountx(amountc, 5, 0.1, "Clicker", clickerbn, True) grandmabn = tk.Button(root, command=lambda: defamountx(amountg, 75, 1, "Grandma", grandmabn, False), width=30, height=2) amountg, priceg, cpsg = defamountx(amountg, 75, 1, "Grandma", grandmabn, True) treebn = tk.Button(root, command=lambda: defamountx(amountt, 500, 5, "Cookie Tree", treebn, False), width=30, height=2) amountt, pricet, cpst = defamountx(amountt, 500, 5, "Cookie Tree", treebn, True) printbn = tk.Button(root, command=printt, width=30, height=2, text='print') printbn.pack() shoptxt["text"] = f"↓Shop↓, {cpsall} c/s" buttons = [clickerbn, grandmabn, treebn] for stf in buttons: stf.pack() root.mainloop()
解决方案:用字典管理升级数据(避免重复代码)
核心思路:Python中整数是不可变类型,函数参数传递的是值副本,无法直接修改全局变量;改用**字典(可变对象)**存储每个升级项的所有数据,函数内直接修改字典元素即可同步更新全局状态,无需手动赋值返回值。
修改后的完整代码:
import tkinter as tk root = tk.Tk() # 用字典统一管理所有升级项的数据,避免零散的全局变量 upgrade_data = { "clicker": {"amount": 0, "price_constant": 5, "cps_constant": 0.1, "name": "Clicker"}, "grandma": {"amount": 0, "price_constant": 75, "cps_constant": 1, "name": "Grandma"}, "tree": {"amount": 0, "price_constant": 500, "cps_constant": 5, "name": "Cookie Tree"} } cpsall = 0 def printt(): # 从字典中提取当前数量打印 print( upgrade_data["clicker"]["amount"], upgrade_data["grandma"]["amount"], upgrade_data["tree"]["amount"] ) def defamountx(upgrade_key, button, refresh): global cpsall # 获取当前升级项的数据(字典引用,修改会同步全局) data = upgrade_data[upgrade_key] if not refresh: data["amount"] += 1 # 计算当前价格和cps data["price"] = round(data["price_constant"] * 1.15 ** data["amount"]) data["cps"] = data["amount"] * data["cps_constant"] # 更新按钮文本和总cps显示 button["text"] = f"{data['name']}\n🍪{data['price']}" cpsall = sum(item["cps"] for item in upgrade_data.values()) shoptxt["text"] = f"↓Shop↓, {cpsall:.1f} c/s" print(data["amount"]) shoptxt = tk.Label(root, height=1, width=40) shoptxt.pack() # 初始化按钮和数据 clickerbn = tk.Button(root, command=lambda: defamountx("clicker", clickerbn, False), width=30, height=2) defamountx("clicker", clickerbn, True) grandmabn = tk.Button(root, command=lambda: defamountx("grandma", grandmabn, False), width=30, height=2) defamountx("grandma", grandmabn, True) treebn = tk.Button(root, command=lambda: defamountx("tree", treebn, False), width=30, height=2) defamountx("tree", treebn, True) printbn = tk.Button(root, command=printt, width=30, height=2, text='print') printbn.pack() buttons = [clickerbn, grandmabn, treebn] for stf in buttons: stf.pack() root.mainloop()
关键改进点
- 用
upgrade_data字典统一存储所有升级项的amount、价格常量、cps常量等数据,避免零散的全局变量 - 函数
defamountx通过升级项的key获取字典引用,修改字典元素直接同步全局状态,无需返回值再手动赋值 - 自动计算总cps,无需手动维护每个升级项的cps总和
- 代码结构更清晰,新增升级项只需在字典中添加条目,无需重复编写变量和初始化代码
内容的提问来源于stack exchange,提问作者user20956663
相关产品推荐
相关产品推荐

