【问题标题】:Tkinter canvas doesn't show my "player" symbolTkinter 画布没有显示我的“玩家”符号
【发布时间】:2018-08-29 19:58:52
【问题描述】:

我是 Python 的初学者,只想制作一个可以通过键盘上的按键移动的红色方块。但是在我运行这个之后,只出现了绿色画布,没有红色方块。代码如下:

进口:

try:
 import Tkinter
except:
 import tkinter as Tkinter

import time

这里只是一些常量

__author__ = "Brano"

print(__author__)

GAME_WIDTH = 800
GAME_HEIGHT = 600
GAME_BG = 'green'
MOVE_SPEED = 10

带有初始化的主类:

class Game(Tkinter.Tk):
  def __init__(self, *args, **kwargs):
    Tkinter.Tk.__init__(self, *args, **kwargs)
    # Trigger Of Other Functions 
    self.x = GAME_WIDTH/2
    self.y = GAME_HEIGHT/2
    self.create_board()
    self.create_men()
    self.bind('<Any-KeyPress>',self.move)

创建板:

  def create_board(self):
    self.board = Tkinter.Canvas(width=GAME_WIDTH, height=GAME_HEIGHT, 
bg=GAME_BG)
    self.board.pack(padx=10, pady=10)
    return

创建红色方块:

def create_men(self):
    self.men = self.board.create_rectangle(300, 300, 310, 310, fill='red')
    return

按键后移动方块:

def move(self, event=None):
    key = event.keysym
    if key=='Left':
        self.x = MOVE_SPEED
    elif key=='Right':
        self.x = -MOVE_SPEED
    elif key=='Up':
        self.y = MOVE_SPEED
    elif key=='Down':
        self.y = -MOVE_SPEED
    else:
        pass
    return

只是 tkinter 更新:

def TkUpdate(self):
    self.update()
    self.update_idletasks()
    return

我的主要动作更新:

def GameUpdate(self):
    self.board.move(self.men, self.x, self.y)
    return

检查是否导入:

if __name__ == '__main__':
 root=Game(className=" Snake Game ")
 while True:
  root.TkUpdate()
  root.GameUpdate()
  time.sleep(0.09)

else :
 print("U cannot import me !")

Here is the canvas I have

这是全班:

class Game(Tkinter.Tk):
def __init__(self, *args, **kwargs):
    Tkinter.Tk.__init__(self, *args, **kwargs)
    # Trigger Of Other Functions 
    self.x = GAME_WIDTH/2
    self.y = GAME_HEIGHT/2
    self.create_board()
    self.create_men()
    self.bind('<Any-KeyPress>',self.move)

def create_board(self):
    self.board = Tkinter.Canvas(width=GAME_WIDTH, height=GAME_HEIGHT, bg=GAME_BG)
    self.board.pack(padx=10, pady=10)
    return


def create_men(self):
    self.men = self.board.create_rectangle(300, 300, 310, 310, fill='red')
    return

def move(self, event=None):
    key = event.keysym
    if key=='Left':
        self.x = MOVE_SPEED
    elif key=='Right':
        self.x = -MOVE_SPEED
    elif key=='Up':
        self.y = MOVE_SPEED
    elif key=='Down':
        self.y = -MOVE_SPEED
    else:
        pass
    return

def TkUpdate(self):
    self.update()
    self.update_idletasks()
    return

def GameUpdate(self):
    self.board.move(self.men, self.x, self.y)
    return

【问题讨论】:

  • 能否提供一个不分成五十个小片段的代码版本?
  • 给你了
  • 请阅读并遵循有关如何创建minimal reproducible example 的建议,并删除所有重复代码。如果可能的话,我们需要一个单一的、简短的代码块。

标签: python tkinter


【解决方案1】:

避免致电updatesleep。而是使用aftermainloop。您的代码应该使用after 安排您的游戏循环,并在设置完所有内容后进入主循环。然后继续使用after 调用来安排游戏循环。

您的实际问题是您混淆了使用 self.x 和 self.y 作为设置中的位置,但随后将它们用作游戏循环中的相对移动。因此,当您第一次调用GameUpdate 时,您将矩形移动了画布大小的一半,它立即移出视图。下面是一个使用这些作为“人”位置的版本,并在游戏循环中每次使用coords 声明该位置。

import tkinter as tk

GAME_WIDTH = 800
GAME_HEIGHT = 600
GAME_BG = 'green'
MOVE_SPEED = 10
MAN_SIZE = 20

class Game(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        # Trigger Of Other Functions 
        self.x = GAME_WIDTH/2
        self.y = GAME_HEIGHT/2
        self.create_board()
        self.create_men()
        self.bind('<Any-KeyPress>',self.move)

    def create_board(self):
        self.board = tk.Canvas(width=GAME_WIDTH, height=GAME_HEIGHT, bg=GAME_BG)
        self.board.pack(padx=10, pady=10)

    def create_men(self):
        self.men = self.board.create_rectangle((self.x, self.y, self.x + MAN_SIZE, self.y + MAN_SIZE), fill='red', outline='black')

    def move(self, event=None):
        key = event.keysym
        print(key)
        if key=='Left':
            self.x = self.x - MOVE_SPEED
        elif key=='Right':
            self.x = self.x + MOVE_SPEED
        elif key=='Up':
            self.y = self.y - MOVE_SPEED
        elif key=='Down':
            self.y = self.y + MOVE_SPEED
        else:
            pass
        return

    def game_loop(self):
        self.board.coords(self.men, (self.x, self.y, self.x + MAN_SIZE, self.y + MAN_SIZE))
        self.after(10, self.game_loop)

def main():
    game = Game(className="Snake")
    game.after(10, game.game_loop)
    game.mainloop()

if __name__ == '__main__':
    main()

【讨论】:

    猜你喜欢
    • 2021-11-18
    • 2017-07-15
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2023-02-07
    • 2014-12-16
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多