Пигмей Спрайт Движение глюк - PullRequest
3 голосов
/ 16 января 2020

Я работаю над проектом Pygame, но у меня есть несколько сложностей с движением персонажа. Анимация не синхронизирована c (в плохом смысле), когда я двигаюсь вправо или влево, предполагается, что анимация персонажа плавно движется влево или вправо, но в моем случае, когда движется влево или вправо, я могу по-прежнему видят изображение персонажа, когда персонаж находится в режиме ожидания, следуя за персонажем в движении при ходьбе. У меня также есть проблема, когда мой персонаж прыгает, он не возвращается самостоятельно. Я подправил скорость персонажа и обновил sh скорость экрана, но ничего не помогло. Вот мой код и изображение ниже.

Файл 1. Управляет запуском игры

import sys
import os
import pygame
from game_settings import GameSettings
from knight import Knight


class AlienApocalypse:
    """Overall class to manage game assets and behaviour"""

    def __init__(self):
        """Initialize the game and create game resources"""
        self.walking_step = 6
        pygame.init()
        self.settings = GameSettings()
        # Set up a clock that regulates the FPS of the game window
        self.clock = pygame.time.Clock()
        self.settings.vertical_momentum = 0

        drivers = ['directfb', 'fbcon', 'svgalib']

        found = False
        for driver in drivers:
            if not os.getenv('SDL_VIDEODRIVER'):
                os.putenv('SDL_VIDEODRIVER', driver)
            try:
                pygame.display.init()
            except pygame.error:
                print('Driver: {0} failed.'.format(driver))
                continue
            found = True
            break

        if not found:
            raise Exception('No suitable video driver found!')

        self.screen_window = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Apocalypse")

        """Setting background color"""
        self.background_color = (0, 0, 255)

        self.knight = Knight(self)

    def run_game(self):
        """Start the main loop for the game"""
        while True:
            self.clock.tick(27)
            self._check_events()
            self.knight.update()
            self._update_screen()

    def _check_events(self):
        """Respond to key presses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_event(event)

            elif event.type == pygame.KEYUP:
                self._check_keyup_event(event)

    def _check_keydown_event(self, event):
        """Respond to KEYDOWN presses"""
        if event.key == pygame.K_RIGHT:
            self.knight.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.knight.moving_left = True
        elif event.key == pygame.K_SPACE:
            self.knight.jump_move = True
        elif event.key == pygame.K_q:
            sys.exit()

    def _check_keyup_event(self, event):
        """Respond to KEY releases"""
        if event.key == pygame.K_RIGHT:
            self.knight.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.knight.moving_left = False
        elif event.key == pygame.K_SPACE:
            self.knight.jump_move = False

    def _update_screen(self):
        # Redraw the screen during each pass through the loop.
        self.screen_window.fill(self.settings.background_color)
        self.knight.blitme()

        # Make the most recently drawn screen visible.
        pygame.display.flip()
        self.clock.tick(60)


if __name__ == "__main__":
    """Make a game instance, and run the game"""
    ap = AlienApocalypse()
    ap.run_game()

Файл2. Обрабатывает настройки игры

class GameSettings:
    """This class stores all the game settings"""

    def __init__(self):
        """Initialize the game's settings attributes"""
        # Screen settings
        self.screen_width = 1200
        self.screen_height = 800
        self.background_color = (0, 0, 255)
        self.vertical_momentum = 0

        # Knight settings
        self.knight_speed = 2.5

        # Bullet/Sword settings
        self.bullet_speed = 1.0
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = (255, 60, 60)

Файл 3. Обрабатывает настройки и атрибуты для моего игрового персонажа

import pygame
from pygame.sprite import Sprite


class Knight:
    """A class that manages the character knight"""

    def __init__(self, ap_game):
        """Initialize the knight and set its starting position."""
        self.neg = 0
        self.screen_window = ap_game.screen_window
        self.settings = ap_game.settings
        self.screen_window_rect = ap_game.screen_window.get_rect()

        # Load images for character walking movement
        self.walk_left = [
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/walk_left/walk_left1.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/walk_left/walk_left2.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/walk_left/walk_left3.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/walk_left/walk_left4.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/walk_left/walk_left5.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/walk_left/walk_left6.bmp")
        ]
        self.walk_right = [
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/Walk_right/walk1.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/Walk_right/walk2.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/Walk_right/walk3.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/Walk_right/walk4.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/Walk_right/walk5.bmp"),
            pygame.image.load("/Users/username/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free"
                              "-pixel-art-game-heroes/PNG/Knight/Walk_right/walk6.bmp")
        ]

        # Load the character - Knight knight_idle and get its rect.
        image_file = "/Users/user/Desktop/alien_apocalypse/craftpix-891165-assassin-mage-viking-free-pixel-art" \
                     "-game-heroes/PNG/Knight/Idle/idle1.bmp"

        self.knight_idle = pygame.image.load(image_file)
        self.rect = self.knight_idle.get_rect()

        # Start each new character at the center of the screen.
        self.rect.center = self.screen_window_rect.center

        # Store the decimal value for the knight's horizontal position.
        self.x = float(self.rect.x)
        # Store the decimal value for the `knight's vertical position.
        self.y = float(self.rect.y)

        # Movement flag
        self.moving_right = False
        self.moving_left = False
        self.jump_move = False
        self.walk_count = 0
        self.jump_count = 10

    def update(self):
        """Update the knight's position based on the movement flag."""
        # Update the knight's x value, not the rect
        if self.moving_right and self.rect.right < self.screen_window_rect.right:
            self.x += self.settings.knight_speed

        if self.moving_left and self.rect.left > 0:
            self.x -= self.settings.knight_speed

        if self.jump_move:
            if self.jump_count >= -10:
                self.neg = 1
                if self.jump_count < 0:
                    self.neg = -1
                self.y -= (self.jump_count ** 2) * 0.5 * self.neg
                self.jump_count -= 1
            else:
                self.jump_count = 10

        # Update rect object from self.x.
        self.rect.x = self.x
        # Update rect object from self.y.
        self.rect.y = self.y

    def blitme(self):
        """Draw the character at its current location."""
        self.screen_window.blit(self.knight_idle, self.rect)
        if self.walk_count + 1 >= 18:
            self.walk_count = 0
        if self.moving_left:
            self.screen_window.blit(self.walk_left[self.walk_count // 3], self.rect)
            self.walk_count += 1

        elif self.moving_right:
            self.screen_window.blit(self.walk_right[self.walk_count // 3], self.rect)
            self.walk_count += 1
        else:
            self.screen_window.blit(self.knight_idle, self.rect)

Изображения игрового окна, когда персонаж ходит влево или вправо: персонаж ходьба влево

ходьба влево

1 Ответ

4 голосов
/ 16 января 2020

, но в моем случае, когда он перемещается влево или вправо, я все еще могу видеть изображение персонажа, когда персонаж находится в режиме ожидания, следуя за персонажем в движении при ходьбе.

Это потому, что первым, что вы делаете в Knight.blitme, является рисование персонажа в нерабочем положении. Затем поверх него рисуются левое или правое изображения:

class Knight:
    # [...]

        def blitme(self):
        """Draw the character at its current location."""

        # self.screen_window.blit(self.knight_idle, self.rect) <------ DELETE

        if self.walk_count + 1 >= 18:
            self.walk_count = 0
        if self.moving_left:
            self.screen_window.blit(self.walk_left[self.walk_count // 3], self.rect)
            self.walk_count += 1
        elif self.moving_right:
            self.screen_window.blit(self.walk_right[self.walk_count // 3], self.rect)
            self.walk_count += 1
        else:
            self.screen_window.blit(self.knight_idle, self.rect)


У меня также возникает проблема, когда мой персонаж прыгает, он не возвращается

Прыжки работают, только если клавиша удерживается нажатой, потому что прыжки отменены _check_keyup_event.

Удалить self.knight.jump_move = False из _check_keyup_event:

def _check_keyup_event(self, event):
    """Respond to KEY releases"""
    if event.key == pygame.K_RIGHT:
        self.knight.moving_right = False
    elif event.key == pygame.K_LEFT:
        self.knight.moving_left = False

    # DELETE
    #elif event.key == pygame.K_SPACE:
    #    self.knight.jump_move = False

Но делайте это, когда прыжок закончен:

class Knight:
    # [...]

    def update(self):
        # [...]

         if self.jump_move:
            if self.jump_count >= -10:
                self.neg = 1
                if self.jump_count < 0:
                    self.neg = -1
                self.y -= (self.jump_count ** 2) * 0.5 * self.neg
                self.jump_count -= 1
            else:
                self.jump_count = 10
                self.jump_move = False # <------
...