Pygame Game приводит к Segmentation Fault (пигментный парашют) - PullRequest
0 голосов
/ 31 мая 2018

Если вы играете в игру и выигрываете, нажатие на экран приведет к повторной игре.Во второй игре сегментация игры дает сбой через секунду или две.

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

Помощь!

import sys
import os
import pygame
import random
import math


#Force static position of screen
os.environ ['SDL_VIDEO_CENTERED'] = '1'

#constants
BLACK = (0,0,0)
WHITE = (255, 255, 255)
SHIP_WIDTH = 13
SHIP_HEIGHT = 13
SIZE = WIDTH, HEIGHT = 920, 570
TOP_BUFFER = 50
PILL_HEIGHT = 30
PILL_WIDTH = 10
YELLOW = (157, 185, 45)
RED = (185, 45, 45)
BLUE = (45, 115, 185)
GREEN = (5, 94, 16)

#Runs imported module
pygame.init()


class Text:
    def __init__(self, size, text, color, xpos, ypos):
        self.font = pygame.font.SysFont("Britannic Bold", size)
        self.image = self.font.render(text, 1, color)
        self.rect = self.image.get_rect()
        self.rect = self.rect.move(xpos, ypos)

class Ship(pygame.sprite.Sprite):
    def __init__ (self, x, y, side):
        pygame.sprite.Sprite.__init__(self)
        self.density = SHIP_HEIGHT * SHIP_WIDTH
        self.speed = 10
        self.image = pygame.Surface((math.sqrt(self.density), math.sqrt(self.density))).convert()
        self.rect = self.image.get_rect()
        self.rect = self.rect.move(x, y)
        self.type = side
        self.score = Text(30, str(self.density - 169), BLACK, WIDTH / 4 , HEIGHT/ 17)
        self.score_2 = Text(30, str(self.density - 169), BLACK, WIDTH * .75, HEIGHT / 17)

    def update(self, pill_group):
        key = pygame.key.get_pressed()

        if self.type == "left":
            if key[pygame.K_w]:
                self.rect.y -= self.speed
            if key[pygame.K_s]:
                self.rect.y += self.speed
            if key[pygame.K_a]:
                self.rect.x -= self.speed
            if key[pygame.K_d]:
                self.rect.x += self.speed

        if self.type == "left":
            #Boundary Conditions
            if self.rect.right > WIDTH/2:
                self.rect.right = WIDTH/2
            if self.rect.left < 0:
                self.rect.left = 0
            if self.rect.top < 50:
                self.rect.top = 50
            if self.rect.bottom > 570:
                self.rect.bottom = 570


        elif self.type == "right":
            if key[pygame.K_UP]:
                self.rect.y -= self.speed
            if key[pygame.K_DOWN]:
                self.rect.y += self.speed
            if key[pygame.K_LEFT]:
                self.rect.x -= self.speed
            if key[pygame.K_RIGHT]:
                self.rect.x += self.speed

                # Ship 2 boundary conditions
            if self.rect.right > WIDTH:
                self.rect.right = WIDTH
            if self.rect.top < TOP_BUFFER:
                self.rect.top = TOP_BUFFER
            if self.rect.left < WIDTH/2:
                self.rect.left = WIDTH/2
            if self.rect.bottom > HEIGHT:
               self.rect.bottom = HEIGHT

        collisions = pygame.sprite.spritecollide(self, pill_group, True)
        for p in collisions:
            self.density += p.density * 50
            print(self.density)

            self.score.image = self.score.font.render(str(self.density - 169), 1, BLACK)
            self.score_2.image = self.score.font.render(str(self.density), 1, BLACK)

            ##if self.density > 500:
               ##self.play == False


        self.rect.width = self.rect.height = math.sqrt(self.density)
        self.image = pygame.transform.scale(self.image, (self.rect.width, self.rect.height))


class Pill(pygame.sprite.Sprite):
    def __init__(self, xpos, density):
        pygame.sprite.Sprite.__init__(self)
        self.density = density
        self.speed = 3
        self.image = pygame.Surface((PILL_WIDTH, PILL_HEIGHT)).convert()
        self.image.fill(self.set_color())
        self.rect = pygame.Rect(xpos, -PILL_HEIGHT, 10, 30)
        self.rect = self.image.get_rect()
        self.rect = self.rect.move(xpos, HEIGHT/15)

    def set_color(self):
        if self.density == 1:
            return YELLOW
        elif self.density == 2:
            return RED
        elif self.density == 3:
            return BLUE
        elif self.density == 4:
            return GREEN

    def update(self):
        self.rect.y += self.speed

        if self.rect.y > HEIGHT:
            self.kill()


def main():
    #Initialize Local Vars
    size = width, height = 920, 570
    fps = 30
    LeftWins = Text(30, "Left Ship Wins!", BLACK, WIDTH / 2.5, HEIGHT / 2)
    RightWins = Text(30, "Right Ship Wins!", BLACK, WIDTH / 2.5, HEIGHT / 2)
    Winner = Text (30, "Click here to play again", BLACK, WIDTH / 2.6, HEIGHT * .75)
    pygame.display.set_caption('Density')
    screen = pygame.display.set_mode(SIZE, pygame.SRCALPHA)
    clock = pygame.time.Clock()
    play = True
    loop_counter = 0



    vertical = pygame.Surface((1, HEIGHT - TOP_BUFFER)).convert()
    horizontal = pygame.Surface((WIDTH, 1)).convert()


    #Create Game Objects
    ship_left = Ship(WIDTH/4 - SHIP_WIDTH/2, HEIGHT - (4 * SHIP_HEIGHT), "left")
    ship_right = Ship((WIDTH * 3) / 4 - SHIP_WIDTH / 2, HEIGHT - (4 * SHIP_HEIGHT), "right")

    #Create Groups
    ship_group = pygame.sprite.Group()
    ship_group.add(ship_left, ship_right)
    pill_group = pygame.sprite.Group()

    #play = True
    outro = True


    while True:
            #Gameplay
        while play:

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

            if loop_counter % 10 == 0:
                pill = Pill(random.randrange(0, (WIDTH/2) - PILL_WIDTH), int(random.choice('1111111111111111111122222334')))
                pill2 = Pill(random.randrange((WIDTH/2) + PILL_WIDTH, WIDTH - PILL_WIDTH), int(random.choice('1111111111111111111122222334')))
                pill_group.add(pill)
                pill_group.add(pill2)

            #Update Groups
            ship_group.update(pill_group)
            pill_group.update()

            #Draw/Blit Groups
            screen.fill(WHITE)
            screen.blit(ship_left.score.image, ship_left.score.rect)
            screen.blit(ship_right.score_2.image, ship_right.score_2.rect)
            ship_group.draw(screen)
            pill_group.draw(screen)
            screen.blit(vertical, (WIDTH/2, TOP_BUFFER))
            screen.blit(horizontal, (0, TOP_BUFFER))

            #60 / second one pill / 10 iterations
            loop_counter += 1

            #Limits frames per iteration of while loop
            clock.tick(60)
            # Writes to main surface
            pygame.display.flip()

            if (ship_left.density >= 500 or ship_right.density >= 500):
                play = False

        while outro:
            for event in pygame.event.get():
                if event.type == pygame.QUIT: sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN or pygame.key.get_pressed()[pygame.K_RETURN != 0]:
                    outro = False
                    play = True
                    ship_left.density = 0
                    ship_right.density = 0
                    for p in pill_group:
                        p.kill()
                    ship_left = Ship(WIDTH / 4 - SHIP_WIDTH / 2, HEIGHT - (4 * SHIP_HEIGHT), "left")
                    ship_right = Ship((WIDTH * 3) / 4 - SHIP_WIDTH / 2, HEIGHT - (4 * SHIP_HEIGHT), "right")
                    screen.blit(ship_left.image, ship_left.rect)
                    screen.blit(ship_right.image, ship_right.rect)

            #Draw/Blit Groups
            screen.fill(WHITE)

            if (ship_left.density >= 500):
                screen.blit(LeftWins.image, LeftWins.rect)
                screen.blit(Winner.image, Winner.rect)

            if (ship_right.density >= 500):
                screen.blit(RightWins.image, RightWins.rect)
                screen.blit(Winner.image, Winner.rect)

            #Limits frames per iteration of while loop
            clock.tick(60)

            # Writes to main surface
            pygame.display.flip()


if __name__ == "__main__":

    main()

1 Ответ

0 голосов
/ 31 мая 2018

Один из способов решить эту проблему (но, возможно, не самый лучший) - переместить код настройки в цикл while True и выбросить код сброса в while outro:

def main():
    # The setup code from here ...
    while True:
        # Goes here

            #Gameplay
        while play:
            # The Gameplay code

        while outro:
            for event in pygame.event.get():
                if event.type == pygame.QUIT: sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN or pygame.key.get_pressed()[pygame.K_RETURN != 0]:
                    outro = False

            #Draw/Blit Groups
            screen.fill(WHITE)
            # The reset of outro
...