Python 在PyGame中移动对象并获取单个输入

Python 在PyGame中移动对象并获取单个输入,python,pygame,Python,Pygame,我正在用PyGame创建一个游戏,我需要拿起一个盘子在厨房里移动。到目前为止,我已经设法让玩家与物体发生碰撞和交互,但无法拾取和移动屏幕上的物体。我已经在这个问题上纠缠了好几个星期,任何帮助都将不胜感激 def new(self): self.plate = pg.sprite.Group() for tile_object in self.map.tmxdata.objects: if tile_object.name == 'plate': self.

我正在用PyGame创建一个游戏,我需要拿起一个盘子在厨房里移动。到目前为止,我已经设法让玩家与物体发生碰撞和交互,但无法拾取和移动屏幕上的物体。我已经在这个问题上纠缠了好几个星期,任何帮助都将不胜感激

def new(self):
  self.plate = pg.sprite.Group()
  for tile_object in self.map.tmxdata.objects:
    if tile_object.name == 'plate':
            self.plate.x = tile_object.x
            self.plate.y = tile_object.y
            Plate(self, self.plate.x, self.plate.y)
touch=False
如果(tx-32)=x和(ty-64)=y:
触摸=真实
elif(ty-32)=y和(tx-64)=x:
触摸=真实
返回(触摸)
def更新(自我):
self.all_sprites.update()
x=self.player.pos[0]
y=self.player.pos[1]
持有=0
按键按下=self.get\u pg\u事件()```
touch=self.grid_位置(self.player.pos[0],self.player.pos[1],self.plate.x,self.plate.y)
如果touch==True:
self.space\u bar\u plate.resposition(self.player.pos[0],self.player.pos[1]+64)
keys=pg.key.get_pressed()
如果键[pg.K_空格]:
now=pg.time.get_ticks()
如果现在-self.player.last_action>action_RATE:
self.player.last_action=现在
self.plate.x=math.cos(self.player.rot*math.pi/180)*80+self.player.pos[0]
self.plate.y=math.sin(self.player.rot*math.pi/180)*80+self.player.pos[1]
self.plate=plate(self,self.plate.x,self.plate.y)
其他:
自我空间板重新定位(-32,0)```
在我的精灵文件中
类别牌(第页雪碧、雪碧):
定义初始化(self,game,x,y):
self.groups=game.all_精灵,game.plate
pg.sprite.sprite.\uuuu init\uuuu(self,self.groups)
self.game=游戏
self.image=game.plate\u img
self.rect=self.image.get_rect()
self.pos=(x,y)
self.rect.center=self.pos
def重新定位(自身、x、y):
self.pos=(x,y)
self.rect.center=self.pos

首先跟踪是否单击并将变量更改为True:

if event.type == pygame.MOUSEBUTTONDOWN:
    clicked = True
如果释放鼠标,则重置此变量:

elif event.type == pygame.MOUSEBUTTONUP:
    clicked = False
然后再次在pygame循环中,通过以下方式跟踪鼠标位置:

elif event.type == pygame.MOUSEMOTION:
    if clicked:
        x, y = pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]

然后,当你点击图像时,你可以使用这些x和y值来进行操作。

下面是一个简单的例子,说明如何进行类似操作。使用W、A、S、D移动黑匣子,使用空格拾取和放下黑匣子

import pygame

RESOLUTION = 800, 600
TILESIZE = 32
PLAYER_SPEED = 200
FPS = 60

class Player(pygame.sprite.Sprite):
    def __init__(self, pos, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((TILESIZE, TILESIZE))
        self.image.fill('dodgerblue')
        self.rect = self.image.get_rect(center=pos)
        self.pos = pygame.Vector2(pos)
        self.movement = pygame.Vector2()
        self.item = None

    def update(self, dt, events):
        pressed = pygame.key.get_pressed()
        self.movement.x, self.movement.y = 0, 0
        if pressed[pygame.K_w]: self.movement.y = -1
        if pressed[pygame.K_a]: self.movement.x = -1
        if pressed[pygame.K_s]: self.movement.y =  1
        if pressed[pygame.K_d]: self.movement.x =  1
        if self.movement.length() > 0:
            self.movement.normalize_ip()
        self.pos += self.movement * dt * PLAYER_SPEED
        self.rect.center = self.pos

        if self.item:
            self.item.pos += self.movement * dt * PLAYER_SPEED
            self.item.rect.center = self.item.pos

        for e in events:
            if e.type == pygame.KEYDOWN and e.key == pygame.K_SPACE:
                self.pick_up() if not self.item else self.drop()

    def pick_up(self):
        collisions = pygame.sprite.spritecollide(self, self.groups()[0], False)
        items = list(s for s in collisions if hasattr(s, 'can_be_picked_up') and s.can_be_picked_up)
        if items:
            self.item = items[0]

    def drop(self):
        self.item = None

class Plate(pygame.sprite.Sprite):
    def __init__(self, pos, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((TILESIZE, TILESIZE))
        self.image.fill('black')
        self.rect = self.image.get_rect(center=pos)
        self.pos = pygame.Vector2(pos)
        self.can_be_picked_up = True

def main():
    pygame.init()
    screen = pygame.display.set_mode(RESOLUTION)
    dt, clock = 0, pygame.time.Clock()
    sprites = pygame.sprite.Group()
    Player((400, 300), sprites)
    Plate((200, 200), sprites)
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
        screen.fill('grey')
        sprites.update(dt, events)
        sprites.draw(screen)
        pygame.display.flip()
        dt = clock.tick(FPS) / 1000

if __name__ == "__main__":
    main()

如您所见,在
播放器的
更新
功能中,我们检查空格是否被按下。然后我们检查我们是否已经持有物品

如果是,我们就放弃它

如果没有,我们将检查当前碰撞的所有精灵,并首先将
可以拾取的精灵设置为
True
(您不必这样做,但为什么不这样做),然后拾取它

拾取它只意味着将其设置为
self.item
,然后在玩家的
update
方法中更新其位置

当然,有多种方法可以做到这一点;但我认为这与您试图在代码中执行的操作非常相似

import pygame

RESOLUTION = 800, 600
TILESIZE = 32
PLAYER_SPEED = 200
FPS = 60

class Player(pygame.sprite.Sprite):
    def __init__(self, pos, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((TILESIZE, TILESIZE))
        self.image.fill('dodgerblue')
        self.rect = self.image.get_rect(center=pos)
        self.pos = pygame.Vector2(pos)
        self.movement = pygame.Vector2()
        self.item = None

    def update(self, dt, events):
        pressed = pygame.key.get_pressed()
        self.movement.x, self.movement.y = 0, 0
        if pressed[pygame.K_w]: self.movement.y = -1
        if pressed[pygame.K_a]: self.movement.x = -1
        if pressed[pygame.K_s]: self.movement.y =  1
        if pressed[pygame.K_d]: self.movement.x =  1
        if self.movement.length() > 0:
            self.movement.normalize_ip()
        self.pos += self.movement * dt * PLAYER_SPEED
        self.rect.center = self.pos

        if self.item:
            self.item.pos += self.movement * dt * PLAYER_SPEED
            self.item.rect.center = self.item.pos

        for e in events:
            if e.type == pygame.KEYDOWN and e.key == pygame.K_SPACE:
                self.pick_up() if not self.item else self.drop()

    def pick_up(self):
        collisions = pygame.sprite.spritecollide(self, self.groups()[0], False)
        items = list(s for s in collisions if hasattr(s, 'can_be_picked_up') and s.can_be_picked_up)
        if items:
            self.item = items[0]

    def drop(self):
        self.item = None

class Plate(pygame.sprite.Sprite):
    def __init__(self, pos, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((TILESIZE, TILESIZE))
        self.image.fill('black')
        self.rect = self.image.get_rect(center=pos)
        self.pos = pygame.Vector2(pos)
        self.can_be_picked_up = True

def main():
    pygame.init()
    screen = pygame.display.set_mode(RESOLUTION)
    dt, clock = 0, pygame.time.Clock()
    sprites = pygame.sprite.Group()
    Player((400, 300), sprites)
    Plate((200, 200), sprites)
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
        screen.fill('grey')
        sprites.update(dt, events)
        sprites.draw(screen)
        pygame.display.flip()
        dt = clock.tick(FPS) / 1000

if __name__ == "__main__":
    main()