0

I'm trying to create a more efficient game with pygame following some example I was able to find online. Basically right now I'm creating various state in different files that are then managed by the game.py and the main.py file. My problem is I'm having an hard time understanding how to use the code for my needs: in my code after showing two random images in the left and in the right side of the screen I'd like to use the def answer(self) to show the self.answered_img in the middle of the screen after a keyboard character("q" or "r") is pressed and then wait two seconds before showing other two random images: Usually I would have done this by writing

def answer(self): 
   self.screen.blit(self.answered_img, middle_rect)
   pygame.time.wait(2000)

but with my current code structure I have not the self.screen variable. This is the rest of my code

game_app.py

import pygame
from .base import BaseState
import os

import random


class GameApp(BaseState):
    def __init__(self):
        super(GameApp, self).__init__()

        self.answered_img = pygame.image.load(
            os.path.join("data", "assets", "images", "feedback", "img_feedback_0.png")
        )

        image_path = os.path.join("data", "assets", "images", "stimuli")

        self.dict = {}

        ## One
        one_path = os.path.join(image_path, "blue")
        one_path_list = os.listdir(one_path)

        self.dict[0] = [
            (
                pygame.image.load(os.path.join(one_path, path)),
                os.path.basename(os.path.join(one_path, path)),
            )
            for path in one_path_list
        ]

        ## Two
        two_path = os.path.join(image_path, "orange")
        two_path_list = os.listdir(two_path)

        self.dict[1] = [
            (
                pygame.image.load(os.path.join(two_path, path)),
                os.path.basename(os.path.join(two_path, path)),
            )
            for path in two_path_list
        ]

        self.image()

    def get_event(self, event):
        if event.type == pygame.QUIT:
            self.quit = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                self.quit = True
            if event.key == pygame.K_q:
                print("q")
                self.keyboard_pressed()
            if event.key == pygame.K_r:
                print("r")
                self.keyboard_pressed()

    def draw(self, surface):
        surface.fill(pygame.Color("black"))

        left_rect = self.left_image.get_rect(midleft=(50, surface.get_height() / 2))

        right_rect = self.right_image.get_rect(
            midright=(surface.get_width() - 50, surface.get_height() / 2)
        )

        surface.blit(self.left_image, left_rect)
        surface.blit(self.right_image, right_rect)

    def keyboard_pressed(self):
        self.answer()

        self.image()

    def image(self):
        left_list = self.dict[0]
        self.left_image = random.choice(left_list)[0]

        right_list = self.dict[1]
        self.right_image = random.choice(right_list)[0]

    def answer(self):

    # show the self.ansered_img

        pygame.time.wait(2000)


this is the rest of my code: main.py

pygame.init()
pygame.mouse.set_visible(False)

screen = pygame.display.set_mode((800, 600))

states = {
    "GAME_APP": GameApp(),
}

game = Game(screen, states, ""GAME_APP": ")
game.run()

pygame.quit()
sys.exit()

game.py

import pygame


class Game(object):
    def __init__(self, screen, states, start_state):
        self.done = False
        self.screen = screen
        self.clock = pygame.time.Clock()
        self.fps = 60
        self.states = states
        self.state_name = start_state
        self.state = self.states[self.state_name]

    def event_loop(self):
        for event in pygame.event.get():
            self.state.get_event(event)

    def flip_state(self):
        current_state = self.state_name
        next_state = self.state.next_state
        self.state.done = False
        self.state_name = next_state
        persistent = self.state.persist
        self.state = self.states[self.state_name]
        self.state.startup(persistent)

    def update(self, dt):
        if self.state.quit:
            self.done = True
        elif self.state.done:
            self.flip_state()
        self.state.update(dt)

    def draw(self):
        self.state.draw(self.screen)

    def run(self):
        while not self.done:
            dt = self.clock.tick(self.fps)
            self.event_loop()
            self.update(dt)
            self.draw()
            pygame.display.update()

How can I show an image in different functions that are not the def draw(self, surface) one?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Diana Mele
  • 135
  • 8
  • You have a state manager, so use it. `pygame.time.wait(2000)` should not be necessary. Instead, you should set a state and draw the scenery depending on that state. Never `wait()` on anything in the application loop. This makes your program unresponsive. (also see [How to wait some time in pygame?](https://stackoverflow.com/questions/18839039/how-to-wait-some-time-in-pygame)) – Rabbid76 Feb 22 '23 at 15:25
  • Thanks for your help! I'm having trouble understanding how I should set a state and draw depending on that. Could you provide me an example? I want to display two images and after that my uer give a keyboard input show the answered_image for some second and then show other two images. Is it posssible without using wait() ? – Diana Mele Feb 24 '23 at 13:14

0 Answers0