0

我面临一个逻辑错误,即无论输入如何,精灵都不会移动。
我的代码将在下面,因此没有遗漏任何上下文,它相当短。
有没有更好的方法将精灵从 blit 中移开?
我在某处看到过关于更新精灵或其他类似的东西,它们的作用与简单的 blitting 完全不同。

import pygame
pygame.init()
import random
import math

screen=pygame.display.set_mode([700,400])
black    = (   0,   0,   0)
white    = ( 255, 255, 255)
red      = ( 255,   0,   0)
player_x=350
player_y=200
player_x_vel=0
player_y_vel=0
rot_player=pygame.image

pi=math.pi

class Player(pygame.sprite.Sprite):
    def __init__(self):
        global player
        pygame.sprite.Sprite.__init__(self)
        self.pos=(350,200)
        self.image=pygame.image.load("arrowtest.png").convert()
        self.rect=self.image.get_rect()
        screen=pygame.display.get_surface()
        self.area=screen.get_rect()
        self.speed=10
        self.state="still"
        self.reinit()       

    def reinit(self):
        self.state="still"
        self.movepos=[0,0]

    def update(self):
        newpos=self.rect.move(self.movepos)
        if self.area.contains(newpos):
            self.rect=newpos
        pygame.event.pump()

    def moveup(self):
        self.movepos[1]-=(self.speed)
        self.state="moveup"
    def movedown(self):
        self.movepos[1]+=(self.speed)
        self.state="movedown"
    def moveleft(self):
        self.movepos[0]-=(self.speed)
        self.state="moveleft"
    def moveright(self):
        self.movepos[0]+=(self.speed)
        self.state="moveright"
    def moveupright(self):
        self.movepos[1]-=(self.speed)
        self.movepos[0]+=(self.speed)
    def moveupleft(self):
        self.movepos[1]-=(self.speed)
        self.movepos[0]-=(self.speed)
    def movedownright(self):
        self.movepos[1]+=(self.speed)
        self.movepos[0]+=(self.speed)
    def movedownleft(self):
        self.movepos[1]+=(self.speed)
        self.movepos[0]-=(self.speed)

    def angleplayer(self):
        mouse_pos=pygame.mouse.get_pos()
        dx=mouse_pos[0]-player_x
        dy=mouse_pos[1]-player_y
        rads=math.atan2(-dy, dx)
        rads %= 2*pi
        angle = math.degrees(rads)
        print angle
        rot_player.image=pygame.transform.rotate(player.image, angle-90)

done=False
clock=pygame.time.Clock()

while done==False:

    player = Player()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done=True
        if event.type == pygame.MOUSEBUTTONDOWN:
            fired_pos=pygame.mouse.get_pos()
            fired=True
        if event.type == pygame.KEYDOWN:
            player.angleplayer()
            if event.key == pygame.K_w:
                player.moveup()
            if event.key == pygame.K_s:
                player.movedown()
            if event.key == pygame.K_a:
                player.moveleft()
            if event.key == pygame.K_d:
                player.moveright()

            print "co ords", player_x,player_y
            print "x vel", player_x_vel
            print "y vel", player_y_vel

        if event.type == pygame.KEYUP:
            player.movepos=[0,0]
            player.state="still"
            player.angleplayer()

        screen.fill(white)
        screen.blit(player.image, player.pos)

    clock.tick(20)
    pygame.display.flip()

pygame.quit()

提前致谢

4

2 回答 2

5

首先,您在主循环的每次迭代中都创建一个新播放器:

...
while done == False:
    player = Player()
    ...

您想创建播放器一次,因此将创建移到循环之外:

...
player = Player()
while not done:
    ...

第二:要获取玩家的位置,请使用player.pos

...
screen.blit(player.image, player.pos)
...

但你永远不会更新player.pos(它总是(350,200)),你只会改变self.rect

def update(self):
    newpos=self.rect.move(self.movepos)
    if self.area.contains(newpos):
        self.rect=newpos
    pygame.event.pump()

要么用于player.rect获取玩家位置,要么player.pos相应地更新:

def update(self):
    newpos=self.rect.move(self.movepos)
    if self.area.contains(newpos):
        self.rect = newpos
        self.pos = self.rect.topleft
        # don't call pygame.event.pump() here. Doesn't make any sense :-)

第三,您在函数中更新玩家位置update,但您从未调用它。在绘制玩家之前调用它:

...
while not done:
    ...
    player.update()
    screen.fill(white)
    screen.blit(player.image, player.pos)
...

movepos您可以通过直接设置和删除move...功能来简化代码。

工作示例:

import pygame
pygame.init()
colors = pygame.color.THECOLORS
screen = pygame.display.set_mode([700,400])

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.surface.Surface((32,32))
        self.image.fill(colors['green'])
        self.rect = self.image.get_rect().move(350, 200)
        self.speed = 4

    def update(self):
        dx, dy = self.movepos[0] * self.speed, self.movepos[1] * self.speed
        self.rect = self.rect.move(dx, dy)


done=False
clock = pygame.time.Clock()
player = Player()

while not done:

    if pygame.event.get(pygame.QUIT):
        break

    pressed = pygame.key.get_pressed()
    l, r, u, d = [pressed[k] for k in pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s]
    player.movepos = -l + r, -u + d
    player.update()

    screen.fill(colors['white'])
    screen.blit(player.image, player.rect.topleft)
    pygame.display.flip()

    clock.tick(60)
于 2013-02-11T09:46:07.707 回答
0

你有很多移动功能。尝试将它们组合成一个简单的两个函数类,如下例所示:

class Puck(pygame.sprite.Sprite):
    def __init__(self, image_file, speed, location):
        pygame.sprite.Sprite.__init__(self)  #call Sprite initializer
        self.image = pygame.image.load(image_file)
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = location

两个主要的控制器是 self.rect.left 和 self.rect.top。通过更改它们的值,您可以像本例中那样移动精灵。

#Name of varible# = Puck('#Image File#', [#value of self.rect.left#, value of self.rect.top]

然后您可以使用事件来更改它们,例如:

    for event in pygame.event.get():
    if event.type==pygame.QUIT:
        pygame.quit()
        exit(0)
    elif event.type == pygame.KEYDOWN:
        if event.key == K_UP:
            random.rect.top =random.rect.top - 75
        elif event.key == K_LEFT:
            random.rect.left = random.rect.left - 75
        elif event.key == K_DOWN:
            random.rect.top = random.rect.top + 75
        elif event.key == K_RIGHT:
            randoml.rect.left = randoml.rect.left + 75
        elif event.key == K_w:
            random.rect.top = random.rect.top - 50
        elif event.key == K_a:
            random.rect.left = random.rect.left - 50
        elif event.key == K_s:
            random.rect.top = random.rect.top + 50
        elif event.key == K_d:
            random.rect.left = random.rect.left + 50

这应该能够移动你的精灵。

于 2014-11-11T03:02:55.857 回答