2

I'm fairly new to python and pygame. I'm trying to make a simple game as a practice. My problem is how do I have a loop (or many loops) inside the main game loop so that the graphic also updates inside sub loops? For example I have a button and a rectangle, if I press on the button I want the rectangle to move across the screen. Things I've tried:

  • Another while loop, it works but the rectangle won't "move" and just appears wherever the loop is finished
  • Custom event, however it either works once per frame or continuously in case of set_timer() function

Here's my code:

import pygame as pg
pg.init()
clock = pg.time.Clock()
running = True
window = pg.display.set_mode((640, 480))
window.fill((255, 255, 255))
btn = pg.Rect(0, 0, 100, 30)
rect1 = pg.Rect(0, 30, 100, 100)

while running:
    clock.tick(60)
    window.fill((255, 255, 255))
    for e in pg.event.get():
        if e.type == pg.MOUSEBUTTONDOWN:
            (mouseX, mouseY) = pg.mouse.get_pos()
            if(btn.collidepoint((mouseX, mouseY))):
                rect1.x = rect1.x + 1
        if e.type == pg.QUIT:
            running = False
    #end event handling

    pg.draw.rect(window, (255, 0, 255), rect1, 1)
    pg.draw.rect(window, (0, 255, 255), btn)

    pg.display.flip()

#end main loop
pg.quit()

Any help is much appreciated

1 Answer 1

1

You have to implement some kind of state. Usually, you would use the Sprite class, but in your case, a simple variable would do.


Take a look at this example:

import pygame as pg
pg.init()
clock = pg.time.Clock()
running = True
window = pg.display.set_mode((640, 480))
window.fill((255, 255, 255))
btn = pg.Rect(0, 0, 100, 30)
rect1 = pg.Rect(0, 30, 100, 100)

move_it = False
move_direction = 1

while running:
    clock.tick(60)
    window.fill((255, 255, 255))
    for e in pg.event.get():
        if e.type == pg.MOUSEBUTTONDOWN:
            (mouseX, mouseY) = pg.mouse.get_pos()
            if(btn.collidepoint((mouseX, mouseY))):
                move_it = not move_it

        if e.type == pg.QUIT:
            running = False
    #end event handling

    if move_it:
        rect1.move_ip(move_direction * 5, 0)
        if not window.get_rect().contains(rect1):
            move_direction = move_direction * -1
            rect1.move_ip(move_direction * 5, 0)

    pg.draw.rect(window, (255, 0, 255), rect1, 1)
    pg.draw.rect(window, (255, 0, 0) if move_it else (0, 255, 255), btn)

    pg.display.flip()

#end main loop
pg.quit()

When the button is pressed, we just set the move_it flag. Then, in the main loop, we check if this flag is set, and then move the Rect.


enter image description here


You should avoid creating multiple logic loops (sorry, I don't have a better word) in your game; see the problems you mentioned. Aim for one single main loop that does three things: input handling, game logic, and drawing.

Sign up to request clarification or add additional context in comments.

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.