user10320906
user10320906

Reputation:

How to draw a square wherever you click in the pygame window

You probably know what I want to do from the title but here's a simple example:

#User clicks somewhere in the pygame window
pos = cursorPosition()
#Function/Class that creates a square where the user clicked.

I have tried this:

import pygame
import sys

running = True
pygame.init()
screen = pygame.display.set_mode((800, 500))
pos = pygame.mouse.get_pos()

class Create():
    cx, cy = pygame.mouse.get_pos()
    square = pygame.Rect(cx, cy, 50, 50)
    def cube(self):
        self.square = pygame.Rect(self.cx, self.cy, 50, 50)
        pygame.draw.rect(screen, (255, 0, 0), self.square)
        pygame.display.flip()
create = Create()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            create.cube()
        screen.fill((0, 255, 0))
        pygame.display.flip()


pygame.quit()
sys.exit()

But it just gives me a Blue screen and when I click anywhere it doesn't do anything, so if you can help me it would be much appreciated. Thanks!

EDIT: I've managed to do it but now I face another problem: The square would appear only if I hold down the mouse button. This is the code

import pygame
import sys

running = True
pygame.init()
screen = pygame.display.set_mode((800, 500))
pos = pygame.mouse.get_pos()

class Create():
    cx, cy = pygame.mouse.get_pos()
    square = pygame.Rect(cx, cy, 50, 50)
    def cube(self):
        self.cx, self.cy = pygame.mouse.get_pos()
        self.square = pygame.Rect(self.cx, self.cy, 50, 50)
        pygame.draw.rect(screen, (255, 0, 0), self.square)
        pygame.display.flip()
create = Create()

while running:
    screen.fill((0, 255, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            create.cube()
        pygame.display.flip()


pygame.quit()
sys.exit()

Upvotes: 2

Views: 3229

Answers (3)

4ndr3i
4ndr3i

Reputation: 1

I am a beginner developer and my method is probably not the most efficient, however it does work. I know that I am writing 2 years late, but I am writing this incase anyone has the same question as I did which is to create multiple rectangles, squares or circles with a mousebutton press or in general any event.

I implemented a class to create a Cube object just like Michael O'Dwyer wrote in his explanation, and while his solution works to create one cube at a time, I needed to create multiple for myself.

In addition to his solution, I just created a list "cubeList" and with each mousebutton event I created a new cube object and appended it to that cubeList. Then, I used a for loop in order to iterate through each cube object in the cubeList and used the draw method. This way, I am able to have multiple cubes drawn at the same time, and I am sure there might be a more efficient or better method to do this, but this worked for me.

    import pygame


WIDTH, HEIGHT = 900, 500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)



Square1 = pygame.Rect(30,30,60,60)
Square2 = pygame.Rect(90,30,60,60)

class Cube:
    def update(self):
        self.cx, self.cy = pygame.mouse.get_pos()
        self.square = pygame.Rect(self.cx - 25, self.cy - 25, 50, 50)
    
    def draw(self):
        pygame.draw.rect(WIN, GREEN, self.square)


def main():
    cubeCount = 0
    run = True

    cubeList = []

    while run:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                print("Ending")
                run = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                cube = Cube()
                cubeList.append(cube)
                cube.update()

        
        clock.tick(60)
        WIN.fill((BLUE))
        pygame.draw.rect(WIN,RED, Square1)
        pygame.draw.rect(WIN, GREEN, Square2)

        for x in cubeList:
            x.draw()
            
                    
        
        pygame.display.flip()


    

    pygame.quit()

if __name__ == "__main__":
    main()

Upvotes: 0

Nishcabible
Nishcabible

Reputation: 21

I have also come across this problem and after a lot of messing around and frustration came up with the following:

import sys
import pygame
import time

pygame.init()

white = (255, 255, 255)
red = (255, 0, 0)
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("OwO")
mouse_cords = []
clicked = False

def draw(cord_list, zero):
    ''' This is what will draw on the screen when the mouse clicks using recursion'''
    pygame.draw.circle(screen, red, cord_list[zero], 100, 1)
    zero += 1
    if len(cord_list) > zero:
        draw(cord_list, zero)

done = False

clock = pygame.time.Clock()


while not done:

    for event in pygame.event.get(): 
        if event.type == pygame.QUIT:
            done = True 
    screen.fill(white)
    if pygame.mouse.get_pressed()[0]:
        mouse_cords.append(pygame.mouse.get_pos())
        clicked = True

    if clicked == True:
        draw(mouse_cords, 0)

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

pygame.quit()

As you can tell I used recursion to solve this problem. Sorry it's circles not boxes but Im sure you can figure out how to change that.

Upvotes: 2

Micheal O'Dwyer
Micheal O'Dwyer

Reputation: 1261

It's great to see that you are making a good effort to solve the by yourself, and that you are editing the question with the work you've done so far!

What I added to the code basically allows the user to change where the cube is being drawn. If you would like to draw multiple cubes, with their positions based on the mouse clicks from the user, edit your question to add those details, and leave a comment below.

First, I wrote a new class called Cube, which essentially has the same code as Create. I won't go into it in detail, but generally in object-oriented programming, objects are nouns, and their methods are actions. Your class is the opposite, which isn't how object-oriented code is generally written.

I added the update() method which simply updates some of the object's fields with the position of the mouse. Your original code was defining class fields or static variables. I won't go into to too much detail here, but if we were to make 100 instances of cube, we would want to have the positions for all the cubes, right? In cases like these, you are operating on the objects, not the class.

Then, there is one variable which gets set to true after the first mouse click, and, as a result, the cube starts being drawn to the screen.

Here is the fixed code:

import pygame

running = True
pygame.init()
screen = pygame.display.set_mode((800, 500))

class Cube:
    def update(self):
        self.cx, self.cy = pygame.mouse.get_pos()
        self.square = pygame.Rect(self.cx, self.cy, 50, 50)

    def draw(self): 
        pygame.draw.rect(screen, (255, 0, 0), self.square)

cube = Cube()
drawing_cube = False

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            cube.update()
            drawing_cube = True     

    screen.fill((0, 255, 0))
    if drawing_cube:
        cube.draw()
    pygame.display.flip()


pygame.quit()
quit()

I hope this answer helped you, and if you have any further questions, please feel free to leave a comment below!

Upvotes: 2

Related Questions