我试图用tkinter进行文字冒险,我慢慢地在一起做些什么。我试图显示从一个房间到另一个房间的命令但是即使按钮出现,按下它们也没有任何反应。
game.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import world
from player import Player
from ui import *
def main():
gui = Window(root())
while True:
gui.mainloop()
else:
pass
if __name__ == '__main__':
main()
ui.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk
import world, tiles, action
from player import Player
class Window(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master=master)
self.master = master
self.player = Player()
self.init_ui()
def init_ui(self):
self.master.title("****")
self.tabs = Tabs(self.master)
world.load_tiles()
self.world = world.tile_exists(self.player.location_x, self.player.location_y)
self.update_main()
def update_main(self):
self.world.scene_init()
self.world.modify_player(self.player)
self.tabs.update_tab(self.world, self.player)
def _label(self, master, text, side=None, anchor=None):
new_label = tk.Label(master, text=text)
new_label.pack(side=side, anchor=anchor)
def _button(self, master, text, command, side=None, anchor=None):
new_button = tk.Button(master, text=text, command=command)
new_button.pack(side=side, anchor=anchor)
class Tabs(Window):
def __init__(self, master):
self.master = master
self.nb = ttk.Notebook(self.master)
nb_1 = ttk.Frame(self.nb)
self.frame_1 = tk.Frame(nb_1, bg='red', bd=2, relief=tk.SUNKEN, padx=5, pady=5)
self.frame_1.pack(expand=1, fill='both', side=tk.LEFT)
self.nb.add(nb_1, text='Game')
self.nb.pack(expand=1, fill='both', side=tk.LEFT)
def update_tab(self, world, player):
avaliable_actions = world.avaliable_actions()
self._label(self.frame_1, world.display_text(), side=tk.LEFT, anchor=tk.N)
for action in avaliable_actions:
self._button(self.frame_1, text=action, command=player.do_action(action, **action.kwargs), side=tk.BOTTOM, anchor=tk.E)
def root():
root = tk.Tk()
root.geometry("600x350+200+200")
return root
world.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
_world = {}
def tile_exists(x, y):
"""Returns the tile at the given coordinates or None if there is no tile.
:param x: the x-coordinate in the worldspace
:param y: the y-coordinate in the worldspace
:return: the tile at the given coordinates or None if there is no tile
"""
return _world.get((x, y))
def load_tiles():
with open('scenes.txt', 'r') as f:
rows = f.readlines()
x_max = len(rows[0].split('\t'))
for y in range(len(rows)):
cols = rows[y].split('\t')
for x in range(x_max):
tile_name = cols[x].replace('\n', '')
_world[(x, y)] = None if tile_name == '' else getattr(__import__('tiles'),
tile_name)(x, y)
return _world
tiles.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import world, action
from player import Player
class MapTile():
def __init__(self, x, y):
self.x = x
self.y = y
def display_text(self):
pass
# raise NotImplementedError()
def modify_player(self, the_player):
raise NotImplementedError()
def adjacent_moves(self):
moves = []
if world.tile_exists(self.x + 1, self.y):
moves.append(action.MoveEast())
if world.tile_exists(self.x - 1, self.y):
moves.append(action.MoveWest())
if world.tile_exists(self.x, self.y - 1):
moves.append(action.MoveNorth())
if world.tile_exists(self.x, self.y + 1):
moves.append(action.MoveSouth())
return moves
def avaliable_actions(self):
'''Returns all of the default avaliable_actions in a room'''
moves = self.adjacent_moves()
# moves.append(action.ViewInventory())
return moves
class Scene_1(MapTile):
def scene_init(self):
self.location = 'Scene_1'
self.long_desc = 'Welcome to {}, the shittiest place on earth.'.format(self.location)
self.short_desc = 'Eh, I don\'t care.'
def display_text(self):
return self.long_desc
def modify_player(self, the_player):
self.first = True
return self.display_text()
class Scene_2(MapTile):
def scene_init(self):
self.location = 'Scene_2'
self.long_desc = 'This is {}, but noone gives a damn.'.format(self.location)
self.short_desc = 'Eh, I don\'t care, really.'
def display_text(self):
return self.long_desc
def modify_player(self, the_player):
self.first = True
return self.display_text()
player.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
class Player():
'''Base for player'''
def __init__(self):
self.inventory = []
self.hp = 100
self.location_x, self.location_y = 1, 1
self.victory = False
def is_alive(self):
return self.hp >= 0
def do_action(self, action, **kwargs):
action_method = getattr(self, action.method.__name__)
if action_method:
action_method(**kwargs)
def print_inventory(self):
for item in self.inventory:
print(item, 'n')
def move(self, dx, dy):
self.location_x += dx
self.location_y += dy
def move_north(self):
self.move(dx=0, dy=-1)
def move_south(self):
self.move(dx=0, dy=1)
def move_east(self):
self.move(dx=1, dy=0)
def move_west(self):
self.move(dx=-1, dy=0)
action.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from player import Player
class Action():
def __init__(self, method, name, **kwargs):
"""Creates a new action
:param method: the function object to execute
:param name: the name of the action
:param ends_turn: True if the player is expected to move after this action else False
:param hotkey: The keyboard key the player should use to initiate this action
"""
self.method = method
self.name = name
self.kwargs = kwargs
def __str__(self):
return "{}".format(self.name)
class MoveNorth(Action):
def __init__(self):
super().__init__(method=Player.move_north, name='north')
class MoveSouth(Action):
def __init__(self):
super().__init__(method=Player.move_south, name='south')
class MoveEast(Action):
def __init__(self):
super().__init__(method=Player.move_east, name='east')
class MoveWest(Action):
def __init__(self):
super().__init__(method=Player.move_west, name='west')
class ViewInventory(Action):
"""Prints the player's inventory"""
def __init__(self):
super().__init__(method=Player.print_inventory, name='View inventory', hotkey='i')
class Attack(Action):
def __init__(self, enemy):
super().__init__(method=Player.attack, name="Attack", hotkey='a', enemy=enemy)
class Flee(Action):
def __init__(self, tile):
super().__init__(method=Player.flee, name="Flee", hotkey='f', tile=tile)
答案 0 :(得分:4)
command
期望函数名称不带()
和参数。
错误:
command=player.do_action(action, **action.kwargs)
这样您就可以分配command
返回的player.do_action()
值,但此函数会返回None
您必须使用lambda
功能
command=lambda:player.do_action(action, **action.kwargs)
但也许您还需要lambda
中的参数,因为您在for
循环中创建了此参数。
command=lambda act=action, kws=action.kwargs : player.do_action(act, **kws)