My assignment is to make a game, were supposed to have multiple modules to avoid clutter in one script. I'm having an issue with import a variable from one of the modules. So far I have a settings one, and a main one. The settings is pretty simple and goes:
class Settings():
def __init__(self):
self.screen_width = 1920
self.screen_height = 1080
self.bg_color = (230, 230, 230)
Pretty simple, yet when I try to reference these variables it says "Unresolved attribute reference 'screen_width' for class 'Settings'
main goes as this:
import sys, pygame
from game_settings import Settings
def run_game():
#Initialize the game and create the window
pygame.init()
screen = pygame.display.set_mode((Settings.screen_width,Settings.screen_height), pygame.FULLSCREEN)
pygame.display.set_caption("Alien Invasion")
while True:
#Listening for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(Settings.bg_color)
pygame.display.flip()
run_game()
I thought maybe this would be a PyCharm issue, but found that it does the same thing in IDLE so what would be the correct way to import the variables?
Thanks for taking the time to read this!
You need to create an instance of your Settings class, since the attributes you set up in its __init__ method are instance attributes.
Try something like this:
def run_game():
my_settings = Settings() # create Settings instance
pygame.init()
screen = pygame.display.set_mode((my_settings.screen_width, # lookup attributes on it
my_settings.screen_height),
pygame.FULLSCREEN)
# ...
You need to create an instance of the Settings object: s = Settings()
Usage: s.bg_color, etc.
OR
Alter your Settings class like so and the properties are accessible statically:
class Settings():
screen_width = 1920
screen_height = 1080
bg_color = (230, 230, 230)
Both files have to be in the same folder and you have to create an instance of your Settings class. Then you can access the properties of your instance.
main.py:
from game_settings import Settings
s = Settings()
print(s.bg_color)
game_settings.py:
class Settings():
def __init__(self):
self.screen_width = 1920
self.screen_height = 1080
self.bg_color = (230, 230, 230)
When you run main.py, the output will be:
(230, 230, 230)
Related
i am trying to open settings.py in main.py by importing it like a library, but whenever i run main.py, the setting page opens immediately and im not sure why
whats is meant to happen is when you press the Account button you are supposed to run the settings page and get that the to load however that doesnt happen, instead whenever you run main.py settings.py instantly gets run without the main menu loading. This worked fine with the button but it doesnt work with the settings page i have tried to use exec and os to open it instead but that doesnt work.
the myLibrary is just the button defintion i used to create the account button
main.py
import pygame, sys, os
import myLibrary as lib
import settings
def runSettings():
print(settings.mainloop())
return
script_dir = sys.path[0]
bg_path = os.path.join(script_dir, '../info/images/backgrounds/MainMenu background.png')
bg = pygame.image.load(bg_path)
(width, height) = (1300, 790)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Main Menu')
Account_img = os.path.join(script_dir, '../info/images/MainMenu buttons/account.png')
Account_btn = lib.Button(Account_img, (180,340), runSettings)
while True:
screen.blit(bg, (0, 0))
screen.blit(Account_btn.image, Account_btn.rect)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
Account_btn.on_click(event)
pygame.display.update()
settings.py
import pygame, sys, os
import myLibrary as lib
script_dir = sys.path[0]
bg_path = os.path.join(script_dir, '../info/images/backgrounds/Settings background.png')
bg = pygame.image.load(bg_path)
(width, height) = (1100, 700)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Settings')
#titles
Username_img = pygame.image.load(os.path.join(script_dir, '../info/images/Settings buttons/username.png'))
def mainloop():
while True:
screen.blit(bg, (0,0))
screen.blit(Username_img, (30,20))
for event in pygame.event.get():
pass
pygame.display.update()
mainloop()
button definition, myLibrary as lib
import pygame
#button class will take the image, the position and callback
#function to create and place buttons
class Button:
def __init__(self, image, position, callback):
self.image = pygame.image.load(image)
self.image.convert()
self.rect = self.image.get_rect(topleft=position)
self.callback = callback
def on_click(self, event):
if event.button == 1:
if self.rect.collidepoint(event.pos):
self.callback()
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Like so many on here I am trying to get the Alien Invasion game going. But I cannot get Pygame to work, it comes up when I execute the program, but it is blank, black screen, and no ship. I have tried using a previous version of Pygame (dev6 right now), but again to no avail. The code below is verbatim from the book (Python Crash Course). Here is the code:
import sys
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
"""Overall class to manage game assets and behavior"""
def __init__(self):
"""initialize the game, and create game resources"""
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self)
# Set the background color
self.bg_color = (230, 230, 230)
def run_game(self):
"""Start the mainloop for tha game"""
while True:
# Watch for keyboard and mouse events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Redraw the screen during each pass.
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
# Make the most recent drawn screen visible.
pygame.display.flip()
if __name__ == '__main__':
# Make a game instance and run the game
ai = AlienInvasion()
ai.run_game()
This is the settings.py file:
class Settings:
"""A class to store all settings for Alien Invasion"""
def __init__ (self):
"""Initialize the game settings"""
# Screen Settings
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230, 230, 230)
and the ship.py file:
import pygame
class Ship:
"""A class to manage the ship"""
def __init__(self, ai_game):
"""Initlialize the ship and its starting position"""
self.screen = ai_game.screen
self.screen_rect = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
# load the ships image and get its rect
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
# start each new ship at the bottom center of the screen
self.rect.midbottom = self.screen_rect.midbottom
def blitme(self):
"""Draw the ship at its current location"""
self.screen.blit(self.image, self.rect)
I am running on windows 10
I am truly stumped as I have seen so many "solutions" that don't work, and the author of the book knows there is a problem, but his solution did not work for me.
It's a matter of Indentation. You have to draw the scene and to update the display in the application rather than affter the loop:
class AlienInvasion:
# [...]
def run_game(self):
"""Start the mainloop for tha game"""
while True:
# Watch for keyboard and mouse events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
#-->| Indentation
# Redraw the screen during each pass.
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
# Make the most recent drawn screen visible.
pygame.display.flip()
I would like to add a background image as a step to creating a basic game but it seems that I can't find a way. The image I am trying to import is the same size as the screen and it's a bmp image.
I also have in my settings folder this line of code which I am sure but not 100% needs to be removed (self.bg_color = (230, 230,230)) if I want to blit the image in background.
import sys
import pygame
from altarboy import Altarboy
from Ship import Ship
from bullet import bullet
from bullet1 import bullet1
from settings import Settings
class SpiritualWar:
def __init__(self):
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("SpiritualWar")
self.Ship = Ship(self)
self.bullets = pygame.sprite.Group()
self.bullet1s = pygame.sprite.Group()
self.altarboys = pygame.sprite.Group()
self._create_fleet()
…
…
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
self.Ship.blitme()
for bullet in self.bullets.sprites():
bullet.draw_bullet()
for bullet1 in self.bullet1s.sprites():
bullet1.draw_bullet1()
self.altarboys.draw(self.screen)
pygame.display.flip()
Possible duplicate of How to add a background image in python-pygame. I also recommend you to see Pygame: Adding a background. Next time, spend some minutes searching your question in StackOverflow before asking it. This way there will be less posts and SO will be cleaner, which helps to find solutions with ease.
I could not test the solution myself, but you can try adding the next line to the funciton __init__():
self.bg_image = pygame.image.load("player1.png")
And then changing your first line in function _update_screen():
self.screen.fill(self.settings.bg_color)
for:
self.screen.blit(self.bg_image, (0, 0))
I'm building a game and I'm trying to show up a little picture in the middle bottom of the screen.
I can't understand why I don't see the image at all?
This is my picture class code which in a file called devil.py:
import pygame
class Devil():
def __init__(self, screen):
"""Initialize the devil and set its starting position"""
self.screen=screen
#Load the devil image and get its rect
self.image=pygame.image.load('images/devil.bmp')
self.rect=self.image.get_rect()
self.screen_rect=screen.get_rect()
#Start each new devil at the bottom center of the screen
self.rect.centerx=self.screen_rect.centerx
self.rect.bottom=self.screen_rect.bottom
def blitme(self):
"""Draw the devil at its current location"""
self.screen.blit(self.image,self.rect)
And this is my main code which is written in another file:
import sys
import pygame
from settings import Settings
from devil import Devil
def run_game():
#Initialize pygame, settings and create a screen object.
pygame.init()
dvs_settings=Settings()
screen=pygame.display.set_mode(
(dvs_settings.screen_width, dvs_settings.screen_height))
pygame.display.set_caption("Devil vs Shitty")
#Make a devil
devil=Devil(screen)
#Start the main loop the game.
while True:
#Watch for keyboard and mouse events.
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()
#Redraw the screen during each pass through the loop.
screen.fill(dvs_settings.bg_color)
devil.blitme()
#Make the most recently drawn screen visible
pygame.display.flip()
run_game()
And this is my settings class in a file called settings.py:
class Settings():
"""A Class to store all settings for Alien Invasion."""
def __init__(self):
"""Initialize the game's settings"""
#Screen settings
self.screen_width = 1000
self.screen_height = 600
self.bg_color=(230,230,230)
I can't find what I am doing wrong here.
I've found the problem - which is a very strange one:
When I was editing my image, I saved it as a 32bit bmp file (The default option was 24 bit, and I thought to myself "I'm using 32bit python, I think it will match better).
But when I tried to show up my image in pygame - it didn't show up.
I've tried anything. And in the end I tried to edit again the image.
Now, I saved it as a 24bit bmp and it works well!!!
I have a Raspberry Pi with a PiTFT module. I'm wanting to use Pygame to display information on the module using the framebuffer (without X). I have all the display stuff working but the problem is that pygame is grabbing the input from the keyboard so that I can't even change the terminal with alt 1-7.
This task is supposed to run in the background so this is not desired behavior. I can't find any way to disable it though. It looked like pygame.event.set_grab() might have been appropriate but did not help. Here is a cut-down version of my code which exhibits the same issue.
import os
import pygame
import time
from time import gmtime,strftime,localtime
class pytest :
screen = None
def __init__(self):
os.environ["SDL_FBDEV"] = "/dev/fb1"
try:
pygame.display.init()
except pygame.error:
print 'Init failed.'
size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
self.screen = pygame.display.set_mode(size, pygame.FULLSCREEN)
pygame.event.set_grab(0)
pygame.font.init()
self.font = pygame.font.SysFont("", 30)
def __del__(self):
"Destructor to make sure pygame shuts down, etc."
def test(self):
lightblue = (92, 92, 176)
self.screen.fill(lightblue)
tm=time.strftime("%H:%M:%S",localtime())
t=self.font.render(tm,1,(255,255,155))
self.screen.blit(t,(240,00))
pygame.display.update()
scope = pytest()
while 1:
scope.test()
pygame.event.pump()
time.sleep(1)