0

I'm working on a game project with Pygame. I'm only just beginning to work on the project and I'm kind of stuck. I have made three files each containing code to perform different functions. The first file - "alien_apocalypse.py"contains the class 'AlienApocalypse', which serves to start and monitor user events in the game and contains a few imported modules such as the game settings (which is the 2nd file - 'game_settings.py') and the a class file which contains the all the attributes of one of the game characters 'knight.py'. I'm trying to run "alien_apocalypse.py" which is meant to display my character-knight and the bottom middle of the display but nothing shows up. I'm running it on a Mac with macOS Mojave, IDE is PyCharm. Here are the files:

  • File 1 - "alien_apocalypse.py":
import sys
import os
import pygame
from game_settings import GameSettings
from knight import Knight


class AlienApocalypse:
    """Overall class to manage game assets and behaviour"""

    def __init__(self):
        """Initialize the game and create game resources"""
        pygame.init()
        self.settings = GameSettings()

        drivers = ['directfb', 'fbcon', 'svgalib']

        found = False
        for driver in drivers:
            if not os.getenv('SDL_VIDEODRIVER'):
                os.putenv('SDL_VIDEODRIVER', driver)
            try:
                pygame.display.init()
            except pygame.error:
                print('Driver: {0} failed.'.format(driver))
                continue
            found = True
            break

        if not found:
            raise Exception('No suitable video driver found!')

        self.screen_window = pygame.display.set_mode((2880, 1800))
        pygame.display.set_caption("Alien Apocalypse")

        """Setting background color"""
        self.background_color = (230, 230, 255)

        self.knight = Knight(self)

    def run_game(self):
        """Start the main loop for the game"""
        while True:
            # Watch for keyboard and mouse actions
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()

            # Redraw the screen during each pass through the loop.
            self.screen_window.fill(self.settings.background_color)
            self.knight.blitme()

            # Make the most recently drawn screen visible.
            pygame.display.flip()


if __name__ == "__main__":
    """Make a game instance, and run the game"""
    ac = AlienApocalypse()
    ac.run_game()


  • File 2 - game_settings.py
class GameSettings:
    """This class stores all the game settings"""

    def __init__(self):
        """Initialize the game's settings attributes"""
        # Screen settings
        self.screen_width = 2880
        self.screen_height = 1800
        self.background_color = (230, 230, 255)

  • File 3 knight.py
import pygame


class Knight:
    """A class that manages the character knight"""

    def __init__(self, ac_game):
        """Initialize the knight and set its starting position."""
        self.screen_window = ac_game.screen_window
        self.screen_window_rect = ac_game.screen_window.get_rect()

        # Load the character - Knight image and get its rect.
        image_file = "/Users/johnphillip/Downloads/craftpix-891165-assassin" \
                     "-mage-viking-free-pixel-art-game-heroes/PNG/Knight" \
                     "/knight.bmp "
        self.image = pygame.image.load(image_file)
        self.rect = self.image.get_rect()

        # Start each new character at the bottom center of the screen.
        self.rect.midbottom = self.screen_window_rect.midbottom

    def blitme(self):
        """Draw the character at its current location."""
        self.screen_window.blit(self.image, self.rect)

Jon Fillip
  • 101
  • 3
  • 10
  • Hi! I think the problem is that you have to set proper driver (os.putenv('SDL_VIDEODRIVER', driver) and initialize display (pygame.display.init()). Take a look to this: http://www.karoltomala.com/blog/?p=679. If you are running on windows, use this: drivers = ['windib', 'directx'] – Kalma Dec 30 '19 at 12:06

1 Answers1

0

Issues I detected so far (now the window is displayed):

  • You have to set proper video driver

  • Then you have to initialize pygame.display

  • You were calling the run_game() function inside the class (ac.run_game()), not the other.

  • The run_game() inside the class does nothing (pass)

  • You have to replace the current run_game() inside the class with the one which is outside, so you can access "self things" like variables and functions.

  • You can not equal self to None as default value if not present (self is the class itself and everything it contains, so if you equal it to None you are "killing" yourself (the class)!!!)

Your alien_apocalypse.py could look like this:

import pygame
from game_settings import GameSettings
from knight import Knight

class AlienApocalypse:
"""Overall class to manage game assets and behaviour"""

def __init__(self):
    """Initialize the game and create game resources"""
    pygame.init()
    self.settings = GameSettings()

    drivers = ['windib', 'directx']

    found = False
    for driver in drivers:
        if not os.getenv('SDL_VIDEODRIVER'):
            os.putenv('SDL_VIDEODRIVER', driver)
        try:
            pygame.display.init()
        except pygame.error:
            print('Driver: {0} failed.'.format(driver))
            continue
        found = True
        break

    if not found:
        raise Exception('No suitable video driver found!')

    self.screen_window = pygame.display.set_mode((2880, 1800))
    pygame.display.set_caption("Alien Apocalypse")

    """Setting background color"""
    self.background_color = (230, 230, 255)

    self.knight = Knight(self)

def run_game(self):
    """Start the main loop for the game"""
    while True:
        # Watch for keyboard and mouse actions
        # for event in pygame.event.get():
        #     if event.type == pygame.QUIT:
        #         sys.exit()

        # Redraw the screen during each pass through the loop.
        self.screen_window.fill(self.settings.background_color)
        self.knight.blitme()

        # Make the most recently drawn screen visible.
        pygame.display.flip()

if __name__ == "__main__":
    """Make a game instance, and run the game"""
    ac = AlienApocalypse()
    ac.run_game()
Kalma
  • 111
  • 2
  • 15
  • Still does not work for me. I guess I'll just have to make this project on linux virtual-machine. But thank though. – Jon Fillip Dec 30 '19 at 16:07
  • I am on Windows now! May I suggest you insert some print() messages to know where can be the problem? (not the best way, but the simplest). In addition to that, if you get any error, please paste it here so we can help. – Kalma Dec 30 '19 at 18:51
  • So I added to print statements in the __init__() method and the run_game() method and only the print statement in the __init__() method worked. I also tried calling the run_game() method and got a AttributeError. ``` ``` – Jon Fillip Dec 31 '19 at 10:38
  • Looking at your code, there are other things wrong. You have two run_game() functions, one inside the class which does nothing (pass), and the other one outside the class, which tries to use self... self is only available inside a class! Apart from this, you can not equal self to None... that means your are "killing yourself (the class). Just erase the run_game() function which is inside the class, then replace it with the one which is outside the class, and let "self" alone as parameter, not self=None. I hope it is clear enough. I will EDIT my answer anyway. – Kalma Dec 31 '19 at 10:50
  • I have done that. I'll update the code in my question. – Jon Fillip Dec 31 '19 at 11:08
  • If you do that, there is no question to be solved for others entering to watch this issue. Just mark the question as solved, so others can understand the problem and the solution (in case they have the same problem or they want to include another answer). – Kalma Dec 31 '19 at 11:25