Pygame Rect не меняет позицию, пока я даю ей новую позицию и обновляю ее - PullRequest
0 голосов
/ 20 февраля 2020

хорошо, так что я довольно новичок в программировании, и я делаю игру, основанную на аркадной игре Alien Invasion. но я хочу сделать вступление с движущимся текстом, чтобы показать кредиты в начале, потому что это весело и хорошая практика, чтобы учиться. но я не могу заставить его работать. я хочу, чтобы текст летел с боковой стороны экрана до середины, а затем снова улетел

, так что вот функция, которая др aws тексты.

from Settings import *
import sys

class TextsObjects:
def __init__(self):
    self.setting = Settings()
    self.intro_settings = IntroSettings()

    self.display_intro_1 = DisplayText(
        self.intro_settings.intro_text_1,
        self.intro_settings.intro_text_1_pos_x,
        self.intro_settings.intro_text_1_pos_y,
        self.intro_settings.font_size,
        self.setting.light_grey
        )

    self.display_intro_2 = DisplayText(
        self.intro_settings.intro_text_2,
        self.intro_settings.intro_text_2_pos_x,
        self.intro_settings.intro_text_2_pos_y,
        self.intro_settings.font_size,
        self.setting.light_grey
        )

    self.display_intro_title = DisplayText(
        self.intro_settings.intro_text_title,
        self.intro_settings.intro_text_title_pos_x,
        self.intro_settings.intro_text_title_pos_y,
        self.intro_settings.font_size,
        self.setting.light_grey)


class Intro:
    def __init__(self, screen, setting):
        self.screen = screen
        self.setting = setting
        self.i_setting = IntroSettings()
        self.intro_text = TextsObjects()
        self.clock = pygame.time.Clock()
        self.speed = 50 * setting.time
        self.screen_c_left = setting.screen_width / 2 - self.speed / 2
        self.screen_c_right = setting.screen_width / 2 + self.speed / 2

    def intro_update(self):
        # reset the background so you don't get multiple drawings onscreen
        self.screen.fill(self.setting.dark_blueish)

        if 0 <= self.i_setting.intro_text_1_pos_x <= \
                self.setting.screen_width:

            # Draw the first text
            self.intro_text.display_intro_1.draw_me_with_shadow(
                    self.screen)

        if self.screen_c_left < self.i_setting.intro_text_2_pos_x < \
                self.screen_c_right:

            # Draw the second text
            self.intro_text.display_intro_2.draw_me_with_shadow(
                self.screen)

        pygame.display.update()

    def show_intro(self):
        self.i_setting.intro_text_1_pos_x += self.speed
        # show the intro for self.intro_time amount of time
        for frames in range(0, self.setting.fps * 3):
            # test for events
            for event in pygame.event.get():
                print(event)
                # when the window is closed stop the game loop
                if event.type == pygame.QUIT:
                    sys.exit()

            self.intro_update()
            self.setting.clock.tick(self.setting.fps)

и здесь классы, которые имеют отношение моя основная игра l oop

import pygame
from Settings import *
from Entities import *
from Game_functions import *
from Menu import *

# make the modules available
setting = Settings()

screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
pygame.display.set_caption("Alien Invasion, By Mark Olieman")

intro = Intro(screen, setting)
player = Player(screen, setting)
bullet = Bullet(screen, setting, player)
intro_set = IntroSettings()

# initizialize pygame
pygame.init()
pygame.mixer.init()

# initizialize the screen and set a caption


# function to start gaming
def gaming():
    bullets = pygame.sprite.Group()
    intro.show_intro()
    intro_set.intro_text_1_pos_x += intro.speed
    print(intro_set.intro_text_1_pos_x)
    # Game Loop
    while True:
        # check events and make actions happen
        events(bullets, player, screen, setting)

        # update everything and draw bullets
        update(player, setting, bullets, screen)

        # update screen at certain fps
        pygame.display.update()
        setting.clock.tick(setting.fps)


# Start the game
gaming()

# Stop the game
pygame.quit()

1 Ответ

1 голос
/ 20 февраля 2020

Я обнаружил две ошибки в Intro.show_intro()

  1. вы добавляете скорость раньше, чем l oop, но вы должны сделать это внутри l oop

  2. вы добавляете скорость к self.i_setting.intro_text_1_pos_x, но вы должны добавить

    self.intro_text.display_intro_1.text_rect.x += self.speed
    self.intro_text.display_intro_1.text_rect_shadow.x += self.speed
    

Правильная версия, которая перемещает текст (и тень) "Игра от:"

def show_intro(self):

    #self.i_setting.intro_text_1_pos_x += self.speed

    # show the intro for self.intro_time amount of time
    for frames in range(0, self.setting.fps * 3):
        # test for events
        for event in pygame.event.get():
            print(event)
            # when the window is closed stop the game loop
            if event.type == pygame.QUIT:
                sys.exit()

        # you have to add speed inside loop
        #self.i_setting.intro_text_1_pos_x += self.speed
        self.intro_text.display_intro_1.text_rect.x += self.speed
        self.intro_text.display_intro_1.text_rect_shadow.x += self.speed

        self.intro_update()
        self.setting.clock.tick(self.setting.fps)

Может быть еще одна проблема - rect.x может содержать только целые значения, но speed имеет значение 0.83, поэтому при добавлении 0.83 его можно округлить до 1 поэтому он может двигаться быстрее, чем вы ожидаете - или он может двигаться слишком далеко (или может двигаться не так гладко, как вы ожидали). Если скорость будет меньше 0,5, то она может даже округлить ее до 0, поэтому она не будет двигаться.

Возможно, вам придется сохранять положение в разделенных значениях как значения с плавающей запятой, изменять их и копировать в rect.x только перед рисованием.


Полный код, который я запускаю в одном файле - я удалил некоторые imports и элементы, которых у меня не было (ie, Player)

import sys

class TextsObjects:
    def __init__(self):
        self.setting = Settings()
        self.intro_settings = IntroSettings()

        self.display_intro_1 = DisplayText(
            self.intro_settings.intro_text_1,
            self.intro_settings.intro_text_1_pos_x,
            self.intro_settings.intro_text_1_pos_y,
            self.intro_settings.font_size,
            self.setting.light_grey
            )

        self.display_intro_2 = DisplayText(
            self.intro_settings.intro_text_2,
            self.intro_settings.intro_text_2_pos_x,
            self.intro_settings.intro_text_2_pos_y,
            self.intro_settings.font_size,
            self.setting.light_grey
            )

        self.display_intro_title = DisplayText(
            self.intro_settings.intro_text_title,
            self.intro_settings.intro_text_title_pos_x,
            self.intro_settings.intro_text_title_pos_y,
            self.intro_settings.font_size,
            self.setting.light_grey)


class Intro:
    def __init__(self, screen, setting):
        self.screen = screen
        self.setting = setting
        self.i_setting = IntroSettings()
        self.intro_text = TextsObjects()
        self.clock = pygame.time.Clock()
        self.speed = 150 * setting.time
        print(self.speed)
        self.screen_c_left = setting.screen_width / 2 - self.speed / 2
        self.screen_c_right = setting.screen_width / 2 + self.speed / 2

    def intro_update(self):
        # reset the background so you don't get multiple drawings onscreen
        self.screen.fill(self.setting.dark_blueish)

        if 0 <= self.i_setting.intro_text_1_pos_x <= self.setting.screen_width:

            # Draw the first text
            self.intro_text.display_intro_1.draw_me_with_shadow(self.screen)

        if self.screen_c_left < self.i_setting.intro_text_2_pos_x < self.screen_c_right:

            # Draw the second text
            self.intro_text.display_intro_2.draw_me_with_shadow(self.screen)

        pygame.display.update()

    def show_intro(self):
        #self.i_setting.intro_text_1_pos_x += self.speed

        # show the intro for self.intro_time amount of time
        for frames in range(0, self.setting.fps * 3):
            # test for events
            for event in pygame.event.get():
                print(event)
                # when the window is closed stop the game loop
                if event.type == pygame.QUIT:
                    sys.exit()

            #self.i_setting.intro_text_1_pos_x += self.speed
            self.intro_text.display_intro_1.text_rect.x += self.speed
            self.intro_text.display_intro_1.text_rect_shadow.x += self.speed

            self.intro_update()
            self.setting.clock.tick(self.setting.fps)


class Settings:
    def __init__(self):

        # screen size
        self.screen_width = 800
        self.screen_height = 500

        # set clock and fps
        self.clock = pygame.time.Clock()
        self.fps = 60
        # calculate the seconds in every frame
        self.time = 1 / self.fps

        self.light_grey = (128,128,128)
        self.dark_blueish = (0,0,255)

class IntroSettings:
    def __init__(self):
        self.setting = Settings()
        self.font_size = 100
        self.timer_font_size = 10

        self.intro_text_1_pos_x = (self.setting.screen_width / 2) - 100
        self.intro_text_1_pos_y = \
            (self.setting.screen_height / 2 - self.font_size)
        self.intro_text_1 = "A game by:"

        self.intro_text_2_pos_x = (self.setting.screen_width / 2)
        self.intro_text_2_pos_y = \
            (self.setting.screen_height / 2 + self.font_size)
        self.intro_text_2 = "Mark Olieman"

        self.intro_text_title_pos_x = (self.setting.screen_width / 2)
        self.intro_text_title_pos_y = (self.setting.screen_height + self.font_size)
        self.intro_text_title = "Alien Invasion!"

        self.intro_text_timer_pos_x = 20
        self.intro_text_timer_pos_y = 20

        self.speed = -2


class DisplayText:
    def __init__(self, text, pos_x, pos_y, font_size, text_color):

        self.font = pygame.font.Font("freesansbold.ttf", font_size)

        self.text_surf = self.font.render(text, True, text_color)
        self.text_rect = self.text_surf.get_rect()
        self.text_rect.center = (pos_x, pos_y)

        self.shadow_color = (0, 0, 0)

        self.text_surf_shadow = self.font.render(text, True, self.shadow_color)
        self.text_rect_shadow = self.text_surf.get_rect()
        self.text_rect_shadow.center = (pos_x + 10, pos_y + 5)

    def draw_me(self, screen):
        screen.blit(self.text_surf, self.text_rect)

    def draw_me_with_shadow(self, screen):
        screen.blit(self.text_surf_shadow, self.text_rect_shadow)
        screen.blit(self.text_surf, self.text_rect)

import pygame
#from Entities import *
#from Game_functions import *
#from Menu import *

# initizialize pygame
pygame.init()
pygame.mixer.init()

# make the modules available
setting = Settings()

screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
pygame.display.set_caption("Alien Invasion, By Mark Olieman")

intro = Intro(screen, setting)
#player = Player(screen, setting)
#bullet = Bullet(screen, setting, player)
intro_set = IntroSettings()

# initizialize the screen and set a caption


# function to start gaming
def gaming():
    bullets = pygame.sprite.Group()
    intro.show_intro()
    intro_set.intro_text_1_pos_x += intro.speed
    print(intro_set.intro_text_1_pos_x)
    # Game Loop
    while True:
        # check events and make actions happen
        #events(bullets, player, screen, setting)

        # update everything and draw bullets
        #update(player, setting, bullets, screen)

        # update screen at certain fps
        pygame.display.update()
        setting.clock.tick(setting.fps)

# Start the game
gaming()

# Stop the game
pygame.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...