Skip to content

Commit ea6fcf8

Browse files
authored
Merge pull request #6 from beeankha/level_up_and_scoring
Add level, score, high score, and lives remaining
2 parents 6096bed + 0441874 commit ea6fcf8

File tree

7 files changed

+165
-8
lines changed

7 files changed

+165
-8
lines changed

cat.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import pygame
2+
from pygame.sprite import Sprite
23

3-
class Cat:
4+
class Cat(Sprite):
45
"""A class to manage the feline savior."""
56

67
def __init__(self, ai_game):
78
"""Initialize the cat and set its starting position."""
9+
super().__init__()
810
self.screen = ai_game.screen
911
self.settings = ai_game.settings
1012
self.screen_rect = ai_game.screen.get_rect()
@@ -48,3 +50,16 @@ def center_cat(self):
4850
"""Center the cat on the screen."""
4951
self.rect.midbottom = self.screen_rect.midbottom
5052
self.x = float(self.rect.x)
53+
54+
55+
class CatFace(Sprite):
56+
"""A class to manage the feline savior's 'lives remaining' images."""
57+
58+
def __init__(self, ai_game):
59+
"""Initialize the cat face."""
60+
super().__init__()
61+
self.screen = ai_game.screen
62+
self.settings = ai_game.settings
63+
self.screen_rect = ai_game.screen.get_rect()
64+
self.image = pygame.image.load('images/catface.png')
65+
self.rect = self.image.get_rect()

cat_save_us.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from button import Button
1010
from cat import Cat
1111
from game_stats import GameStats
12+
from scoreboard import Scoreboard
1213
from settings import Settings
1314
from stars import Stars
1415

@@ -26,11 +27,14 @@ def __init__(self):
2627
# (the pygame method get_rect() returns a Rect object from an image)
2728
pygame.display.set_caption("Cat Save Us!")
2829

29-
# Create an instance to store game stats.
30+
# Create an instance to store game stats and create a scoreboard.
3031
self.stats = GameStats(self)
32+
self.sb = Scoreboard(self)
3133

3234
self.cat = Cat(self)
3335
# ^^ The self argument here refers to the current instance of CatSaveUs.
36+
self.cat_face = Cat(self)
37+
# ^^ The self argument here refers to the current instance of CatSaveUs.
3438

3539
self.bullets = pygame.sprite.Group()
3640
self.aliens = pygame.sprite.Group()
@@ -108,16 +112,28 @@ def _check_bullet_alien_collisions(self):
108112
# ^^ The sprite.groupcollide() function compares the rects of each element
109113
# in one group with the rects of each element in another group.
110114

115+
# NOTE
111116
# To make a high-powered bullet that can travel to the top of the screen,
112117
# destroying every alien in its path, you could set the first Boolean
113118
# argument to False and keep the second Boolean argument set to True.
114119
# The aliens hit would disappear, but all bullets would stay active until
115120
# they disappeared off the top of the screen.
116121

122+
if collisions:
123+
for aliens in collisions.values():
124+
self.stats.score += self.settings.alien_points * len(aliens)
125+
self.sb.prep_score()
126+
self.sb.check_high_score()
127+
117128
if not self.aliens:
118129
# Destroy existing bullets and create a new fleet.
119130
self.bullets.empty()
120131
self._create_fleet()
132+
self.settings.increase_speed()
133+
134+
# Increase level.
135+
self.stats.level += 1
136+
self.sb.prep_level()
121137

122138
def _update_aliens(self):
123139
"""
@@ -137,8 +153,9 @@ def _update_aliens(self):
137153
def _cat_hit(self):
138154
"""Respond to the cat being hit by an alien ship."""
139155
if self.stats.cats_left > 0:
140-
# Decrement cats_left.
156+
# Decrement cats_left, and update scoreboard.
141157
self.stats.cats_left -= 1
158+
self.sb.prep_cats()
142159

143160
# Get rid of any remaining aliens and bullets.
144161
self.aliens.empty()
@@ -179,9 +196,14 @@ def _check_play_button(self, mouse_pos):
179196
"""Start a new game when the player clicks Play."""
180197
button_clicked = self.play_button.rect.collidepoint(mouse_pos)
181198
if button_clicked and not self.stats.game_active:
199+
# Reset the game settings.
200+
self.settings.initialize_dynamic_settings()
182201
# Reset the game statistics.
183202
self.stats.reset_stats()
184203
self.stats.game_active = True
204+
self.sb.prep_score()
205+
self.sb.prep_level()
206+
self.sb.prep_cats()
185207

186208
# Hide the mouse cursor.
187209
pygame.mouse.set_visible(False)
@@ -285,6 +307,9 @@ def _update_screen(self):
285307
bullet.draw_bullet()
286308
self.aliens.draw(self.screen)
287309

310+
# Draw the score information.
311+
self.sb.show_score()
312+
288313
# Draw the play button if the game is inactive.
289314
if not self.stats.game_active:
290315
self.play_button.draw_button()

game_stats.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ def __init__(self, ai_game):
1212
# Start Cat Save Us! in an inactive state.
1313
self.game_active = False
1414

15+
# High score should never be reset.
16+
self.high_score = 0
17+
1518
def reset_stats(self):
1619
"""Initialize statistics that can change during the game."""
1720
self.cats_left = self.settings.cat_limit
21+
self.score = 0
22+
self.level = 1

images/.DS_Store

0 Bytes
Binary file not shown.

images/catface.png

9.05 KB
Loading

scoreboard.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import pygame.font
2+
from pygame.sprite import Group
3+
from cat import CatFace
4+
5+
6+
class Scoreboard:
7+
"""A class to report scoring information."""
8+
9+
def __init__(self, ai_game):
10+
"""Initialize scorekeeping attributes."""
11+
self.ai_game = ai_game
12+
self.screen = ai_game.screen
13+
self.screen_rect = self.screen.get_rect()
14+
self.settings = ai_game.settings
15+
self.stats = ai_game.stats
16+
17+
# We give __init__() the ai_game parameter here so that it can access
18+
# the settings, screen, and stats objects, which it will need to report
19+
# the values we’re tracking
20+
21+
# Font settings for scoring information.
22+
self.text_color = (0, 200, 100)
23+
self.font = pygame.font.SysFont(None, 48)
24+
25+
# Prepare the initial score images.
26+
self.prep_score()
27+
self.prep_high_score()
28+
self.prep_level()
29+
self.prep_cats()
30+
31+
def prep_score(self):
32+
"""Turn the score into a rendered image."""
33+
rounded_score = round(self.stats.score, -1)
34+
# ^^ The above rounds the score to multiples of 10
35+
score_str = "{:,}".format(rounded_score)
36+
self.score_image = self.font.render(score_str, True, self.text_color, self.settings.bg_color)
37+
38+
# Display the score at the top right of the screen.
39+
self.score_rect = self.score_image.get_rect()
40+
self.score_rect.right = self.screen_rect.right - 20
41+
self.score_rect.top = 20
42+
# ^^ To make sure the score always lines up with the right side of the screen,
43+
# there is a rect called score_rect and its right edge is set 20 pixels from
44+
# the right edge of the screen. We then place the top edge 20 pixels down
45+
# from the top of the screen.
46+
47+
def prep_high_score(self):
48+
"""Turn the high score into a rendered image."""
49+
high_score = round(self.stats.high_score, -1)
50+
high_score_str = "High Score: {:,}".format(high_score)
51+
self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.settings.bg_color)
52+
53+
# Center the high score at the top of the screen.
54+
self.high_score_rect = self.high_score_image.get_rect()
55+
self.high_score_rect.centerx = self.screen_rect.centerx
56+
self.high_score_rect.top = self.score_rect.top
57+
58+
def show_score(self):
59+
"""Draw scores, level, and cats to the screen."""
60+
self.screen.blit(self.score_image, self.score_rect)
61+
self.screen.blit(self.high_score_image, self.high_score_rect)
62+
self.screen.blit(self.level_image, self.level_rect)
63+
self.cats.draw(self.screen)
64+
65+
def check_high_score(self):
66+
"""Check ot see if there's a new high score."""
67+
if self.stats.score > self.stats.high_score:
68+
self.stats.high_score = self.stats.score
69+
self.prep_high_score()
70+
71+
def prep_level(self):
72+
"""Turn the level into a rendered image."""
73+
level_str = str(self.stats.level)
74+
current_level = "Level: {}".format(level_str)
75+
self.level_image = self.font.render(current_level, True, self.text_color, self.settings.bg_color)
76+
77+
# Position the level below the score.
78+
self.level_rect = self.level_image.get_rect()
79+
self.level_rect.right = self.score_rect.right
80+
self.level_rect.top = self.score_rect.bottom + 10
81+
82+
def prep_cats(self):
83+
"""Show how many cat lives are left."""
84+
self.cats = Group()
85+
for cat_number in range(self.stats.cats_left):
86+
cat = CatFace(self.ai_game)
87+
cat.rect.x = 10 + cat_number * cat.rect.width
88+
cat.rect.y = 10
89+
self.cats.add(cat)

settings.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Settings:
44
"""A class to store all settings for "Cat Save Us!" game."""
55

66
def __init__(self):
7-
"""Initialize the game's settings."""
7+
"""Initialize the game's static settings."""
88
# Screen settings
99
self.screen_width = 1350
1010
self.screen_height = 800
@@ -15,19 +15,42 @@ def __init__(self):
1515
# self.bg_color = (104, 130, 158) (greyish blue, aka "Daytime Mode")
1616

1717
# Cat settings
18-
self.cat_speed = 5
19-
# (the higher the number, the faster the cat)
2018
self.cat_limit = 3
2119

2220
# Bullet settings
23-
self.bullet_speed = 5.0
2421
self.bullet_width = 8
2522
self.bullet_height = 12
2623
self.bullet_color = (200, 0, 200)
2724
self.bullets_allowed = 20
2825

2926
# Alien settings
30-
self.alien_speed = 2
3127
self.fleet_drop_speed = 10
28+
29+
# How quickly the game speeds up
30+
self.speedup_scale = 1.3
31+
32+
# How quickly the alien point values increase
33+
self.score_scale = 1.5
34+
35+
self.initialize_dynamic_settings()
36+
37+
def initialize_dynamic_settings(self):
38+
"""Initialize settings that change throughout the game."""
39+
self.cat_speed = 5
40+
# (the higher the number, the faster the cat)
41+
self.bullet_speed = 5.0
42+
self.alien_speed = 2
43+
3244
# fleet_direction of 1 represents right; -1 represents left.
3345
self.fleet_direction = 1
46+
47+
# Scoring
48+
self.alien_points = 50
49+
50+
def increase_speed(self):
51+
"""Increase speed settings and alien point values."""
52+
self.cat_speed *= self.speedup_scale
53+
self.bullet_speed *= self.speedup_scale
54+
self.alien_speed *= self.speedup_scale
55+
56+
self.alien_points = int(self.alien_points * self.score_scale)

0 commit comments

Comments
 (0)