Python 在PyGame中移动对象并获取单个输入
我正在用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.
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()