Reputation: 129
This is a typing game in Python. Click the 'Play' button and the game is supposed to start. Random letters will fall down and each letter will disappear when you strike the corresponding key. However, it failed to begin when I click on the button. I think the problem must be related to the if statements if play_button.rect.collidepoint(mouse_x , mouse_y):
in method check_play_button() of game_functions.py since if the if statement is removed, the stats.game_active is changed to True. On the other hand, if the if statement is removed, then click anywhere on the screen would change the value of stats.game_active to True. I am quite puzzled about the malfunction of the if statement. Please shed light on it.
Here are my codes( a bit long but a challenge:P):
import pygame
import time
from pygame.locals import *
from settings import Settings
import game_functions as gf
from game_stats import GameStats
from button import Button
def run_game():
pygame.init()
az_settings =Settings()
screen = pygame.display.set_mode((0,0), RESIZABLE)
pygame.display.set_caption("Alphabet Zoo")
play_button = Button(screen, "Play")
stats = GameStats(az_settings)
letters = pygame.sprite.Group()
start = time.time()
sleepTime = 3
while True:
now = time.time()
gf.check_events(letters, stats, play_button)
if stats.game_active:
gf.update_screen(az_settings, stats, screen, letters, play_button)
if now - start >sleepTime:
gf.letter_generator(az_settings ,screen, letters)
start = now
else:
gf.update_screen(az_settings, stats, screen, letters, play_button)
run_game()
import pygame.font
class Button():
def __init__(self, screen, msg):
self.screen = screen
self.screen_rect = screen.get_rect()
self.width, self.height = 200, 50
self.button_color = (0, 0, 255)
self.text_color = (255, 255, 255)
self.font = pygame.font.SysFont(None, 48)
self.rect = pygame.Rect(0, 0, self.width, self.height)
self.rect.center = self.screen_rect.center
self.prep_msg(msg)
def prep_msg(self, msg):
self.msg_image = self.font.render(msg, True, self.text_color,
self.button_color)
self.msg_image_rect = self.msg_image.get_rect()
self.msg_image_rect.center = self.rect.center
def draw_button(self):
self.screen.fill(self.button_color, self.rect)
self.screen.blit(self.msg_image, self.msg_image_rect)
class Settings():
def __init__(self):
self.bg_color = (0, 0, 0)
self.letter_speed_factor = 10
self.lives_limit = 10
class GameStats():
def __init__(self, az_settings):
self.az_settings = az_settings
self.reset_stats()
self.game_active = False
def reset_stats(self):
self.lives_left = self.az_settings.lives_limit
import pygame
import random
from pygame.sprite import Sprite
class Letter(Sprite):
def __init__(self, az_settings, screen):
super().__init__()
self.screen = screen
self.az_settings = az_settings
a = random.randint(97, 122)
c = chr(a)
self.image = pygame.image.load('images/' + c.upper() + '.png')
self.ascii = a
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
self.rect.centerx = random.randint(0, self.screen_rect.right)
self.rect.top = self.screen_rect.top
self.center = float(self.rect.centerx)
def update(self):
if self.rect.bottom < self.screen_rect.bottom:
self.rect.centery += self.az_settings.letter_speed_factor
import sys
import pygame
from letter import Letter
def letter_generator(az_settings, screen, letters):
new_letter = Letter(az_settings, screen)
letters.add(new_letter)
def check_events(letters, stats, play_button):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
check_play_button(stats, play_button, mouse_x, mouse_y)
print(stats.game_active) # for test
elif event.type == pygame.KEYDOWN:
for ltr in letters:
if ltr.ascii == event.key:
letters.remove(ltr)
def check_play_button(stats, play_button, mouse_x, mouse_y):
if play_button.rect.collidepoint(mouse_x , mouse_y):
stats.game_active = True
def letter_fallen(stats):
if stats.lives_left > 0:
stats.lives_left -= 1
else:
stats.game_active = False
def check_letter_bottom(screen, letters, stats):
screen_rect = screen.get_rect()
for ltr in letters.sprites():
if ltr.rect.bottom > screen_rect.bottom: # there might be some problems
ltr.rect.bottom = screen_rect.bottom
letter_fallen(stats)
def update_screen(az_settings, stats, screen, letters, play_button):
screen.fill(az_settings.bg_color)
check_letter_bottom(screen, letters, stats)
letters.draw(screen)
letters.update()
if not stats.game_active:
play_button.draw_button()
pygame.display.flip()
Upvotes: 1
Views: 105
Reputation:
Obviously I cannot test this but I think your problem is that you are not assigning position to your play_button.rect
. By default, rect
's positions values are (0, 0)
. I had the same problem a little while ago, so you are read some more details in answer to this question. One way to fix the problem - in button class make a getRect method:
class Button:
def getRect(self):
return pygame.Rect(x, y, width, height) # Since you will
#be using this rect for collision, enter the arguments accordingly
Then,
if play_button.getRect().collidepoint(mouse_x , mouse_y):
Other option is to directly assign position to the button rect but I prefer the first solution, its just a personal preference:
class Button():
def __init__(self, screen, msg):
self.rect.topleft = #your button position
Upvotes: 2