Cesar Ortiz
Cesar Ortiz

Reputation: 3

How do i make the code to work and use a image when clicked to trigger a function?

i need a way when i enter to the second window, or the window with the image, it shows 3 images of burgers but i cant find a way to click on a image and trigger a function which allows me to ask if they want other things in the menu.

the images for the program are here

# Imports
import pygame
from threading import Timer

# start the game
pygame.init()

w, h = 200, 300

# making the windows
window = pygame.display.set_mode((1280, 720))
window2 = pygame.display.set_mode((1280, 720))
window3 = pygame.display.set_mode((1280, 720))
# set up the games name
pygame.display.set_caption("Ordering Simulator")

# Variables
pyX = 1280
pyY = 720
nextWindow = 0
# sprites
beefSprite = pygame.image.load("Hamburger.png").convert_alpha()
beefSprite.convert()
rectBeef = beefSprite.get_rect()
rectBeef.center = w // 2, h // 2
# Set up the text
font = pygame.font.Font('freesansbold.ttf', 64)
font2 = pygame.font.Font('freesansbold.ttf', 30)
white = (255, 255, 255)
black = (0, 0, 0)
# Text
text = font.render("Welcome to Cesar's ordering sim", True, black, white)
text2 = font2.render("What would you like? We have beef, chicken and tofu sandwich.", True, white, black)
text3 = font2.render("So you have chosen.", True, white, black)
# icon
icon = pygame.image.load("cheeseburger.png")
pygame.display.set_icon(icon)
# setup text pt2
textRect = text.get_rect()
textRect2 = text2.get_rect()
textRect3 = text3.get_rect()
textRect.center = (pyX // 2, pyY // 2)
textRect2.midtop = (pyX // 2, pyY - 600)
textRect3.midtop = (pyX // 2, pyY - 600)
# add a background
bg = pygame.image.load("restaurant.jpg")
bg = pygame.transform.scale(bg, (1280, 720))


# define the background and the selection menu
def image():
    window2.blit(bg, (0, 0))
    window2.blit(beefSprite, (200, 300))
    window2.blit(text2, textRect2)


def selection1():
    window3.blit(text3, textRect3)


# timer setup
timer = Timer(3.0, image)
timerLoop = 0

# loop for game window
running = True
running2 = True
running3 = True
while running:
    window.blit(text, textRect)
    if timerLoop == 0:
        timer.start()
        timerLoop = timerLoop + 1
        nextWindow = nextWindow + 1
    else:
        running2 = True
        running = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            running2 = False
            running3 = False
    pygame.display.update()

# Second screen which starts the game
while running2:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            running2 = False
            running3 = False
        if nextWindow == 1:
            if event.type == pygame.MOUSEBUTTONDOWN:
                mousePos = pygame.mouse.get_pos()
                if beefSprite.get_rect().collidepoint(mousePos):
                    selection1()
                    nextWindow = nextWindow + 1
        else:
            running = False
            running2 = False
            running3 = True
pygame.display.update()

# third screen
while running3:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running3 = False
pygame.display.update()

Upvotes: 0

Views: 301

Answers (1)

furas
furas

Reputation: 142641

I found two problems with Hamburger image

First:

You have image in beefSprite and at start you set position in rectBeef

rectBeef = beefSprite.get_rect()
rectBeef.center = w // 2, h // 2

but later you compare mouse position with beefSprite.get_rect()

if beefSprite.get_rect().collidepoint(mousePos):

which always gives (x,y) = (0,0) - so you compare with wrong rectangle.

You should use rectBeef instead of beefSprite.get_rect()

if rectBeef.collidepoint(mousePos):

Second:

You display image using position (200, 300)

window2.blit(beefSprite, (200, 300))

but you compare mouse position with rectBeef which may have different position

You should again use rectBeef

window2.blit(beefSprite, rectBeef)

And position (200, 300) you should set in rectBeef at start

rectBeef.lefttop = (200, 300)

or you could keep previous position

rectBeef.center = w // 2, h // 2

Other problem is Timer and timerLoop

Timer wait 3 seconds to run image but meanwhile code runs running = False so it moves from while running to while running2 - so you can still see first screen but code may already run second loop and check MOUSEBUTTONDOWN. You should set running = False inside image() which is executed after 3 seconds.

Or maybe you should rather use pygame.timer to check current time and exit first loop after 3 seconds, and next display images and run second loop


Other "problem" is window, window2, window3.

PyGame can display only one window - so there is no sense to create 3 windows. You can draw all in one window.

If you want switch content in window then you could create 3 Surface(), and blit on these surfaces, and later you can blit different surface in different moment.


EDIT:

My version with fixes. I also used pygame.time instead of threading.Timer but it could use special event for this.

But I see one disadvance: it can't move back from window 3 to window 2. It would have to run both windows in one while-loop with if nextWindow == 2: and if nextWindow == 3:

import pygame

# --- constants --- 

w, h = 200, 300

pyX = 1280
pyY = 720

white = (255, 255, 255)
black = (0, 0, 0)

# --- functions ---

def draw_window1():
    window.blit(bg, (0, 0))
    window.blit(text1, textRect1)

def draw_window2():
    window.blit(bg, (0, 0))
    window.blit(beefSprite, rectBeef)
    window.blit(text2, textRect2)

def draw_window3():
    window.blit(bg, (0, 0))
    window.blit(text3, textRect3)

# --- main ---

# start the game
pygame.init()

# making the windows
window = pygame.display.set_mode((1280, 720))

# set up the games name
pygame.display.set_caption("Ordering Simulator")

# Variables
nextWindow = 0

# sprites
beefSprite = pygame.image.load("Hamburger.png").convert_alpha()
rectBeef = beefSprite.get_rect()
rectBeef.center = window.get_rect().center

# Set up the text
font1 = pygame.font.Font('freesansbold.ttf', 64)
font2 = pygame.font.Font('freesansbold.ttf', 30)

# Text
text1 = font1.render("Welcome to Cesar's ordering sim", True, black, white)
text2 = font2.render("What would you like? We have beef, chicken and tofu sandwich.", True, white, black)
text3 = font2.render("So you have chosen.", True, white, black)

# icon
icon = pygame.image.load("cheeseburger.png")
pygame.display.set_icon(icon)

# setup text pt2
textRect1 = text1.get_rect()
textRect2 = text2.get_rect()
textRect3 = text3.get_rect()
textRect1.center = (pyX // 2, pyY // 2)
textRect2.midtop = (pyX // 2, pyY - 600)
textRect3.midtop = (pyX // 2, pyY - 600)

# add a background
bg = pygame.image.load("restaurant.jpg")
bg = pygame.transform.scale(bg, (1280, 720))

# loop for game window
running1 = True
running2 = True
running3 = True

# timer setup
current_time = pygame.time.get_ticks()
loop_end = current_time + 3000  # 3000ms

print('[DEBUG] first')

draw_window1()

while running1:

    current_time = pygame.time.get_ticks()
    
    if current_time >= loop_end:
        nextWindow = nextWindow + 1
        running1 = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running1 = False
            running2 = False
            running3 = False
            
    pygame.display.update()

# Second screen which starts the game
print('[DEBUG] second')

draw_window2()

while running2:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            #running1 = False
            running2 = False
            running3 = False
            
        if event.type == pygame.MOUSEBUTTONDOWN:
            if rectBeef.collidepoint(event.pos):
                nextWindow = nextWindow + 1
                running2 = False
            
    pygame.display.update()

# third screen
print('[DEBUG] third')

draw_window3()

while running3:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            #running1 = False
            #running2 = False
            running3 = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            nextWindow = nextWindow + 1
            running3 = False
            
    pygame.display.update()

# --- end ---

pygame.quit()  # some systems need it to close window

EDIT:

Version with window 2 and window 3 in one while-loop - so you can go back from window 3 to window 2, and next go again to window 3 and again go back to window 2, etc.

import pygame

# --- constants --- 

w, h = 200, 300

pyX = 1280
pyY = 720

white = (255, 255, 255)
black = (0, 0, 0)

# --- functions ---

def draw_window1():
    window.blit(bg, (0, 0))
    window.blit(text1, textRect1)

def draw_window2():
    window.blit(bg, (0, 0))
    window.blit(beefSprite, rectBeef)
    window.blit(text2, textRect2)

def draw_window3():
    window.blit(bg, (0, 0))
    window.blit(text3, textRect3)
    window.blit(text3a, text3a_rect)
    window.blit(text3b, text3b_rect)

# --- main ---

# start the game
pygame.init()

# making the windows
window = pygame.display.set_mode((1280, 720))

# set up the games name
pygame.display.set_caption("Ordering Simulator")

# Variables
nextWindow = 0

# sprites
beefSprite = pygame.image.load("Hamburger.png").convert_alpha()
rectBeef = beefSprite.get_rect()
rectBeef.center = window.get_rect().center

# Set up the text
font1 = pygame.font.Font('freesansbold.ttf', 64)
font2 = pygame.font.Font('freesansbold.ttf', 30)

# Text
text1 = font1.render("Welcome to Cesar's ordering sim", True, black, white)
text2 = font2.render("What would you like? We have beef, chicken and tofu sandwich.", True, white, black)
text3 = font2.render("So you have chosen.", True, white, black)

text3a = font2.render("BACK", True, white, black)
text3a_rect = text3a.get_rect(center=window.get_rect().center)
text3a_rect.x -= 200

text3b = font2.render("NEXT (EXIT)", True, white, black)
text3b_rect = text3b.get_rect(center=window.get_rect().center)
text3b_rect.x += 200

# icon
#icon = pygame.image.load("cheeseburger.png")
#pygame.display.set_icon(icon)

# setup text pt2
textRect1 = text1.get_rect()
textRect2 = text2.get_rect()
textRect3 = text3.get_rect()
textRect1.center = (pyX // 2, pyY // 2)
textRect2.midtop = (pyX // 2, pyY - 600)
textRect3.midtop = (pyX // 2, pyY - 600)

# add a background
bg = pygame.image.load("restaurant.jpg")
bg = pygame.transform.scale(bg, (1280, 720))

# loop for game window
running1 = True
running2 = True

# timer setup
current_time = pygame.time.get_ticks()
loop_end = current_time + 3000  # 3000ms

print('[DEBUG] first')

draw_window1()

while running1:

    current_time = pygame.time.get_ticks()
    
    if current_time >= loop_end:
        nextWindow = nextWindow + 1
        running1 = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running1 = False
            running2 = False
            
    pygame.display.update()

# Second screen which starts the game
print('[DEBUG] second & third')

nextWindow = 2

while running2:

    if nextWindow == 2:
    
        draw_window2()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                #running1 = False
                running2 = False
                
            if event.type == pygame.MOUSEBUTTONDOWN:
                if rectBeef.collidepoint(event.pos):
                    nextWindow = nextWindow + 1


    elif nextWindow == 3:
        draw_window3()
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                #running1 = False
                running2 = False

            if event.type == pygame.MOUSEBUTTONDOWN:
                if text3a_rect.collidepoint(event.pos):
                    nextWindow = nextWindow - 1
                if text3b_rect.collidepoint(event.pos):
                    nextWindow = nextWindow + 1
                    running2 = False
        
    pygame.display.update()

# --- end ---

pygame.quit()  # some systems need it to close window

Upvotes: 1

Related Questions