跳转验证码无法使用y轴(pygame)

时间:2018-02-12 20:23:58

标签: python python-3.x pygame

当验证玩家的状态(跑步,跳跃,空转)时,跳跃会覆盖它们,因为y轴速度(代码包含矢量)虽然没有移动(我认为)但不会停止。

跳转验证码:

if self.vel.y != 0:
   self.jumping = True
else:
   self.jumping = False

空转验证码:

if self.vel.x == 0 and self.vel.y == 0:
   self.jumping = False
   self.running = False

运行验证码:

keys = pg.key.get_pressed()

if keys[pg.K_a] or keys[pg.K_d] and not self.jumping:
    self.running = True
 else:
    self.running = False

还有其他方法可以验证玩家是否在跳跃吗?

当删除此代码时,没有更多的跳跃动画,但是空闲工作正常,在删除代码之前,空闲根本不起作用,但运行有或没有代码。 我已经尝试过指向重要​​的位,然后它们都会通过。

我正在使用此代码为播放器制作动画,动画代码完美无缺。

以下是Player类和Wall类的所有代码:

sprites.py

import pygame as pg
from settings import *
import os
vec = pg.math.Vector2


game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, 'img')
animation_folder = os.path.join(img_folder, 'animations')

class Sprite_sheet:
    def __init__(self, filename):
        self.sprite_sheet = pg.image.load(os.path.join(animation_folder, filename)).convert()

    def get_image(self, x, y, width, height):
        image = pg.Surface((width, height))
        image.blit(self.sprite_sheet, (0,0), (x, y, width, height))
        return image


def collide_hit_rect(one, two):
    return one.hit_rect.colliderect(two.rect)


def collide_with_walls(sprite, group, dir):
    if dir == 'x':
        hits = pg.sprite.spritecollide(sprite, group, False, collide_hit_rect)
        if hits:
            if hits[0].rect.centerx > sprite.hit_rect.centerx:
                sprite.pos.x = hits[0].rect.left - sprite.hit_rect.width / 2
            if hits[0].rect.centerx < sprite.hit_rect.centerx:
                sprite.pos.x = hits[0].rect.right + sprite.hit_rect.width / 2
            sprite.vel.x = 0
            sprite.hit_rect.centerx = sprite.pos.x
    if dir == 'y':
        hits = pg.sprite.spritecollide(sprite, group, False, collide_hit_rect)
        if hits:
            if hits[0].rect.centery > sprite.hit_rect.centery:
                sprite.pos.y = hits[0].rect.top - sprite.hit_rect.height / 2
            if hits[0].rect.centery < sprite.hit_rect.centery:
                sprite.pos.y = hits[0].rect.bottom + sprite.hit_rect.height / 2
            sprite.vel.y = 0
            sprite.hit_rect.centery = sprite.pos.y


class Player(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.load_images()
        self.image = self.standing_frames_r[0]
        self.rect = self.image.get_rect()
        self.x = x * TILESIZE
        self.y = y * TILESIZE
        self.rect.center = (x, y)
        self.hit_rect = PLAYER_HIT_RECT
        self.hit_rect.center = self.rect.center
        self.vel = vec(0, 0)
        self.pos = vec(x, y)
        self.jumping = False
        self.running = False
        self.current_frame = 0
        self.last_update = 0
        self.idle_right = True
        self.idle_left = False
        self.falling_right = True
        self.falling_left = False

    def load_images(self):
        #idle right
        self.spritesheet_idle = Sprite_sheet('idle.png')
        self.standing_frames_r = [self.spritesheet_idle.get_image(0, 0, 19, 34),
                                  self.spritesheet_idle.get_image(19, 0, 19, 34),
                                  self.spritesheet_idle.get_image(38, 0, 19, 34),
                                  self.spritesheet_idle.get_image(57, 0, 19, 34),
                                  self.spritesheet_idle.get_image(76, 0, 19, 34),
                                  self.spritesheet_idle.get_image(95, 0, 19, 34),
                                  self.spritesheet_idle.get_image(114, 0, 19, 34),
                                  self.spritesheet_idle.get_image(133, 0, 19, 34),
                                  self.spritesheet_idle.get_image(152, 0, 19, 34),
                                  self.spritesheet_idle.get_image(171, 0, 19, 34),
                                  self.spritesheet_idle.get_image(190, 0, 19, 34),
                                  self.spritesheet_idle.get_image(209, 0, 19, 34)]
        for frame in self.standing_frames_r:
            frame.set_colorkey(BLACK)

        # idle left
        self.standing_frames_l = []
        for frame in self.standing_frames_r:
            self.standing_frames_l.append(pg.transform.flip(frame, True, False))
            frame.set_colorkey(BLACK)

        # walk right
        self.spritesheet_walk = Sprite_sheet('walk.png')
        self.walk_frames_r = [self.spritesheet_walk.get_image(0, 0, 21, 33),
                              self.spritesheet_walk.get_image(21, 0, 21, 33),
                              self.spritesheet_walk.get_image(42, 0, 21, 33),
                              self.spritesheet_walk.get_image(63, 0, 21, 33),
                              self.spritesheet_walk.get_image(84, 0, 21, 33),
                              self.spritesheet_walk.get_image(105, 0, 21, 33),
                              self.spritesheet_walk.get_image(126, 0, 21, 33),
                              self.spritesheet_walk.get_image(147, 0, 21, 33)]
        for frame in self.walk_frames_r:
            frame.set_colorkey(BLACK)

        # walk left
        self.walk_frames_l = []
        for frame in self.walk_frames_r:
            self.walk_frames_l.append(pg.transform.flip(frame, True, False))
            frame.set_colorkey(BLACK)

        # falling right
        self.spritesheet_falling = Sprite_sheet('falling.png')
        self.falling_frames_r = [self.spritesheet_falling.get_image(0, 0, 20, 35),
                                 self.spritesheet_falling.get_image(20, 0, 20, 35)]
        for frame in self.falling_frames_r:
            frame.set_colorkey(BLACK)

        # falling left
            self.falling_frames_l = []
        for frame in self.falling_frames_r:
            self.falling_frames_l.append(pg.transform.flip(frame, True, False))

    def jump(self):
        self.hit_rect.y += 1
        hits = pg.sprite.spritecollide(self, self.game.walls, False, collide_hit_rect)
        self.hit_rect.y -= 1
        if hits:
            self.vel.y = -6

    def animate(self):
        # determining the direction
        if self.vel.x > 0:
            self.idle_right = True
            self.idle_left = False
            self.falling_right = True
            self.falling_left = False
        if self.vel.x < 0:
            self.idle_right = False
            self.idle_left = True
            self.falling_right = False
            self.falling_left = True

        now = pg.time.get_ticks()
        keys = pg.key.get_pressed()
        # Testing for the states

        if self.vel.y != 0:
            self.jumping = True
            self.running = False
        elif keys[pg.K_a] or keys[pg.K_d]:
            self.running = True
            self.jumping = False
        elif self.vel.y == 0:
            self.jumping = False
        else:
            self.jumping = False
            self.running = False

        # Animating (changing the image)
        if self.jumping:
            if now - self.last_update > 150:
                self.last_update = now
                self.current_frame = (self.current_frame + 1) % len(self.falling_frames_r)
                bottom = self.rect.bottom
                if self.falling_right:
                    self.image = self.falling_frames_r[self.current_frame]
                elif self.falling_left:
                    self.image = self.falling_frames_l[self.current_frame]
                self.rect.bottom = bottom

        if not self.jumping and not self.running:
            if now - self.last_update > 200:
                bottom = self.rect.bottom
                self.last_update = now
                self.current_frame = (self.current_frame + 1) % len(self.standing_frames_r)
                if self.idle_left:
                    self.image = self.standing_frames_l[self.current_frame]
                elif self.idle_right:
                    self.image = self.standing_frames_r[self.current_frame]
                self.rect.bottom = bottom

        if self.running:
            if now - self.last_update > 100:
                self.last_update = now
                self.current_frame = (self.current_frame + 1) % len(self.walk_frames_r)
                bottom = self.rect.bottom
                if self.vel.x > 0:
                    self.image = self.walk_frames_r[self.current_frame]
                else:
                    self.image = self.walk_frames_l[self.current_frame]
                self.rect.bottom = bottom

    def update(self):
        self.animate()
        self.acc = vec(0, PLAYER_GRAV)
        keys = pg.key.get_pressed()
        if keys[pg.K_a]:
            self.acc.x = -PLAYER_ACC
        if keys[pg.K_d]:
            self.acc.x = PLAYER_ACC
        if keys[pg.K_SPACE]:
            self.jump()
        self.acc.x += self.vel.x * PLAYER_FRICTION
        self.vel += self.acc
        self.pos += self.vel + 0.5 * self.acc

        self.hit_rect.centerx = self.pos.x
        collide_with_walls(self, self.game.walls, 'x')
        self.hit_rect.centery = self.pos.y
        collide_with_walls(self, self.game.walls, 'y')
        self.rect.center = self.hit_rect.center


class Wall(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites, game.walls
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.image = pg.Surface((TILESIZE, TILESIZE))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.x = x
        self.y = y
        self.rect.x = x * TILESIZE
        self.rect.y = y * TILESIZE

感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

我修复了您的代码,以便回答您的​​问题并解决您的问题。跳跃验证现在有效,这就是你的问题所在。但我认为代码的其他部分需要修复,但我会留给你。

我对代码所做的更改:

  • 摆脱self.hit_rect的所有用途。我不知道为什么你需要这个以及它为什么被使用。在所有情况下,我只是将其更改为self.rect。据我所知,你真的只需要一个rect

  • 我在collide_with_walls函数中注释掉了一些代码。我还删除了与hit_rect相关的代码行。每当根据return True中是否有任何精灵时,我也会使用return Falsehits这个函数。这样做是为了允许稍后在update方法中使用代码。

    • 现在根据玩家是否与墙壁发生碰撞来设置self.vel.y变量。我通过加速来评论大部分代码,以简化一些事情。我添加了一些,但你会把剩下的留给你。

    • update方法中,hit_rect不再使用。

这是固定代码:

<强> sprites.py

import pygame as pg
from settings import *
import os
vec = pg.math.Vector2


game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, 'img')
animation_folder = os.path.join(img_folder, 'animations')

class Sprite_sheet:
    def __init__(self, filename):
        self.sprite_sheet = pg.image.load(os.path.join(animation_folder, filename)).convert()

    def get_image(self, x, y, width, height):
        image = pg.Surface((width, height))
        image.blit(self.sprite_sheet, (0,0), (x, y, width, height))
        return image


def collide_hit_rect(one, two):
    return one.rect.colliderect(two.rect)


def collide_with_walls(sprite, group, dir):
    if dir == 'x':
        hits = pg.sprite.spritecollide(sprite, group, False, collide_hit_rect )
        if hits:
            # if hits[0].rect.centerx > sprite.rect.centerx:
                # sprite.pos.x = hits[0].rect.left - sprite.rect.width / 2
            # if hits[0].rect.centerx < sprite.rect.centerx:
                # sprite.pos.x = hits[0].rect.right + sprite.rect.width / 2
            sprite.vel.x = 0
            return True

    if dir == 'y':
        hits = pg.sprite.spritecollide(sprite, group, False, collide_hit_rect)
        if hits:
            # if hits[0].rect.centery > sprite.rect.centery:
                # sprite.pos.y = hits[0].rect.top - sprite.rect.height / 2
            # if hits[0].rect.centery < sprite.rect.centery:
                # sprite.pos.y = hits[0].rect.bottom + sprite.rect.height / 2
            sprite.vel.y = 0    
            return True

    if hits == []:
        return False
    elif hits != []:
        return True 


class Player(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.load_images()
        self.image = self.standing_frames_r[0]
        self.rect = self.image.get_rect()
        self.x = x * TILESIZE
        self.y = y * TILESIZE
        self.rect.center = (x, y)


        self.vel = vec(0, 0)
        self.pos = vec(x, y)
        self.jumping = False
        self.running = False
        self.current_frame = 0
        self.last_update = 0
        self.idle_right = True
        self.idle_left = False
        self.falling_right = True
        self.falling_left = False

        # hit_rect

    def load_images(self):
        #idle right
        self.spritesheet_idle = Sprite_sheet('idle.png')
        self.standing_frames_r = [self.spritesheet_idle.get_image(0, 0, 19, 34),
                                  self.spritesheet_idle.get_image(19, 0, 19, 34),
                                  self.spritesheet_idle.get_image(38, 0, 19, 34),
                                  self.spritesheet_idle.get_image(57, 0, 19, 34),
                                  self.spritesheet_idle.get_image(76, 0, 19, 34),
                                  self.spritesheet_idle.get_image(95, 0, 19, 34),
                                  self.spritesheet_idle.get_image(114, 0, 19, 34),
                                  self.spritesheet_idle.get_image(133, 0, 19, 34),
                                  self.spritesheet_idle.get_image(152, 0, 19, 34),
                                  self.spritesheet_idle.get_image(171, 0, 19, 34),
                                  self.spritesheet_idle.get_image(190, 0, 19, 34),
                                  self.spritesheet_idle.get_image(209, 0, 19, 34)]
        for frame in self.standing_frames_r:
            frame.set_colorkey(BLACK)

        # idle left
        self.standing_frames_l = []
        for frame in self.standing_frames_r:
            self.standing_frames_l.append(pg.transform.flip(frame, True, False))
            frame.set_colorkey(BLACK)

        # walk right
        self.spritesheet_walk = Sprite_sheet('walk.png')
        self.walk_frames_r = [self.spritesheet_walk.get_image(0, 0, 21, 33),
                              self.spritesheet_walk.get_image(21, 0, 21, 33),
                              self.spritesheet_walk.get_image(42, 0, 21, 33),
                              self.spritesheet_walk.get_image(63, 0, 21, 33),
                              self.spritesheet_walk.get_image(84, 0, 21, 33),
                              self.spritesheet_walk.get_image(105, 0, 21, 33),
                              self.spritesheet_walk.get_image(126, 0, 21, 33),
                              self.spritesheet_walk.get_image(147, 0, 21, 33)]
        for frame in self.walk_frames_r:
            frame.set_colorkey(BLACK)

        # walk left
        self.walk_frames_l = []
        for frame in self.walk_frames_r:
            self.walk_frames_l.append(pg.transform.flip(frame, True, False))
            frame.set_colorkey(BLACK)

        # falling right
        self.spritesheet_falling = Sprite_sheet('falling.png')
        self.falling_frames_r = [self.spritesheet_falling.get_image(0, 0, 20, 35),
                                 self.spritesheet_falling.get_image(20, 0, 20, 35)]
        for frame in self.falling_frames_r:
            frame.set_colorkey(BLACK)

        # falling left
            self.falling_frames_l = []
        for frame in self.falling_frames_r:
            self.falling_frames_l.append(pg.transform.flip(frame, True, False))

    def jump(self):
        self.rect.y += 1
        hits = pg.sprite.spritecollide(self, self.game.walls, False, collide_hit_rect)
        self.rect.y -= 1
        if hits:
            print("Jump")
            self.vel.y = -30


    def animate(self):
        # determining the direction
        if self.vel.x > 0:
            self.idle_right = True
            self.idle_left = False
            self.falling_right = True
            self.falling_left = False
        if self.vel.x < 0:
            self.idle_right = False
            self.idle_left = True
            self.falling_right = False
            self.falling_left = True

        now = pg.time.get_ticks()
        keys = pg.key.get_pressed()
        # Testing for the states

        if self.vel.y != 0:
            self.jumping = True
            self.running = False
        elif keys[pg.K_a] or keys[pg.K_d]:
            self.running = True
            self.jumping = False
        elif self.vel.y == 0:
            self.jumping = False
        else:
            self.jumping = False
            self.running = False

        print(self.jumping)

        # Animating (changing the image)
        if self.jumping:
            if now - self.last_update > 150:
                self.last_update = now
                self.current_frame = (self.current_frame + 1) % len(self.falling_frames_r)
                bottom = self.rect.bottom
                if self.falling_right:
                    self.image = self.falling_frames_r[self.current_frame]
                elif self.falling_left:
                    self.image = self.falling_frames_l[self.current_frame]
                self.rect.bottom = bottom

        if not self.jumping and not self.running:
            if now - self.last_update > 200:
                bottom = self.rect.bottom
                self.last_update = now
                self.current_frame = (self.current_frame + 1) % len(self.standing_frames_r)
                if self.idle_left:
                    self.image = self.standing_frames_l[self.current_frame]
                elif self.idle_right:
                    self.image = self.standing_frames_r[self.current_frame]
                self.rect.bottom = bottom

        if self.running:
            if now - self.last_update > 100:
                self.last_update = now
                self.current_frame = (self.current_frame + 1) % len(self.walk_frames_r)
                bottom = self.rect.bottom
                if self.vel.x > 0:
                    self.image = self.walk_frames_r[self.current_frame]
                else:
                    self.image = self.walk_frames_l[self.current_frame]
                self.rect.bottom = bottom

    def update(self):
        self.animate()

        self.acc = vec(0, PLAYER_GRAV)

        keys = pg.key.get_pressed()

        if keys[pg.K_a]:
            self.acc.x = -PLAYER_ACC
        if keys[pg.K_d]:
            self.acc.x = PLAYER_ACC

        self.acc.x += self.vel.x * PLAYER_FRICTION

        if collide_with_walls(self, self.game.walls, 'y'):
            # print("Colliding")
            self.vel.y = 0
            self.acc.y = 0
        else:
            # print("Falling")
            self.vel.y = 2

        if keys[pg.K_SPACE]:
            self.jump()

        if self.vel.y > 0:
            self.vel.y += PLAYER_GRAV

        self.pos += self.vel + 0.5 * self.acc

        self.rect.centerx = self.pos.x
        self.rect.centery = self.pos.y


class Wall(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites, game.walls
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.image = pg.Surface((TILESIZE, TILESIZE))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.x = x
        self.y = y
        self.rect.x = x * TILESIZE
        self.rect.y = y * TILESIZE

我希望这个答案可以帮助您,如果您在下面发表评论时遇到任何其他问题!

答案 1 :(得分:0)

您可以在一个地方合并州检查代码以防止竞争条件吗?

if self.vel.y != 0:
    self.jumping = True
    self.running = False
elif keys[pg.K_a] or keys[pg.K_d]:
    # perhaps modify self.vel.x here?
    self.running = True
    self.jumping = False
else:  # must be idle here
    self.running = False
    self.jumping = False