How do you make text appear when you click a key in pygame

This method for detecting keypresses that I am showing here will actually detect if you are holding down a key, instead of just activating when you press the key. It just keeps a dictionary of what keys you have pressed already.

keyboard = {}

def get_key(key):
    try:
        return keyboard[key]
    except KeyError:
        return False

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            keyboard[event.key] = True
        elif event.type == pygame.KEYUP:
            keyboard[event.key] = False
    
    if get_key(pygame.K_y):
        # do some code here

What this allows you to do is run a piece of code repeatedly while the key is held down. The get_key() function uses a try, except statement, because if you havent pressed the key yet, it will give an error when you try to get it from the dictionary.

How can you use it?

if you use this method and then put your code inside and if statement in the game loop.

while True:
    for event in pygame.event.get():
        ...
    
    if get_key(pygame.K_y):
        WINDOW.blit(goodVibes, (100, 100))
2 Likes

I also noticed an error in your code. This error is actually crashing your program. When you call WINDOW.blit(goodVibes,100,100) it crashes because you didn’t input the position correctly. You gave it 3 arguments. surface, x, y but it is supposed to be like this surface, pos where pos is a tuple or list like this (100, 100). So your code should really do this WINDOW.blit(goodVibes, (100, 100))

ok thanks for helping

its not loading now for some reason

what do i need to add to make this work?

can you look it over?

can someone explain how to fix this

please i really cant do this

@SharkCoding something happened and i broke it

Hey sorry, I had to go. I can help you now if you want.

Ok, so I finished looking through your code, and I found 3 big errors. I’m going to try and explain the errors you made. There are quite a few, and most are pretty easy to fix and are just logic errors (meaning that the code works, but the structure, or way of doing it is wrong).


The Error Message

So first, I noticed the error it gives you is this:

image

Now python does a pretty good job of telling you what went wrong, so let’s look through this error message.

First, it says that the error came from main.py on line 48, which is WINDOW.blit(goodVibes, textX, textY), and the error is TypeError: invalid destination position for blit. Now earlier I mentioned that when called WINDOW.blit(...), it takes in TWO arguments, the surface to blit, and the position. Now what went wrong is that you put in two arguments for the x and y, but it is supposed to only take in ONE argument for the position. So it is a simple fix, just put the X and Y values into a tuple like this: (x, y). Now your line should look like this: WINDOW.blit(goodVibes, (textX, textY)) notice how the X and Y values are wrapped in parathases. And just for future reference, when you have an X and a Y value, ALWAYS blit like this mySurface.blit(otherSurface, (x, y)).


Update Ordering

Now if you made the changes I suggested, you will still notice that nothing shows up on the window. This is because this is your current update order:

  • draw the text
  • clear the screen
  • draw some other stuff
  • update the screen

Now, can you see the problem? You are drawing the text BEFORE you clear the screen, resulting in it never showing up in the first place. So what you want to do is change the update order to something more like this:

  • clear the screen
  • draw some other stuff
  • draw the text
  • update the screen

Implementation

while True:
    # vvvvvvvvvvvvvvv    this is the important part
    keypressed = False
    for event in pygame.event.get(): # go through all the events
          if event.type == QUIT:
            pygame.quit()
            sys.exit()
          if event.type == pygame.KEYDOWN:
            if myOtherRect.colliderect(myRect):
              keypressed = True
                
    WINDOW.fill("white")
    pygame.draw.rect(WINDOW, rectColour, myRect)
    pygame.draw.rect(WINDOW, myOtherRectColour, myOtherRect)
    # vvvvvvvvvvv now we check if the key was pressed, and if so, draw the image
    if keypressed:
        WINDOW.blit(goodVibes, (textX, textY))

    pygame.display.flip()
    clock.tick(FPS)

This code just uses a boolean to basically move the time you actually draw the text to after the screen is cleared, so you will actually see it.


Key Presses

The last major issue with your code, is that, even if you were able to change the update order, it still only flashes on the screen for one frame. If you wanted to make it stay up as long a you held down the key, you will need to change some things.

So first you should create a dictionary called keyboard.

keyboard = {}

Next you want to create a function called get_key()

def get_key(key):
    if key in keyboard:
        return keyboard[key]
    else:
        return False

This function will tell you whether or not the given key is pressed. If so, it returns True, and if not it returns False.

Then you have to add this code to your main loop.

while True:
    for event in pygame.event.get():
        ...
        if event.type == pygame.KEYDOWN:
            keyboard[event.key] = True
        elif event.type == pygame.KEYUP:
            keyboard[event.key] = False

Now you have a function get_key() that at any time will tell you whether or not a given key is pressed. (eg. get_key(pygame.K_a) returns True or False). This method of handling the key pressed is EXTREMELY useful especially in game development, because it can be used to move the player continuously without having to press the same key over and over to move.


Putting it All Together

Now it’s time to use all of this to make your program work.

keyboard = {}

def get_key(key):
    if key in keyboard:
        return keyboard[key]
    else:
        return False

while True:
    for event in pygame.event.get():
          if event.type == QUIT:
            pygame.quit()
            sys.exit()
        ...
        if event.type == pygame.KEYDOWN:
            keyboard[event.key] = True
            ...
        elif event.type == pygame.KEYUP:
            keyboard[event.key] = False
            ...
                
    WINDOW.fill("white")
    pygame.draw.rect(WINDOW, rectColour, myRect)
    pygame.draw.rect(WINDOW, myOtherRectColour, myOtherRect)
    if get_key(pygame.K_y) and myOtherRect.colliderect(myRect):
        WINDOW.blit(goodVibes, (textX, textY))

    pygame.display.flip()
    clock.tick(FPS)

Also I have made a working example for you here


TL;DR

The error message is because you put in two arguments for x and y instead of one tuple of (x, y).
You were drawing the text, then clearing the screen right after, so you need to change the order.
You can use this method to detect if a key is held down, which is good for many purposes.

And also I would recommend looking at the pygame docs for help too.


Wow this took a really long time to make. I hope this helps you and gives you tips for the future, because this is about all I can give you right now.

2 Likes

Yes, I know, I’ve made a TON of really long posts in this topic.

2 Likes

dang you deserve a tip lemme find your mainsite profile

2 Likes

You have too much time on your hands :laughing:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.