Skip to content Skip to sidebar Skip to footer

How Can I Generate The Position Of A Second Click In Pygame?

I'm making the Towers of Hanoi. It should work like this: you click on the first tower, from where you want a disk to move, and then on the second where you want the disk to move

Solution 1:

Keep in mind that your code runs in a loop, so you have to do keep track of the state of your game.

Clicking on the first tower changes the state of your game: Now one tower is selected, and clicking on a tower now does something different (it moves a block from the first to the second tower).

In your example, you just need to keep track of the fact if a tower is currently selected or not (and the blocks each tower has, of course). Don't be afraid of the word state, a simple variable is enough.

Take a look at the following code (note the comments). It just keeps track of the selected rod in the variable selected, then later checks if it is set to decide if a block needs to be moved.

import pygame
from collections import namedtuple

pygame.init()
screen = pygame.display.set_mode((500, 400))

# create a named tuple to keep track of the size/location of the rods and their blocks
Rod = namedtuple('Rod', ['rect', 'items'])

# first rod has 4 items. The just use a number to keep track of the size of the blocks 
rods = (Rod(pygame.rect.Rect((100, 150, 25, 250)), [6, 5, 4, 3, 2, 1]),
        Rod(pygame.rect.Rect((225, 150, 25, 250)), []),
        Rod(pygame.rect.Rect((350, 150, 25, 250)), []))

# keep track of the currently selected rod
selected = NonewhileTrue:
    if pygame.event.get(pygame.QUIT): break

    screen.fill(pygame.color.Color('white'))

    # draw the rods. It's easy since every rod has a rect which we can use with pygame.draw.rectfor rod in rods:
        # if a rod is selected, we draw it yellow instead of black
        pygame.draw.rect(screen, pygame.color.Color('yellow'if selected == rod else'black'), rod.rect)    
        # draw each block of each rodfor i, item inenumerate(rod.items):
            r = pygame.rect.Rect(rod.rect.x - item * 8, 375 - 25 * i, 25 + item * 16, 25) 
            pygame.draw.rect(screen, pygame.color.Color('green'if selected == rod else'darkgreen'), r)    

    for e in pygame.event.get():
        if e.type == pygame.MOUSEBUTTONDOWN:
            # check if we clicked a rod. It's easy since every rod has a rect
            rod = next((r for r in rods if r.rect.collidepoint(pygame.mouse.get_pos())), None)
            if rod:
                if selected:
                    # if there's already a rod selected, move block from one the selected# rod to the clicked rod
                    rod.items.append(selected.items.pop())
                    selected = Noneelif rod.items:
                    # if no rod is selected, selected the currently clicked one (if it has blocks)
                    selected = rod
            else:
                selected = None

    pygame.display.flip()   

Result:

enter image description here

Solution 2:

I think this line will not do what you expect it to:

eliflen(rod1) == 1or2or3:

Test in the interpreter that it does not evaluate to True but rather always to the value of 2.

You probably meant to do something like:

elif len(rod1) in (1, 2, 3):

Or even:

eliflen(rod1) > 0:

Additionally, you could still go for a series of "or" statements to cover your needs:

[not recommended]

eliflen(rod1) == 1orlen(rod1) == 2orlen(rod1) == 3:

If any one of the statements evaluates to True, the conditional statement will also be True.

Solution 3:

What I would personally do is put a loop around your code...

clicklocations = []
for clicknumber inrange(0,1):
    # get the position of the mouse click
    foreventin pygame.event.get():
        ifevent.type == MOUSEBUTTONDOWN:
            mousex, mousey = pygame.mouse.get_pos()
            clicklocations.append([mousex, mousey])

 # code for left part of the screenif clicklocations[0] in left part of screen, do stuff etc. etc.
 # code for middle part of the screen# code for right part of the screen

Something like this.

Then, you'll have both click locations stored and won't have to rewrite your clicking code twice.

Post a Comment for "How Can I Generate The Position Of A Second Click In Pygame?"