Muhammad Umer
Muhammad Umer

Reputation: 123

How to remove the previous rect draw in pygame?

I am trying to build a illustrator in pygame. Till now i am able to draw a square in it on mouse drag.

import pygame 
import random
pygame.init()

HEIGHT = 700
WIDTH = 1000

WHITE  = (255, 255, 255)
BLACK  = (0, 0, 0) 

window = pygame.display.set_mode((WIDTH, HEIGHT), pygame.RESIZABLE)
pygame.display.set_caption("Illustrator")

window.fill(WHITE)

def draw(window, x, y, width, height): 
    color = "black"
    pygame.draw.rect(window, color, pygame.Rect(x, y, width, height))

def main():
    run = True
    mouse_button_down = False
    mouse_button_up = False
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_x_button_down, mouse_y_button_down = pygame.mouse.get_pos()
                print(mouse_x_button_down, mouse_y_button_down)
                mouse_button_down = True
                
            if event.type == pygame.MOUSEBUTTONUP:
                mouse_x_button_up, mouse_y_button_up = pygame.mouse.get_pos()
                print(mouse_x_button_up, mouse_y_button_up)
                mouse_button_up = True
            
        if mouse_button_down == True :
            if mouse_button_up == True:
                mouse_button_down = False
                mouse_button_up = False
                delta_x = mouse_x_button_up - mouse_x_button_down
                delta_y = mouse_y_button_up - mouse_y_button_down
                print(delta_x, delta_y)
                draw(window, mouse_x_button_down, mouse_y_button_down, delta_x, delta_y)
            else:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                delta_x = mouse_x - mouse_x_button_down
                delta_y = mouse_y - mouse_y_button_down
                print(delta_x, delta_y)
                draw(window, mouse_x_button_down, mouse_y_button_down, delta_x, delta_y)

        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()

It works like when the user mouse button is down it detects it and it is the start of the rectangle. The user drags it to any place it likes and the rectangle first shows how it will be drawn and if the user mouse button is up the rectangle is drawn. THe problem is that lets say the user starts at P and holds the mouse drag to Q. A rectangle is drawn. BUt the user still havenot left the button its still down. Now the user drags the same rectangle to point R and left mouse button to up. The problem is that the rectangle which orientation was first showed to user was also there. In particular we dont want it.

See this image:

Now how can i fix this issue. If you require more explaination tell me.

Upvotes: 1

Views: 443

Answers (1)

Rabbid76
Rabbid76

Reputation: 210876

You have to redraw the scene in every frame. The typical PyGame application loop has to:

Create a list o f rectangles

rectangles = []
start_of_new_rect = None

Store the start position of a rectangle when the mouse button is pressed:

if event.type == pygame.MOUSEBUTTONDOWN:
    start_of_new_rect = event.pos
    print(start_of_new_rect)

Add a new rectangle to the list when the mouse button is released:

if event.type == pygame.MOUSEBUTTONUP:
    w = event.pos[0] - start_of_new_rect[0]
    h = event.pos[1] - start_of_new_rect[1] 
    new_rect = pygame.Rect(*start_of_new_rect, w, h)
    new_rect.normalize()
    rectangles.append(new_rect)
    start_of_new_rect = None

Draw all the rectangles in the list in each frame:

for r in rectangles:
    pygame.draw.rect(window, "black", r)

Draw the rectangle that is currently drawn in each frame

if start_of_new_rect:
    mx, my = pygame.mouse.get_pos()
    new_rect = pygame.Rect(*start_of_new_rect, mx - start_of_new_rect[0],  my - start_of_new_rect[1])
    new_rect.normalize()
    pygame.draw.rect(window, "black", new_rect)

Minimal example

import pygame 
pygame.init()

HEIGHT = 700
WIDTH = 1000
window = pygame.display.set_mode((WIDTH, HEIGHT), pygame.RESIZABLE)
clock = pygame.time.Clock()
pygame.display.set_caption("Illustrator")

def main():
    run = True
    rectangles = []
    start_of_new_rect = None
    while run:

        # limit the frames per second
        clock.tick(100)

        # handle the events and update the  positions of objects
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                
            if event.type == pygame.MOUSEBUTTONDOWN:
                start_of_new_rect = event.pos
                print(start_of_new_rect)
                
            if event.type == pygame.MOUSEBUTTONUP:
                w = event.pos[0] - start_of_new_rect[0]
                h = event.pos[1] - start_of_new_rect[1] 
                new_rect = pygame.Rect(*start_of_new_rect, w, h)
                new_rect.normalize()
                rectangles.append(new_rect)
                start_of_new_rect = None

        # clear the display     
        window.fill("white")

        # draw the scene
        for r in rectangles:
            pygame.draw.rect(window, "black", r)
        if start_of_new_rect:
            mx, my = pygame.mouse.get_pos()
            new_rect = pygame.Rect(*start_of_new_rect, mx - start_of_new_rect[0],  my - start_of_new_rect[1])
            new_rect.normalize()
            pygame.draw.rect(window, "black", new_rect)

        # update the display
        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()

Upvotes: 2

Related Questions