pygame.error: video system not initialized(pycharm) - python

I am trying to learn pygame by replicating and examining this: https://www.wikihow.com/Program-a-Game-in-Python-with-Pygame#Adding_a_Player_Object_sub
however when I run either the original version(step 4) as seen above or my code
it brings me a black screen and this error:
Traceback (most recent call last):
File "C:/Users/Mohamed/Desktop/mopy/pys/first pycharm.py", line 77, in <module>
game().gameloo()
File "C:/Users/Mohamed/Desktop/mopy/pys/first pycharm.py", line 60, in gameloo
self.handle()
File "C:/Users/Mohamed/Desktop/mopy/pys/first pycharm.py", line 74, in handle
for event in pygame.event.get():
pygame.error: video system not initialized
here is my code:
import pygame
from pygame.locals import *
pygame.init()
resolution = (400, 350)
white = (250, 250, 250)
black = (0, 0, 0)
red = (250, 0, 0)
green = (0, 250, 0)
screen = pygame.display.set_mode(resolution)
class Ball:
def __init__(self, xPos=resolution[0] / 2, yPos=resolution[1] / 2, xVel=1, yVel=1, rad=15):
self.x = xPos
self.y = yPos
self.dx = xVel
self.dy = yVel
self.radius = rad
self.type = "ball"
def draw(self, surface):
pygame.draw.circle(surface, black, (int(self.x), int(self.y)), self.radius)
def update(self):
self.x += self.dx
self.y += self.dy
if (self.x <= 0 or self.x >= resolution[0]):
self.dx *= -1
if (self.y <= 0 or self.y >= resolution[1]):
self.dy *= -1
class player:
def __init__(self, rad=20):
self.x = 0
self.y = 0
self.radius = rad
def draw(self, surface):
pygame.draw.circle(surface, red, (self.x, self.y))
ball = Ball()
class game():
def __init__(self):
self.screen = pygame.display.set_mode(resolution)
self.clock = pygame.time.Clock()
self.gameobjct = []
self.gameobjct.append(Ball())
self.gameobjct.append(Ball(100))
def handle(self):
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
def gameloo(self):
self.handle()
for gameobj in self.gameobjct:
gameobj.update()
screen.fill(green)
for gameobj in self.gameobjct:
gameobj.draw(self.screen)
pygame.display.flip()
self.clock.tick(60)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
game().gameloo()

You've initialized the window twice pygame.display.set_mode(). Remove the global window initialization, but keep and use the window set to the .screen attribute of the class game.
The method handle should only do the event loop, but the method gameloo should contain the main loop. Inside the main loop the events have to be handled by self.handle():
screen = pygame.display.set_mode(resolution)
class game():
def __init__(self):
self.screen = pygame.display.set_mode(resolution)
self.clock = pygame.time.Clock()
self.gameobjct = []
self.gameobjct.append(Ball())
self.gameobjct.append(Ball(100))
def handle(self):
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
def gameloo(self):
while True:
self.handle()
for gameobj in self.gameobjct:
gameobj.update()
self.screen.fill(green)
for gameobj in self.gameobjct:
gameobj.draw(self.screen)
pygame.display.flip()
self.clock.tick(60)
game().gameloo()

Related

Access sprite/class position outside the class

I want to access my player position, I tried following Moving a Sprite Class from outside of the original Class in pygame but then I got "AttributeError: 'GroupSingle' object has no attribute 'rect'" as my error. I need to access player position inside my obstacle class.
This is my code:
import pygame
import os
import random
from sys import exit
pygame.init()
os.system("cls")
WIDTH = 288
HEIGHT = 512
FPS = 60
JUMP_POWER = 60
GRAVITY = 0.15
GAME_ACTIVE = 1
OBSTACLE_INTERVAL = 1000
AWAY_FROM_BIRD = 100
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("assets/images/player/bird.png").convert_alpha()
self.rect = self.image.get_rect(center = (WIDTH/4, HEIGHT/2))
self.gravity_store = 0
self.jump_sfx = pygame.mixer.Sound("assets/audio/jump.wav")
self.jump_sfx.set_volume(0.1)
def player_input(self):
for event in event_list:
if event.type == pygame.KEYDOWN:
if self.rect.bottom <= 0:
pass
else:
if event.key == pygame.K_SPACE:
self.gravity_store = 0
self.rect.y -= JUMP_POWER
self.jump_sfx.play()
def gravity(self):
self.gravity_store += GRAVITY
self.rect.y += self.gravity_store
print(int(self.gravity_store), int(clock.get_fps()))
def collision(self):
if self.rect.colliderect(ground_rect):
GAME_ACTIVE = 0
def update(self):
self.player_input()
self.gravity()
self.collision()
class Obstacles(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("assets/images/obstacles/pipe-green.png")
def obstacle_spawn(self):
#I want to access player position here
print(player.rect.x)
self.rect = self.image.get_rect(midleft = (0, 0))
def update(self):
self.obstacle_spawn()
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Mama Bird")
clock = pygame.time.Clock()
background_surf = pygame.image.load("assets/images/background/background-day.png")
ground_surf = pygame.image.load("assets/images/background/base.png")
ground_rect = ground_surf.get_rect(topleft = (0, HEIGHT-112))
player = pygame.sprite.GroupSingle()
player.add(Player())
obstacle = pygame.sprite.Group()
obstacle.add(Obstacles())
OBSTACLESPAWN = pygame.USEREVENT + 1
pygame.time.set_timer(OBSTACLESPAWN, OBSTACLE_INTERVAL)
while True:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
pygame.quit()
exit()
SCREEN.blit(background_surf, (0,0))
player.draw(SCREEN)
player.update()
for event in event_list:
if event.type == OBSTACLESPAWN and GAME_ACTIVE == 1:
obstacle.update()
obstacle.draw(SCREEN)
SCREEN.blit(ground_surf, ground_rect)
pygame.display.update()
clock.tick(FPS)
I tried to see if it would access the player position using "print(player.rect.x)". And got this error:
Traceback (most recent call last):
File "c:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird\main.py", line 98, in <module>
obstacle.update()
File "C:\Users\46722\AppData\Local\Programs\Python\Python310\lib\site-packages\pygame\sprite.py", line 539, in update
sprite.update(*args, **kwargs)
File "c:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird\main.py", line 65, in update
self.obstacle_spawn()
File "c:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird\main.py", line 61, in obstacle_spawn
print(player.rect.x)
AttributeError: 'GroupSingle' object has no attribute 'rect'
PS C:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird>
player is an instance of pygame.sprite.Group():
player = pygame.sprite.GroupSingle()
player.add(Player())
Use the sprite property to access the pygame.sprite.Sprite in a pygame.sprite.GroupSingle:
print(player.rect.x)
print(player.sprite.rect.x)

My pygame window displays a black screen everytime I run my project

I wrote this code below and just get a black screen on my pygame window everytime I run my project on pycharm
I copied this code through a tutorial step by step and checked it but the teacher didn’t seem to have this problem when running the code
import pygame
width = 500
height = 500
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Client")
clientNumber = 0
class Player():
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = (x, y, width, height)
self.vel = 3
def draw(self, win):
pygame.draw.rect(win, self.color, self.rect)
def move(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.x -= self.vel
if keys[pygame.K_RIGHT]:
self.x += self.vel
if keys[pygame.K_UP]:
self.y -= self.vel
if keys[pygame.K_DOWN]:
self.y += self.vel
self.rect = (self.x, self.y, self.width, self.height)
def redrawWindow(win, player):
win.fill((255, 255, 255))
player.draw(win)
pygame.display.update()
def main():
run = True
p = Player(50, 50, 100, 100, (0, 255, 0))
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
p.move()
redrawWindow(win, p)
main()
Press tab before p.move() and redrawWindow(win, p) so they look like this
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
p.move()
redrawWindow(win, p)
They should be indented under while loop.

How to spawn enemy blocks continuously without manually creating them? [duplicate]

This question already has answers here:
Spawning multiple instances of the same object concurrently in python
(1 answer)
Issues with pygame.time.get_ticks() [duplicate]
(1 answer)
How to make instances spawn automatically around the player? [duplicate]
(1 answer)
Closed 1 year ago.
I am creating a game similar to the "Internet T-rex Game", Right now my game creates enemy blocks according to how many I manually create. I want it to be created by itself. My game is not fully completed yet, so please ignore the empty functions.
Heres my main.py
import pygame as pg
import random
from settings import *
from sprites import *
from os import path
class Game(object):
"""docstring for Game"""
def __init__(self):
# initialise game
global points , game_speed
pg.init()
self.screen = pg.display.set_mode((s_HEIGHT , s_WIDTH))
pg.display.set_caption(TITLE)
self.icon = pg.image.load("C:/Users/DELL/Documents/Jump Cube/Img/cube.png")
pg.display.set_icon(self.icon)
self.clock = pg.time.Clock()
self.running = True
self.game_speed = 14
points = 0
font = pygame.font.Font('freesansbold.ttf', 20)
self.load_data()
def load_data(self):
self.dir = path.dirname(__file__)
img_dir = path.join(self.dir, "Img")
#load spritesheet image
self.spritesheet = Spritesheet(path.join(img_dir, SPRITESHEET))
def new(self):
# Stars a new game
self.all_sprites = pg.sprite.Group()
self.platforms = pg.sprite.Group()
self.ene = pg.sprite.Group()
self.player = Player(self)
self.all_sprites.add(self.player)
pl = Platform(0, s_HEIGHT - 230, 800, 40)
en1 = Enemy(700, 517, 50, 50)
en2 = Enemy(600, 517, 50, 50)
en3 = Enemy(500, 517, 50, 50)
self.all_sprites.add(pl)
self.platforms.add(pl)
self.all_sprites.add([en1, en2, en3])
self.ene.add([en1, en2, en3])
self.Run()
def Run(self):
# Game Loop
self.playing = True
while self.playing:
self.clock.tick(FPS)
self.Events()
self.Update()
self.Draw()
self.score()
def Update(self):
# Game Loop - Update
self.all_sprites.update()
hits = pg.sprite.spritecollide(self.player, self.platforms, False)
if hits:
self.player.pos.y = hits[0].rect.top
self.player.vel.y = 0
pass
def score(self):
global points , game_speed
points += 1
if points % 100 == 0:
game_speed += 1
text = font.render("Points : " + str(points), True, WHITE)
textrec = text.get_rect()
textrec.center = (700, 50)
self.screen.blit(text, textrec)
def Events(self):
# Game Loop - Events
for event in pg.event.get():
if event.type == pg.QUIT:
if self.playing:
self.playing = False
self.running = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
self.player.jump()
if event.type == pg.KEYDOWN:
if event.key == pg.K_RIGHT:
self.player.mover()
elif event.key == pg.K_LEFT:
self.player.movel()
def Draw(self):
# Game Loop - Draw
self.screen.fill(BLACK)
self.score()
self.all_sprites.draw(self.screen)
pg.display.update()
pass
def start_screen(self):
# shows the start screen
pass
def end_screen(self):
# shows the end screen
pass
g = Game()
g.start_screen()
while g.running:
g.new()
g.end_screen()
pg.quit()
sprites.py
import pygame as pg
from settings import *
vec = pg.math.Vector2
class Spritesheet():
# utility class for laoding and parsing spritesheets
def __init__(self, filename):
self.spritesheet = pg.image.load(filename).convert()
def get_image(self, x, y, width, height):
# grabs images from large spritesheets
image = pg.Surface((width, height))
image.blit(self.spritesheet, (0,0), (x, y, width, height))
image = pg.transform.scale(image , (50, 85))
return image
class Player(pg.sprite.Sprite):
def __init__(self, game):
pg.sprite.Sprite.__init__(self)
self.game = game
self.image = self.game.spritesheet.get_image(614, 1063, 120, 191)
self.image.set_colorkey(BLACK1)
self.rect = self.image.get_rect()
self.rect.center = (s_WIDTH / 2, s_HEIGHT / 2)
self.pos = vec(100, 600)
self.vel = (0, 0)
self.acc = (0, 0)
def jump(self):
#jump only if standing on plat
self.rect.y += 1
hits = pg.sprite.spritecollide(self, self.game.platforms, False)
self.rect.y -= 1
if hits:
self.vel.y = -8
def mover(self):
#move right
self.vel.x = 5
def movel(self):
#move right
self.vel.x = -5
def update(self):
self.acc = vec(0, PLAYER_GRAV)
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
self.rect.midbottom = self.pos
class Platform(pg.sprite.Sprite):
def __init__(self, x, y, w, h):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w, h))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Enemy(pg.sprite.Sprite):
def __init__(self, x, y, w1, h1):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w1, h1))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
self.rect.x -= game_speed
settings.py
import pygame
pygame.init()
#game options
TITLE = "Ninja Jump"
s_WIDTH = 600
s_HEIGHT = 800
FPS = 60
game_speed = 14
points = 0
font = pygame.font.Font('freesansbold.ttf', 20)
SPRITESHEET = "spritesheet_jumper.png"
#player properties
PLAYER_ACC = 0.5
PLAYER_GRAV = 0.3
#colors
WHITE = (199, 198, 196)
BLACK = (23, 23, 23)
GRAY = (121, 121, 120)
GREEN = (72, 161, 77)
BLACK1 = (0,0,0)
GRAY1 = (162, 162, 162)
Thanks for any help and let me know if the problem needs more clarification.
Spawn the enemies by a time interval. In pygame the system time can be obtained by calling pygame.time.get_ticks(), which returns the number of milliseconds since pygame.init() was called. Define a time interval to spawn enemies. Continuously compare the current time with the time when the next enemy must appear. When the time comes, spawn an enemy and set the time the next enemy must spawn:
class Game(object):
# [...]
def Run(self):
self.next_enemy_time = 0
self.enemy_time_interval = 1000 # 1000 milliseconds == 1 second
# Game Loop
self.playing = True
while self.playing:
current_time = pygame.time.get_ticks()
if current_time > self.next_enemy_time:
self.next_enemy_time += self.enemy_time_interval
new_enemy = Enemy(700, 517, 50, 50)
self.all_sprites.add(new_enemy)
self.ene.add(new_enemy)
self.clock.tick(FPS)
self.Events()
self.Update()
self.Draw()
self.score()

My pygame player sprite is not moving and/or updating

I am trying to build a simple "flappy bird" like game. I am trying to sort all the code into classes and methods. How do I fix this problem? Is it the code not working because of calling some method too early or is it because there's something missing? I would really love it if someone would try to explain to me.
sprites.py:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect()
self.rect.x = 0
self.rect.y = (700 / 2)
self.movex = 0
self.movey = 0
def control(self, x, y):
self.movex += x
self.movey += y
def update(self):
self.rect.x += self.movex
self.rect.y += self.movey
def animate(self):
pass
class Obstacle(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
main.py:
from sprites import *
import pygame
WIDTH = 700
HEIGHT = 700
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
self.score = 0
self.running = True
def new(self):
pass
def events(self):
self.game_on = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.game_on = False
self.running = False
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_UP:
self.croc.control(0, -20)
def update(self):
self.croc = Player()
self.all_sprites = pygame.sprite.Group()
self.all_sprites.add(self.croc)
self.all_sprites.update()
def draw(self):
self.screen.fill((0, 0, 0))
self.all_sprites.draw(self.screen)
pygame.display.flip()
game = Game()
while game.running:
game.clock.tick(60)
game.new()
game.events()
game.update()
game.draw()
Thank you
There are 2 mistakes. The Player object is recreated in every frame. Create the player in the constructor of Game rather than in the method update:
class Game:
def __init__(self):
# [...]
self.croc = Player() # <--- ADD
self.all_sprites = pygame.sprite.Group() # <--- ADD
self.all_sprites.add(self.croc) # <--- ADD
def update(self):
# self.croc = Player() # <--- DELETE
# self.all_sprites = pygame.sprite.Group() # <--- DELETE
# self.all_sprites.add(self.croc) # <--- DELETE
self.all_sprites.update()
There is a type in the event loop. You've to get the key from the .key attribute rather than the .type attriburte:
if event.type == pygame.K_UP:
if event.key == pygame.K_UP:
Complete code:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect()
self.rect.x = 0
self.rect.y = (700 / 2)
self.movex = 0
self.movey = 0
def control(self, x, y):
self.movex += x
self.movey += y
def update(self):
self.rect.x += self.movex
self.rect.y += self.movey
def animate(self):
pass
class Obstacle(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
WIDTH = 700
HEIGHT = 700
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
self.score = 0
self.running = True
self.croc = Player()
self.all_sprites = pygame.sprite.Group()
self.all_sprites.add(self.croc)
def new(self):
pass
def events(self):
self.game_on = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.game_on = False
self.running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.croc.control(0, -20)
def update(self):
self.all_sprites.update()
def draw(self):
self.screen.fill((0, 0, 0))
self.all_sprites.draw(self.screen)
pygame.display.flip()
game = Game()
while game.running:
game.clock.tick(60)
game.new()
game.events()
game.update()
game.draw()

How to fix the occurrence of Black Screen when running the program

I am new to Python Game Development and I am trying to learn by following the tutorial on Youtube by FreeCodeCamp but not getting the expected output. When I run the program the window opens but displays a black screen with no output.
Tried to include pygame.init() and pygame.display.init() but that didn't work either.
import pygame
width = 500
height = 500
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Client")
client_number = 0
class Player():
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.rect = (x, y, width, height)
self.vel = 3
def draw(self, win):
pygame.draw.rect(win, self.color, self.rect)
def move(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.x -= self.vel
if keys[pygame.K_RIGHT]:
self.x += self.vel
if keys[pygame.K_DOWN]:
self.y += self.vel
if keys[pygame.K_UP]:
self.y -= self.vel
self.rect = (self.x, self.y, self.width, self.height)
def redraw_Window(win, player):
win.fill((255, 255, 255))
player.draw(win)
pygame.display.update()
def main():
run = True
p = Player(50, 50, 100, 100, (0, 255, 0))
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
p.move()
redraw_Window(win, p)
main()
You've to respect the Indentation.
p.move() and redraw_Window(win, p) have to be in the scope of the main loop (in scope of while run:) rather than in scope of the function main main:
def main():
run = True
p = Player(50, 50, 100, 100, (0, 255, 0))
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
# ->>>
p.move()
redraw_Window(win, p)
main()

Categories