/r/pygame
Pygame is a set of Python modules designed for writing games.
Pygame adds functionality on top of the excellent SDL library. This allows you to create fully featured games and multimedia programs in the python language.
Pygame is highly portable and runs on nearly every platform and operating system.
Despite the name, content related to other Python game libraries (pyglet, panda3d, etc.) is also welcome.
If asking for help with your code, please provide a link to the entire code and resources if possible. Consider making a Github account if you don't have one already.
In Python indentation is part of the language syntax and as such is extremely important.
When posting code every line must be indented an additional four spaces. You can indent the code in a text editor before pasting, or after pasting into reddit, highlight the text and press the editor button that looks like this <>
.
You can also place small amounts of code inline
by surrounding it with ticks:
`like this`
If you have a large amount of code to share it would be best use a third party site for posting code. Gist is a really good choice. For code that relies on external resources like images please create a repo on github or similar.
When posting links please provide a brief description in the comments of the thread. Failure to do so may result in post removal.
Installation notes for Microsoft Windows users
It is easier to install python32 and pygame32 even if you are running a 64-bit version of Microsoft Windows.
/r/pygame
Hello everyone !
I'm doing a project in Pygame where I have to code only in Python, and I was wondering if you had any interesting resources to give me, to make maps, characters or already made code for exemple ?
Thanks a lot !
I have a menu where after space is pressed it opens the game tutorial but the menu will not close after space is pressed. I have tried setting "run = False" but it doesn't seem to work. Any ideas?
I'm trying to figure out how to display text in pygame that is selectable. Like if I were browser reading text, I would be able to select the text and copy and paste it.
Does Pygame support this functioanlity?
I like programming in Linux and OS X as opposed to windows, and I want my entire Pygame workflow to be in this type of setting. But, when I want to try other people's games, they often come as .exe's, which I can't really use on mac. I've tried Wine, though I know it's outdated and doesn't work some of the time. Anyone else deal with this? Have any workarounds? thanks!
I've connected two Nintendo Switch Joycons to my computer, using bluetooth, and I copied the code from https://www.pygame.org/docs/ref/joystick.html
When I run it, it's just a black window that stays up for maybe half a second, and then crashes with this error:
pygame 2.5.2 (SDL 2.28.3, Python 3.12.3)
Hello from the pygame community. https://www.pygame.org/contribute.html
KeyError: 1
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\Users\MYNAME\Desktop\Coding\Python Projects\joycons.py", line 148, in <module>
main()
File "c:\Users\MYNAME\Desktop\Coding\Python Projects\joycons.py", line 52, in main
for event in pygame.event.get():
^^^^^^^^^^^^^^^^^^
SystemError: <built-in function get> returned a result with an exception set
It runs fine without any joycons connected.
I tried running another pygame project, which had no joystick code whatsoever, and it crashed with them connected too.
Here is the code that I have copied from the website:
import pygame
pygame.init()
# This is a simple class that will help us print to the screen.
# It has nothing to do with the joysticks, just outputting the
# information.
class TextPrint:
def __init__(self):
self.reset()
self.font = pygame.font.Font(None, 25)
def tprint(self, screen, text):
text_bitmap = self.font.render(text, True, (0, 0, 0))
screen.blit(text_bitmap, (self.x, self.y))
self.y += self.line_height
def reset(self):
self.x = 10
self.y = 10
self.line_height = 15
def indent(self):
self.x += 10
def unindent(self):
self.x -= 10
def main():
# Set the width and height of the screen (width, height), and name the window.
screen = pygame.display.set_mode((500, 700))
pygame.display.set_caption("Joystick example")
# Used to manage how fast the screen updates.
clock = pygame.time.Clock()
# Get ready to print.
text_print = TextPrint()
# This dict can be left as-is, since pygame will generate a
# pygame.JOYDEVICEADDED event for every joystick connected
# at the start of the program.
joysticks = {}
done = False
while not done:
# Event processing step.
# Possible joystick events: JOYAXISMOTION, JOYBALLMOTION, JOYBUTTONDOWN,
# JOYBUTTONUP, JOYHATMOTION, JOYDEVICEADDED, JOYDEVICEREMOVED
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True # Flag that we are done so we exit this loop.
if event.type == pygame.JOYBUTTONDOWN:
print("Joystick button pressed.")
if event.button == 0:
joystick = joysticks[event.instance_id]
if joystick.rumble(0, 0.7, 500):
print(f"Rumble effect played on joystick {event.instance_id}")
if event.type == pygame.JOYBUTTONUP:
print("Joystick button released.")
# Handle hotplugging
if event.type == pygame.JOYDEVICEADDED:
# This event will be generated when the program starts for every
# joystick, filling up the list without needing to create them manually.
joy = pygame.joystick.Joystick(event.device_index)
joysticks[joy.get_instance_id()] = joy
print(f"Joystick {joy.get_instance_id()} connencted")
if event.type == pygame.JOYDEVICEREMOVED:
del joysticks[event.instance_id]
print(f"Joystick {event.instance_id} disconnected")
# Drawing step
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill((255, 255, 255))
text_print.reset()
# Get count of joysticks.
joystick_count = pygame.joystick.get_count()
text_print.tprint(screen, f"Number of joysticks: {joystick_count}")
text_print.indent()
# For each joystick:
for joystick in joysticks.values():
jid = joystick.get_instance_id()
text_print.tprint(screen, f"Joystick {jid}")
text_print.indent()
# Get the name from the OS for the controller/joystick.
name = joystick.get_name()
text_print.tprint(screen, f"Joystick name: {name}")
guid = joystick.get_guid()
text_print.tprint(screen, f"GUID: {guid}")
power_level = joystick.get_power_level()
text_print.tprint(screen, f"Joystick's power level: {power_level}")
# Usually axis run in pairs, up/down for one, and left/right for
# the other. Triggers count as axes.
axes = joystick.get_numaxes()
text_print.tprint(screen, f"Number of axes: {axes}")
text_print.indent()
for i in range(axes):
axis = joystick.get_axis(i)
text_print.tprint(screen, f"Axis {i} value: {axis:>6.3f}")
text_print.unindent()
buttons = joystick.get_numbuttons()
text_print.tprint(screen, f"Number of buttons: {buttons}")
text_print.indent()
for i in range(buttons):
button = joystick.get_button(i)
text_print.tprint(screen, f"Button {i:>2} value: {button}")
text_print.unindent()
hats = joystick.get_numhats()
text_print.tprint(screen, f"Number of hats: {hats}")
text_print.indent()
# Hat position. All or nothing for direction, not a float like
# get_axis(). Position is a tuple of int values (x, y).
for i in range(hats):
hat = joystick.get_hat(i)
text_print.tprint(screen, f"Hat {i} value: {str(hat)}")
text_print.unindent()
text_print.unindent()
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 30 frames per second.
clock.tick(30)
if __name__ == "__main__":
main()
# If you forget this line, the program will 'hang'
# on exit if running from IDLE.
pygame.quit()
import neat.config
import pygame, neat, os, time, random
from flappy_bird_ai_with_pygame import main
def load_run():
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward.txt')
config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet, neat.DefaultStagnation, config_path)
print(f'Loaded {config}')
p = neat.Population(config)
p.add_reporter(neat.StdOutReporter(True))
stats= neat.StatisticsReporter()
p.add_reporter(stats)
winner = p.run(main,50)
def load_image(img_path):
return pygame.transform.scale2x(pygame.image.load(os.path.join('imgs', img_path)))
def draw_window(win, birds, pipes, base, score):
win.blit(Config.BG_IMG, (0,0))
for pipe in pipes:
pipe.draw(win)
text = Config.STAT_FONT.render('Score: ' + str(score), 1,(255,255,255))
win.blit(text, (Config.WIN_WIDTH - 10 - text.get_width(), 10))
base.draw(win)
for bird in birds:
bird.draw(win)
pygame.display.update()
class Config:
WIN_WIDTH = 500
WIN_HEIGHT= 800
BIRD_IMGS = [load_image(img) for img in ['bird1.png', 'bird2.png', 'bird3.png']]
PIPE_IMG = load_image('pipe.png')
BG_IMG = load_image('bg.png')
BASE_IMG = load_image('base.png')
pygame.font.init()
STAT_FONT = pygame.font.SysFont('comicsans', 50)
class Bird:
IMGS = Config.BIRD_IMGS
MAX_ROTATION = 25
ROT_VEL = 20
ANIMATION_TIME = 5
def __init__(self, x, y):
self.x = x
self.y = y
self.tilt = 0
self.tick_count = 0
self.vel = 0
self.height = self.y
self.img_count = 0
self.img = self.IMGS[0]
def jump(self):
self.vel = -10.5
self.tick_count = 0
self.height = self.y
def move(self):
self.tick_count += 1
displacement = self.vel*self.tick_count + .5*self.tick_count**2
if displacement >= 16:
displacement = 16
if displacement < 0:
displacement -= 2
self.y = self.y + displacement
if displacement < 0 or self.y < self.height + 50:
if self.tilt < self.MAX_ROTATION:
self.tilt = self.MAX_ROTATION
else:
if self.tilt > -90:
self.tilt -= self.ROT_VEL
def draw(self, win):
self.img_count += 1
if self.img_count < self.ANIMATION_TIME:
self.img = self.IMGS[0]
elif self.img_count < self.ANIMATION_TIME*2:
self.img = self.IMGS[1]
elif self.img_count < self.ANIMATION_TIME*3:
self.img = self.IMGS[2]
elif self.img_count < self.ANIMATION_TIME*4:
self.img = self.IMGS[1]
elif self.img_count < self.ANIMATION_TIME*4 + 1:
self.img = self.IMGS[0]
self.img_count = 0
if self.tilt <= -80:
self.img =self.IMGS[1]
self.img_count = self.ANIMATION_TIME*2
rotated_image = pygame.transform.rotate(self.img, self.tilt)
new_rect = rotated_image.get_rect(center=self.img.get_rect(topleft = (self.x, self.y)).center)
win.blit(rotated_image, new_rect.topleft)
def get_mask(self):
return pygame.mask.from_surface(self.img)
class Pipe:
GAP = 200
VEL = 5
def __init__(self, x):
self.x = x
self.height = 0
self.gap = 100
self.top = 0
self.bottom = 0
self.PIPE_TOP = pygame.transform.flip(Config.PIPE_IMG, False, True)
self.PIPE_BOTTOM = Config.PIPE_IMG
self.passed = False
self.set_height()
def set_height(self):
self.height = random.randrange(50, 450)
self.top = self.height - self.PIPE_TOP.get_height()
self.bottom = self.height + self.GAP
def move(self):
self.x -= self.VEL
def draw(self, win):
win.blit(self.PIPE_TOP, (self.x, self.top))
win.blit(self.PIPE_BOTTOM, (self.x, self.bottom))
def collide(self, bird):
bird_mask = bird.get_mask()
top_mask = pygame.mask.from_surface(self.PIPE_TOP)
bottom_mask = pygame.mask.from_surface(self.PIPE_BOTTOM)
top_offset = (self.x - bird.x, self.top - round(bird.y))
bottom_offset = (self.x - bird.x, self.bottom - round(bird.y))
b_point = bird_mask.overlap(bottom_mask, bottom_offset)
t_point = bird_mask.overlap(top_mask, top_offset)
if t_point or b_point:
return True
return False
class Base:
VEL = 5
WIDTH = Config.BASE_IMG.get_width()
IMG = Config.BASE_IMG
def __init__(self, y):
self.y = y
self.x1 = 0
self.x2 = self.WIDTH
def move(self):
self.x1 -= self.VEL
self.x2 -= self.VEL
if self.x1 + self.WIDTH < 0:
self.x1 = self.x2 + self.WIDTH
if self.x2 + self.WIDTH < 0:
self.x2 = self.x1 + self.WIDTH
def draw(self, win):
win.blit(self.IMG, (self.x1, self.y))
win.blit(self.IMG, (self.x2, self.y))
----------------------------------------------------------------
import classes_functions as cf
def main(genomes, config):
nets = []
ge = []
birds = []
for _, g in genomes:
net = cf.neat.nn.FeedForwardNetwork.create(g, config)
nets.append(net)
birds.append(cf.Bird(230, 350))
g.fitness = 0
ge.append(g)
base = cf.Base(730)
pipes = [cf.Pipe(600)]
win = cf.pygame.display.set_mode((cf.Config.WIN_WIDTH, cf.Config.WIN_HEIGHT))
clock = cf.pygame.time.Clock()
score = 0
run = True
while run:
clock.tick(30)
for event in cf.pygame.event.get():
if event.type == cf.pygame.QUIT:
run = False
cf.pygame.quit()
quit()
pipe_ind = 0
if len(birds) > 0:
if len(pipes) > 1 and birds[0].x > pipes[0].x + pipes[0].PIPE_TOP.get_width():
pipe_ind = 1
for x, bird in enumerate(birds):
bird.move()
ge[x].fitness += 0.1
output = nets[x].activate((bird.y, abs(bird.y - pipes[pipe_ind].height), abs(bird.y - pipes[pipe_ind].bottom)))
if output[0] > 0.5:
bird.jump()
add_pipe = False
removed_pipes = []
for pipe in pipes:
for x, bird in enumerate(birds):
if pipe.collide(bird):
ge[x].fitness -= 1
birds.pop(x)
nets.pop(x)
ge.pop(x)
if not pipe.passed and pipe.x < bird.x:
pipe.passed = True
add_pipe = True
if pipe.x + pipe.PIPE_TOP.get_width() < 0:
removed_pipes.append(pipe)
pipe.move()
if add_pipe:
score += 1
for g in ge:
g.fitness += 5
pipes.append(cf.Pipe(600))
for r in removed_pipes:
pipes.remove(r)
for x, bird in enumerate(birds):
if bird.y + bird.img.get_height() >= 730 or bird.y < 0:
birds.pop(x)
nets.pop(x)
ge.pop(x)
base.move()
cf.draw_window(win, birds , pipes, base, score)
if __name__ == '__main__':
cf.load_run()
____________________________________________________
I've been following this tutorial for rendering sprites from a spritesheet (up until the part regarding json files, because that seemed unnecessary for the project I'm working on), but when I run the code, the sprite I'm trying to render from the sheet doesn't appear on screen. I initially assumed that it was because the colour key was removing it (The sprites themselves are just black line art, so I made the background colour cyan, and then altered the code of the colour key slightly so that it wouldn't remove the black when colour keying (that is, replaced the "sprite.set_colorkey((0, 0, 0))" with "sprite.set_colorkey((0, 255, 255))" ).), however, I'm unable to figure to find the exact reason. Any ideas of what it could be and/or advice on troubleshooting?
I am not well acquainted witth pygame as I only ever used it to represent math stuff which I didn't know how to represent with matplotlib.
I am now trying to visualize a vector field interactively making small dots move across the screen depending on the field.
in order to visualize better the movement as a whole I found that not filling the screen up each frame improved things, but now after some time the screen is just filled with the small dots. is there a way to , instead of filling the screen with a solid color, filling it with an alpha layer so that the "older" traces left by the dots appear dimmer while at the same time not having to calculate every pixel manually? Currently the dots are not objects but just colorated pixels from an array of coordinates.
EDIT: repo currently hosted at https://github.com/NeekoKun/diffeq-renderer
If not, could you still* help
https://github.com/clear-code-projects/PirateMaker/blob/main/27_sound/editor.py
In the code, there is a single origin point that everything should be relative to. We're using a grid, so this method is used to obtain the cell position of this grid.
Im struggling with line 81, for the sake of understanding I wonder if it was a mistake.
If you want to get the cell position of the object, obj.distance_to_origin is the answer. You divide that by Tile_Size and you're done.
I tested this and it always gives cell position of the object relative to the origin, but the given code gives some erratic behavior.
I would really appreciate if someone could take the time out to explain what subtracting self.origin from obj.distance_to_origin even does.
edit: in the video, he says it is the same logic as for tiles (which is distance_to_origin for the first part of the statement before the conditional), except you are using the position of the object instead of the mouse position. That would make complete sense if you used obj.rect.topleft instead of obj.distance_to_origin (which completely works after checking), and I am really wondering if that is what he meant. But he went all the way through a ten hour video without changing this, and had no logical errors? And never changed his Github code either.
double edit: he even SPECIFIES later on, do not use obj.rect.topleft because it must be relative to the origin, and obj.distance_to_origin is more flexible. I really need help understanding what this does.
I've made a spritesheet that contains all of the sprites (which are facing right) I'm intending to use for the player character in my game's test build, and I'm trying to figure out how to make it so that pressing right renders the necessary section of the spritesheet to the screen, and pressing left will render the same section, but flipped horizontally. (This way I don't have to elongate the spritesheet by having separate sprites for the left and right directions).
(I would post my code, but I'm currently on mobile).
I am running into an error when trying to run a script with pygame_gui on Linux. The error reads: filenotfounderror: Unable to load resource with path: pygame_gui.data.NotoSans-Regular.ttf. Which seems like it cant locate the NotoSans-Regular font. However, the font is indeed installed. Has anybody run into this issue before?
This is going to be a long one:
Yesterday I started a new pygame project. I have not used pygame for over a year. I was writing the basics of a new project I was going to work on (clock, screen, main loop). When I ran my program for the first time the window started flickering (see video below). Then I tested all my old projects and the same thing was happening. The window becomes unresponsive after trying to close it.
What I am running:
Things I have tried:
Things I have observed:
so ive been trying to figure out why my text display isn't showing up. Its probably something super easy that I'm just over looking but I need help. I really new to all this and cant figure out the problem.
Script:
import pygame
import sys
import random
import math
pygame.init()
screen = pygame.display.set_mode((640, 480))
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
class Plane(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
# Define constants for plane states
self.STRAIGHT = 0
self.ROLL_R = 1
self.ROLL_L = 2
# Load regular plane images
self.load_images()
# Load shield images
self.load_shield_images()
# Set initial image and rect
self.image = self.image_stand
self.rect = self.image.get_rect()
self.rect.center = (320, 240)
# Other attributes
self.frame = 0
self.delay = 2
self.pause = 0
self.state = self.STRAIGHT
self.shield_active = False
self.shield_cooldown = 5000 # in milliseconds
self.shield_duration = 7000 # in milliseconds
self.shield_start_time = 0
def load_images(self):
# Load regular plane images
self.image_stand = pygame.image.load("images/pa_fold009.jpg")
self.image_stand = self.image_stand.convert()
tran_color = self.image_stand.get_at((1, 1))
self.image_stand.set_colorkey(tran_color)
self.r_roll_images = []
for i in range(10):
img_name = "images/pa_roll_right000%d.jpg" % i
tmp_image = pygame.image.load(img_name)
tmp_image = tmp_image.convert()
trans_color = tmp_image.get_at((1, 1))
tmp_image.set_colorkey(trans_color)
self.r_roll_images.append(tmp_image)
self.l_roll_images = []
for i in range(10):
img_name = "images/pa_roll_left000%d.jpg" % i
tmp_image = pygame.image.load(img_name)
tmp_image = tmp_image.convert()
trans_color = tmp_image.get_at((1, 1))
tmp_image.set_colorkey(trans_color)
self.l_roll_images.append(tmp_image)
def load_shield_images(self):
# Load shield images
self.shield_stand = pygame.image.load("images/plane_shield.jpg")
self.shield_stand = self.shield_stand.convert()
tran_color = self.shield_stand.get_at((1, 1))
self.shield_stand.set_colorkey(tran_color)
self.r_roll_shield_images = []
for i in range(10):
img_name = "images/plane_shield_roll_right.jpg"
tmp_image = pygame.image.load(img_name)
tmp_image = tmp_image.convert()
trans_color = tmp_image.get_at((1, 1))
tmp_image.set_colorkey(trans_color)
self.r_roll_shield_images.append(tmp_image)
self.l_roll_shield_images = []
for i in range(10):
img_name = "images/plane_shield_roll_left.jpg"
tmp_image = pygame.image.load(img_name)
tmp_image = tmp_image.convert()
trans_color = tmp_image.get_at((1, 1))
tmp_image.set_colorkey(trans_color)
self.l_roll_shield_images.append(tmp_image)
def update(self):
mousex, mousey = pygame.mouse.get_pos()
self.rect.center = (mousex, mousey)
self.pause += 0.5
if self.pause >= self.delay:
self.pause = 0
self.frame += 1
if self.frame >= len(self.r_roll_images):
self.frame = 0
self.state = self.STRAIGHT
self.image = self.image_stand
elif self.state == self.ROLL_R:
if self.shield_active:
self.image = self.r_roll_shield_images[self.frame]
else:
self.image = self.r_roll_images[self.frame]
elif self.state == self.ROLL_L:
if self.shield_active:
self.image = self.l_roll_shield_images[self.frame]
else:
self.image = self.l_roll_images[self.frame]
if self.shield_active:
current_time = pygame.time.get_ticks()
if current_time - self.shield_start_time >= self.shield_duration:
self.shield_active = False
self.load_images() # Reload original non-shield images
def activate_shield(self):
if not self.shield_active:
self.shield_active = True
self.shield_start_time = pygame.time.get_ticks() # Update shield start time
# print("Shield activated")
else:
self.shield_active = False
self.shield_start_time = 0
# print("Shield deactivated")
class NPCBullet(pygame.sprite.Sprite):
def __init__(self, npc_position, player_position):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((10,10))
self.image.fill((255,0,0))
self.rect = self.image.get_rect()
self.rect.center = npc_position
dx = player_position[0] - npc_position[0]
dy = player_position[1] - npc_position[1]
dist = max(1, math.sqrt(dx ** 2 + dy ** 2))
self.dx = dx / dist * 5
self.dy = dy / dist * 5
self.timer = 0 # Initialize timer
def update(self):
self.rect.x += self.dx
self.rect.y += self.dy
self.timer += 1 # Increment timer
if self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT or self.rect.right < 0 or self.rect.left > SCREEN_WIDTH:
self.kill()
if self.timer >= 35:
self.kill()
class NPC(pygame.sprite.Sprite):
def __init__(self, plane, npc_bullet_sprites):
pygame.sprite.Sprite.__init__(self)
self.plane = plane
self.npc_bullet_sprites = npc_bullet_sprites
self.image = pygame.image.load("images/NPC.bmp")
self.image = self.image.convert()
self.image = pygame.transform.flip(self.image, 0, 1)
self.image = pygame.transform.scale(self.image, (160, 120))
tranColor = self.image.get_at((1, 1))
self.image.set_colorkey(tranColor)
self.rect = self.image.get_rect()
self.rect.center = (
random.randrange(0, screen.get_width()),
random.randrange(0, screen.get_height()),
) # Randomize NPC position
self.dx = 5
self.dy = 5
self.shieldAmt = 100
self.shooting_rate = 0.5 # Adjust shooting rate here
self.last_shot_time = pygame.time.get_ticks()
self.respawn_delay = 24000 # Adjust respawn delay here (in milliseconds)
self.respawn_timer = 0
self.respawn_trigger = False
def update(self):
if self.respawn_trigger:
self.respawn_timer += 1
if self.respawn_timer >= self.respawn_delay:
self.reset()
self.respawn_trigger = False
self.respawn_timer = 0
else:
self.rect.centerx += self.dx
self.boundaryCheck()
self.shoot()
def boundaryCheck(self):
if self.rect.centerx >= screen.get_width():
self.dx *= -1
elif self.rect.centerx <= 0:
self.dx *= -1
def reset(self):
self.rect.center = (
random.randrange(0, screen.get_width()),
random.randrange(0, screen.get_height()),
) # Reset NPC position
self.dx *= -1
self.boundaryCheck()
self.shieldAmt = 100
def shoot(self):
current_time = pygame.time.get_ticks()
if current_time - self.last_shot_time > 1000 / self.shooting_rate:
npc_bullet = NPCBullet(self.rect.center, self.plane.rect.center)
self.npc_bullet_sprites.add(npc_bullet)
self.last_shot_time = current_time
def hit(self):
self.respawn_trigger = True
class Ocean(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images/ocean.gif")
self.rect = self.image.get_rect()
self.dy = 5
class Bullet(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((15, 15))
self.image.fill((255, 255, 255))
pygame.draw.circle(self.image, (0, 0, 0), (7, 7), 7)
self.rect = self.image.get_rect()
self.dy = 0
self.timer = 0
def update(self):
self.dy = -10
self.rect.centery += self.dy
self.timer += 1
if self.timer >= 25: # Adjust the timer value as needed
print("BOOM")
self.kill()
def game():
pygame.display.set_caption("Paper Air Force")
background = pygame.Surface(screen.get_size())
background.fill((0, 0, 0))
screen.blit(background, (0, 0))
plane = Plane()
ocean = Ocean()
bullet = Bullet()
npc_bullet_sprites = pygame.sprite.Group()
npc = NPC(plane, npc_bullet_sprites)
# Font initialization
pygame.font.init()
font = pygame.font.SysFont(None, 36) # Change the font size as needed
pygame.key.set_repeat(1, 1)
oceanSprites = pygame.sprite.Group(ocean)
planeSprites = pygame.sprite.Group(plane)
bulletSprites = pygame.sprite.Group()
npcSprites = pygame.sprite.Group(npc)
clock = pygame.time.Clock()
cntdwn = pygame.USEREVENT + 1 # Creates a custom user event that will create a simple countdown
pygame.time.set_timer(cntdwn, 1000) # uses milliseconds
cntdwn_sec = 60 # in seconds
keepGoing = True
while keepGoing:
clock.tick(30)
pygame.mouse.set_visible(False)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
pygame.display.quit()
pygame.quit()
sys.exit()
if event.type == cntdwn:
if cntdwn_sec > 0:
cntdwn_sec -= 1
print("Countdown:", cntdwn_sec)
else:
print("times up!")
keepGoing = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullet = Bullet()
bulletSprites.add(bullet)
bullet.rect.center = plane.rect.center
elif event.key == pygame.K_q:
plane.activate_shield()
if event.type == pygame.MOUSEMOTION:
mouseDir = pygame.mouse.get_rel()
if mouseDir[0] > 0:
plane.state = plane.ROLL_R
if mouseDir[0] < 0:
plane.state = plane.ROLL_L
if mouseDir[0] == 0:
plane.state = plane.STRAIGHT
shootNPCs = pygame.sprite.groupcollide(bulletSprites, npcSprites, True, False)
if shootNPCs:
for npc_hit in shootNPCs.values():
for npc in npc_hit:
npc.reset()
oceanSprites.update()
planeSprites.update()
bulletSprites.update()
npcSprites.update()
npc_bullet_sprites.update()
# Draw text for shield duration and cooldown
current_time = pygame.time.get_ticks()
shield_text = font.render("Shield: {:.2f} sec".format(plane.shield_duration / 1000), True, (255, 255, 255))
cooldown_text = font.render("Cooldown: {:.2f} sec".format(plane.shield_cooldown / 1000), True, (255, 255, 255))
screen.blit(shield_text, (10, 10)) # Adjust the position of the text as needed
screen.blit(cooldown_text, (10, 40)) # Adjust the position of the text as needed
oceanSprites.draw(screen)
planeSprites.draw(screen)
bulletSprites.draw(screen)
npcSprites.draw(screen)
npc_bullet_sprites.draw(screen)
pygame.display.flip()
pygame.mouse.set_visible(True)
if __name__ == "__main__":
game()
Im a beginner in python / pygame and I have a problem with this simple code:
import pygame
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
posY_player = 300
posX_player = 400
wall1 = pygame.Rect((0, 0, 50, 600))
wall2 = pygame.Rect((750, 0, 50, 600))
wall3 = pygame.Rect((0, 0, 800, 50))
wall4 = pygame.Rect((0, 550, 800, 50))
walls = [50, 750]
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
player = pygame.Rect((400, 300, 50 ,50))
run = True
while run == True:
screen.fill((0, 6, 0))
pygame.draw.rect(screen, (255, 0, 6), wall1)
pygame.draw.rect(screen, (255, 0, 6), wall2)
pygame.draw.rect(screen, (255, 0, 6), wall3)
pygame.draw.rect(screen, (255, 0, 6), wall4)
pygame.draw.rect(screen, (255, 45, 78), player)
key = pygame.key.get_pressed()
if key[pygame.K_a] == True:
posX_player -= 1
player.move_ip(-1, 0)
elif key[pygame.K_d] == True:
posX_player += 1
player.move_ip(1, 0)
elif key[pygame.K_s] == True:
posY_player += 1
player.move_ip(0, 1)
elif key[pygame.K_w] == True:
posY_player -= 1
player.move_ip(0, -1)
print(posY_player)
print(posX_player)
if player.collidepoint(49 , posY_player):
player.move_ip(1, 0)
elif player.collidepoint(750 , posY_player):
player.move_ip(-1, 0)
elif player.collidepoint(posX_player , 50):
player.move_ip(0, 1)
elif player.collidepoint(posX_player , 550):
player.move_ip(0, -1)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.update()
pygame.quit()
import pygame
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
posY_player = 300
posX_player = 400
wall1 = pygame.Rect((0, 0, 50, 600))
wall2 = pygame.Rect((750, 0, 50, 600))
wall3 = pygame.Rect((0, 0, 800, 50))
wall4 = pygame.Rect((0, 550, 800, 50))
walls = [50, 750]
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
player = pygame.Rect((400, 300, 50 ,50))
run = True
while run == True:
screen.fill((0, 6, 0))
pygame.draw.rect(screen, (255, 0, 6), wall1)
pygame.draw.rect(screen, (255, 0, 6), wall2)
pygame.draw.rect(screen, (255, 0, 6), wall3)
pygame.draw.rect(screen, (255, 0, 6), wall4)
pygame.draw.rect(screen, (255, 45, 78), player)
key = pygame.key.get_pressed()
if key[pygame.K_a] == True:
posX_player -= 1
player.move_ip(-1, 0)
elif key[pygame.K_d] == True:
posX_player += 1
player.move_ip(1, 0)
elif key[pygame.K_s] == True:
posY_player += 1
player.move_ip(0, 1)
elif key[pygame.K_w] == True:
posY_player -= 1
player.move_ip(0, -1)
print(posY_player)
print(posX_player)
if player.collidepoint(49 , posY_player):
player.move_ip(1, 0)
elif player.collidepoint(750 , posY_player):
player.move_ip(-1, 0)
elif player.collidepoint(posX_player , 50):
player.move_ip(0, 1)
elif player.collidepoint(posX_player , 550):
player.move_ip(0, -1)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.update()
pygame.quit()
Because only the first two walls the player is touching (up and down or left and right) are functioning. It is my first try with pygame so it probably (and hopfully) is an easy fix.
I'm trying to detect when a clipping mask collides with the edge of a window. My current code works like this:
def checkEdge(self, window:Surface):
windowMask:pygame.mask.Mask = pygame.mask.from_surface(window)
fullArea = self.hitbox.overlap_area(windowMask, (0,0))
currentArea = self.hitbox.overlap_area(windowMask, self.pos)
print(f"Full Area: {fullArea}")
print(f"Current Area: {currentArea}")
return currentArea == fullArea
when I run it, it outputs:
Full Area: 400
Current Area: 0
this doesn't change when the object goes off screen Any ideas?
I'm trying to install pygame_menu for a game i'm working on but everytime i run this code:
pip install pygame_menu
I get this error:
Could not fetch URL https://pypi.org/simple/pygame-menu/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pygame-menu/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)'))) - skipping
ERROR: Could not find a version that satisfies the requirement pygame-menu (from versions: none)
ERROR: No matching distribution found for pygame-menu
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)'))) - skipping
Are there any fixes?
Hello, I am new to pygame and coding in general. I want to add a login function where there would be a login button that you can press which would switch the screen and create text entry for people to be able to login. The button works fine, but the text entry doesn't appear on the screen after it has switched. I'm not sure why it's not working and was wondering if I could get some help with this if possible. Sorry if the code is not very efficient, I am still pretty new to this.
Here is the link to the code: https://pastebin.com/hyKRxvyX
Ive tried everything to auto start this pipboy replica pygame at boot on my rpi4 running bullseye on a 3.5" touch screen. I've tried cron jobs, autostart lxde, .profile edits. Nothing has worked. The code for the pipboy I'm using is here. https://github.com/ColtonMcCasland/pypboy3000
What is the trick to get the main.py to run at startup in the desktop?
Exactly what the title says. I have a flight simulator and I wanted to position some buildings on the ground, and I was trying to find the bottom corner instead of the top one to position them. How can I find these coordinates?
code:
def flip(sprites):
return [pygame.transform.flip(sprite ,True,False) for sprite in sprites]
def load_spite_sheets(dir1,dir2,width,heigth,direction=False):
path = join("assets", dir1, dir2)
images = [f for f in listdir(path) if isfile(join(path, f))]
all_sprites = {}
for image in images:
sprite_sheet = pygame.image.load(join(path, image)).convert_alpha()
sprites = []
for i in range(sprite_sheet.get_width() // width):
surface = pygame.Surface((width, heigth), pygame.SRCALPHA, 32)
rect = pygame.Rect(i * width, 0, width, heigth)
surface.blit(sprite_sheet, (0, 0), rect)
sprites.append(pygame.transform.scale2x(surface))
if direction:
all_sprites[image.replace(".png", "") + "_right"] = sprites
all_sprites[image.replace(".png", "") + "_left"] = flip(sprites)
else:
all_sprites[image.replace(".png", "")] = sprites
return all_sprites
class Player(pygame.sprite.Sprite):
COLOR = (255, 0, 255)
GRAVITY=1
SPRITES=load_spite_sheets("MainCharacters","PinkMan",32,32,True)
ANIMATION_DELAY=5
def __init__(self,x,y,width,height):
super().__init__()
self.rect=pygame.Rect(x,y,width,height)
self.x_vel=0
self.y_Vel=0
self.mask=None
self.direction="left"
self.animation_count=0
self.fall_count=0
def move(self,dx,dy):
self.rect.x+=dx
self.rect.y+=dy
def move_left(self,vel):
self.x_vel=-vel
if self.direction!="left":
self.direction="left"
self.animation_count=0
def move_right(self,vel):
self.x_vel=vel
if self.direction!="right":
self.direction="right"
self.animation_count=0
def loop(self,fps):
#self.y_Vel+=min(1,(self.fall_count/fps)*self.GRAVITY)
self.move(self.x_vel,self.y_Vel)
self.fall_count+=1
self.update_sprite()
def update_sprite(self):
sprite_sheet="idle"
if self.x_vel != 0:
sprite_sheet = "run"
sprite_sheet_name = sprite_sheet + "_" + self.direction
sprites = self.SPRITES[sprite_sheet_name]
sprite_index = (self.animation_count // self.ANIMATION_DELAY) % len(sprites)
self.sprite = sprites[sprite_index]
self.animation_count += 1
def draw(self,win):
win.blit(self.sprite,(self.rect.x,self.rect.y))
Asked ChatGPT to give me an example and we came up with this after a little bit:
import pygame
import random
import math
# Define some colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# Define window dimensions
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
# Define component types
class PositionComponent:
def __init__(self, x, y):
self.x = x
self.y = y
class ColorComponent:
def __init__(self, color):
self.color = color
class VelocityComponent:
def __init__(self, vx, vy):
self.vx = vx
self.vy = vy
# Define Entity
class Entity:
def __init__(self, *components):
self.components = components
# Function to generate random color
def random_color():
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
# Function to create random entities
def create_entities(num_entities):
entities = []
for _ in range(num_entities):
angle = random.uniform(0, 2 * math.pi)
radius = random.uniform(50, min(WINDOW_WIDTH, WINDOW_HEIGHT) / 2)
x = WINDOW_WIDTH / 2 + radius * math.cos(angle)
y = WINDOW_HEIGHT / 2 + radius * math.sin(angle)
color = random_color()
position = PositionComponent(x, y)
color_comp = ColorComponent(color)
direction_x = 3 - int(random.uniform(0, 2 * math.pi))
direction_y = 3 - int(random.uniform(0, 2 * math.pi))
velocity = VelocityComponent(direction_x, direction_y)
entity = Entity(position, color_comp, velocity)
entities.append(entity)
return entities
# Function to calculate distance between two entities
def distance(entity1, entity2):
pos1 = entity1.components[0] # PositionComponent of entity1
pos2 = entity2.components[0] # PositionComponent of entity2
return math.sqrt((pos1.x - pos2.x) ** 2 + (pos1.y - pos2.y) ** 2)
# Function to update entities
def update_entities(entities):
for entity in entities:
position = None
velocity = None
for component in entity.components:
if isinstance(component, PositionComponent):
position = component
elif isinstance(component, VelocityComponent):
velocity = component
angle = math.atan2(position.y - WINDOW_HEIGHT / 2, position.x - WINDOW_WIDTH / 2)
distance_from_center = math.sqrt((position.x - WINDOW_WIDTH / 2) ** 2 + (position.y - WINDOW_HEIGHT / 2) ** 2)
speed = random.uniform(0, 1) * 0.0001 # Adjust this value to change the speed of entity movement
velocity.vx += math.cos(angle) * speed
velocity.vy += math.sin(angle) * speed
position.x += velocity.vx
position.y += velocity.vy
# Change direction if entity reaches the edge of the screen
if position.x < 0 or position.x > WINDOW_WIDTH:
velocity.vx = -velocity.vx
if position.y < 0 or position.y > WINDOW_HEIGHT:
velocity.vy = -velocity.vy
# Function to draw entities and lines between nearest neighbors
def draw_entities(screen, entities):
for i, entity in enumerate(entities):
for component in entity.components:
if isinstance(component, PositionComponent):
x1 = int(component.x)
y1 = int(component.y)
elif isinstance(component, ColorComponent):
color = component.color
nearest_neighbor = None
min_dist = float('inf')
for j, other_entity in enumerate(entities):
if i != j:
dist = distance(entity, other_entity)
if dist < min_dist:
min_dist = dist
nearest_neighbor = other_entity
r = random.randrange(0, 255)
g = random.randrange(0, 255)
b = random.randrange(0, 255)
line_color = (r, g, b, 255) # Black color with transparency based on distance
if min_dist <= 255:
r = random.randrange(0, 255)
g = random.randrange(0, 255)
b = random.randrange(0, 255)
line_color = (r, g, b, min(255, int(255 - min_dist))) # Black color with transparency based on distance
for component in nearest_neighbor.components:
if isinstance(component, PositionComponent):
x2 = int(component.x)
y2 = int(component.y)
if dist <= 1000:
for component in nearest_neighbor.components:
if isinstance(component, PositionComponent):
x2 = int(component.x)
y2 = int(component.y)
pygame.draw.line(screen, line_color, (x1, y1), (x2, y2))
pygame.draw.circle(screen, color, (x1, y1), 10)
def main():
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("ECS with Pygame")
clock = pygame.time.Clock()
entities = create_entities(20)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4: # Scroll up
for entity in entities:
position = entity.components[0] # PositionComponent
angle = math.atan2(position.y - WINDOW_HEIGHT / 2, position.x - WINDOW_WIDTH / 2)
distance = math.sqrt((position.x - WINDOW_WIDTH / 2) ** 2 + (position.y - WINDOW_HEIGHT / 2) ** 2)
distance += 10 # Increase distance by 10 pixels
position.x = WINDOW_WIDTH / 2 + distance * math.cos(angle)
position.y = WINDOW_HEIGHT / 2 + distance * math.sin(angle)
elif event.button == 5: # Scroll down
for entity in entities:
position = entity.components[0] # PositionComponent
angle = math.atan2(position.y - WINDOW_HEIGHT / 2, position.x - WINDOW_WIDTH / 2)
distance = math.sqrt((position.x - WINDOW_WIDTH / 2) ** 2 + (position.y - WINDOW_HEIGHT / 2) ** 2)
distance -= 10 # Decrease distance by 10 pixels
position.x = WINDOW_WIDTH / 2 + distance * math.cos(angle)
position.y = WINDOW_HEIGHT / 2 + distance * math.sin(angle)
screen.fill(BLACK)
update_entities(entities)
draw_entities(screen, entities)
pygame.display.flip()
clock.tick(60)
pygame.quit()
if __name__ == "__main__":
main()
Hi, i use this function "minimize" to scale the image during game loop with scale[1] it's value is .9 .8 and keep decreas until 0 like code below
but it seems like nothing hapen. i have this video to show you the problem. the numbers in top left are list of scale values.
thank you in advance and sorry for my bad english
Heres the github link. I also need this done really soon, please help.
https://github.com/DigitalDman/Rainfall
Hello, I am new to pygame. I have been working on a game where a timer constantly counts up and every 60 seconds the enemies get faster and the timer resets back to 0. I have been trying to find a way to make it where when the player presses "Enter," and the game pasues, everything stops moving until Enter is pressed again. When this is done in my program everything is stopped except the timer. I have been trying to find a way to grab the amount of time that has passed sense the game was paused and subtract it from the current time with not much luck. I looked at a few examples online but they did not seem to work with what I have for my setup.
The timer related displays and code are found around line 608.
The if else statements for grabbing the time when the pause starts and the total time the game has been paused can be found on lines 332 and 334.
Sorry if the code is a bit of a mess, I was testing lots of different things.
Link to Code --> https://pastebin.com/AG972d0b
No errors in my code but for some reason it keeps closing about 1 second after trying to run it
Update: Thanks guys! I fortunately managed to figure it out!
I’m essentially generating a pattern iteratively so this isn’t really about programming frames of a preloaded image. Thanks in advance