Python 在pygame教程中使用重力时,玩家不会停在屏幕底部边缘

Python 在pygame教程中使用重力时,玩家不会停在屏幕底部边缘,python,pygame,gravity,Python,Pygame,Gravity,我正试图按照这个教程,让我的精灵去底部边缘的屏幕,没有更多。但遵循教程代码,直到它说: 。。。使重力函数如下所示: 即使玩家在使用重力时没有停在屏幕底部边缘。 我试图按照教程中的建议再添加一个ty,教程中说 。。。一个简单的解决方法是,在玩家的精灵到达游戏世界的底部后,在其新的Y位置添加另一个-ty,使其反弹得更高: 因此我的代码如下所示: import pygame import sys import os ''' Objects ''' class Enemy(pygame.sprite.

我正试图按照这个教程,让我的精灵去底部边缘的屏幕,没有更多。但遵循教程代码,直到它说:

。。。使重力函数如下所示:

即使玩家在使用重力时没有停在屏幕底部边缘。 我试图按照教程中的建议再添加一个
ty
,教程中说

。。。一个简单的解决方法是,在玩家的精灵到达游戏世界的底部后,在其新的Y位置添加另一个-ty,使其反弹得更高:

因此我的代码如下所示:

import pygame
import sys
import os
'''
Objects
'''

class Enemy(pygame.sprite.Sprite):
    '''
    Spawn an enemy
    '''

    def __init__(self, x, y, img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images', img))
        #self.image.convert_alpha()
        #self.image.set_colorkey(ALPHA)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.counter = 0

    def move(self):
        '''
        enemy movement
        '''
        distance = 20
        speed = 8

        if self.counter >= 0 and self.counter <= distance:
            self.rect.x += speed
        elif self.counter >= distance and self.counter <= distance * 2:
            self.rect.x -= speed
        else:
            self.counter = 0

        self.counter += 1


class Level:

    def __init__(self):
        self.enemy_list = pygame.sprite.Group()  # create enemy group

    def bad_1(self, lvl, eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
            self.enemy_list.add(enemy)              # add enemy to group
        if lvl == 2:
            print("Level " + str(lvl) )

        return self.enemy_list

    def bad_2(self, lvl, eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'spr.png') # spawn enemy
            self.enemy_list.add(enemy)              # add enemy to group
        if lvl == 2:
            print("Level " + str(lvl) )

        return self.enemy_list

class Player(pygame.sprite.Sprite):
    '''
    Spawn a player
    '''
    def gravity(self):
        self.movey += 3.2 # how fast player falls

        if self.rect.y > worldy and self.movey >= 0:
            self.movey = 0
            self.rect.y = worldy-ty-ty-ty-ty-ty-ty
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.health = 10
        self.frame = 0
        self.images = []
        for i in range(1, 5):
            img = pygame.image.load(
                os.path.join('images', 'hero' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(ALPHA)
            self.images.append(img)
            self.image = self.images[0]
            self.rect = self.image.get_rect()

    def control(self, x, y):
        '''
        control player movement
        '''
        self.movex += x
        self.movey += y

    def update(self):
        '''
        Update sprite position
        '''

        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey

        # moving left
        if self.movex < 0:
            self.frame += 1
            if self.frame > 3 * ani:
                self.frame = 0
            self.image = self.images[self.frame // ani]
        # collisions
        enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
        for enemy in enemy_hit_list:
            self.health -= 1
            print(self.health)

        # moving right
        if self.movex > 0:
            self.frame += 1
            if self.frame > 3 * ani:
                self.frame = 0
            self.image = self.images[(self.frame // ani)]


'''
Setup
'''

worldx = 560
worldy = 420

fps = 40  # frame rate
ani = 4  # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True

BLUE = (25, 25, 200)
BLACK = (23, 23, 23)
WHITE = (254, 254, 254)
ALPHA = (0, 255, 0)

world = pygame.display.set_mode([worldx, worldy])
backdrop = pygame.image.load(os.path.join('images', 'stage.png')).convert()
backdropbox = world.get_rect()
player = Player()  # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10  # how fast to move
l = Level()
eloc = [200,20]
enemy_list = l.bad_1(1, eloc)
eloc = [100,10]
enemy_list = l.bad_2(1, eloc)

'''
Main loop
'''
while main == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            main = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(-steps, 0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(steps, 0)
            if event.key == pygame.K_UP or event.key == ord('w'):
                print('jump')

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(steps, 0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(-steps, 0)
            if event.key == ord('q'):
                pygame.quit()
                sys.exit()
                main = False

#    world.fill(BLACK)
    world.blit(backdrop, backdropbox)
    player.gravity() # check gravity
    player.update()
    player_list.draw(world)  #refresh player position
    enemy_list.draw(world)
    for e in enemy_list:
        e.move()
    pygame.display.flip()
    clock.tick(fps)
worldx = 560
worldy = 420
Traceback (most recent call last):
  File "game.py", line 188, in <module>
    player.gravity() # check gravity
  File "game.py", line 72, in gravity
    self.rect.y = worldy-ty
NameError: name 'ty' is not defined
我得到以下错误:

import pygame
import sys
import os
'''
Objects
'''

class Enemy(pygame.sprite.Sprite):
    '''
    Spawn an enemy
    '''

    def __init__(self, x, y, img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images', img))
        #self.image.convert_alpha()
        #self.image.set_colorkey(ALPHA)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.counter = 0

    def move(self):
        '''
        enemy movement
        '''
        distance = 20
        speed = 8

        if self.counter >= 0 and self.counter <= distance:
            self.rect.x += speed
        elif self.counter >= distance and self.counter <= distance * 2:
            self.rect.x -= speed
        else:
            self.counter = 0

        self.counter += 1


class Level:

    def __init__(self):
        self.enemy_list = pygame.sprite.Group()  # create enemy group

    def bad_1(self, lvl, eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
            self.enemy_list.add(enemy)              # add enemy to group
        if lvl == 2:
            print("Level " + str(lvl) )

        return self.enemy_list

    def bad_2(self, lvl, eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'spr.png') # spawn enemy
            self.enemy_list.add(enemy)              # add enemy to group
        if lvl == 2:
            print("Level " + str(lvl) )

        return self.enemy_list

class Player(pygame.sprite.Sprite):
    '''
    Spawn a player
    '''
    def gravity(self):
        self.movey += 3.2 # how fast player falls

        if self.rect.y > worldy and self.movey >= 0:
            self.movey = 0
            self.rect.y = worldy-ty-ty-ty-ty-ty-ty
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.health = 10
        self.frame = 0
        self.images = []
        for i in range(1, 5):
            img = pygame.image.load(
                os.path.join('images', 'hero' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(ALPHA)
            self.images.append(img)
            self.image = self.images[0]
            self.rect = self.image.get_rect()

    def control(self, x, y):
        '''
        control player movement
        '''
        self.movex += x
        self.movey += y

    def update(self):
        '''
        Update sprite position
        '''

        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey

        # moving left
        if self.movex < 0:
            self.frame += 1
            if self.frame > 3 * ani:
                self.frame = 0
            self.image = self.images[self.frame // ani]
        # collisions
        enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
        for enemy in enemy_hit_list:
            self.health -= 1
            print(self.health)

        # moving right
        if self.movex > 0:
            self.frame += 1
            if self.frame > 3 * ani:
                self.frame = 0
            self.image = self.images[(self.frame // ani)]


'''
Setup
'''

worldx = 560
worldy = 420

fps = 40  # frame rate
ani = 4  # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True

BLUE = (25, 25, 200)
BLACK = (23, 23, 23)
WHITE = (254, 254, 254)
ALPHA = (0, 255, 0)

world = pygame.display.set_mode([worldx, worldy])
backdrop = pygame.image.load(os.path.join('images', 'stage.png')).convert()
backdropbox = world.get_rect()
player = Player()  # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10  # how fast to move
l = Level()
eloc = [200,20]
enemy_list = l.bad_1(1, eloc)
eloc = [100,10]
enemy_list = l.bad_2(1, eloc)

'''
Main loop
'''
while main == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            main = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(-steps, 0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(steps, 0)
            if event.key == pygame.K_UP or event.key == ord('w'):
                print('jump')

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(steps, 0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(-steps, 0)
            if event.key == ord('q'):
                pygame.quit()
                sys.exit()
                main = False

#    world.fill(BLACK)
    world.blit(backdrop, backdropbox)
    player.gravity() # check gravity
    player.update()
    player_list.draw(world)  #refresh player position
    enemy_list.draw(world)
    for e in enemy_list:
        e.move()
    pygame.display.flip()
    clock.tick(fps)
worldx = 560
worldy = 420
Traceback (most recent call last):
  File "game.py", line 188, in <module>
    player.gravity() # check gravity
  File "game.py", line 72, in gravity
    self.rect.y = worldy-ty
NameError: name 'ty' is not defined
回溯(最近一次呼叫最后一次):
文件“game.py”,第188行,在
player.gravity()#检查重力
文件“game.py”,第72行,重力
self.rect.y=世俗
NameError:未定义名称“ty”
我遇到过这个问题,但我不明白代码失败的原因

原始图像来自此处,但为了便于解释,我已在imgur中分开:

内容文件夹图像:

import pygame
import sys
import os
'''
Objects
'''

class Enemy(pygame.sprite.Sprite):
    '''
    Spawn an enemy
    '''

    def __init__(self, x, y, img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images', img))
        #self.image.convert_alpha()
        #self.image.set_colorkey(ALPHA)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.counter = 0

    def move(self):
        '''
        enemy movement
        '''
        distance = 20
        speed = 8

        if self.counter >= 0 and self.counter <= distance:
            self.rect.x += speed
        elif self.counter >= distance and self.counter <= distance * 2:
            self.rect.x -= speed
        else:
            self.counter = 0

        self.counter += 1


class Level:

    def __init__(self):
        self.enemy_list = pygame.sprite.Group()  # create enemy group

    def bad_1(self, lvl, eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
            self.enemy_list.add(enemy)              # add enemy to group
        if lvl == 2:
            print("Level " + str(lvl) )

        return self.enemy_list

    def bad_2(self, lvl, eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'spr.png') # spawn enemy
            self.enemy_list.add(enemy)              # add enemy to group
        if lvl == 2:
            print("Level " + str(lvl) )

        return self.enemy_list

class Player(pygame.sprite.Sprite):
    '''
    Spawn a player
    '''
    def gravity(self):
        self.movey += 3.2 # how fast player falls

        if self.rect.y > worldy and self.movey >= 0:
            self.movey = 0
            self.rect.y = worldy-ty-ty-ty-ty-ty-ty
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.health = 10
        self.frame = 0
        self.images = []
        for i in range(1, 5):
            img = pygame.image.load(
                os.path.join('images', 'hero' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(ALPHA)
            self.images.append(img)
            self.image = self.images[0]
            self.rect = self.image.get_rect()

    def control(self, x, y):
        '''
        control player movement
        '''
        self.movex += x
        self.movey += y

    def update(self):
        '''
        Update sprite position
        '''

        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey

        # moving left
        if self.movex < 0:
            self.frame += 1
            if self.frame > 3 * ani:
                self.frame = 0
            self.image = self.images[self.frame // ani]
        # collisions
        enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
        for enemy in enemy_hit_list:
            self.health -= 1
            print(self.health)

        # moving right
        if self.movex > 0:
            self.frame += 1
            if self.frame > 3 * ani:
                self.frame = 0
            self.image = self.images[(self.frame // ani)]


'''
Setup
'''

worldx = 560
worldy = 420

fps = 40  # frame rate
ani = 4  # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True

BLUE = (25, 25, 200)
BLACK = (23, 23, 23)
WHITE = (254, 254, 254)
ALPHA = (0, 255, 0)

world = pygame.display.set_mode([worldx, worldy])
backdrop = pygame.image.load(os.path.join('images', 'stage.png')).convert()
backdropbox = world.get_rect()
player = Player()  # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10  # how fast to move
l = Level()
eloc = [200,20]
enemy_list = l.bad_1(1, eloc)
eloc = [100,10]
enemy_list = l.bad_2(1, eloc)

'''
Main loop
'''
while main == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            main = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(-steps, 0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(steps, 0)
            if event.key == pygame.K_UP or event.key == ord('w'):
                print('jump')

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(steps, 0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(-steps, 0)
            if event.key == ord('q'):
                pygame.quit()
                sys.exit()
                main = False

#    world.fill(BLACK)
    world.blit(backdrop, backdropbox)
    player.gravity() # check gravity
    player.update()
    player_list.draw(world)  #refresh player position
    enemy_list.draw(world)
    for e in enemy_list:
        e.move()
    pygame.display.flip()
    clock.tick(fps)
worldx = 560
worldy = 420
Traceback (most recent call last):
  File "game.py", line 188, in <module>
    player.gravity() # check gravity
  File "game.py", line 72, in gravity
    self.rect.y = worldy-ty
NameError: name 'ty' is not defined
敌人(精灵)是雪人。png:

背景是stage.png:

以及玩家的形象:

spr.png:

在is上的原始代码中

但是您的代码中没有它,它会给出错误

但是您可以使用
rect.bottom
,然后您可能不需要
ty

def gravity(self):
    self.movey += 3.2  # how fast player falls

    if self.rect.bottom > worldy and self.movey >= 0: # <-- uses bottom
        self.movey = 0
        self.rect.bottom = worldy # <-- uses bottom
降低重力速度也很好,因为在非常大的速度下,它可能会跳到平台下方,而不会检查与平台的碰撞

def gravity(self):
    self.movey += 3.2 # how fast player falls
    #print(self.rect.bottom, worldy)

    # reduce speed so it will not jump out platfrom
    if self.movey >= 15:
        self.movey = 6

    if self.rect.bottom > worldy and self.movey >= 0:
        self.movey = 0
        self.rect.bottom = worldy

    #print(self.rect.bottom, worldy) 
在原始代码中是

但是您的代码中没有它,它会给出错误

但是您可以使用
rect.bottom
,然后您可能不需要
ty

def gravity(self):
    self.movey += 3.2  # how fast player falls

    if self.rect.bottom > worldy and self.movey >= 0: # <-- uses bottom
        self.movey = 0
        self.rect.bottom = worldy # <-- uses bottom
降低重力速度也很好,因为在非常大的速度下,它可能会跳到平台下方,而不会检查与平台的碰撞

def gravity(self):
    self.movey += 3.2 # how fast player falls
    #print(self.rect.bottom, worldy)

    # reduce speed so it will not jump out platfrom
    if self.movey >= 15:
        self.movey = 6

    if self.rect.bottom > worldy and self.movey >= 0:
        self.movey = 0
        self.rect.bottom = worldy

    #print(self.rect.bottom, worldy) 


您在何处定义
ty
?如果它不是全局变量,那么它将不起作用。或者可能是
self.ty
,而不是
ty
。顺便说一句:也许你应该使用
self.rect.y=worldy
或者更好的
self.rect.bottom=worldy
。您还应该比较
bottom
-
if self.rect.bottom>worldy
顺便说一句:在您添加的链接中,您可以看到
ty=64#tile size
,但您的代码中没有它。但是如果您使用
rect.bottom
,那么就不需要
ty
,可能您还有其他问题,或者是作者在原始代码中犯了错误。您可以使用
print(self.rect.y,worldy)
检查
gravity()中变量的值
我运行代码,问题是它检查
如果self.rect.y>worldy
但它应该比较
如果self.rect.y>worldy
或者
如果self.rect.y+ty>worldy
或者更好地使用
bottom
如果self.rect.bottom>worldy在哪里定义
ty
?如果它不是全局变量,那么它将不起作用。或者可能是
self.ty
,而不是
ty
。顺便说一句:也许你应该使用
self.rect.y=worldy
或者更好的
self.rect.bottom=worldy
。您还应该比较
bottom
-
if self.rect.bottom>worldy
顺便说一句:在您添加的链接中,您可以看到
ty=64#tile size
,但您的代码中没有它。但是如果您使用
rect.bottom
,那么就不需要
ty
,可能您还有其他问题,或者是作者在原始代码中犯了错误。您可以使用
print(self.rect.y,worldy)
检查
gravity()中变量的值
我运行代码,问题是它检查
如果self.rect.y>worldy
,但它应该比较
如果self.rect.y>worldy
或者
如果self.rect.y+ty>worldy
或者更好地使用
bottom
如果self.rect.bottom>worldy,可能本教程还有下一部分,因为。我看到一些不完整的元素-我认为它不会停在平台上,等等。。我添加了一些其他更改。我使用
if self.rect.bottom>worldy
,但原始代码使用
if self.rect.y>worldy
,这也会产生问题。我在
gravity()
中添加了注释-在两个地方必须使用
bottom
world ty
。原始代码只在一个地方使用了
world ty
,这就产生了问题。顺便说一句:我给作者发了一条关于这个问题的信息。关于可能有本教程的下一部分,因为…,请参阅此地址顶部,您可以看到本系列中的10个教程。可能有本教程的下一部分,因为。我看到一些不完整的元素-我认为它不会停在平台上,等等。。我添加了一些其他更改。我使用
if self.rect.bottom>worldy
,但原始代码使用
if self.rect.y>worldy
,这也会产生问题。我在
gravity()
中添加了注释-在两个地方必须使用
bottom
world ty
。原始代码只在一个地方使用了
world ty
,这就产生了问题。顺便说一句:我向作者发送了一条消息,提供了有关此问题的信息。关于可能有本教程的下一部分,因为…,请参见此地址顶部的10个教程。