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 d
What I would personally do is put a loop around your code...
clicklocations = []
for clicknumber in range(0,1):
# get the position of the mouse click
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
mousex, mousey = pygame.mouse.get_pos()
clicklocations.append([mousex, mousey])
# code for left part of the screen
if 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.
I think this line will not do what you expect it to:
elif len(rod1) == 1 or 2 or 3:
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:
elif len(rod1) > 0:
Additionally, you could still go for a series of "or" statements to cover your needs:
[not recommended]
elif len(rod1) == 1 or len(rod1) == 2 or len(rod1) == 3:
If any one of the statements evaluates to True, the conditional statement will also be True.
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 = None
while True:
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.rect
for 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 rod
for i, item in enumerate(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 = None
elif 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: