How can I generate the position of a second click in Pygame?

前端 未结 3 645
耶瑟儿~
耶瑟儿~ 2021-01-21 22:40

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

相关标签:
3条回答
  • 2021-01-21 23:12

    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.

    0 讨论(0)
  • 2021-01-21 23:17

    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.

    0 讨论(0)
  • 2021-01-21 23:24

    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:

    enter image description here

    0 讨论(0)
提交回复
热议问题