Как сделать фон прокруткой вниз - PullRequest
1 голос
/ 09 апреля 2020

Ниже приведен код, над которым я работаю

Как я могу заставить их прокручивать все, что работает нормально, если я не вставляю что-то или пытаюсь сделать фоновый пьяный, когда я делаю это, просто сбой, я пытаюсь создать игру, похожую на galaga, но более современную

import sys
import os
import pygame
from pygame.locals import *
import random

LIGHT_YELLOW = (255, 255, 204)
WHITE = (255, 255, 255)

SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 786
SCOREBOARD_MARGIN = 4

MISSILE_PLATFORM = 62
MISSILE_SPEED = 15
GAME_MISSILES = 20

UFO_UPPER_Y = 20
UFO_LOWER_Y = 240
UFO_HIT_TIME = 20
UFO_OFF_TIME = 60
UFO_SCORE = 50

RANDOM_VERTICAL_CHANGE = 20
RANDOM_HORIZONTAL_CHANGE = 100
UFO_DIRECTIONS = ['left', 'right', 'up', 'down']

RANDOM_RAY = 200
RANDOM_RAY_TIME_MAX = 120
RANDOM_RAY_TIME_MIN = 30

BASE_SPEED = 6

os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.mixer.pre_init(44100, -16, 2, 512)
pygame.mixer.init()
pygame.init()
game_screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Alien Invasion')
pygame.key.set_repeat(10, 20)
clock = pygame.time.Clock()
font = pygame.font.SysFont('Helvetica', 48)

background_image = pygame.image.load('background1.png').convert()
background_image2 = pygame.image.load('background1.png').convert()
base_image = pygame.image.load('base.png').convert_alpha()
missile_image = pygame.image.load('missile1.png').convert_alpha()
missile_fired_image = pygame.image.load('missile2.png').convert_alpha()

ufo_1_image = pygame.image.load('ufo1.png').convert_alpha()
ufo_2_image = pygame.image.load('ufo2.png').convert_alpha()
ufo_1_exploded_image = pygame.image.load('explosion1.png').convert_alpha()
ufo_2_exploded_image = pygame.image.load('explosion2.png').convert_alpha()
ufo_ray_image_1 = pygame.image.load('ray2.png').convert_alpha()
ufo_ray_image_2 = pygame.image.load('ray3.png').convert_alpha()

spaceship_hit_sound = pygame.mixer.Sound('spaceship_hit.ogg')
launch_sound = pygame.mixer.Sound('launch.ogg')

def main():
base_x = SCREEN_WIDTH / 2 - 70
base_y = 550
base_width = base_image.get_rect().width

ufo_width = ufo_1_image.get_rect().width
ufo_height = ufo_1_image.get_rect().height

ray_width = ufo_ray_image_1.get_rect().width

ufo_1_x = SCREEN_WIDTH - ufo_width
ufo_1_y = random.randint(UFO_UPPER_Y, UFO_LOWER_Y)

ufo_1 = {'x_loc': ufo_1_x, 'y_loc': ufo_1_y, 'direction': 'left', 'hit': False, 'hit_time': 0, 'off_time': 0,
         'ray_time': 0, 'speed': 10}

ufo_2_y = random.randint(UFO_UPPER_Y, UFO_LOWER_Y)

ufo_2 = {'x_loc': 0, 'y_loc': ufo_2_y, 'direction': 'right', 'hit': False, 'hit_time': 0, 'off_time': 0,
         'ray_time': 0, 'speed': 5}

missile_x = 0
missile_y = 0
missile_firing = False

missile_width = missile_image.get_rect().width
missile_height = missile_image.get_rect().height

score = 0
hi_score = 0
missiles = GAME_MISSILES
game_over = False

    while True:
        for event in pygame.event.get():
            key_pressed = pygame.key.get_pressed()

            if key_pressed[pygame.K_a]:
                base_x -= BASE_SPEED
                if base_x < 0:
                    base_x = 0

            elif key_pressed[pygame.K_d]:
                base_x += BASE_SPEED
                if base_x > SCREEN_WIDTH - base_width:
                    base_x = SCREEN_WIDTH - base_width

            elif key_pressed[pygame.K_SPACE] and missile_firing is False and game_over is False:
                missile_firing = True
                missile_x = base_x + 58
                missile_y = base_y - missile_height
                missiles -= 1
                launch_sound.play()
                if missiles == 0:
                    game_over = True

            elif key_pressed[pygame.K_RETURN] and game_over is True:
                game_over = False
                score = 0
                missiles = GAME_MISSILES

            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        if missile_firing is True:
            missile_y -= MISSILE_SPEED
            if missile_y < 0:
                missile_firing = False

        move_ufo(ufo_1, ufo_width)
        move_ufo(ufo_2, ufo_width)

        update_ray(ufo_1)
        update_ray(ufo_2)

        missile_rect = pygame.Rect(missile_x, missile_y, missile_width, missile_height)

        if ufo_1.get('hit') is False and missile_firing is True:
            ufo_hit = check_ufo_hit(ufo_1, missile_rect, ufo_width, ufo_height)
            if ufo_hit == 'missile destroyed':
                missile_firing = False
                pygame.mixer.stop()

            elif ufo_hit == 'direct hit':
                missile_firing = False
                score += UFO_SCORE * 2
                ufo_1['hit_time'] = UFO_HIT_TIME
                ufo_1['hit'] = True
                spaceship_hit_sound.play()

        if ufo_2.get('hit') is False and missile_firing is True:
            ufo_hit = check_ufo_hit(ufo_2, missile_rect, ufo_width, ufo_height)

            if ufo_hit == 'missile destroyed':
                missile_firing = False
                pygame.mixer.stop()

            elif ufo_hit == 'direct hit':
                missile_firing = False
                score += UFO_SCORE
                ufo_2['hit_time'] = UFO_HIT_TIME
                ufo_2['hit'] = True
                pygame.mixer.stop()
                spaceship_hit_sound.play()

        update_hit_ufo(ufo_1, SCREEN_WIDTH - ufo_width, 'left')
        update_hit_ufo(ufo_2, 0, 'right')

        game_screen.blit(background_image, [0, 0])

        game_screen.blit(base_image, [base_x, base_y])

        if missile_firing is True:
            game_screen.blit(missile_fired_image, [missile_x, missile_y])

        else:
            game_screen.blit(missile_image, [base_x + MISSILE_PLATFORM, base_y - missile_height])

        if ufo_1.get('hit_time') > 0:
            game_screen.blit(ufo_1_exploded_image, [ufo_1.get('x_loc'), ufo_1.get('y_loc')])

        elif ufo_1.get('hit') is False:
            game_screen.blit(ufo_1_image, [ufo_1.get('x_loc'), ufo_1.get('y_loc')])

        if ufo_2.get('hit_time') > 0:
            game_screen.blit(ufo_2_exploded_image, [ufo_2.get('x_loc'), ufo_2.get('y_loc')])

        elif ufo_2.get('hit') is False:
            game_screen.blit(ufo_2_image, [ufo_2.get('x_loc'), ufo_2.get('y_loc')])

        if ufo_1.get('ray_time') > 0:
            ray_x = ufo_1.get('x_loc') + (ufo_width - ray_width) / 2
            ray_y = ufo_1.get('y_loc') + ufo_height
            if ufo_1.get('ray_time') % 4 == 0 or ufo_1.get('ray_time') % 5 == 0:
                game_screen.blit(ufo_ray_image_2, [ray_x, ray_y])
            else:
                game_screen.blit(ufo_ray_image_1, [ray_x, ray_y])

        if ufo_2.get('ray_time') > 0:
            ray_x = ufo_2.get('x_loc') + (ufo_width - ray_width) / 2
            ray_y = ufo_2.get('y_loc') + ufo_height
            if ufo_2.get('ray_time') % 4 == 0 or ufo_2.get('ray_time') % 5 == 0:
                game_screen.blit(ufo_ray_image_2, [ray_x, ray_y])
            else:
                game_screen.blit(ufo_ray_image_1, [ray_x, ray_y])

        if game_over is True and missile_firing is False:
            if score > hi_score:
                hi_score = score

            display_game_over()

        score_text = 'Score: ' + str(score)
        display_scoreboard_data(score_text, 'left')

        missile_text = 'Missiles: ' + str(missiles)
        display_scoreboard_data(missile_text, 'centre')

        hi_score_text = 'Hi: ' + str(hi_score)
        display_scoreboard_data(hi_score_text, 'right')

        pygame.display.update()
        clock.tick(30)


def move_ufo(ufo, ufo_width):
    if ufo.get('hit') is False:
        if ufo.get('direction') == 'left':
            ufo['x_loc'] -= ufo.get('speed')
        elif ufo.get('direction') == 'right':
            ufo['x_loc'] += ufo.get('speed')
        elif ufo.get('direction') == 'up':
            ufo['y_loc'] -= ufo.get('speed')
        elif ufo.get('direction') == 'down':
            ufo['y_loc'] += ufo.get('speed')

        if ufo.get('x_loc') < 0:
            ufo['x_loc'] = 0
            ufo['direction'] = 'right'

        elif ufo.get('x_loc') > SCREEN_WIDTH - ufo_width:
            ufo['x_loc'] = SCREEN_WIDTH - ufo_width
            ufo['direction'] = 'left'

        elif ufo.get('y_loc') < UFO_UPPER_Y:
            ufo['y_loc'] = UFO_UPPER_Y
            ufo['direction'] = 'down'

        elif ufo.get('y_loc') > UFO_LOWER_Y:
            ufo['y_loc'] = UFO_LOWER_Y
            ufo['direction'] = 'up'

        else:
            if ufo.get('direction') == 'up' or ufo.get('direction') == 'down':
                ufo_direction_chance = random.randint(0, RANDOM_VERTICAL_CHANGE)
            else:
                ufo_direction_chance = random.randint(0, RANDOM_HORIZONTAL_CHANGE)
            if ufo_direction_chance == 1:
                ufo['direction'] = random.choice(UFO_DIRECTIONS)


def update_ray(ufo):
    if ufo.get('ray_time') == 0 and ufo.get('hit') is False:
        random_ray = random.randint(0, RANDOM_RAY)
        if random_ray == 1:
            ufo['ray_time'] = random.randint(RANDOM_RAY_TIME_MIN, RANDOM_RAY_TIME_MAX)

    elif ufo.get('ray_time') > 0:
        ufo['ray_time'] -= 1


def check_ufo_hit(ufo, missile_rect, ufo_width, ufo_height):
    ufo_rect = pygame.Rect(ufo.get('x_loc'), ufo.get('y_loc'), ufo_width, ufo_height)
    if missile_rect.colliderect(ufo_rect):
        if ufo.get('ray_time') == 0:
            ufo_hit = 'direct hit'
        else:
            ufo_hit = 'missile destroyed'
    else:
        ufo_hit = 'no hit'
    return ufo_hit


def update_hit_ufo(ufo, new_x_loc, new_direction):
    if ufo.get('hit_time') > 0:
        ufo['hit_time'] -= 1
        if ufo.get('hit_time') == 0:
            ufo['off_time'] = UFO_OFF_TIME
    elif ufo.get('off_time') > 0:
        ufo['off_time'] -= 1
        if ufo.get('off_time') == 0:
            ufo['y_loc'] = random.randint(UFO_UPPER_Y, UFO_LOWER_Y)
            ufo['x_loc'] = new_x_loc
            ufo['direction'] = new_direction
            ufo['hit'] = False


def display_scoreboard_data(scoreboard_text, alignment):
    display_text = font.render(scoreboard_text, True, LIGHT_YELLOW)
    text_rect = display_text.get_rect()
    text_loc = [0, 0]
    if alignment == 'left':
        text_loc = [SCOREBOARD_MARGIN, SCOREBOARD_MARGIN]
    elif alignment == 'right':
        text_loc = [SCREEN_WIDTH - text_rect.width - SCOREBOARD_MARGIN, SCOREBOARD_MARGIN]
    elif alignment == 'centre':
        text_loc = [(SCREEN_WIDTH - text_rect.width) / 2, SCOREBOARD_MARGIN]
    game_screen.blit(display_text, text_loc)


def display_game_over():
    text_line_1 = font.render('GAME OVER', True, WHITE)
    text_rect_1 = text_line_1.get_rect()
    text_line_1_loc = [(SCREEN_WIDTH - text_rect_1.width) / 2, (SCREEN_HEIGHT / 2) - 16]
    text_line_2 = font.render('Hit RETURN for new game', True, WHITE)
    text_rect_2 = text_line_2.get_rect()
    text_line_2_loc = [(SCREEN_WIDTH - text_rect_2.width) / 2, (SCREEN_HEIGHT / 2) + 40]
    game_screen.blit(text_line_1, text_line_1_loc)
    game_screen.blit(text_line_2, text_line_2_loc)



if __name__ == '__main__':
    main()

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

1 Ответ

1 голос
/ 09 апреля 2020

Таким образом, у вас есть переменная, которая содержит значение y фона. и каждый кадр заставляет y увеличиваться на скорость, а фон на значении y уменьшается. Снова переверните фон, но с помощью y-screen_height, а затем используйте оператор if, чтобы проверить if y == screen_height, если он возвращает y к 0.

Вот пример, который я сделал очень быстро, чтобы убедиться, что он работает.

import pygame

pygame.init()

screen = pygame.display.set_mode((500,500))

background = pygame.Surface((500,500))
background.fill((100,100,100))
pygame.draw.rect(background,(255,0,0),(100,30,40,30))

clock = pygame.time.Clock()

y = 0

while True:
    screen.fill((255,255,255))
    screen.blit(background,(0,y))
    screen.blit(background,(0,y-500))

    pygame.display.update()
    y+= 1
    clock.tick(60)
    if y == 500:
        y = 0

Вверху, где у вас есть все остальные переменные, поместите background_y = 0

Там, где вы перелистываете экран game_screen.blit(background_image, [0, 0]), измените его на

game_screen.blit(background_image,(0,background_y))
game_screen.blit(background_image,(0,background_y - SCREEN_HEIGHT))
background_y += 1
background_y = 0 if background_y >= SCREEN_HEIGHT else background_y

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

...