Skip to content

Commit

Permalink
working version
Browse files Browse the repository at this point in the history
  • Loading branch information
konstanzer committed Mar 13, 2022
1 parent 468c81f commit 16703e1
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 13 deletions.
19 changes: 17 additions & 2 deletions src/alien.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ class Alien(Sprite):
"""A single alien"""

def __init__(self, ai_game):

super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings

self.image = pygame.image.load(join(path, "img", "alien.bmp"))
self.rect = self.image.get_rect()
Expand All @@ -19,4 +20,18 @@ def __init__(self, ai_game):
self.rect.y = self.rect.height

#Decimal value for horizontal position
self.x = float(self.rect.x)
self.x = float(self.rect.x)


def check_edges(self):

screen_rect = self.screen.get_rect()
if self.rect.right >= screen_rect.right or self.rect.left <= 0:
return True


def update(self):

self.x += self.settings.alien_speed * self.settings.fleet_direction
self.rect.x = self.x

128 changes: 123 additions & 5 deletions src/alieninvasion.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import sys
from time import sleep
import pygame
from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alien
from stats import Stats
from button import Button
from scoreboard import Scoreboard


class AlienInvasion:
Expand All @@ -21,13 +25,18 @@ def __init__(self):

self.bg_color = (230, 230, 230)
pygame.display.set_caption("Alien Invasion")


self.stats = Stats(self)
self.sb = Scoreboard(self)
self.ship = Ship(self)

self.bullets = pygame.sprite.Group()
self.aliens = pygame.sprite.Group()

self._create_fleet()

self.play_button = Button(self, "Play")


def _create_fleet(self):

Expand All @@ -38,7 +47,8 @@ def _create_fleet(self):

ship_height = self.ship.rect.height
available_space_y = self.settings.screen_height - 3*alien_height - ship_height
n_rows = available_space_y // (2*alien_height)
#Scale divisor to limit rows.
n_rows = available_space_y // (3*alien_height)

for row in range(n_rows):
for col in range(n_aliens_x):
Expand All @@ -51,16 +61,36 @@ def _create_alien(self, col, row):
alien_width, alien_height = alien.rect.size
alien.x = alien_width + 2*alien_width*col
alien.rect.x = alien.x
alien.rect.y = alien_height + 2*alien_height*row
#Scale height up to lower ships.
alien.rect.y = alien_height*5 + 2*alien_height*row
self.aliens.add(alien)


def _check_fleet_edges(self):

for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break


def _change_fleet_direction(self):

for alien in self.aliens.sprites():
alien.rect.y += self.settings.fleet_drop_speed
self.settings.fleet_direction *= -1


def run_game(self):

while True:
self._check_events()
self.ship.update()
self._update_bullets()

if self.stats.game_active:
self.ship.update()
self._update_bullets()
self._update_aliens()

self._update_screen()


Expand All @@ -73,6 +103,27 @@ def _check_events(self):
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
self._check_play_button(mouse_pos)


def _check_play_button(self, mouse_pos):

clicked = self.play_button.rect.collidepoint(mouse_pos)

if clicked and not self.stats.game_active:
self.settings.initialize_dynamic_settings()
pygame.mouse.set_visible(False)
self.stats.reset_stats()
self.stats.game_active = True
self.sb.prep_score()
self.sb.prep_level()
self.sb.prep_ships()
self.aliens.empty()
self.bullets.empty()
self._create_fleet()
self.ship.center_ship()


def _check_keydown_events(self, event):
Expand Down Expand Up @@ -111,15 +162,82 @@ def _update_bullets(self):
if bullet.rect.bottom <= 0:
self.bullets.remove(bullet)

self._check_bullet_alien_collisions()


def _check_bullet_alien_collisions(self):
#Whenever the rects of a bullet and alien overlap, groupcollide() adds a key-value pair to the dictionary it returns. The two True arguments tell Pygame to delete the bullets and aliens that have collided.
#Set first boolean to False for piercing bullets
collisions = pygame.sprite.groupcollide(self.bullets,
self.aliens, True, True)

if collisions:
for aliens in collisions.values():
self.stats.score += self.settings.alien_points * len(aliens)
self.sb.prep_score()
self.sb.check_high_score()

if not self.aliens:
self.bullets.empty()
self._create_fleet()
self.settings.increase_speed()
self.stats.level += 1
self.sb.prep_level()


def _update_aliens(self):

self._check_fleet_edges()
self.aliens.update()

if pygame.sprite.spritecollideany(self.ship, self.aliens):
self._ship_hit()

self._check_aliens_bottom()


def _ship_hit(self):

if self.stats.ships_left > 0:
self.stats.ships_left -= 1
self.sb.prep_ships()
self.aliens.empty()
self.bullets.empty()
self._create_fleet()
self.ship.center_ship()
sleep(.5)
else:
self.stats.game_active = False

if self.stats.score >= self.stats.high_score:
with open('high_score.txt', 'w') as f:
f.write(str(self.stats.score))

pygame.mouse.set_visible(True)


def _check_aliens_bottom(self):

screen_rect = self.screen.get_rect()
for alien in self.aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
self._ship_hit()
break


def _update_screen(self):

self.screen.fill(self.settings.bg_color)
self.ship.blitme()
for bullet in self.bullets.sprites():
bullet.draw_bullet()

#Draw each alien in the group
self.aliens.draw(self.screen)
self.sb.show_score()

if not self.stats.game_active:
self.play_button.draw_button()

pygame.display.flip()

Expand Down
32 changes: 32 additions & 0 deletions src/button.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import pygame.font

class Button:

def __init__(self, ai_game, msg):

self.screen = ai_game.screen
self.screen_rect = self.screen.get_rect()

self.width, self.height = 200, 50
self.button_color = (0, 255, 0)
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)
1 change: 1 addition & 0 deletions src/high_score.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1599330
82 changes: 82 additions & 0 deletions src/scoreboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import pygame.font
from pygame.sprite import Group
from ship import Ship


class Scoreboard:
"""Report scoring information"""
def __init__(self, ai_game):

self.ai_game = ai_game
self.screen = ai_game.screen
self.screen_rect = self.screen.get_rect()
self.settings = ai_game.settings
self.stats = ai_game.stats

self.text_color = (30, 30, 30)
self.font = pygame.font.SysFont(None, 48)

self.prep_score()
self.prep_high_score()
self.prep_level()
self.prep_ships()


def prep_score(self):
"""Render score"""
rounded_score = round(self.stats.score, -1)
score_str = "{:,}".format(rounded_score)
self.score_image = self.font.render(score_str, True,
self.text_color, self.settings.bg_color)

self.score_rect = self.score_image.get_rect()
self.score_rect.right = self.screen_rect.right - 20
self.score_rect.top = 20


def show_score(self):

self.screen.blit(self.score_image, self.score_rect)
self.screen.blit(self.high_score_image, self.high_score_rect)
self.screen.blit(self.level_image, self.level_rect)
self.ships.draw(self.screen)


def prep_high_score(self):

high_score = round(self.stats.high_score, -1)
high_score_str = "{:,}".format(high_score)
self.high_score_image = self.font.render(high_score_str, True,
self.text_color, self.settings.bg_color)

self.high_score_rect = self.high_score_image.get_rect()
self.high_score_rect.centerx = self.screen_rect.centerx
self.high_score_rect.top = self.score_rect.top


def check_high_score(self):

if self.stats.score > self.stats.high_score:
self.stats.high_score = self.stats.score
self.prep_high_score()


def prep_level(self):

level_str = str(self.stats.level)
self.level_image = self.font.render(level_str, True,
self.text_color, self.settings.bg_color)

self.level_rect = self.level_image.get_rect()
self.level_rect.right = self.score_rect.right
self.level_rect.top = self.score_rect.bottom + 10


def prep_ships(self):

self.ships = Group()
for n in range(self.stats.ships_left):
ship = Ship(self.ai_game)
ship.rect.x = 10 + n*ship.rect.width
ship.rect.y = 10
self.ships.add(ship)
30 changes: 27 additions & 3 deletions src/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,34 @@ def __init__(self):
self.screen_height = 800
self.bg_color = (230, 230, 230)
#Ship
self.ship_speed = 1.5
self.ship_limit = 3
#Bullets
self.bullet_speed = 1.
self.bullet_width = 3
self.bullet_height = 12
self.bullet_color = (60, 60, 60)
self.bullet_limit = 3
self.bullet_limit = 3
#Fleet
self.fleet_drop_speed = 10
self.speedup_scale = 1.1

self.score_scale = 1.5

self.initialize_dynamic_settings()


def initialize_dynamic_settings(self):

self.ship_speed = 1.5
self.bullet_speed = 3.
self.alien_speed = 1.
self.alien_points = 50
self.fleet_direction = 1 #-1 is left


def increase_speed(self):

self.ship_speed *= self.speedup_scale
self.bullet_speed *= self.speedup_scale
self.alien_speed *= self.speedup_scale

self.alien_points = int(self.alien_points * self.score_scale)
Loading

0 comments on commit 16703e1

Please sign in to comment.