如何只注册一个鼠标点击 - Pygame

时间:2015-10-28 14:04:59

标签: python events pygame mouse

我正在使用升级系统在Pygame中制作游戏。每轮结束后,玩家将进入升级屏幕,点击他们想要使用他们收集的积分升级的统计数据。但是,如果玩家有足够的积分进行第一次升级并点击ATK升级,它将升级攻击然后再次检查循环。因此,如果玩家也有足够的积分进行第二次升级,我的程序第二次运行升级而玩家没有点击按钮两次。

如果只注册一次点击,我该怎么做才能让我的程序在一次点击中不会花费每一点?

更新:我发现,如果我真的很快点击升级按钮,那么它会注册为一次点击,但如果它被保持不超过一秒钟,它会重复“点击”。当按下鼠标按钮然后释放时,有没有人知道如何只输入一次?

按钮类逻辑:

if x + width > mouse_pos[0] > x and y + height > mouse_pos[1] > y:    
    text_to_button(message, color, x, y, width, height)

    if event.type == pygame.MOUSEBUTTONDOWN and pygame.mouse.get_pressed() == (1, 0, 0) and action != None:

实际按钮:

button("ATK", RED, D_RED, 110, 280, 145, 50, action = "ATK")

ATK升级逻辑:

if action == "ATK":
    if player.attack == 1 and up_points >= 3:
        player.attack += .5
        up_points -= 3
    elif player.attack == 1.5 and up_points >= 6:
        player.attack += .5
        up_points -= 6

完整(相关)代码:

def button(message, color, color_d, x, y, width, height, action = "nothing"):
    global main_menu
    global control_menu
    global how_to_play_menu
    global gameplay
    global upgrade_screen

    global game_timer
    global score
    global up_points
    global Max_ammo
    global ammo
    global ammo_refill
    global reload_time
    global Max_range
    global shoot_range
    global ms
    global attack
    global defence
    global current_health
    global reloading
    global up_points

    global a
    global d
    global m
    global am
    global re
    global ra

    mouse_pos = pygame.mouse.get_pos()
    pygame.draw.rect(screen, BLACK, (x, y, width, height))

    if x + width > mouse_pos[0] > x and y + height > mouse_pos[1] > y:

        text_to_button(message, color, x, y, width, height)

        if event.type == pygame.MOUSEBUTTONDOWN and action != "nothing":
            if action == "quit game":
                pygame.quit()
                quit()

            if action == "controls":
                main_menu = False
                how_to_play_menu = False
                control_menu = True

            if action == "how to play":
                main_menu = False
                how_to_play_menu = True
                control_menu = False

            if action == "back":
                main_menu = True
                control_menu = False
                how_to_play_menu = False

            if action == "ATK":
                pygame.time.wait(150)
                if player.attack == 1 and up_points >= 5:
                    player.attack += .5
                    up_points -= 5
                    a = "8 UP"
                elif player.attack == 1.5 and up_points >= 8:
                    player.attack += .5
                    up_points -= 8
                    a = "12 UP"
                elif player.attack == 2 and up_points >= 12:
                    player.attack += .5
                    up_points -= 12
                    a = "15 UP"
                elif player.attack == 2.5 and up_points >= 15:
                    player.attack += .5
                    up_points -= 15
                    a = "18 UP"
                elif player.attack == 3 and up_points >= 18:
                    player.attack += .5
                    up_points -= 18
                    a = "23 UP"
                elif player.attack == 3.5 and up_points >= 23:
                    player.attack += .5
                    up_points -= 23
                    a = "27 UP"
                elif player.attack == 4 and up_points >= 27:
                    player.attack += .5
                    up_points -= 27
                    a = "32 UP"
                elif player.attack == 4.5 and up_points >= 32:
                    player.attack += .5
                    up_points -= 32
                    a = "MAXED"


            if action == "DEF":
                pygame.time.wait(150)
                if player.defence == 1 and up_points >= 4:
                    player.defence += .5
                    up_points -= 4
                    d = "8 UP"
                elif player.defence == 1.5 and up_points >= 8:
                    player.defence += .5
                    up_points -= 8
                    d = "12 UP"
                elif player.defence == 2 and up_points >= 12:
                    player.defence += .5
                    up_points -= 12
                    d = "16 UP"
                elif player.defence == 2.5 and up_points >= 16:
                    player.defence += .5
                    up_points -= 16
                    d = "20 UP"
                elif player.defence == 3 and up_points >= 20:
                    player.defence += .5
                    up_points -= 20
                    d = "23 UP"
                elif player.defence == 3.5 and up_points >= 23:
                    player.defence += .5
                    up_points -= 23
                    d = "MAXED"

            if action == "MS":
                pygame.time.wait(150)
                if ms == 2 and up_points >= 4:
                    ms += .5
                    up_points -= 5
                    m = "8 UP"
                elif ms == 2.5 and up_points >= 8:
                    ms += .5
                    up_points -= 8
                    m = "12 UP"
                elif ms == 3 and up_points >= 12:
                    ms += .5
                    up_points -= 12
                    m = "17 UP"
                elif ms == 3.5 and up_points >= 17:
                    ms += .5
                    up_points -= 17
                    m = "24 UP"
                elif ms == 4 and up_points >= 24:
                    ms += .5
                    up_points -= 24
                    m = "30 UP"
                elif ms == 4.5 and up_points >= 30:
                    ms += .5
                    up_points -= 30
                    m = "MAXED"

            if action == "AMMO":
                pygame.time.wait(150)
                if Max_ammo == 3 and up_points >= 8:
                    Max_ammo += 1
                    up_points -= 8
                    am = "12 UP"
                elif Max_ammo == 4 and up_points >= 12:
                    Max_ammo += 1
                    up_points -= 12
                    am = "16 UP"
                elif Max_ammo == 5 and up_points >= 16:
                    Max_ammo += 1
                    up_points -= 16
                    am = "20 UP"
                elif Max_ammo == 6 and up_points >= 20:
                    Max_ammo += 1
                    up_points -= 20
                    am = "25 UP"
                elif Max_ammo == 7 and up_points >= 25:
                    Max_ammo += 1
                    up_points -= 25
                    am = "MAXED"

            if action == "RELOAD":
                pygame.time.wait(150)
                if reload_time == 2 and up_points >= 4:
                    reload_time += .5
                    up_points -= 4
                    re = "7 UP"
                elif reload_time == 2.5 and up_points >= 7:
                    reload_time += .5
                    up_points -= 7
                    re = "11 UP"
                elif reload_time == 3 and up_points >= 11:
                    reload_time += .5
                    up_points -= 11
                    re = "15 UP"
                elif reload_time == 3.5 and up_points >= 15:
                    reload_time += .5
                    up_points -= 15
                    re = "18 UP"
                elif reload_time == 4 and up_points >= 18:
                    reload_time += .5
                    up_points -= 18
                    re = "22 UP"
                elif reload_time == 4.5 and up_points >= 22:
                    reload_time += .5
                    up_points -= 22
                    re = "26 UP"
                elif reload_time == 5 and up_points >= 26:
                    reload_time += .5
                    up_points -= 26
                    re = "30 UP"
                elif reload_time == 5.5 and up_points >= 30:
                    reload_time += .5
                    up_points -= 30
                    re = "MAXED"

            if action == "RANGE":
                pygame.time.wait(150)
                if Max_range == 10 and up_points >= 5:
                    Max_range += 6
                    up_points -= 5
                    ra = "9 UP"
                elif Max_range == 16 and up_points >= 9:
                    Max_range += 6
                    up_points -= 9
                    ra = "13 UP"
                elif Max_range == 22 and up_points >= 13:
                    Max_range += 6
                    up_points -= 13
                    ra = "17 UP"
                elif Max_range == 28 and up_points >= 17:
                    Max_range += 6
                    up_points -= 17
                    ra = "20 UP"
                elif Max_range == 34 and up_points >= 20:
                    Max_range += 6
                    up_points -= 20
                    ra = "24 UP"
                elif Max_range == 40 and up_points >= 24:
                    Max_range += 6
                    up_points -= 24
                    ra = "28 UP"
                elif Max_range == 46 and up_points >= 28:
                    Max_range += 6
                    up_points -= 28
                    ra = "32 UP"
                elif Max_range == 52 and up_points >= 32:
                    Max_range += 8
                    up_points -= 32
                    ra = "MAXED"

            if action == "start": # VERY IMPORTANT!! This if statement resets the game when the
                main_menu = False # player presses "START" in the main menu. Everything will be
                                  # reset to these values WHEN THE PLAYER STARTS A NEW GAME

                game_timer = 1280
                score = 0
                up_points = 1500 # change to 0
                Max_ammo = 3
                ammo = Max_ammo
                ammo_refill = (0)
                reload_time = 2
                player.current_health = 210
                player.attack = 1
                player.defence = 1
                ms = 2
                Max_range = 10
                bullet.shoot_range = Max_range
                reloading = False
                a = "5 UP"
                d = "4 UP"
                m = "4 UP"
                am = "8 UP"
                re = "4 UP"
                ra = "5 UP"
                player.rect.x = int(screen_width / 2)
                player.rect.y = int(screen_height / 2) + 200
                player.change_x = 0
                player.change_y = 0
                all_sprites_list.add(player)

                for i in range(5):
                    zombie = Enemy(ZOMBIE_GREEN)
                    all_sprites_list.add(zombie)
                    zombie_list.add(zombie)

                gameplay = True



    else:
        text_to_button(message, color_d, x, y, width, height)




pygame.init()

screen_size = pygame.display.Info()

size = (1300, 720)
screen = pygame.display.set_mode(size)

#size = (screen_size.current_w, screen_size.current_h)
#screen = pygame.display.set_mode(((screen_size.current_w, screen_size.current_h)),pygame.FULLSCREEN)

screen_width = 1300     #screen_size.current_w
screen_height = 720    #screen_size.current_h

pygame.display.set_caption("HOARD")

wall_list = pygame.sprite.Group()
zombie_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
up_list = pygame.sprite.Group()
all_sprites_list = pygame.sprite.Group()

# Walls are made here = (x_coord for where it starts,
# y_coord for where it starts, width of wall, height of wall)
# These walls are made with fullscreen dimentions, not any set dimentions
# Left
wall = Wall(BLUE, 0, 0, 10, screen_height)
wall_list.add(wall)
all_sprites_list.add(wall)

# Top
wall = Wall(BLUE, 0, 0, screen_width, 10)
wall_list.add(wall)
all_sprites_list.add(wall)

# Bottom
wall = Wall(BLUE, 0, screen_height - 10, screen_width, 10)
wall_list.add(wall)
all_sprites_list.add(wall)

# Right
wall = Wall(BLUE, screen_width - 10, 0, 10, screen_width)
wall_list.add(wall)
all_sprites_list.add(wall)

# HUD Border
wall = Wall(BLUE, 0, screen_height - 100, screen_width, 10)
wall_list.add(wall)
all_sprites_list.add(wall)


player = Player(WHITE)
player.walls = wall_list
all_sprites_list.add(player)

zombie = Enemy(ZOMBIE_GREEN)
zombie.walls = wall_list


cursor = Cursor(7, 7)
cursor.walls = wall_list
all_sprites_list.add(cursor)

bullet = Bullet()
up = Up(zombie.rect.center)


tiny_font = pygame.font.Font("/Users/tannerbeeson/Documents/Python Programs/Pygame 3.5/HOARD/hypefonts_crushed/crushed.ttf", 15)
small_font = pygame.font.Font("/Users/tannerbeeson/Documents/Python Programs/Pygame 3.5/HOARD/hypefonts_crushed/crushed.ttf", 25)
med_font = pygame.font.Font("/Users/tannerbeeson/Documents/Python Programs/Pygame 3.5/HOARD/hypefonts_crushed/crushed.ttf", 45)
big_font = pygame.font.Font("/Users/tannerbeeson/Documents/Python Programs/Pygame 3.5/HOARD/hypefonts_crushed/crushed.ttf", 80)


done = False

clock = pygame.time.Clock()

main_menu = True
gameplay = False
control_menu = False
how_to_play_menu = False
upgrade_screen = False




# -------- Main Program Loop -----------
while not done:

    while gameplay:

        pygame.mouse.set_visible(0)

        # --- Actual Gameplay Loop ---
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            # Press 'Escape' to exit the game_____
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    for i in zombie_list:
                        i.kill()
                    for i in up_list:
                        i.kill()
                    for i in bullet_list:
                        i.kill()
                    for i in all_sprites_list:
                        if i is player:
                            player.kill()
                    gameplay = False
                    main_menu = True


            # Keyboard controls. The numbers inside change the speed of the player
            if event.type == pygame.KEYDOWN and (player.alive()):
                if event.key == pygame.K_a:
                    player.movement(-ms, 0)
                elif event.key == pygame.K_d:
                    player.movement(ms, 0)
                elif event.key == pygame.K_w:
                    player.movement(0, -ms)
                elif event.key == pygame.K_s:
                    player.movement(0, ms)
                elif event.key == pygame.K_SPACE:
                    player.change_x = 0
                    player.change_y = 0
                    pause()

            elif event.type == pygame.KEYUP and (player.alive()):
                if event.key == pygame.K_a:
                    player.movement(ms, 0)
                elif event.key == pygame.K_d:
                    player.movement(-ms, 0)
                elif event.key == pygame.K_w:
                    player.movement(0, ms)
                elif event.key == pygame.K_s:
                    player.movement(0, -ms)

            # Shooting / Reloading Logic

            elif not reloading and event.type == pygame.MOUSEBUTTONDOWN and pygame.mouse.get_pressed() == (1, 0, 0) and ammo > 0 and (player.alive()):
                ammo -= 1
                bullet = Bullet()
                all_sprites_list.add(bullet)
                bullet_list.add(bullet)
            elif event.type == pygame.MOUSEBUTTONDOWN and pygame.mouse.get_pressed() == (0, 0, 1) and player.alive() and ammo != Max_ammo and reloading != True:
                reloading = True
#--------------------------------------

        # Reloading Animation
        if reloading == True:
            ammo = 0
            ammo_refill += reload_time
            if ammo_refill >= 200:
                reloading = False
                ammo = Max_ammo
                ammo_refill = 0

        # Gameplay Timer Speed and Animation
        if gameplay == True and player.alive():
            game_timer -= 100 # Change to 1
            if game_timer <= -10:
                end_round()
                break



        # Mouse Controls----------------------------
        pos = pygame.mouse.get_pos()
        cursor_x = pos[0]
        cursor_y = pos[1]

        if cursor_x <= 10:
            cursor_x = 10
        if cursor_x >= (screen_width - 17):
            cursor_x = (screen_width - 17)

        if cursor_y <= 10:
            cursor_y = 10
        if cursor_y >= (screen_height - 107):
            cursor_y = (screen_height - 107)
        #-------------------------------------------

        # If the player falls off the map, kill them
        if (player.rect.x >= screen_width or player.rect.x <= 0) or (player.rect.y >= screen_height or player.rect.y <= 0):
            player.kill()

        all_sprites_list.update()

        # How bullets vanish when they hit something______________________________
        for shot in bullet_list:
            shot.shoot_range -= 1
            if shot.shoot_range <= 0:
                shot.kill()

            block_hit_list = pygame.sprite.spritecollide(bullet, zombie_list, False)
            for z in block_hit_list:
                z.hp -= player.attack
                bullet.kill()
                if z.hp <= 0:
                    z.kill()
                    bullet.kill()
                    score += 100
                    if random.randrange(1, 11) >= 8:
                        Up(z.rect.center).add(all_sprites_list, up_list)
                        if random.randrange(1, 3) == 2:
                            Up(z.rect.center).add(all_sprites_list, up_list)


        for bullet in bullet_list:
            block_hit_list = pygame.sprite.spritecollide(bullet, wall_list, False)
            for i in block_hit_list:
                bullet_list.remove(bullet)
                all_sprites_list.remove(bullet)
        #--------------------------------------------------------------------------

        for point in up_list:
            block_hit_list = pygame.sprite.spritecollide(player, up_list, True)
            for point in block_hit_list:
                up.kill()
                up_points += 1

        if player.current_health < 0:
            player.kill()


        # .update() will 'update' or change the screen with what
        # we've told it to everytime we run throught the loop. Without
        # this our player would not appear to move on the screen because
        # we wouldn't be telling the screen to change the coordinates of the player.
        all_sprites_list.update()
        bullet_list.update()
        cursor.update()

        # Drawing commands: What you actually see happening (along with update commands)
        screen.fill(BLACK)

        # HUD
        pygame.draw.rect(screen, HUD_GREY, [10, screen_height - 90, screen_width, 80])

        score_text = small_font.render("SCORE: " + str(score), True, PURPLE)
        screen.blit(score_text, [20, screen_height - 64])

        up_text = small_font.render("UP: " + str(up_points), True, YELLOW)
        screen.blit(up_text, [365, screen_height - 64])

        ammo_text = small_font.render("AMMO: " + str(ammo), True, ORANGE)
        screen.blit(ammo_text, [1014, screen_height - 74])
        pygame.draw.rect(screen, BLACK, [1017, screen_height - 43, 200, 15])
        pygame.draw.rect(screen, ORANGE, [1018, screen_height - 43, float(ammo_refill), 15])
        pygame.draw.rect(screen, ORANGE, [1018, screen_height - 43, float(ammo / Max_ammo) * 200, 15])
        pygame.draw.rect(screen, WHITE, [1017, screen_height - 43, 200, 15], 2)

        health_text = small_font.render("HEALTH:", True, GREEN)
        pygame.draw.rect(screen, BLACK, [745, screen_height - 70, 220, 40])
        screen.blit(health_text, [560, screen_height - 64])
        pygame.draw.rect(screen, WHITE, [745, screen_height - 70, 220, 40], 3)

        # Game Timer
        pygame.draw.rect(screen, WHITE, [9, screen_height - 20, game_timer + 1, 10])

        all_sprites_list.draw(screen)

        # Player Health
        if player.alive() == True:
            if player.taking_damage == True:
                pygame.Surface.fill(screen, RED, [750, screen_height - 65, int(player.current_health), 30], 5)
            else:
                pygame.Surface.fill(screen, GREEN, [750, screen_height - 65, int(player.current_health), 30], 5)


        pygame.display.flip()

        clock.tick(60)

1 个答案:

答案 0 :(得分:0)

您没有显示完整的代码,但我猜您的问题是在pygame.mouse.get_pressed()某处使用MOUSEBUTTONDOWN事件。

每次鼠标点击都会生成一个MOUSEBUTTONDOWN个事件;但是如果你在循环中检查pygame.mouse.get_pressed(),你会看到该循环的多次迭代按下按钮(如果你的速度不够快,不能释放鼠标按钮)。

请注意,MOUSEBUTTONDOWN事件具有button属性,可用于检查按下了哪个按钮。