0

I'm new to python/pygame and I can't figure this out. Whenever I press and hold a key it won't loop the KEYDOWN. Also, if I hold the key on my keyboard down and move the mouse at the same time, it seems to move continuously.

Can someone tell me what I'm doing wrong?

import pygame
import random
pygame.init()

#Colors
white = 255, 255, 255
black = 0, 0, 0
back_color = 48, 255, 124
light_color = 34, 155, 78

#Display W/H
display_width = 800
display_height = 600

#X/Y
x_axis = 400
y_axis = 580

Block_size = 20
x_int = 0
y_int = 0

ON = True



Window = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Game')



#On Loop
while ON == True:
    #Screen Event
    for Screen in pygame.event.get():
        #Quit Screen
        if Screen.type == pygame.QUIT:
            pygame.quit()
            exit()
        #Quit Full Screen
        if Screen.type == pygame.KEYDOWN:
            if Screen.key == pygame.K_q:
                pygame.quit()
                exit()

        #Full Screen !!!!!!!! EDIT THIS !!!!!!!!
        if Screen.type == pygame.KEYDOWN:
            if Screen.key == pygame.K_1:
                pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)
            if Screen.key == pygame.K_2:
                pygame.display.set_mode((display_width, display_height))

        #Player Movement K DOWN
        if Screen.type == pygame.KEYDOWN:
            if Screen.key == pygame.K_d:
                x_int = 20
            if Screen.key == pygame.K_a:
                x_int = -20
       #Player Movement K UP
        if Screen.type == pygame.KEYUP:
            if Screen.key == pygame.K_d or Screen.key == pygame.K_a:
                x_int = 0

        x_axis += x_int



        Window.fill((back_color))
        Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])



        pygame.display.update()
quit()
1
  • 2
    You don't have a loop here, and in fact this code will just raise an IndentationError. If you want us to debug your problem, you need to give us a minimal reproducible example that we can debug. Commented Aug 31, 2018 at 17:30

2 Answers 2

2

I have improved your code. You have placed the screen update (drawing the screen) portion in the events loop whereas it should be in the while loop. The code I have mode is a bit complex but works as expected. Why it is complex? When the key is held down, then the events list is empty (you can print the events). I have also made the block not to go out of the screen. The speed of the block was high so I decreased it to 10.

import pygame
import random
pygame.init()

#Colors
white = 255, 255, 255
black = 0, 0, 0
back_color = 48, 255, 124
light_color = 34, 155, 78

#Display W/H
display_width = 800
display_height = 600

#X/Y
x_axis = 400
y_axis = 580
global x_int
Block_size = 20
x_int = 0
y_int = 0

ON = True



Window = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Game')

global topass_a,topass_d
x_int,topass_a,topass_d = 0,0,0
#On Loop
while ON:
    #Screen Event
    events = pygame.event.get()
    def on_a_press():
        global topass_a,x_int
        x_int = -10
        topass_a = 1
    def on_d_press():
        global topass_d,x_int
        x_int = 10
        topass_d = 1
    if len(events) == 0:
         if topass_a == 1:on_a_press()
         if topass_d == 1:on_d_press()
    for Screen in events:
        if Screen.type == pygame.QUIT:
            pygame.quit()
            exit()
        if Screen.type == pygame.KEYDOWN:
            if Screen.key == pygame.K_q:
                pygame.quit()
                exit()
            if Screen.key == pygame.K_1:
                    pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)
            if Screen.key == pygame.K_2:
                    pygame.display.set_mode((display_width, display_height))
            if Screen.key == pygame.K_d or topass_d == 1:
                on_d_press()
            if Screen.key == pygame.K_a or topass_a == 1:
                on_a_press()
        if Screen.type == pygame.KEYUP:
            if Screen.key == pygame.K_d or Screen.key == pygame.K_a:
                x_int = 0
                topass_a = 0
                topass_d = 0

    x_axis += x_int
    x_int = 0
    if x_axis < 0:x_axis=0
    elif x_axis >= display_width-Block_size:x_axis = display_width-Block_size
    Window.fill((back_color))
    Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])
    pygame.display.update()

You can further improve the code as you need.

Edit:

Why complex? Easy things come first. I have realized that there is no need to track the keys. pygame.key.get_pressed() returns the pressed key. Here is a smaller , better and improved code. I have also implemented the w and s (y_axis) keys.

import pygame
import random
pygame.init()

#Colors
white = 255, 255, 255
black = 0, 0, 0
back_color = 48, 255, 124
light_color = 34, 155, 78

#Display W/H
display_width = 800
display_height = 600

#X/Y
x_axis = 400
y_axis = 580
Block_size = 20
x_int = 0
y_int = 0

ON = True



Window = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Game')
while ON:
    events = pygame.event.get()
    for Screen in events:
        if Screen.type == pygame.QUIT:
            pygame.quit()
            exit()
        if Screen.type == pygame.KEYDOWN:
            if Screen.key == pygame.K_q:
                pygame.quit()
                exit()
            if Screen.key == pygame.K_1:
                    pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)
            if Screen.key == pygame.K_2:
                    pygame.display.set_mode((display_width, display_height))
                    
    keys = pygame.key.get_pressed()
    if keys[pygame.K_a]:
        x_int = -10
    if keys[pygame.K_d]:
        x_int = 10
    # keys controlling y axis, you can remove these lines
    if keys[pygame.K_w]:
        y_int = -10
    if keys[pygame.K_s]:
        y_int = 10
    #x_axis......
    x_axis += x_int
    x_int = 0
    if x_axis < 0:x_axis=0
    elif x_axis >= display_width-Block_size:x_axis = display_width-Block_size
    #y axis
    y_axis += y_int
    y_int = 0
    if y_axis < 0:y_axis=0
    elif y_axis >= display_height-Block_size:y_axis = display_height-Block_size
    #updaing screen
    Window.fill((back_color))
    Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])
    pygame.display.update()
Sign up to request clarification or add additional context in comments.

Comments

1

You only receive pygame.KEYDOWN when the key is first pressed - not while it is held down. The simple solution is to only draw while the key is down (ie. when x_int != 0)

#On Loop
while ON == True:
    #Screen Event
    for Screen in pygame.event.get():
        # <Removed not relevant code for brevity>
        #Player Movement K DOWN
        if Screen.type == pygame.KEYDOWN:
            if Screen.key == pygame.K_d:
                x_int = 20
            if Screen.key == pygame.K_a:
                x_int = -20
       #Player Movement K UP
        if Screen.type == pygame.KEYUP:
            if Screen.key == pygame.K_d or Screen.key == pygame.K_a:
                x_int = 0

    # Render only happens if x_int is not zero
    # (Need to add code to force render first time)
    if x_int:
        x_axis += x_int
        Window.fill((back_color))
        Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])
        pygame.display.update()

As the program grows and gets more complex, you'll need better logic for when to render, but this will get you started.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.