okay so i'm fairly new to programming and i'm making a game based on the arcade game alien invasion. but i want to make an intro with moving text to show credits at the start because it's fun and good practice to learn. but i cant seem to make it work. i want the text to fly from the side of the screen to middle stop there then fly away again
so here is the function that draws the texts.
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)
and here are the classes that are relevant:
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
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)
i am sorry for the amount of code but because i don't know where the problem lies i want you guys to have all the relevant information so at last here is my main game loop
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()
I found two mistakes in Intro.show_intro()
you add speed before loop but you have to do it inside loop
you add speed to self.i_setting.intro_text_1_pos_x
but you have to add
self.intro_text.display_intro_1.text_rect.x += self.speed self.intro_text.display_intro_1.text_rect_shadow.x += self.speed
Correct version which moves text (and shadow) "A game by:"
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)
There can be another problem - rect.x
can keep only integer values but speed
has value 0.83
so when you add 0.83
then it can be rounded to 1
so it may move faster then you expect - or it can move too far (or may move not so smooth as you expected). If speed will be smaller then 0.5 then it may even round it to 0
so it will not move.
You may have to keep position in separated values as float values, change them and copy to rect.x
only before drawing.
Full code which I run in one file - I removed some imports
and elements which I hadn't (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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.