Anonymous
Кнопка в pygame работает в 1/25 случаев
Сообщение
Anonymous » 15 ноя 2024, 11:47
Я пытаюсь создать магазин для моего симулятора лопания воздушных шаров, но кнопка магазина не работает должным образом.
Я попробовал создать разные переменные, чтобы остановить метод воспроизведения, и переместил все вокруг.
Я думаю, это связано с основным игровым циклом, но я не уверен, поскольку это не проблема с меню.
Ниже приведена ссылка на мою игру на Google Диске в виде папки с папкой ресурсов внутри. Пожалуйста, храните эти файлы вместе, как в коде, который я ссылаюсь на "assets/asset.png"
https://drive.google.com/drive/folders/ ... sp=sharing
Код: Выделить всё
import pygame
import random
import math
pygame.init()
class Button():
def __init__(self, x, y, image, scale, mask):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
self.use_mask = mask
self.mask = pygame.mask.from_surface(self.image)
def draw(self, surface):
action = False
pos = pygame.mouse.get_pos()
pos_in_mask = pos[0] - self.rect.x, pos[1] - self.rect.y
# Determine if the mouse is over the button using either the mask or bounding box
if self.use_mask:
touching = self.rect.collidepoint(*pos) and self.mask.get_at(pos_in_mask)
else:
touching = self.rect.collidepoint(*pos)
# Check if the button was clicked and not previously clicked
if touching and pygame.mouse.get_pressed()[0] == 1:
if not self.clicked:
self.clicked = True
action = True
elif pygame.mouse.get_pressed()[0] == 0:
# Reset clicked state when mouse button is released
self.clicked = False
# Draw the button
surface.blit(self.image, (self.rect.x, self.rect.y))
return action
SCREEN_WIDTH = 450
SCREEN_HEIGHT = 700
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
shop_img = pygame.image.load('assets/shop.png').convert_alpha()
shop_button = Button(SCREEN_WIDTH - shop_img.get_width(), SCREEN_HEIGHT - shop_img.get_width(), shop_img, 1, False)
font = pygame.font.Font(None, 50)
mid_font = pygame.font.Font(None, 63)
big_font = pygame.font.Font(None, 75)
def chooseBalloon():
b1 = pygame.image.load('assets/blue.png').convert_alpha()
b2 = pygame.image.load('assets/green.png').convert_alpha()
b3 = pygame.image.load('assets/red.png').convert_alpha()
b4 = pygame.image.load('assets/pink.png').convert_alpha()
b5 = pygame.image.load('assets/yellow.png').convert_alpha()
chosen_ballon = random.randint(1,5)
if chosen_ballon == 1:
chosen_ballon = b1
if chosen_ballon == 2:
chosen_ballon = b2
if chosen_ballon == 3:
chosen_ballon = b3
if chosen_ballon == 4:
chosen_ballon = b4
if chosen_ballon == 5:
chosen_ballon = b5
rect = chosen_ballon.get_rect()
mask = pygame.mask.from_surface(chosen_ballon)
return chosen_ballon, mask, rect
def draw_centered_text(text, font, color, y_position):
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect(center=(SCREEN_WIDTH // 2, y_position))
screen.blit(text_surface, text_rect)
def shop(coins):
shop_items = {
"extra_life": {"cost": 50, "description": "Gain an extra life", "effect": "extra_life"},
"slower_balloons": {"cost": 100, "description": "Reduce balloon speed", "effect": "slower_balloons"},
"+Multiplier": {"cost": 20, "description": "Increase your multiplier", "effect": "+Multiplier"},
}
back_img = pygame.image.load('assets/back.png').convert_alpha()
back_button = Button(SCREEN_WIDTH - back_img.get_width(), SCREEN_HEIGHT - back_img.get_width(), back_img, 1, False)
shopping = True
while shopping:
screen.fill((200, 200, 200)) # Light grey background for shop
if back_button.draw(screen):
return coins
for e in pygame.event.get():
if e.type == pygame.QUIT:
shopping = False
pygame.display.update()
def play():
run = True
balloonX = 225
balloonY = 700
balloon_speed = 0.1
score = 0
coins = 0
score2coinsX = 1.5
lives = 3
scale = 0.5
scale_add = 0.25
max_scale = 1.5
chosen_balloon, balloon_mask, balloonRect = chooseBalloon()
bg = pygame.image.load('assets/bg.png').convert_alpha()
pop_sound = pygame.mixer.Sound(r"assets/pop.mp3")
while run:
screen.fill((255, 255, 255))
screen.blit(bg, (0, 0))
multiplier_text = font.render(f"{score2coinsX}x", True, (255, 230, 0))
lives_text = font.render(f"{lives}", True, (255, 0, 0))
screen.blit(multiplier_text, (10, 10))
draw_centered_text(f"${coins}", font, (69, 255, 55), 30)
screen.blit(lives_text, (SCREEN_WIDTH - 30, 10))
balloon_speed = 0.1 * (score / 5) + 0.2
balloonY -= balloon_speed
# Ensure the shop button is drawn
if shop_button.draw(screen):
coins = shop(coins)
# Update the balloon's position rect
balloonRect.topleft = (balloonX, balloonY)
if lives = max_scale:
score += 1
coins = score * score2coinsX
scale = 0.5 # Reset scale when balloon pops
balloonX = random.randint(0, SCREEN_WIDTH)
balloonY = SCREEN_HEIGHT + 50
chosen_balloon, balloon_mask, balloonRect = chooseBalloon()
pop_sound.play()
else:
# Update balloon size and keep it centered
new_width = chosen_balloon.get_width() * scale
new_height = chosen_balloon.get_height() * scale
scaled_balloon = pygame.transform.scale(chosen_balloon, (new_width, new_height))
chosen_balloon = scaled_balloon
balloonRect = scaled_balloon.get_rect(center=(balloonX, balloonY))
balloon_mask = pygame.mask.from_surface(scaled_balloon)
pygame.display.update()
def menu():
play_img = pygame.image.load('assets/play.png').convert_alpha()
play_button = Button(60,300,play_img,1, True)
menu = True
while menu:
screen.fill((0, 0, 0))
if play_button.draw(screen):
play()
for event in pygame.event.get():
if event.type == pygame.QUIT:
menu = False
pygame.display.update()
menu()
pygame.quit()
Выше приведен код, но для его запуска вам потребуются ресурсы, я включил их выше в ссылку на Google Диск.
Подробнее здесь:
https://stackoverflow.com/questions/791 ... f-the-time
1731660458
Anonymous
Я пытаюсь создать магазин для моего симулятора лопания воздушных шаров, но кнопка магазина не работает должным образом. Я попробовал создать разные переменные, чтобы остановить метод воспроизведения, и переместил все вокруг. Я думаю, это связано с основным игровым циклом, но я не уверен, поскольку это не проблема с меню. Ниже приведена ссылка на мою игру на Google Диске в виде папки с папкой ресурсов внутри. Пожалуйста, храните эти файлы вместе, как в коде, который я ссылаюсь на "assets/asset.png" https://drive.google.com/drive/folders/1m970IfwHI1womobRPX-Jce6jUrxSGt8j?usp=sharing [code]import pygame import random import math pygame.init() class Button(): def __init__(self, x, y, image, scale, mask): width = image.get_width() height = image.get_height() self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale))) self.rect = self.image.get_rect() self.rect.topleft = (x, y) self.clicked = False self.use_mask = mask self.mask = pygame.mask.from_surface(self.image) def draw(self, surface): action = False pos = pygame.mouse.get_pos() pos_in_mask = pos[0] - self.rect.x, pos[1] - self.rect.y # Determine if the mouse is over the button using either the mask or bounding box if self.use_mask: touching = self.rect.collidepoint(*pos) and self.mask.get_at(pos_in_mask) else: touching = self.rect.collidepoint(*pos) # Check if the button was clicked and not previously clicked if touching and pygame.mouse.get_pressed()[0] == 1: if not self.clicked: self.clicked = True action = True elif pygame.mouse.get_pressed()[0] == 0: # Reset clicked state when mouse button is released self.clicked = False # Draw the button surface.blit(self.image, (self.rect.x, self.rect.y)) return action SCREEN_WIDTH = 450 SCREEN_HEIGHT = 700 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) shop_img = pygame.image.load('assets/shop.png').convert_alpha() shop_button = Button(SCREEN_WIDTH - shop_img.get_width(), SCREEN_HEIGHT - shop_img.get_width(), shop_img, 1, False) font = pygame.font.Font(None, 50) mid_font = pygame.font.Font(None, 63) big_font = pygame.font.Font(None, 75) def chooseBalloon(): b1 = pygame.image.load('assets/blue.png').convert_alpha() b2 = pygame.image.load('assets/green.png').convert_alpha() b3 = pygame.image.load('assets/red.png').convert_alpha() b4 = pygame.image.load('assets/pink.png').convert_alpha() b5 = pygame.image.load('assets/yellow.png').convert_alpha() chosen_ballon = random.randint(1,5) if chosen_ballon == 1: chosen_ballon = b1 if chosen_ballon == 2: chosen_ballon = b2 if chosen_ballon == 3: chosen_ballon = b3 if chosen_ballon == 4: chosen_ballon = b4 if chosen_ballon == 5: chosen_ballon = b5 rect = chosen_ballon.get_rect() mask = pygame.mask.from_surface(chosen_ballon) return chosen_ballon, mask, rect def draw_centered_text(text, font, color, y_position): text_surface = font.render(text, True, color) text_rect = text_surface.get_rect(center=(SCREEN_WIDTH // 2, y_position)) screen.blit(text_surface, text_rect) def shop(coins): shop_items = { "extra_life": {"cost": 50, "description": "Gain an extra life", "effect": "extra_life"}, "slower_balloons": {"cost": 100, "description": "Reduce balloon speed", "effect": "slower_balloons"}, "+Multiplier": {"cost": 20, "description": "Increase your multiplier", "effect": "+Multiplier"}, } back_img = pygame.image.load('assets/back.png').convert_alpha() back_button = Button(SCREEN_WIDTH - back_img.get_width(), SCREEN_HEIGHT - back_img.get_width(), back_img, 1, False) shopping = True while shopping: screen.fill((200, 200, 200)) # Light grey background for shop if back_button.draw(screen): return coins for e in pygame.event.get(): if e.type == pygame.QUIT: shopping = False pygame.display.update() def play(): run = True balloonX = 225 balloonY = 700 balloon_speed = 0.1 score = 0 coins = 0 score2coinsX = 1.5 lives = 3 scale = 0.5 scale_add = 0.25 max_scale = 1.5 chosen_balloon, balloon_mask, balloonRect = chooseBalloon() bg = pygame.image.load('assets/bg.png').convert_alpha() pop_sound = pygame.mixer.Sound(r"assets/pop.mp3") while run: screen.fill((255, 255, 255)) screen.blit(bg, (0, 0)) multiplier_text = font.render(f"{score2coinsX}x", True, (255, 230, 0)) lives_text = font.render(f"{lives}", True, (255, 0, 0)) screen.blit(multiplier_text, (10, 10)) draw_centered_text(f"${coins}", font, (69, 255, 55), 30) screen.blit(lives_text, (SCREEN_WIDTH - 30, 10)) balloon_speed = 0.1 * (score / 5) + 0.2 balloonY -= balloon_speed # Ensure the shop button is drawn if shop_button.draw(screen): coins = shop(coins) # Update the balloon's position rect balloonRect.topleft = (balloonX, balloonY) if lives = max_scale: score += 1 coins = score * score2coinsX scale = 0.5 # Reset scale when balloon pops balloonX = random.randint(0, SCREEN_WIDTH) balloonY = SCREEN_HEIGHT + 50 chosen_balloon, balloon_mask, balloonRect = chooseBalloon() pop_sound.play() else: # Update balloon size and keep it centered new_width = chosen_balloon.get_width() * scale new_height = chosen_balloon.get_height() * scale scaled_balloon = pygame.transform.scale(chosen_balloon, (new_width, new_height)) chosen_balloon = scaled_balloon balloonRect = scaled_balloon.get_rect(center=(balloonX, balloonY)) balloon_mask = pygame.mask.from_surface(scaled_balloon) pygame.display.update() def menu(): play_img = pygame.image.load('assets/play.png').convert_alpha() play_button = Button(60,300,play_img,1, True) menu = True while menu: screen.fill((0, 0, 0)) if play_button.draw(screen): play() for event in pygame.event.get(): if event.type == pygame.QUIT: menu = False pygame.display.update() menu() pygame.quit() [/code] Выше приведен код, но для его запуска вам потребуются ресурсы, я включил их выше в ссылку на Google Диск. Подробнее здесь: [url]https://stackoverflow.com/questions/79191190/button-in-pygame-works-1-25-of-the-time[/url]