import random import sys import time import arcade from Score import Score from Bullet import Bullet from Alien import Alien DEBUG = True SLOW = False SLOW_SPEED = 0.01 SCREEN_SCALE = 3 SCREEN_HEIGHT = 256 * SCREEN_SCALE SCREEN_WIDTH = 224 * SCREEN_SCALE SCREEN_TITLE = "Space Invaders" PLAYER_SPEED = 1 PLAYER_BOUNDS = 32 ALIEN_BOUNDS = 16 class MyGame(arcade.Window): """ Main application class""" def __init__(self): super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) self.activeBullet = False self.wall_list = None self.player_list = None self.Won = False self.Score = 0 self.bullet = None self.aliens = [[Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien], [Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien], [Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien], [Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien], [Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien]] self.alienCounterY = 4 self.alienCounterX = 0 self.alienChangeDir = 0 self.alienCurrentDir = -1 self.movedown = False self.current_player_texture_index = 0 self.player_sprite = None self.movePlayer = 0 if DEBUG: arcade.set_background_color(arcade.color.BLUE) else: arcade.set_background_color(arcade.csscolor.BLACK) self.i = 0 def setup(self): """start / restart game""" self.scene = arcade.Scene() self.scene.add_sprite_list("Players") self.scene.add_sprite_list("Walls", use_spatial_hash=True) self.player_list = arcade.SpriteList() self.wall_list = arcade.SpriteList(use_spatial_hash=True) self.rend = 0 self.lives = 3 self.level = 0 self.score = None # self.overlay_color = (0,255,0,128) self.player_sprite_death = None self.somethingalsi = True self.death_textures = None # set up the player image_source = "assets/Sprites/Player/Player.png" self.player_sprite = arcade.Sprite(image_source, SCREEN_SCALE) self.player_sprite.center_x = 32 * SCREEN_SCALE self.player_sprite.center_y = (32 + 4) * SCREEN_SCALE self.player_list.append(self.player_sprite) # Create Left Boundry if DEBUG == True: wall = arcade.SpriteSolidColor(1, SCREEN_HEIGHT, arcade.color.RED) else: wall = arcade.SpriteSolidColor(0, SCREEN_HEIGHT, arcade.color.BLACK) wall.center_x = (PLAYER_BOUNDS - 8) * SCREEN_SCALE wall.center_y = SCREEN_HEIGHT / 2 self.wall_list.append(wall) # Create Right Boundry if DEBUG == True: wall = arcade.SpriteSolidColor(1, SCREEN_HEIGHT, arcade.color.RED) else: wall = arcade.SpriteSolidColor(0, SCREEN_HEIGHT, arcade.color.BLACK) wall.center_x = (224 - PLAYER_BOUNDS + 8) * SCREEN_SCALE wall.center_y = SCREEN_HEIGHT / 2 self.wall_list.append(wall) if DEBUG == True: wall = arcade.SpriteSolidColor(1, SCREEN_HEIGHT, arcade.color.GREEN) else: wall = arcade.SpriteSolidColor(0, SCREEN_HEIGHT, arcade.color.BLACK) wall.center_x = (ALIEN_BOUNDS - 8) * SCREEN_SCALE wall.center_y = SCREEN_HEIGHT / 2 self.wall_list.append(wall) # Create Right Boundry if DEBUG == True: wall = arcade.SpriteSolidColor(1, SCREEN_HEIGHT, arcade.color.GREEN) else: wall = arcade.SpriteSolidColor(0, SCREEN_HEIGHT, arcade.color.BLACK) wall.center_x = (224 - ALIEN_BOUNDS + 8) * SCREEN_SCALE wall.center_y = SCREEN_HEIGHT / 2 self.wall_list.append(wall) # Aliens for b in range (0,5,1): for a in range(0, 11, 1): if b == 0: alienType = "SA" elif b == 1 or b == 2: alienType = "MA" else: alienType = "LA" aliena = Alien(16 * (a+1) + 16, 200 - (16 * (b+1)), SCREEN_SCALE, DEBUG,alienType) # aliena.update(None,None,None) self.aliens[b][a] = aliena self.score = Score(SCREEN_SCALE,DEBUG) def collisionCheck(self, x1, y1, x2, y2, rx, ry): if abs(x1 - x2) <= rx and abs(y1 - y2) <= ry: return True else: return False def on_key_press(self, key, modifiers): if key == arcade.key.SPACE and self.activeBullet == False: self.bullet = Bullet(SCREEN_SCALE, DEBUG, self.player_sprite.center_x, self.player_sprite.center_y) self.activeBullet = True if key == arcade.key.LEFT: self.movePlayer = -PLAYER_SPEED * SCREEN_SCALE elif key == arcade.key.RIGHT: self.movePlayer = PLAYER_SPEED * SCREEN_SCALE def on_key_release(self, key, modifiers): if key == arcade.key.LEFT and self.movePlayer == -PLAYER_SPEED * SCREEN_SCALE: self.movePlayer = 0 elif key == arcade.key.RIGHT and self.movePlayer == PLAYER_SPEED * SCREEN_SCALE: self.movePlayer = 0 def load_death_animation(self): self.death_textures = [] for i in range(0,5): texture = arcade.load_texture("assets/Sprites/Player/PlayerDeath1.png") self.death_textures.append(texture) texture = arcade.load_texture("assets/Sprites/Player/PlayerDeath2.png") self.death_textures.append(texture) def play_death_animation(self): if self.current_player_texture_index < len(self.death_textures): self.player_sprite.set_texture(self.current_player_texture_index) self.current_player_texture_index += 1 def on_draw(self): self.clear() # try: # self.player_sprite_death.draw(pixelated=True) # except Exception as e: # pass # Render player bullet if it exists try: self.bullet.bullet_sprite.draw(pixelated=True) except Exception as e: if DEBUG: self.rend += 1 if self.rend >= 20: print(e) self.rend = 0 # Render alien bullets if they exist and render aliens try: for alienx in self.aliens: for alien in alienx: try: alien.bullet.bullet_sprite.draw(pixelated=True) except Exception as e: pass alien.alien_sprite.draw(pixelated=True) except Exception as e: pass self.player_list.draw(pixelated=True) self.wall_list.draw(pixelated=True) self.score.drawEach() def KillBullet(self): self.bullet = None self.activeBullet = False def respawn(self): # for alienRow in self.aliens: # for alien in alienRow: # alien.bullet = None self.player_sprite.center_x = 32*SCREEN_SCALE time.sleep(2) def death(self): if self.lives > 0: self.somethingalsi = False self.load_death_animation() self.play_death_animation() self.respawn() else: if DEBUG: print(str(self.Score)) sys.exit() def update(self, delta_time): if self.somethingalsi: # Picking numbers to possibly spawn an alien bullet testx = random.randint(0, 5 + 100 - self.level) testy = random.randint(0, 11 + 100 - self.level) # Checking if player bullet is off-screen, if so, set bullet to None, else, update bullet try: if self.bullet.getY() >= SCREEN_HEIGHT: self.KillBullet() if self.bullet != None: self.bullet.update() except Exception as e: self.error = e # Run the update method for each alien's bullet that exists in the self.aliens list try: for alienx in self.aliens: for alien in alienx: try: alien.bullet.update() except Exception as e: pass except Exception as e: pass # Checks if the alien's bullet is below -50, if so, set alien's bullet to None # Checks to see if testx and testy == self.alien[testx],[testy]. if yes: spawn new alien bullet try: for indexx, alienx in enumerate(self.aliens): for index, alien in enumerate(alienx): try: alien.checkBullet() if indexx == testx and index == testy: alien.spawnBullet() except Exception as e: pass except Exception as e: pass if self.alienCounterY < 0: # Reset the X and Y counter variables self.alienCounterY = len(self.aliens) - 1 self.alienCounterX = 0 # Alien Movement if self.Won == False: #Left - Right Movement if self.alienCounterX <= len(self.aliens[self.alienCounterY]) - 1: x = self.aliens[self.alienCounterY][self.alienCounterX].getX() # Right Alien Bound Check if x <= ALIEN_BOUNDS * SCREEN_SCALE + SCREEN_SCALE: self.alienChangeDir = 1 # Left Alien Bound Check elif x >= SCREEN_WIDTH - ALIEN_BOUNDS * SCREEN_SCALE - SCREEN_SCALE: self.alienChangeDir = -1 # Update current alien self.aliens[self.alienCounterY][self.alienCounterX].update(True, self.alienCurrentDir, self.movedown) # Move the X counter variable to the next alien self.alienCounterX += 1 # If an exeption is reached, it is likely that the X counter is out of bounds # which means we need to go to the next row of aliens else: # Reset X counter self.alienCounterX = 0 # Decrease Y counter so that we move to the next row of aliens self.alienCounterY -= 1 # if we go outside the minimum index of our aliens list, which means we reached the # very end of the list of aliens, raise an exception so that the except block runs if self.alienCounterY < 0: # Reset the X and Y counter variables self.alienCounterY = len(self.aliens) - 1 self.alienCounterX = 0 # if the aliens are at the right alien bound if self.alienChangeDir == -1: if self.alienChangeDir != self.alienCurrentDir: self.movedown = True else: self.movedown = False self.alienCurrentDir = -1 # Reset alienChangeDir self.alienChangeDir = 0 # if the aliens are at the left alien bound elif self.alienChangeDir == 1: if self.alienChangeDir != self.alienCurrentDir: self.movedown = True else: self.movedown = False self.alienCurrentDir = 1 self.alienChangeDir = 0 else: self.alienChangeDir = 0 # if DEBUG: # print(e) if len(self.aliens) == 0: self.Won = True # except Exception as e: # if DEBUG: # print(e) print("You Won!") sys.exit() # Check to see if any aliens are colliding with a player's bullet for alienRow in self.aliens: if alienRow == []: self.aliens.remove(alienRow) for alien in alienRow: try: # Check for alien colliding with player bullet if self.collisionCheck(alien.getX(), alien.getY(), self.bullet.getX(), self.bullet.getY(), alien.getSizeX(), alien.getSizeY()): # For Scoring Points type = alien.getType() if type == "SA": self.Score += 40 elif type == "MA": self.Score += 20 elif type == "LA": self.Score += 10 alienRow.remove(alien) if DEBUG: print(str(self.Score)) # Kill player bullet that hit the alien self.KillBullet() except Exception as e: pass try: # Check for player colliding with alien bullet if self.collisionCheck(self.player_sprite.center_x, self.player_sprite.center_y, alien.bullet.getX(), alien.bullet.getY(), 7 * SCREEN_SCALE, 5 * SCREEN_SCALE): self.lives -= 1 self.death() except Exception as e: pass if self.player_sprite.center_x >= 193 * SCREEN_SCALE and self.movePlayer == PLAYER_SPEED * SCREEN_SCALE: self.movePlayer = 0 elif self.player_sprite.center_x <= (PLAYER_BOUNDS - 2) * SCREEN_SCALE and self.movePlayer == -PLAYER_SPEED * SCREEN_SCALE: self.movePlayer = 0 else: self.player_sprite.center_x += self.movePlayer if SLOW: time.sleep(SLOW_SPEED) else: self.death() self.score.update(self.Score) def main(): window = MyGame() window.setup() arcade.run() if __name__ == "__main__": main()