Python 使用graphics.py和键盘,如何根据键盘输入移动角色?

Python 使用graphics.py和键盘,如何根据键盘输入移动角色?,python,graphics,keyboard,Python,Graphics,Keyboard,我是一个非常初级的python程序员,刚刚开始修补graphics.py,所以请原谅我的代码可能很糟糕。我只想知道如何使用有效的键盘/图形功能。现在如果我运行这个,它不会按我希望的方式移动角色。我想能够按下WASD键,让屏幕上的方块移动 from graphics import * import keyboard point1 = Point(680, 420) point2 = Point(720, 380) class Player: def __init__(self, ch

我是一个非常初级的python程序员,刚刚开始修补graphics.py,所以请原谅我的代码可能很糟糕。我只想知道如何使用有效的键盘/图形功能。现在如果我运行这个,它不会按我希望的方式移动角色。我想能够按下WASD键,让屏幕上的方块移动

from graphics import *
import keyboard

point1 = Point(680, 420)
point2 = Point(720, 380)


class Player:
    def __init__(self, char, window):
        self.p1 = char
        self.win = window

    def create_Player(self):
        self.p1.setFill(color_rgb(0, 255, 0))
        self.p1.draw(self.win)
        self.win.getMouse()
        self.win.close()

    def movement(self):
        global point1, point2
        if keyboard.is_pressed("d"):
            self.p1.move(10, 0)
        if keyboard.is_pressed("a"):
            self.p1.move(-10, 0)
        if keyboard.is_pressed("s"):
            self.p1.move(0, 10)
        if keyboard.is_pressed("w"):
            self.p1.move(0, -10)



p1 = Player(Rectangle(point1, point2), GraphWin("mini graphic game", 1400, 800))
p1.create_Player()
while True:
    p1.movement()

所有GUI都运行事件循环,直到关闭窗口并阻止其他元素为止,您必须学习如何使用此循环

在您的代码中,此循环位于
self.win.getMouse()
中,所以您的循环在关闭窗口后运行

使用来自
self.win.getMouse()
的代码,我创建了自己的循环,该循环运行相同的元素,并使用
self.win.lastKey
获得最后一个单击的键。此时的问题是,该值即使在释放最后一个关键点时也保持不变,所以即使不按关键点,对象也会移动。它使用隐藏的
\u onKey()
,这意味着
onKeyPress
,但代码也需要
\u onkeyprelease()
。也许后来我成功了

顺便说一句:我查过这些信息

from graphics import *
import time

# --- classes ---

class Player:
    def __init__(self, window, char):
        self.p1 = char
        self.win = window

    def create(self):
        self.p1.setFill(color_rgb(0, 255, 0))
        self.p1.draw(self.win)

    def movement(self):
        if self.win.lastKey == "d":
            self.p1.move(10, 0)
        if self.win.lastKey == "a":
            self.p1.move(-10, 0)
        if self.win.lastKey == "s":
            self.p1.move(0, 10)
        if self.win.lastKey == "w":
            self.p1.move(0, -10)

# --- main ---

point1 = Point(680, 420)
point2 = Point(720, 380)

win = GraphWin("mini graphic game", 1400, 800)

p1 = Player(win, Rectangle(point1, point2))
p1.create()

while not win.isClosed():
    p1.movement()

    win.update()
    time.sleep(.1)

win.close()

编辑:当您不按键时停止播放的版本。我添加了
onKeyPress
onkeyrease
来设置
self.keys[“d”]=True/False
中的值,可用于运行和停止播放器

我还添加了随机移动的敌人

from graphics import *
import time
import random

# --- classes ---

class Window(GraphWin):

    def __init__(self, title="Graphics Window",
                 width=200, height=200, autoflush=True):
        super().__init__(title, width, height, autoflush)

        self.bind_all("<KeyPress>",   self._onKeyPress)
        self.bind_all("<KeyRelease>", self._onKeyRelease)

        self.keys = dict() # dictionary for `keys[event.keysym] = True/False`

    def _onKeyPress(self, event):
        self.keys[event.keysym] = True

    def _onKeyRelease(self, event):
        self.keys[event.keysym] = False


class Player:
    def __init__(self, window, char, color):
        self.win = window
        self.rect = char
        self.color = color

        self.rect.setFill(self.color)
        self.rect.draw(self.win)

    def movement(self):
        # use `keys.get("d")` instead of `keys["d"]` because `"d"` may not exists in dictionary `key`
        if self.win.keys.get("d"):
            self.rect.move(10, 0)
        if self.win.keys.get("a"):
            self.rect.move(-10, 0)
        if self.win.keys.get("s"):
            self.rect.move(0, 10)
        if self.win.keys.get("w"):
            self.rect.move(0, -10)

class Enemy:
    def __init__(self, window, rect, color):
        self.win = window
        self.rect = rect
        self.color = color

        self.rect.setFill(self.color)
        self.rect.draw(self.win)

    def movement(self):
        dx = random.randint(-30, 30)
        dy = random.randint(-30, 30)
        self.rect.move(dx, dy)

# --- main ---

point1 = Point(680, 420)
point2 = Point(720, 380)

point3 = Point(180, 420)
point4 = Point(220, 380)

win = Window("mini graphic game", 1400, 800)

player = Player(win, Rectangle(point1, point2), color_rgb(0, 255, 0))
enemies = [Enemy(win, Rectangle(point3, point4), color_rgb(255, 0, 0)) for _ in range(10)]

while not win.isClosed():
    player.movement()
    for e in enemies:
        e.movement()

    win.update()
    time.sleep(.1)

win.close()
从图形导入*
导入时间
随机输入
#---班级---
类窗口(图形窗口):
def _uinit _;(self,title=“图形窗口”,
宽度=200,高度=200,自动冲洗=True):
超级()
self.bind\u all(“,self.\u onKeyPress)
self.bind\u all(“,self.\u onKeyRelease)
self.keys=dict()#`keys[event.keysym]=True/False的字典`
def_onKeyPress(自身,事件):
self.keys[event.keysym]=True
def_onKeyRelease(自身、事件):
self.keys[event.keysym]=False
职业球员:
定义初始化(自、窗口、字符、颜色):
self.win=窗口
self.rect=char
self.color=颜色
self.rect.setFill(self.color)
self.rect.draw(self.win)
def移动(自):
#使用`keys.get(“d”)而不是`keys[“d”]`因为字典`key`中可能不存在`d``
如果self.win.keys.get(“d”):
自校正移动(10,0)
如果self.win.keys.get(“a”):
自校正移动(-10,0)
如果self.win.keys.get(“s”):
自校正移动(0,10)
如果self.win.keys.get(“w”):
自校正移动(0,-10)
阶级敌人:
定义初始化(自、窗口、矩形、颜色):
self.win=窗口
self.rect=rect
self.color=颜色
self.rect.setFill(self.color)
self.rect.draw(self.win)
def移动(自):
dx=random.randint(-30,30)
dy=random.randint(-30,30)
自校正移动(dx,dy)
#---梅因---
点1=点(680420)
点2=点(720380)
点3=点(180420)
点4=点(220380)
win=窗口(“迷你图形游戏”,1400,800)
player=player(赢,矩形(点1,点2),颜色(0,255,0))
敌人=[范围(10)内的敌人(赢,矩形(点3,点4),颜色(255,0,0))]
而不是赢。isClosed():
player.movement()
对于敌人中的e:
e、 运动()
win.update()
时间。睡眠(.1)
赢

所有GUI都有自己的功能来使用鼠标和键,它们不需要模块键盘-我希望在
graphics.py中也有同样的功能。如果我记得
graphics.py
使用模块
tkinter
,该模块具有
bind()
为按键/鼠标事件分配函数。是的,我是一个非常初级的初学者。我试着去读,但我很难理解。我尝试过使用if(self.win.getKey()=“w”),但是它也不起作用。我知道我可能在graphics.py中遗漏了一些东西,但我似乎无法理解。这就是为什么我恢复使用键盘,这似乎更容易理解。您的主要问题是,您不知道每个GUI都运行循环,从系统获取键/鼠标事件并将其发送到小部件,然后重新绘制windget。在您的代码中,self.win.getMouse()
运行这个循环,当您关闭窗口时结束工作-所以关闭窗口后所有的键都在检查-所以它是无用的。可能您同时使用了
getKey
,所以在关闭窗口后检查它。必须以完全不同的方式完成。顺便说一句:你尝试的方法可以在PyGame中工作,因为你必须从头开始编写自己的偶数循环-所以你可以做你想做的-但在GUI中,你使用现有的事件循环,当你创建经典的windows程序时它是可以的,但现在在游戏中。