1

I am new to coding games using pygame so I thought of making a cookie clicker type of game for my first project. My problem is that I can press the cookie and it gives me cookies when pressed but I cannot press the BUY picture that I have on screen. It's like it doesn't register the click. Please help me I have searched for 2 hours I can'ẗ find a solution anywhere. Here's my code:

# import the pygame module
import pygame
pygame.init()


# Define a function for what will happen if the player buys an item (not done)
def shop():
    if buy_image.get_rect().collidepoint(pos):
        times_clicked -= 15

# Start with no clicks
times_clicked = 0


background_colour = ("white")

screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
  

pygame.display.set_caption("Cookies")
  

screen.fill(background_colour)



# create a font object.
# 1st parameter is the font file
# which is present in pygame.
# 2nd parameter is size of the font
font = pygame.font.SysFont("arial",32, True)


fullscreen = False


# Variable to keep our game loop running
running = True

clock = pygame.time.Clock()
# game loop
while running:
    
    # Amount of cookies here
    text = font.render(f"Cookies: {times_clicked}", True, "orange")
    
    

    # create a rectangular object for the
    # text surface object
    textRect = text.get_rect()
    
   

    # set the center of the rectangular object.
    textRect.center = (880, 100)
    


    
    # Shop pic
    shop_text = pygame.image.load("shop.png")
    shop_text = pygame.transform.scale(shop_text, (400, 100))

    # Cursor (shop)
    cursor_image = pygame.image.load("cursor.png")
    cursor_image = pygame.transform.scale(cursor_image, (100, 100))

    # Cookie pic
    image = pygame.image.load("cookie.jpeg")
    image = pygame.transform.scale(image, (800, 800))

    # "BUY" pic that doesn't work
    buy_image = pygame.image.load("buy.jpeg")
    buy_image = pygame.transform.scale(buy_image, (100, 80))


    for event in pygame.event.get():
        screen.fill(background_colour)
        screen.blit(image, (100, 60))
        screen.blit(text, textRect)
        screen.blit(shop_text, (1250, 20))
        screen.blit(cursor_image, (1550, 120))
        screen.blit(buy_image, (1400, 130))
        
        
        if event.type == pygame.MOUSEBUTTONDOWN:

            # Set the pos postions of the mouse click
            pos = pygame.mouse.get_pos()

            # Check if cookie picture is pressed
            if image.get_rect().collidepoint(pos):
                
                times_clicked += 1
            
            # Check if BUY picture is pressed
            shop()
            
        
        
                

        # Check for QUIT event      
        if event.type == pygame.QUIT:
            running = False
    # Update the display using flip
    pygame.display.flip()
    clock.tick(60)
Ali
  • 29
  • 5
  • Welcome to Stack Overflow. "My problem is that I can press the cookie and it gives me cookies when pressed but I cannot press the BUY picture that I have on screen. It's like it doesn't register the click." I understand that, when you click the picture, you want the `shop` function to get called. Did you *test* whether that happens? *Does it*? If the function gets called, then what? `if buy_image.get_rect().collidepoint(pos)`, right? So. Is the `get_rect()` result what you expect it to be? is the `pos` what you expect it to be? Does `collidepoint` give the result you expect? – Karl Knechtel May 19 '22 at 19:50
  • Please read https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ and try to *diagnose* the problem. The reason you "can't find a solution anywhere" is because you don't have anything specific to search for. Nobody else is going to be making the exact same game as you and have run into the exact same problem, and you aren't going to copy and paste your entire code into the search box; so the first step is to *understand, diagnose and categorize* the problem. – Karl Knechtel May 19 '22 at 19:52
  • Please also read [mre] and try to *isolate* the problem by removing functionality from your code that isn't relevant. For example, if you take out the cookie picture (and the clicking feature) entirely, does the same problem still happen, or does the buy button start working again? Repeating this process helps create an example that's easier for others to understand, and sometimes lets you find the problem yourself. – Karl Knechtel May 19 '22 at 19:54
  • 1
    Here's a hint, though: what happens if you click right near the top-left corner of the window, outside the cookie image? What happens if you click near the bottom-right of the cookie, in the space outside the (I'm assuming it's drawn to be round) cookie, but inside the rectangle that would be drawn around it? Based on those results, where do you suppose Pygame *actually* thinks the cookie is? Now, look closely at the code `image.get_rect()`, and `screen.blit(image, (100, 60))`. Does the image in some way "know" where it has been drawn? – Karl Knechtel May 19 '22 at 19:56
  • I already tried the things you said, I have isolated (removed) the cookie part, I have also just straight up coded the code where I call my function since I thought that had an issue. Not only that but I have also coded in print(pos) for when I click so that I can know which pixels im clicking on. It seemed accurate because it was around where I placed my picture. Also, "buy_image.get_rect().collidepoint(pos)" works for the cookie so what is the problem for the buy image? If it helps, both are in .jpeg format – Ali May 19 '22 at 20:02
  • What do you think should be the result of `buy_image.get_rect()`? Now, try to `print` it. Did you get the result you expect? "works for the cookie" No, it doesn't. If you try the clicks that I describe, you should find that the click in the top left activates the cookie even though it shouldn't, and the click in the bottom right doesn't activate the cookie even though it should. – Karl Knechtel May 19 '22 at 20:03
  • I mean I'm new to pygame but I suppose that it would know because it creates a rectangular shape around it where I can interract with. The small white spaces on the corners do have a hitbox because I think the rectangle makes it like that. I also give information about how big it is supposed to be. – Ali May 19 '22 at 20:06
  • No, I mean, actually write the exact numbers that you expect to see if you call `buy_image.get_rect()`. Then try it. – Karl Knechtel May 19 '22 at 20:07
  • I get the result: – Ali May 19 '22 at 20:11
  • Okay, and what do you think that means? In particular: what do you think is the top-left corner of such a rectangle? – Karl Knechtel May 19 '22 at 20:13
  • Once you have understood why that is a problem, please see https://stackoverflow.com/questions/68796613/how-can-i-check-if-an-image-is-clicked-in-pygame, as well as the other questions linked from there. – Karl Knechtel May 19 '22 at 20:17
  • I think 1400, 130. The reason is because i did print(pos) and clicked on that corner. The answer was 1402, 133, so maybe its a little off. – Ali May 19 '22 at 20:18
  • "I get the result: " "I think [the top-left corner of that rectangle] is 1400, 130". According to what logic? not the top-left corner of the *image that was drawn on the screen*; the corner of *the rectangle that your code told you about*. They are *different*, and *that is why there is a problem running the code*. – Karl Knechtel May 19 '22 at 20:20
  • I went to that forum and copied the list thing and I got the output that I actually did press the buy button. That means that the click doesn't have a problem right? It's just that it the code for it won't run. – Ali May 19 '22 at 20:58
  • 1
    It means that Pygame doesn't think the mouse is inside the image's rectangle - because "the image's rectangle" *has nothing to do with* the code that actually drew the image onto the screen. In the long run, you should use a data structure that keeps the relevant information for something you're drawing onto the screen - the actual image data, and the position where it "is" in the game world - in one place. Pygame provides a class for this purpose, called `Sprite`. Please look for it in the documentation. – Karl Knechtel May 19 '22 at 21:08
  • `image.get_rect()` gives `Rect()` but only with size of image - it always gives `(0,0)` as its position. You should get it only once and assign to variable ie. `image_rect` and assign position to this object `image_rect.x = ...` `image_rect.y = ...`. And later use it to check collision `image_rect.collidepoint(pos)`. And to draw it `blit(image, image_rect)` – furas May 19 '22 at 22:45
  • Thanks for the clrification and rewriting of my code. You made it much nicer and it actually works now! – Ali May 20 '22 at 14:25

1 Answers1

1

image.get_rect() gives Rect() but only with size of image - it always gives (0,0) as its position.

You should get it only once (before loop) and assign to variable ie. image_rect and assign position to this object

image_rect = image.get_rect()
image_rect.x = 100
image_rect.y = 60

And later use it to check collision

if image_rect.collidepoint(event.pos):

And you can use it also to display image.

blit(image, image_rect)

EDIT:

I didn't run it because I don't have images but it could be something like this:

import pygame

# --- classes ---

# empty

# --- functions ---

def shop(pos, times_clicked):
    if buy_image_rect.collidepoint(pos):
        times_clicked -= 15
    return times_clicked

# --- main ---

times_clicked = 0

background_colour = "white"

fullscreen = False

# - start -

pygame.init()

screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
pygame.display.set_caption("Cookies")

# - objects -

shop_text = pygame.image.load("shop.png")
shop_text = pygame.transform.scale(shop_text, (400, 100))
shop_text_rect = shop_text.get_rect()
shop_text_rect.x = 1250
shop_text_rect.y = 20

cursor_image = pygame.image.load("cursor.png")
cursor_image = pygame.transform.scale(cursor_image, (100, 100))
cursor_image_rect = cursor_image.get_rect()
cursor_image_rect.x = 1550
cursor_image_rect.y = 120

image = pygame.image.load("cookie.jpeg")
image = pygame.transform.scale(image, (800, 800))
image_rect = image.get_rect()
image_rect.x = 100
image_rect.y = 60

buy_image = pygame.image.load("buy.jpeg")
buy_image = pygame.transform.scale(buy_image, (100, 80))
buy_image_rect = buy_image.get_rect()
buy_image_rect.x = 1400
buy_image_rect.y = 130

font = pygame.font.SysFont("arial", 32, True)

# - loop -

running = True

clock = pygame.time.Clock()

while running:
    
    # - events -
    
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:

            if image_rect.collidepoint(event.pos):
                times_clicked += 1

            times_clicked = shop(event.pos, times_clicked)

        if event.type == pygame.QUIT:
            running = False

    # - calculations -

    text = font.render(f"Cookies: {times_clicked}", True, "orange")
    #text_rect = text.get_rect()
    #text_rect.center = (880, 100)
    text_rect = text.get_rect(center=(880, 100))

    # - draws -
    
    screen.fill(background_colour)
    
    screen.blit(image, image_rect)
    screen.blit(text, text_rect)
    screen.blit(shop_text, shop_text_rect)
    screen.blit(cursor_image, cursor_image_rect)
    screen.blit(buy_image, buy_image_rect)

    # - update -

    pygame.display.flip()
    clock.tick(60)
furas
  • 134,197
  • 12
  • 106
  • 148