У меня проблемы с лагом в этой простой игре, которую я сделал в Pygame, Python 3. Как я могу это исправить? - PullRequest
2 голосов
/ 07 октября 2019

Я программировал свою игру без лагов и проблем. Внезапно, когда я добавил свое вступление, игра начала отставать.

Я пытался создать много функций и заменить многие числа переменными. Я удалил вступление, и игра все еще отстала.

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

import pygame
import sys
import random

pygame.init()

pygame.display.set_caption("Game Draft")


clock = pygame.time.Clock()


# Variables 

width = 500
height = 500

LightBlue = (0, 150, 215)
Pink = (215, 0, 100)
Green = (51, 204, 51)
Black = (0, 0, 0)
Blue = (0,0,255)
Yellow = (255, 255, 0)
White = (255, 255, 255)

background_color = (102, 204, 255)
scoreboard_color = (255,255,255)
plataform_color =  (153, 102, 51)
intro_background = (128, 128, 128)


player_name = "Neme"
player_color = (0, 0, 0)
player_size = 20
player_vel_x = 20
player_vel_y = 10
player_pos = [width/2, height - (2 * player_size)]

enemy_color = (102, 51, 0)
enemy_size = 20
enemy_vel_x = 20
enemy_vel_y = 5
enemy_pos = [random.randint(0, width-enemy_size), (24 / 25 * height)]
enemy_list = [enemy_pos]
enemy_dif = 4
enemy_dif_increase = 2
enemy_amount = 30

prop_color = (0, 51, 204)
prop_size = 1
prop_vel_y = 5
prop_vel_x = 5
prop_pos = [random.randint(0, width - prop_size), (21 / 25 * height)]
prop_list = [prop_pos]
prop_dif = 4
prop_dif_increase = 2
prop_amount = 50

intro_size1 = 50
intro_size2 = 40
intro_sentence1 = "Welcome to Game Draft"
intro_sentence2 = "Press key to start!"
scoreboard_font = pygame.font.SysFont("monoface", 50)
ign_font = pygame.font.SysFont("monoface", player_size)
intro_font1 = pygame.font.SysFont("monoface", intro_size1)
intro_font2 = pygame.font.SysFont("monoface", intro_size2)

score = 0

#Velocity Functions
def player_level_y(score, player_vel_y):

    pvy = player_vel_y
    sc = score
    if sc < 100:
        pvy = player_size*.25
    elif sc < 200:
        pvy = player_size*.5
    elif sc < 300:
        pvy = player_size*.75
    elif sc < 400:
        pvy = player_size
    elif sc < 500:
        pvy = player_size*1.25
    else:
        pvy = player_size * 1.25
    return pvy

def player_level_x(score, player_vel_x):

    sc = score
    pvx = player_vel_x
    if sc < 100:
        pvx = player_size/2
    elif sc < 200:
        pvx = player_size*.75
    elif sc < 300:
        pvx = player_size*1
    elif sc < 400:
        pvx = player_size*1.15
    elif sc < 500:
        pvx = player_size*1.25
    else:
        pvx = player_size * 1.25
    return pvx

def enemy_level_y(score, enemy_vel_y):

    sc = score
    evy = enemy_vel_y
    if sc < 100:
        evy = enemy_dif + enemy_dif_increase*1
    elif sc < 300:
        evy = enemy_dif + enemy_dif_increase*2
    elif sc < 500:
        evy = enemy_dif + enemy_dif_increase*3
    elif sc < 700:
        evy = enemy_dif + enemy_dif_increase*4
    elif sc < 1500:
        evy = enemy_dif + enemy_dif_increase*5
    else:
        evy = enemy_dif + enemy_dif_increase*6
    return enemy_vel_y

#Enemey Functions
def drop_enemies(enemy_list):
    delay = random.random()
    if len(enemy_list) < enemy_amount and delay < 0.1:
        x_pos = random.randint(0, width - enemy_size)
        y_pos = enemy_size
        enemy_list.append([x_pos, y_pos])

def draw_enemies(enemy_list):
    for enemy_pos in enemy_list:
        pygame.draw.rect(screen, enemy_color, (enemy_pos[0], enemy_pos[1], enemy_size, enemy_size))

def update_enemy_pos(enemy_list, score):
    for idx, enemy_pos in enumerate(enemy_list):
        if enemy_pos[1] >= 0 and enemy_pos[1] <= height:
            enemy_pos[1] += enemy_vel_y
        else:
            enemy_list.pop(idx)
            score += 5
    return score

# Prop Functions
def drop_props(prop_list):
    delay = random.random()
    if len(prop_list) < prop_amount and delay < 0.1:
        x_pos = random.randint(0, width - prop_size)
        y_pos = prop_size
        prop_list.append([x_pos, y_pos])

def draw_props(prop_list):
    for prop_pos in prop_list:
        pygame.draw.rect(screen, prop_color, (prop_pos[0], prop_pos[1], width/20, prop_size))

def update_prop_pos(prop_list):
    for idx, prop_pos in enumerate(prop_list):
        if prop_pos[1] >= 0 and prop_pos[1] <= height:
            prop_pos[1] += prop_vel_y
        else:
            prop_list.pop(idx)


# Boarder Functions
def boarder_left(player_pos):
    if player_pos[0] <= 0 - player_size:
        return True
    return False

def boarder_right(player_pos):
    if player_pos[0] >= width:
        return True
    return False

def boarder_down(player_pos):
    if player_pos[1] >= height - player_size:
        return True
    return False

# Game_Over Functions
def collision_check(enemy_list, player_pos):
    for enemy_pos in enemy_list:
        if detect_collision(enemy_pos, player_pos):
            return True
    return False

def detect_collision(player_pos, enemy_pos):
    p_x = player_pos[0]
    p_y = player_pos[1]

    e_x = enemy_pos[0]
    e_y = enemy_pos[1]

    if (e_x >= p_x and e_x < (p_x + enemy_size)) or (p_x >= e_x and p_x < (e_x + player_size)):
        if (e_y >= p_y and e_y < (p_y + enemy_size)) or (p_y >= e_y and p_y < (e_y + player_size)):
            return True
    return False

#Winning Function
def winning(player_pos):
    if player_pos[1] <= 0 - player_size:
        return True
    return False


# Intro Screen
screen = pygame.display.set_mode((width, height))

intro = True

while intro:
    pygame.time.delay(100)

    for event in pygame.event.get():
        keys = pygame.key.get_pressed()

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

        elif event.type == pygame.KEYDOWN:
            intro = False

    screen.fill(intro_background)

    welcome = str(intro_sentence1)
    tfs1 = intro_font1.render(welcome, 1, White)
    screen.blit(tfs1, (width/4 - intro_size1, height/3))

    welcome = str(intro_sentence2)
    tfs1 = intro_font2.render(welcome, 1, White)
    screen.blit(tfs1, (width/4 - intro_size2, height/2))

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


# Game Screen

screen = pygame.display.set_mode((width, height))

game_over = False
run = True

while run:
    pygame.time.delay(100)

    for event in pygame.event.get():
        keys = pygame.key.get_pressed()

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

        elif event.type == pygame.KEYDOWN:

            x = player_pos[0]
            y = player_pos[1]
            if keys[pygame.K_a] or keys[pygame.K_LEFT]:
                x -= player_vel_x
            elif keys[pygame.K_d] or keys[pygame.K_RIGHT]:
                x += player_vel_x
            elif keys[pygame.K_s] or keys[pygame.K_DOWN]:
                y += player_vel_y
            elif keys[pygame.K_w] or keys[pygame.K_UP]:
                y -= player_vel_y

            elif keys[pygame.K_PERIOD]:
                enemy_dif += 1
            elif keys[pygame.K_COMMA]:
                enemy_dif -= 1


            player_pos = [x,y]


    screen.fill(background_color)

    drop_enemies(enemy_list)
    drop_props(prop_list)

    score = update_enemy_pos(enemy_list, score)

    player_vel_y = player_level_y(score, player_vel_y)
    player_vel_x = player_level_x(score, player_vel_x)
    enemy_vel_y = enemy_level_y(score, enemy_vel_y)
    update_prop_pos(prop_list)



    if boarder_left(player_pos):
        player_pos[0] = width - player_size/2

    if boarder_right(player_pos):
        player_pos[0] = 0 - player_size/2

    if boarder_down(player_pos):
        player_pos[1] = height - player_size

    if winning(player_pos):
        enemy_amount = 0
        enemy_vel_y = 0
        player_pos[1] = 0


    if collision_check(enemy_list, player_pos):
        game_over = True
        break

    pygame.draw.rect(screen, plataform_color, (0, 0, width, height - (23 / 25 * height) ) )
    pygame.draw.rect(screen, player_color, (player_pos[0], player_pos[1], player_size, player_size))
    draw_enemies(enemy_list)
    draw_props(prop_list)


    scoreboard = str(score)
    tfs2 = scoreboard_font.render(scoreboard, 1, scoreboard_color)
    screen.blit(tfs2, (width - 125, height - ( .98 * height)))

    ign = str(player_name)
    tfs3 = ign_font.render(ign, 1, White)
    screen.blit(tfs3, (player_pos[0] - player_size/4, player_pos[1] + player_size))


    clock.tick(60)

    pygame.display.update()

Нет ошибок, просто случайное отставание.

1 Ответ

2 голосов
/ 07 октября 2019

[...] нужна помощь, чтобы выяснить, почему моя игра так сильно отстает [...]

Конечно, чего вы ожидаете? У вас задержка в игровом цикле 0,1 секунды:

pygame.time.delay(100)

Удалите задержку, используйте pygame.time.Clock, чтобы установить скорость игры.
Далее переместите код, который выводит игрока из цикла событий в главном цикле приложения для плавного движения:

while run:
    #pygame.time.delay(100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    # <--
    keys = pygame.key.get_pressed()
    x = player_pos[0]
    y = player_pos[1]
    if keys[pygame.K_a] or keys[pygame.K_LEFT]:
        x -= player_vel_x
    elif keys[pygame.K_d] or keys[pygame.K_RIGHT]:
        x += player_vel_x
    elif keys[pygame.K_s] or keys[pygame.K_DOWN]:
        y += player_vel_y
    elif keys[pygame.K_w] or keys[pygame.K_UP]:
        y -= player_vel_y

    elif keys[pygame.K_PERIOD]:
        enemy_dif += 1
    elif keys[pygame.K_COMMA]:
        enemy_dif -= 1

    player_pos = [x,y]

    # [...]

    clock.tick(30)
...