Python, pygame Couldn't open chic.jpg - python

I'm creating a small game with python. although that the program and the images are in the same folder, I don't see an image when I open the program. I have just black window, but I should see my pic. whats could be wrong?
And there is my code:
import os, sys
import pygame
class Game:
def __init__(self, width=640, height=480):
pygame.init()
self.width = width
self.height = height
self.screen = pygame.display.set_mode([self.width, self.height])
def MainLoop(self):
self.ChickenLoad();
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
self.chicken_sprites.draw(self.screen)
pygame.display.flip()
def ChickenLoad(self):
self.chicken = Chicken()
self.chicken_sprites = pygame.sprite.Group(self.chicken)
class Chicken(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("duch.jpg")
self.rect = self.image.get_rect()
if __name__ == "__main__":
MainWindow = Game()
MainWindow.MainLoop()

It is your trailing semi-colon that is preventing the photo to appear.
In my IDE, the semicolon is deemed unneeded, and it is right. After the removal of the semicolon, your program worked fine. So from this:
self.ChickenLoad();
to this:
self.ChickenLoad()

Related

Why are my images Overlapping for Pygame?

import pygame
import random
import os
import time
pygame.init()
#window and background
win = pygame.display.set_mode((1000,750))
pygame.display.set_caption("TD GaME")
background_img = pygame.image.load('best_backgroundv2.png')
background = pygame.transform.scale(background_img,(1000,750))
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, scale):
pygame.sprite.Sprite.__init__(self)
img = pygame.image.load('Run/HeavyBandit_Run_0.png')
self.image = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def draw(self):
win.blit(self.image, self.rect)
e_1 = Enemy(400, 500, 3)
So I am relatively new and trying to make a enemy(image) appear but is seems it has been overlapped by my background. I think it is due to how poor my code is in reference to setting the "background"
Your issue is missing the bit of code you have in your program that explains the order you are adding background and images to the window. Lacking that, I came up with the additional code snippet that I added to the end of the code you included above.
while True:
win.blit(background,(0, 0)) # Place the background into the window first
e_1.draw() # Draw the bandit or other image(s) next
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
pygame.display.update()
pygame.quit()
The takeaway here is the order in which the background and image are placed into the window. In this sequence, I got the following screen.
I didn't have your actual image files so I substituted some image files. See if you can work with that.

Whenever i try run my python code with pygame the window opens and then stops responding after a second or any input

heres all the code i have currently, it is just a start of a pacman game i am creating all that should be shown is a tab with press space to play
ive looked at previous responses to similar questions and i have what i should need to make it work but it still doesn't... i hope someone can help, thanks.
import os
import sys
import pygame
Start_window_font = 'arial black'
pygame.init()
vector=pygame.math.Vector2
class RPMGame:
def __init__(self):
self.screen = pygame.display.set_mode((450, 600))
self.clock = pygame.time.Clock()
self.running = True
self.state = 'startwindow'
self.load()
self.node_width = 450//25
self.node_height = 600//30
def run(self):
while self.running:
if self.state == 'startwindow':
self.startwindow_events()
self.startwindow_update()
self.startwindow_draw()
if self.state == 'gaming':
self.gaming_events()
self.gaming_update()
self.gaming_draw()
#fps
self.clock.tick(60)
pygame.quit()
sys.exit()
def draw_text(self, words, screen, position, size, colour, font_name, centered = False):
font = pygame.font.SysFont(font_name, size)
text = font.render(words, False, colour)
text_size = text.get_size()
#centering the starting text##
if centered:
position[0] = position[0]-text_size[0]//2
position[1] = position[1]-text_size[1]//2
screen.blit(text, position)
def load(self):
self.gameboard = pygame.image.load('pacmanmaze.png')
self.gameboard = pygame.transform.scale(self.gameboard, (450, 600))
def draw_maze(self):
for x in range(450//self.node_width):
pygame.draw.line(self.screen, 107,107,107, (x*self.node_height, 0), (x*self.node_width, 600))
def startwindow_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
###key used to start game##
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
self.state= 'gaming'
def startwindow_update(self):
pass
def startwindow_draw(self):
####colour of background##
self.screen.fill(0,0,0)
##start game text (text, position, text size, colour, centering)##
self.draw_text('CLICK TO START GAME', self.screen, (225,300), 16,(255,0,0),
Start_window_font, centered= True)
self.draw_text('HIGH SCORE', self.screen, [5,0] ,(225,300), 16,(255,255,255),
Start_window_font)
pygame.display.update()
def gaming_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
def gaming_update(self):
pass
def gaming_draw(self):
self.screen.blit(self.gameboard, (0,0))
self.draw_maze()
pygame.display.update()
game = RPMGame()
game.run()
**edit
i realised that i forgot to change the variable for one of my states which was needed for the stop part
You have a number of minor issues. When the app started and then immediately stopped, did you not notice that you're getting syntax and runtime errors on the console?
In this line:
self.screen.fill(0,0,0)
fill accepts one parameter, which is an RGB tuple:
self.screen.fill((0,0,0))
You have the same problem in draw_maze:
pygame.draw.line(self.screen, 107,107,107, (x*self.node_height, 0), (x*self.node_width, 600))
... should be ...
pygame.draw.line(self.screen, (107,107,107), (x*self.node_height, 0), (x*self.node_width, 600))
Then, in this call:
self.draw_text('HIGH SCORE', self.screen, [5,0] ,(225,300), 16,(255,255,255),
I don't know what the [5,0] was trying to do, but draw_text isn't expecting that parameter. Just remove it.
Then, in this code:
if centered:
position[0] = position[0]-text_size[0]//2
position[1] = position[1]-text_size[1]//2
screen.blit(text, position)
you pass in position as a tuple. You can't modify a tuple. You need to build a new tuple, or just change to a list:
pos = list(position)
if centered:
pos[0] = pos[0]-text_size[0]//2
pos[1] = pos[1]-text_size[1]//2
screen.blit(text, pos)
With that, your app at least starts for me.

Pygame_menu loop overrides the transition to another screen

Currently working on a backgammon game with eventual multiplayer support.
I have a mainmenu function that is working, and its exceptions and draws are handled by the mainloop() attribute. However, I have a button that, when pressed, should switch to the game with the backgammon board as the background.
The image appears briefly, then the main menu continues to run. I've tried to find ways to disable the menuloop using conditional statements to no avail.
Here is the full source code:
import sys, pygame, os, pygame_menu
width, height = 1280, 960
class mainBackgammonGame():
global width, height
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Bootleg Backgammon")
self.clock = pygame.time.Clock()
def updateScreen(self):
self.clock.tick(60)
pygame.display.flip()
def startGame():
surface = pygame.display.set_mode((width, height))
currPath = os.path.dirname(os.path.abspath(__file__))
boardPath = os.path.join(currPath, "images/mainboard.png")
boardImage = pygame.image.load(boardPath)
surface.blit(boardImage, (0,0))
pygame.display.flip()
def mainMenu():
surface = pygame.display.set_mode((width, height))
menu = pygame_menu.Menu(960, 1280, 'Welcome to Backgammon', theme = pygame_menu.themes.THEME_DARK)
menu.add_text_input("Your Name: ", default = "Joseph Smith")
menu.add_button('Play', mainBackgammonGame.startGame)
menu.add_button('Quit', pygame_menu.events.EXIT)
menu.mainloop(surface)
bg = mainBackgammonGame()
mainMenu()
while 1:
for event in pygame.event.get():
if event == pygame.QUIT:
exit()
bg.updateScreen()
Figured it out.
def mainMenu():
def disable():
menu.disable()
mainBackgammonGame.startGame()
surface = pygame.display.set_mode((width, height))
menu = pygame_menu.Menu(960, 1280, 'Welcome to Backgammon', theme = pygame_menu.themes.THEME_DARK)
menu.add_text_input("Your Name: ", default = "Joseph Smith")
menu.add_button('Play', disable)
menu.add_button('Quit', pygame_menu.events.EXIT)
menu.mainloop(surface)
Added a new function within the main menu function that initially disables the menu, then will call the startGame function that loads the screen.
I recommend reading the following example:
https://github.com/ppizarror/pygame-menu/blob/master/pygame_menu/examples/game_selector.py
You can see that the main part of that is having a main menu variable
main_menu: Optional['pygame_menu.Menu'] = None
Which gets initialized elsewhere in the code.
Additionally when it's time for that menu to leave, like if you want to move to the game after being in the menu then you want a function like this:
def start_game():
global menu
# Do stuff here
menu.disable()
Then in your pygame main loop you can guard the mainloop call like so:
if menu.is_enabled():
menu.mainloop(screen)

Pygame screen output not displaying

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)
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()

How to remove sprites out of group, outside of the class: Pygame

#Importing Modules
import pygame as pg
import sys
import random
#All pygame stuff under here
pg.init()
#Font definitions
backFont = pg.font.SysFont("monospace",40)
titleFont = pg.font.SysFont("garamond", 100)
cipherFont = pg.font.SysFont("garamond", 50)
buttonFont = pg.font.SysFont("garamond", 25)
bigFont = pg.font.SysFont("garamond",100)
Font = pg.font.SysFont(None,32)
inputFont = pg.font.SysFont('consola', 35)
errorFont = pg.font.SysFont('tahoma',20)
diagramFont = pg.font.SysFont('courier new',25)
#Colour definitions
BackGray = pg.Color('gray60')
screenGray = pg.Color('gray80')
buttonGray2 = pg.Color('gray50')
textColour = pg.Color('navy')
#Screen size set
screen = pg.display.set_mode((400, 400))
clock = pg.time.Clock()
class Button(pg.sprite.Sprite):
def __init__(self, text, x, y, width, height, colour, enabled):
super().__init__()
self.image = pg.Surface((width, height))
self.image.fill(colour)
self.rect = self.image.get_rect()
txt = buttonFont.render(text, True, textColour)
txtRect = txt.get_rect(center = self.rect.center)
self.image.blit(txt, txtRect)
self.rect.topleft = x, y
self.enabled = enabled
def isPressed(self, event):
if self.enabled == True:
if event.type == pg.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
return True
return False
def Function():
background = pg.Surface(screen.get_size())
background.fill(screenGray)
Button1 = Button('Encrypt',100,100,125,50,buttonGray2,True)
Button2 = Button('Decrypt',100,200,125,50,buttonGray2,True)
buttonsGroup = pg.sprite.Group(Button1,Button2)
ACTIONPRINT = False
Active1 = False
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
sys.exit()
elif Button1.isPressed(event):
print("1")
Active1 = True
elif Button2.isPressed(event):
print("2")
if Active1 == True:
ACTIONPRINT = True
buttonsGroup = pg.sprite.Sprite.remove(Button2)
screen.blit(background,(0,0))
buttonsGroup.draw(screen)
pg.display.flip()
clock.tick(60)
Function()
Above is the code for the class of Buttons, and a simple function that runs two buttons. What I'd like to do is remove one of the buttons, when one is pressed, which are set as sprites. When the button is removed from the group, I believe it should disappear from the screen, after one is pressed.
The above code at the minute returns an error saying that there is an AttributeError: 'NoneType' object has no attribute 'draw'. However, in another program, when it did work, it said that in the Sprite.remove method, the parameters must be a sequence and not a button - what does this mean?
I have looked online, and all the removing sprites examples are inside a class. Does that mean that the only way for this to work is by changing the class?
Or can sprites still be removed from outside the class, and if so how is it done?
Any other methods are welcome to
Thanks in advance!
sprite.Group.remove doesn't return anything, it removes the sprite from the group that calls it, so instead of:
buttonsGroup = pg.sprite.Sprite.remove(Button2)
Try:
buttonsGroup.remove(Button2)

Categories