python – ¿Cómo mover un sprite después de actualizarlo en pygame?

Espero tengan un buen día actualmente estoy desarrollando un juego con pygame y actualmente me encuentro estancando en la parte del movimiento de los sprites,lo que llevo hasta ahorita es que se cargue el sprite estándar pero a la hora de presionar la tecla “d” para mover hacia la izquierda si carga el otro sprite pero no hace el movimiento, por favor ayúdenme llevo dos días intentando resolverlo, se los agradecería muchísimo.

    import pygame
from pygame.locals import *

#- Funciones -
class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("gab0.png").convert()
        self.image.set_colorkey((0, 0, 0))
        self.rect = self.image.get_rect()
        self.rect = pygame.Rect.move(self.rect, 420, 340)
        self.image=pygame.transform.scale(self.image,(220,220))
        
class Player2(pygame.sprite.DirtySprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("gaboc.png").convert()
        self.image.set_colorkey((0, 0, 0))
        self.rect = self.image.get_rect()
        self.rect = pygame.Rect.move(self.rect, 420, 340)
        self.image=pygame.transform.scale(self.image,(220,220))
        self.velocidad=0
    
        
#- Ventana -
pygame.display.set_caption("CCGame")
screen=pygame.display.set_mode((1000, 550))
display_rect = screen.get_rect()
bg=pygame.image.load("fondo.png").convert()

# - Sprites -
all_sprites = pygame.sprite.Group()

player = Player()

all_sprites.add(player)

#- Cerrar la ventana -
clock=pygame.time.Clock()
done=False

#- bucle principal -
while not done:
    
    #- moviendo el personaje -
    player2=Player2()
    tecla=pygame.key.get_pressed()
    if tecla(K_d):
        all_sprites.add(player2)
        pygame.sprite.Sprite.kill(player)
        all_sprites.update()
        all_sprites.draw(screen)
    if player2.velocidad <=0:
        player2.rect.right += player2.velocidad

    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            done=True
            
    #- Actualizando venta y sprites 
    all_sprites.update()
    screen.blit(bg, (0, 0))
    all_sprites.draw(screen)
    pygame.display.flip()
    clock.tick(60)
    
pygame.quit()

python – When using pygame and pyinstaller I get an error telling me “excpected str, bytes or os.Pathlike object, not BytesIO

I’ve been making a small game in pygame where you click on a rectangle, it disappears with a small animation and then pops up in a new random place on the screen. I used pyinstaller to make the file executable so my friends could try out what I made, but when I made the exe with pyinstaller (file) –onefile –noconsole and then opened it in the same folder as my assets folder, this error pops up.
Any ideas?

enter image description here

enter image description here

pygame – Layer sprites according to their vertical position

I need advanced blitting options in my game. It’s a 2D game that has trees’ sprites along with the player’s sprite.

I want that every tree sprite to be displayed either in front of or behind the player sprite, depending on whether the player is standing higher or lower on the screen than the tree’s base.

These are the possible cases :

cases

I have an idea in mind, which is to check for the player’s coordinates and depending on them, blit the tree’s sprite underneath it or above it (respecting the layers system). However, I think that this won’t work or will make the tree’s sprite flicker in case there is more than one player (or another object that can pass beside the tree). So what is a good solution for that ?

The reason why I want to solve this problem is adding some depth and reality into the game though it’s a 2D one.

sprites – Pygame advanced blitting and collision options

I need advanced collision detection and blitting options in my game as the latter is a 2D game that has trees’ sprites along with the player’s sprite.

I want that every tree sprite gets blitted at a specific position relatively with the player’s coordinates.
Take a look at the images below:

CASE 1 :

case 1

Case 2:

case2

So I just want to get the result shown in the previous pictures so that the game works a little more realistic though it’s a 2D one.

partial collision detection

As you can see in this image, I want to detect collision only between the player and a part of the tree (that’s in this case the bottom of the trunk). This is because it won’t be realistic at all to detect collision with the entire tree and prevent the player from moving “underneath” it (as it looks in 2d games).

Back to the blitting options, I have an idea in mind which is check for the player’s coordinates and depending on them, blit the tree’s sprite underneath it or above it (respecting the layers system). However, I think that this won’t work or will make the tree’s sprite flicker in case there is more than one player (or another object that can pass beside the tree). So what is a good solution for that ?

Regarding the collision detection, I also got a good idea in my mind that is to make an independent sprite for the part of the tree that I need to check collision with and blit it in a way that it can’t seem to be independent from the entire tree and then check collision between it and player(s). Yet, I guess there is a better implementation using subsurfaces, no ?

To conclude, I want to implement the 2 features I have explained in a coherent way.

mathematics – Pygame : problem with calculating an angle between two points

I’ve been struggling to calculate the angle alpha between an object and a certain point M so that I can move that object to M.

To calculate alpha, I’m using trigonometry and more precisely the atan2 function from the python math module :

class Obj:
...
    @property
    def alpha(self):
        return atan2(self.center(1) - my, self.center(0) - mx)

The problem I’m struggling with is that alpha, the calculated angle is not accurate.
Take a look at this image :

image

So as the representation shows, in a situation where the obj and the point M are aligned, and that obj is on top of M, alpha is equal to 90 degrees !!

I can’t understand why this happens. I know in math that a straight line is 180° or pi radians but not 90° !

Furthermore, if the point M was situated on top of the object on the screen, alpha will be negative.

What I want to do, is to suppose that the center of the obj is center of an ‘imaginary’ circle. Then, calculate the angle between the obj and M just like the image below shows :

This means that I want alpha to be equal to zero degrees if M is on the right of the obj forming a horizontal line, and I want it to be equal to 90° if M is on top of the obj forming a vertical line and so on ..

python – Generar sonido al clickar la imagen Pygame

Trabajando con pygame, he creado un programa que genera diversas cosas en pantalla (puntuación, cajita para introducir respuestas…). Entre todo ésto, hay una imagen en medio de la pantalla llamada Clickaudio1.png
Quisiera que la imagen generara un áudio cada vez que el usuario diera click sobre ella, utilizando mixer del mismo pygame. Qué canvios debería hacer para llevar ésto a cabo?

import pygame
from InputBox import InputBox

pygame.init()
#Variables
yousayrun = True
clock = pygame.time.Clock()
pointz = 0
base_font = pygame.font.Font(None, 32)
user_text = ''
color_active = pygame.Color('lightskyblue3')

def main():
    pygame.init()
    surface = pygame.display.set_mode((600,400))
    surface.fill((255, 70, 90))

    #Aquí se genera la imagen 
    imageaudio1 = pygame.image.load("ClickAudio1.png").convert()
    surface.blit(imageaudio1,(190,70))

    font = pygame.font.SysFont('comicsans', 50)
    punts = font.render("Puntuació: " + str(pointz), True, (255, 255, 255))
    surface.blit(punts, (350, 30))
    titolsuma3 = font.render("SUMA (3)", True, (0, 0, 0))
    surface.blit(titolsuma3, (10, 20))
    pygame.display.set_caption("Projecte MatZanfe")
    input_box.draw(surface)
    pygame.display.flip()

input_box = InputBox(190, 250, 200, 32)

#Main Loop
while yousayrun:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            yousayrun = False
        else:
            main()
            result = input_box.handle_event(event)
            if result != None:
                if int(result) == int(5):
                    pointz = pointz + 5

                input_box = InputBox(190, 250, 200, 32)
        pygame.display.update()

pygame.quit()

Aunque no es necesario, la InputBox importada se puede encontrar aquí por si la queréis hechar un ojo: https://github.com/Maskedllama/InputBox/blob/main/InputBox.py

Unable to restart level in Pygame

So, I am making Flappy Bird and when the player dies I have the spacebar assigned to reset the game.
However, it’s not working and I truly have no idea why (after like 3 hours of going through tutorials and rereading the code).

import pygame
import random

# Initiating pygame
pygame.init()

# Variables:
FPS = 60

WHITE = (255, 255, 255)

ORIGIN = (0, 0)
ground_X_pos = 0

run = True
not_collided = True

BIRD_STARTING_POS = (50, 280)
bird_pos = 0
gravity = 0.3

pipe_list = ()
available_pipe_height = (300, 310, 320, 330, 340, 350,
                         360, 370, 380, 390, 400, 410, 420, 430, 440, 450)
SPAWN_PIPE = pygame.USEREVENT

GAP = 200

# Setting the display window
pygame.display.set_caption("Crappy Bird")

SCREEN_DIMENSIONS = (352, 600)
SCREEN = pygame.display.set_mode(SCREEN_DIMENSIONS)

# Loading required images as surfaces
bg = pygame.image.load("assets/sprites/background-day.png").convert()
bg = pygame.transform.scale(bg, SCREEN_DIMENSIONS)

ground = pygame.image.load("assets/sprites/base.png").convert()
ground = pygame.transform.scale(ground, (352, 75))

bird = pygame.image.load("assets/sprites/yellowbird-midflap.png").convert()
bird = pygame.transform.scale(bird, (50, 34))

pipe = pygame.image.load("assets/sprites/pipe-red.png").convert()

_game_over = pygame.image.load("assets/sprites/gameover.png")
_game_over = pygame.transform.scale(_game_over, (352, 77))

# Loading required rectangles
bird_rect = bird.get_rect(center=BIRD_STARTING_POS)

# Spawning pipes
pygame.time.set_timer(SPAWN_PIPE, 1010)


# This will load all the required surfaces of entities
def update(_pipe_list):
    # Loading in background surfaces
    SCREEN.blit(bg, ORIGIN)

    # Loading in the bird
    SCREEN.blit(bird, bird_rect)

    # Loading in the pipes
    for _pipe in _pipe_list:
        if _pipe.bottom >= 600:
            SCREEN.blit(pipe, _pipe)
        else:
            _pipe_ = pygame.transform.flip(pipe, False, True)
            SCREEN.blit(_pipe_, _pipe)

    # Loading in the ground
    SCREEN.blit(ground, (ground_X_pos, 525))
    SCREEN.blit(ground, (ground_X_pos + 352, 525))


# This will spawn in pipes
def spawn_pipe():
    seed = random.choice(available_pipe_height)

    bottom_pipe = pipe.get_rect(midtop=(360, seed))
    top_pipe = pipe.get_rect(midbottom=(360, seed - GAP))

    return bottom_pipe, top_pipe


# Puts the pipe in their correct positions
def pipe_pos(_pipe_list):
    for _pipe in _pipe_list:
        _pipe.centerx -= 5

    return _pipe_list


# This checks if the bird has collided with anything or not
def collision_checker(_pipe_list):
    for _pipe in _pipe_list:
        if bird_rect.colliderect(_pipe):
            return False
        else:
            pass

        if bird_rect.bottom >= 525 or bird_rect.top <= 0:
            return False
        else:
            pass

    return True


def game_over():
    SCREEN.fill(WHITE)
    SCREEN.blit(_game_over, (0, 261.5))


# This is the main loop for running the game
while run:
    # Setting a fixed frame rate
    pygame.time.Clock().tick(FPS)

    # Checking if the game needs to be closed
    for event in pygame.event.get():  # pygame.event.get() gets all events occurring (like key press, mouse clicks, etc)
        if event.type == SPAWN_PIPE:
            pipe_list.extend(spawn_pipe())
        else:
            pass

        if event.type == pygame.QUIT:
            run = False
        else:
            pass

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE and not_collided:
                bird_pos = 0
                bird_pos -= 8.25
            else:
                pass

            if event.type == pygame.K_SPACE:
                bird_pos = 0
                bird_rect.center = BIRD_STARTING_POS
                print("Debug : This works.")
                pipe_list.clear()

                not_collided = True
            else:
                pass
        else:
            pass

    # Running the game
    if not_collided:
        update(pipe_list)
        ground_X_pos -= 5

        if ground_X_pos <= -352:
            ground_X_pos = 0
        else:
            pass

        bird_pos += gravity
        bird_rect.centery += bird_pos

        pipe_list = pipe_pos(pipe_list)

        not_collided = collision_checker(pipe_list)

    #Ending the game
    if not not_collided:
        game_over()

    pygame.display.update()

pygame.quit()

It gets stuck on this screen.

help_me_please

python – Pygame inaccurate countdown from a self-made timer class

I’ve been making a simple Timer class to use it in my pygame projects .
Here is a part of it :

class Timer:
    def __init__(self):
        self.event = USEREVENT+20
        self.time_left = 0
        self.reinit = True
       pygame.time.set_timer(self.event, 100)

    def countdown(self, start, event_queue):
        if self.reinit:
            self.time_left = start
            self.reinit = False
        for e in event_queue:
            if e.type == self.event:
                self.time_left -= 0.1
        if self.time_left <= 0:
            self.time_left = 0
        formatted = f'{self.time_left:.2f}'
        return float(formatted)

timer = Timer()

Notice that I’m using a self.reinit boolean and that’s to be able to restart the countdown and not just use it once:

def move(self):
    ...
    if mycondition:
        self.hurry_up()
    else:
        timer.reinit = True

def hurry_up(self):
    if condition:
        time_left = timer.countdown(10, events)
        print(time_left)
        if time_left == 0:
           # do smth

The problem that I’m facing is that the countdown runs very fast, the countdown from 10 to 0 takes less than 5 seconds !
For me, I believe the issue is related to the framerate, so keep in mind that I’m running my game at a max of 50 FPS.

Now how can I solve that ?