├── README.md ├── game.py └── refactored ├── assets └── selfie.jpg ├── color.py ├── game.py ├── levels ├── boss_level.py └── level2.py ├── main.py ├── player.py └── screen.py /README.md: -------------------------------------------------------------------------------- 1 | # YouTube Source Code 2 | 3 | game.py contains the source code for my video on how to program a game in python 4 | 5 | Link to original video: https://youtu.be/-8n91btt5d8 6 | 7 | "refactored" folder contains code from my follow up video on Classes & Object oriented programming 8 | 9 | Link to follow up video: https://youtu.be/731LoaZCUjo 10 | -------------------------------------------------------------------------------- /game.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import random 3 | import sys 4 | 5 | pygame.init() 6 | 7 | WIDTH = 800 8 | HEIGHT = 600 9 | 10 | RED = (255,0,0) 11 | BLUE = (0,0,255) 12 | YELLOW = (255,255,0) 13 | BACKGROUND_COLOR = (0,0,0) 14 | 15 | player_size = 50 16 | player_pos = [WIDTH/2, HEIGHT-2*player_size] 17 | 18 | enemy_size = 50 19 | enemy_pos = [random.randint(0,WIDTH-enemy_size), 0] 20 | enemy_list = [enemy_pos] 21 | 22 | SPEED = 10 23 | 24 | screen = pygame.display.set_mode((WIDTH, HEIGHT)) 25 | 26 | game_over = False 27 | 28 | score = 0 29 | 30 | clock = pygame.time.Clock() 31 | 32 | myFont = pygame.font.SysFont("monospace", 35) 33 | 34 | def set_level(score, SPEED): 35 | if score < 20: 36 | SPEED = 5 37 | elif score < 40: 38 | SPEED = 8 39 | elif score < 60: 40 | SPEED = 12 41 | else: 42 | SPEED = 15 43 | return SPEED 44 | # SPEED = score/5 + 1 45 | 46 | 47 | def drop_enemies(enemy_list): 48 | delay = random.random() 49 | if len(enemy_list) < 10 and delay < 0.1: 50 | x_pos = random.randint(0,WIDTH-enemy_size) 51 | y_pos = 0 52 | enemy_list.append([x_pos, y_pos]) 53 | 54 | def draw_enemies(enemy_list): 55 | for enemy_pos in enemy_list: 56 | pygame.draw.rect(screen, BLUE, (enemy_pos[0], enemy_pos[1], enemy_size, enemy_size)) 57 | 58 | def update_enemy_positions(enemy_list, score): 59 | for idx, enemy_pos in enumerate(enemy_list): 60 | if enemy_pos[1] >= 0 and enemy_pos[1] < HEIGHT: 61 | enemy_pos[1] += SPEED 62 | else: 63 | enemy_list.pop(idx) 64 | score += 1 65 | return score 66 | 67 | def collision_check(enemy_list, player_pos): 68 | for enemy_pos in enemy_list: 69 | if detect_collision(enemy_pos, player_pos): 70 | return True 71 | return False 72 | 73 | def detect_collision(player_pos, enemy_pos): 74 | p_x = player_pos[0] 75 | p_y = player_pos[1] 76 | 77 | e_x = enemy_pos[0] 78 | e_y = enemy_pos[1] 79 | 80 | if (e_x >= p_x and e_x < (p_x + player_size)) or (p_x >= e_x and p_x < (e_x+enemy_size)): 81 | if (e_y >= p_y and e_y < (p_y + player_size)) or (p_y >= e_y and p_y < (e_y+enemy_size)): 82 | return True 83 | return False 84 | 85 | while not game_over: 86 | 87 | for event in pygame.event.get(): 88 | if event.type == pygame.QUIT: 89 | sys.exit() 90 | 91 | if event.type == pygame.KEYDOWN: 92 | 93 | x = player_pos[0] 94 | y = player_pos[1] 95 | 96 | if event.key == pygame.K_LEFT: 97 | x -= player_size 98 | elif event.key == pygame.K_RIGHT: 99 | x += player_size 100 | 101 | player_pos = [x,y] 102 | 103 | screen.fill(BACKGROUND_COLOR) 104 | 105 | drop_enemies(enemy_list) 106 | score = update_enemy_positions(enemy_list, score) 107 | SPEED = set_level(score, SPEED) 108 | 109 | text = "Score:" + str(score) 110 | label = myFont.render(text, 1, YELLOW) 111 | screen.blit(label, (WIDTH-200, HEIGHT-40)) 112 | 113 | if collision_check(enemy_list, player_pos): 114 | game_over = True 115 | break 116 | 117 | draw_enemies(enemy_list) 118 | 119 | pygame.draw.rect(screen, RED, (player_pos[0], player_pos[1], player_size, player_size)) 120 | 121 | clock.tick(30) 122 | 123 | pygame.display.update() -------------------------------------------------------------------------------- /refactored/assets/selfie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeithGalli/Basic-Python-Game/200351378dac9e21a19a4a8f12c0e3d26cd1b56b/refactored/assets/selfie.jpg -------------------------------------------------------------------------------- /refactored/color.py: -------------------------------------------------------------------------------- 1 | class Color: 2 | RED = (255,0,0) 3 | BLUE = (0,0,255) 4 | YELLOW = (255,255,0) 5 | BLACK = (0,0,0) -------------------------------------------------------------------------------- /refactored/game.py: -------------------------------------------------------------------------------- 1 | import random 2 | from player import Enemy, LargeEnemy, KeithEnemy 3 | 4 | class Game: 5 | Enemy = Enemy 6 | def __init__(self, speed=10, score=0, max_enemies=10, delay=0.1): 7 | self.speed = speed 8 | self.score = score 9 | self.max_enemies = max_enemies 10 | self.delay = delay 11 | 12 | self.enemy_list = [] 13 | 14 | def drop_enemies(self, screen_width): 15 | delay = random.random() 16 | if len(self.enemy_list) < self.max_enemies and delay < self.delay: 17 | random_x = random.randint(0, screen_width) 18 | y_pos = 0 19 | enemy = self.Enemy(random_x, y_pos) 20 | self.enemy_list.append(enemy) 21 | 22 | def update_enemy_positions(self, screen_height): 23 | new_enemy_list = [] 24 | for enemy in self.enemy_list: 25 | if enemy.y >= 0 and enemy.y < screen_height: 26 | enemy.y += self.speed 27 | new_enemy_list.append(enemy) 28 | else: 29 | self.score += 1 30 | self.enemy_list = new_enemy_list 31 | 32 | def set_level(self): 33 | if self.score < 20: 34 | self.speed = 5 35 | elif self.score < 40: 36 | self.speed = 8 37 | elif self.score < 60: 38 | self.speed = 12 39 | else: 40 | self.speed = 15 41 | 42 | def collision_check(self, player): 43 | for enemy in self.enemy_list: 44 | if enemy.detect_collision(player): 45 | return True 46 | return False 47 | 48 | class HardGame(Game): 49 | Enemy = LargeEnemy 50 | 51 | def set_level(self): 52 | self.speed = self.score/5 + 1 53 | 54 | class BossGame(Game): 55 | Enemy = KeithEnemy 56 | 57 | -------------------------------------------------------------------------------- /refactored/levels/boss_level.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, '../') 3 | import pygame 4 | from player import HumanPlayer 5 | from screen import Screen 6 | from game import Game, HardGame, BossGame 7 | from main import play_game 8 | 9 | if __name__ == "__main__": 10 | pygame.init() 11 | 12 | screen = Screen(width=1000, height=1400) 13 | player = HumanPlayer(screen.width/2, screen.height-100) 14 | game = BossGame() 15 | 16 | play_game(screen, player, game) -------------------------------------------------------------------------------- /refactored/levels/level2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, '../') 3 | import pygame 4 | from player import HumanPlayer 5 | from screen import Screen 6 | from game import Game, HardGame 7 | from main import play_game 8 | 9 | if __name__ == "__main__": 10 | pygame.init() 11 | 12 | screen = Screen() 13 | player = HumanPlayer(screen.width/2, screen.height-100) 14 | game = HardGame() 15 | 16 | play_game(screen, player, game) -------------------------------------------------------------------------------- /refactored/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import pygame 3 | from player import HumanPlayer 4 | from screen import Screen 5 | from game import Game 6 | 7 | def play_game(screen, player, game): 8 | game_over = False 9 | while not game_over: 10 | 11 | for event in pygame.event.get(): 12 | if event.type == pygame.QUIT: 13 | sys.exit() 14 | 15 | if event.type == pygame.KEYDOWN: 16 | if event.key == pygame.K_LEFT and player.x > 0: 17 | player.x -= player.size 18 | elif event.key == pygame.K_RIGHT and player.x < (screen.width - player.size): 19 | player.x += player.size 20 | 21 | game.drop_enemies(screen.width) 22 | game.update_enemy_positions(screen.height) 23 | game.set_level() 24 | 25 | screen.update_screen(game.enemy_list, player, game.score) 26 | 27 | if game.collision_check(player): 28 | game_over = True 29 | break 30 | 31 | if __name__ == "__main__": 32 | pygame.init() 33 | 34 | screen = Screen() 35 | player = HumanPlayer(screen.width/2, screen.height-100) 36 | game = Game() 37 | 38 | play_game(screen, player, game) -------------------------------------------------------------------------------- /refactored/player.py: -------------------------------------------------------------------------------- 1 | from color import Color 2 | import pygame 3 | 4 | class Player: 5 | def __init__(self, x, y, size, color=Color.RED): 6 | self.x = x 7 | self.y = y 8 | self.size = size 9 | self.color = color 10 | 11 | def draw(self, screen): 12 | pygame.draw.rect(screen, self.color, (self.x, self.y, self.size, self.size)) 13 | 14 | def detect_collision(self, other): 15 | if (other.x >= self.x and other.x < (self.x + self.size)) or (self.x >= other.x and self.x < (other.x + other.size)): 16 | if (other.y >= self.y and other.y < (self.y + self.size)) or (self.y >= other.y and self.y < (other.y + self.size)): 17 | return True 18 | return False 19 | 20 | class Enemy(Player): 21 | def __init__(self, x, y): 22 | super().__init__(x, y, size=50, color=Color.BLUE) 23 | 24 | class LargeEnemy(Player): 25 | def __init__(self, x, y): 26 | super().__init__(x, y, size=100, color=Color.BLUE) 27 | 28 | class KeithEnemy(Player): 29 | img = pygame.image.load("C:/Users/keith/Youtube/Code/Games/Refactor/assets/selfie.jpg") 30 | def __init__(self, x, y): 31 | super().__init__(x, y, size=75, color=Color.BLUE) 32 | 33 | def draw(self, screen): 34 | rect = pygame.Rect(self.x, self.y, self.size,self.size) 35 | scaled_img = pygame.transform.scale(self.img, rect.size) 36 | scaled_img = scaled_img.convert() 37 | screen.blit(scaled_img, rect) 38 | 39 | class HumanPlayer(Player): 40 | def __init__(self, x, y): 41 | super().__init__(x, y, size=50, color=Color.RED) -------------------------------------------------------------------------------- /refactored/screen.py: -------------------------------------------------------------------------------- 1 | from color import Color 2 | import pygame 3 | 4 | class Screen: 5 | def __init__(self, width=800, height=600, background_color=Color.BLACK, font_type="monospace", font_size=35, clock_tick=30): 6 | self.width = width 7 | self.height = height 8 | self.background_color = background_color 9 | self.screen = pygame.display.set_mode((width, height)) 10 | self.font = pygame.font.SysFont(font_type, font_size) 11 | self.clock = pygame.time.Clock() 12 | self.clock_tick = clock_tick 13 | 14 | def refresh_background(self): 15 | self.screen.fill(self.background_color) 16 | 17 | def draw_enemies(self, enemy_list): 18 | for enemy in enemy_list: 19 | enemy.draw(self.screen) 20 | 21 | def draw_player(self, player): 22 | player.draw(self.screen) 23 | 24 | def draw_score_label(self, score, color=Color.YELLOW): 25 | text = f"Score: {score}" 26 | label = self.font.render(text, 1, color) 27 | self.screen.blit(label, (self.width-200, self.height-40)) 28 | 29 | def update_screen(self, enemy_list, player, score): 30 | self.refresh_background() 31 | self.draw_enemies(enemy_list) 32 | self.draw_player(player) 33 | self.draw_score_label(score) 34 | 35 | self.clock.tick(self.clock_tick) 36 | pygame.display.update() --------------------------------------------------------------------------------