Reputation: 123
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
Reputation: 210876
You have to redraw the scene in every frame. The typical PyGame application loop has to:
pygame.time.Clock.tick
pygame.event.pump()
or pygame.event.get()
.blit
all the objects)pygame.display.update()
or pygame.display.flip()
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