Игрок не двигается - PullRequest
       2

Игрок не двигается

0 голосов
/ 01 сентября 2018

Я пишу игру в pygame, изучая ООП и класс pygame.sprite.Sprite вместе с атрибутами rect, но по какой-то причине после кодирования этого очень простого кода игрок не переходит к справа он перемещается только влево, и без кода обнаружения столкновения он останавливается, когда его координаты равны ширине. Почему это так?

import pygame
import random

width = 800
height = 600

black = (0, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
red = (255, 0, 0)
white = (255, 255, 255)

pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Shmup")
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 40))
        self.image.fill(green)
        self.rect = self.image.get_rect()
        self.rect.centerx = width/2
        self.rect.bottom = height - 10
        self.x_change = 0
        self.speedx = 0.2

    def change_left(self):
        self.x_change += -self.speedx

    def change_right(self):
        self.x_change += self.speedx

    def move_left(self):
        self.rect.x += self.x_change

    def move_right(self):
        self.rect.x += self.x_change

    def stop_move_left(self):
        self.x_change = 0

    def stop_move_right(self):
        self.x_change = 0


player = Player()
all_sprites = pygame.sprite.Group()
all_sprites.add(player)

exitGame = False
while not exitGame:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exitGame = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                player.change_left()
            if event.key == pygame.K_d:
                player.change_right()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                player.stop_move_left()
            if event.key == pygame.K_d:
                player.stop_move_right()

    player.move_left()
    player.move_right()
    screen.fill(white)
    all_sprites.draw(screen)
    pygame.display.update()

pygame.quit()
quit()

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Если вы на самом деле хотите использовать числа с плавающей запятой для движения, вам нужно сохранить фактическую позицию в качестве отдельного атрибута, сначала изменить его при перемещении спрайта, а затем обновить также и прямоугольную позицию (поскольку self.rect используется в качестве блит-позиции).

Рекомендую сохранять фактическое положение и скорость как pygame.math.Vector2 объектов. Затем вы можете просто добавить скорость к вектору положения и установить rect.center (или один из других прямоугольных атрибутов) на новую позицию.

import pygame
from pygame.math import Vector2

width = 800
height = 600

green = (0, 255, 0)
white = (255, 255, 255)

pygame.init()
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 40))
        self.image.fill(green)
        self.rect = self.image.get_rect(midbottom=(width/2, height-10))
        self.pos = Vector2(self.rect.center)
        self.velocity = Vector2(0, 0)

    def update(self):
        self.pos += self.velocity
        self.rect.center = self.pos


player = Player()
all_sprites = pygame.sprite.Group(player)

exitGame = False
while not exitGame:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exitGame = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                player.velocity.x = -0.8
            elif event.key == pygame.K_d:
                player.velocity.x = 0.8
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                player.velocity.x = 0
            elif event.key == pygame.K_d:
                player.velocity.x = 0

    all_sprites.update()  # Calls the `update` methods of the sprites.

    screen.fill(white)
    all_sprites.draw(screen)
    pygame.display.update()
    clock.tick(60)

pygame.quit()
0 голосов
/ 01 сентября 2018

Проблема с вашим кодом в том, что вы только увеличиваете или уменьшаете player.rect.x на 0.2, а pygame сохраняет позиции в виде целых чисел. Если значение player.rect.x установлено на 280 и уменьшено на 0.2, оно должно стать 279.8, но на самом деле оно становится 279 из-за преобразования в целое число! Значение действительно изменяется при перемещении влево, но при движении вправо значение увеличивается на 0.2, но оно просто округляется до исходного значения.

Примечание: из-за того, как функция int() работает в Python, -0.2 округляется до 0, поэтому блок не может перемещаться за границу окна, даже если нет явного "столкновения" обнаружение "код выполняется.

Быстрое и простое решение этой проблемы - изменить значение self.speedx на 1 или больше:

self.speedx = 1

Я надеюсь, что этот ответ помог вам, и если у вас есть какие-либо дополнительные вопросы, касающиеся этого ответа, пожалуйста, не стесняйтесь оставлять комментарии ниже!

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