diff --git a/Game4.py b/Game4.py index a55d8d1..dae9271 100644 --- a/Game4.py +++ b/Game4.py @@ -1,8 +1,21 @@ +""" +Blockade is competitive arcade game. It has two players. Player 1 is a white +block that is continually moving forward. Player 2’s job is to stop Player 1 by +throwing obstacles in its way. Player 1 can avoid obstacles by jumping over or +ducking under them. Both players are limited by a stamina bar. Actions such +jumping or throwing obstacles depletes player’s stamina and if the stamina gets +too low players cannot perform actions. The game uses keyboard inputs as commands. + +@author: Vivien Chen and Harrison Young +""" + + import os, sys import pygame from random import randint -from misc import * +from models import * +from config import * class Game4Main: @@ -20,73 +33,96 @@ def __init__(self, width=480,height=360): # create clock self.clock = pygame.time.Clock() self.score = 0 + self.oneplayer = True - def mainLoop(self): + def start_menu(self): + """Start screen for game.""" + while True: + if pygame.QUIT in {event.type for event in pygame.event.get()}: + sys.exit() + + # display start menu + self.screen.fill(colors['BLACK']) + # title + font = pygame.font.SysFont("comicsansms", int(self.width/8)) + text = font.render("Blockade", True, colors['WHITE']) + text_rect = text.get_rect(center=(self.width/2, self.height/3)) + self.screen.blit(text, text_rect) + # instructions + font = pygame.font.SysFont("comicsansms", int(self.width/30)) + text = font.render("Player 1: Arrow Keys, Player 2: ZXC", True, colors['WHITE']) + text_rect = text.get_rect(center=(self.width/2, self.height/2)) + self.screen.blit(text, text_rect) + # buttons + self.button("One Player",self.width*1/8-20,self.height*3/4,colors['GREEN'],True,self.main_loop) + self.button("Two Player",self.width*5/8-20,self.height*3/4,colors['RED'],False,self.main_loop) + + # update screen + pygame.display.flip() + + + def main_loop(self): """Main screen for game.""" - # initialize player + # start count count = 0 - play_len = 25 - play_x = 100 - play_y = self.height - play_len - player = Player(play_x, play_y, play_len, self.screen) + + # initialize player + player = Player(PLAY_X, self.height-PLAY_LEN, PLAY_LEN, self.screen) # initialize stamina bars - P1_stamina_bar = StaminaBar(self.screen,25,"WHITE") - P2_stamina_bar = StaminaBar(self.screen,350,"RED") + P1_stamina_bar = StaminaBar(self.screen, P1_STAMINA_BAR_OFFSET, 'WHITE') + P2_stamina_bar = StaminaBar(self.screen, self.width - P2_STAMINA_BAR_OFFSET, 'RED') # initialize obstacle length, x and y coordinates - obs_len = 25 - obs_x = self.width - obs_y = self.height - obs_len - obstical_height = self.height - obs_len + OBS_X = self.width + OBS_Y = self.height - OBS_LEN # create list of obstacles - obstacles = [] - new_obstical = False - # uncomment and place line below in [] of obstacles = [] to generate random obstacles: - # Obstacle(obs_x, obs_y, obs_len, self.screen,'BLUE') - + if self.oneplayer: + obstacles = [Obstacle(OBS_X, OBS_Y, OBS_LEN, self.screen,'BLUE')] + else: + obstacles = [] + new_obstacle = False + obstacle_height = OBS_Y # initialize time variables prev_time = 0 obs_dt = 500 # main event loop - while 1: + while True: count+=1 + # if pygame.QUIT in {event.type for event in pygame.event.get()}: + # sys.exit() + # elif pygame.KEYDOWN in {event.type for event in pygame.event.get()}: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() - # check keyboard for obstacle player - if event.type == pygame.KEYDOWN: - # z to create obstacle at ground level - if event.key == pygame.K_z: - new_obstical = True - obstical_height = obs_y - # x to create obstacle at second level - if event.key == pygame.K_x: - new_obstical = True - obstical_height = obs_y-25 - # c to create obstacle at third level - if event.key == pygame.K_c: - new_obstical = True - obstical_height = obs_y-50 + if not self.oneplayer: + # check keyboard for obstacle player + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_z: + new_obstacle = True + obstacle_height = OBS_Y-LEVEL_OFFSETS['ground'] + if event.key == pygame.K_x: + new_obstacle = True + obstacle_height = OBS_Y-LEVEL_OFFSETS['first'] + if event.key == pygame.K_c: + new_obstacle = True + obstacle_height = OBS_Y-LEVEL_OFFSETS['second'] # check keyboard for main player pressed = pygame.key.get_pressed() - # up to jump - if pressed[pygame.K_UP] and P1_stamina_bar.bars >= player.jumpcost: - if player.play_y == (360 - player.play_len): - P1_stamina_bar.decreaseBar(player.jumpcost) + if pressed[pygame.K_UP] and P1_stamina_bar.bars >= JUMP_COST: + if player.play_y == (self.height - player.play_len): + P1_stamina_bar.decrease_bar(JUMP_COST) player.jump() P1_stamina_bar.draw() - # left to move left if pressed[pygame.K_LEFT]: - player.moveLeft() - # right to move right + player.move_left() if pressed[pygame.K_RIGHT]: - player.moveRight() + player.move_right() # refresh screen self.screen.fill(colors['BLACK']) @@ -98,68 +134,98 @@ def mainLoop(self): # update current time current_time = pygame.time.get_ticks() - # generate obstacle at random time - if (current_time - prev_time > obs_dt): - # uncomment below to generate random obstacles: - # obstacles.append(Obstacle(obs_x, obs_y, obs_len, self.screen,'BLUE')) - new_obstical = False - prev_time = current_time - obs_dt = randint(1000, 3000) - # generate obstacle player's obstacle at appropriate height - if (new_obstical == True and P2_stamina_bar.bars >= 33): - new_obstical = False - P2_stamina_bar.decreaseBar(33) - obstacles.append(Obstacle(obs_x, obstical_height, obs_len, self.screen,'RED')) + if self.oneplayer: + # generate obstacle at random time + if (current_time - prev_time > obs_dt): + obstacles.append(Obstacle(OBS_X, OBS_Y, OBS_LEN, self.screen,'GREEN')) + prev_time = current_time + obs_dt = randint(250, 1000) + if not self.oneplayer: + # generate obstacle player's obstacle at appropriate height + if (new_obstacle == True and P2_stamina_bar.bars >= OBSTACLE_COST): + new_obstacle = False + P2_stamina_bar.decrease_bar(OBSTACLE_COST) + obstacles.append(Obstacle(OBS_X, obstacle_height, OBS_LEN, self.screen,'RED')) # move each obstacle forward for obstacle in obstacles: - obstacle.moveForward() + obstacle.move_forward() + obstacle.draw() # check for collision between player and obstacles - if player.isCollide(obstacle.obs_x, obstacle.obs_y, obstacle.obs_len): - self.gameOver(str(count)) + if player.is_collide(obstacle.obs_x, obstacle.obs_y, obstacle.obs_len): + self.game_over(str(count)) # remove obstacle from list if off screen - obstacles = [obstacle for obstacle in obstacles if not obstacle.isGone()] + obstacles = [obstacle for obstacle in obstacles if not obstacle.is_gone()] # update stamina bars - P1_stamina_bar.increaseBar() - P2_stamina_bar.increaseBar(1.5) + P1_stamina_bar.increase_bar() P1_stamina_bar.draw() - P2_stamina_bar.draw() + if not self.oneplayer: + P2_stamina_bar.increase_bar(1.5) + P2_stamina_bar.draw() # display score - font = pygame.font.SysFont("comicsansms", 72) - text = font.render(str(count), True, (255,255,255)) - self.screen.blit(text,[200,10]) + font = pygame.font.SysFont("comicsansms", int(self.width/8)) + text = font.render(str(count), True, colors['WHITE']) + text_rect = text.get_rect(center=(self.width/2, self.height/8)) + self.screen.blit(text, text_rect) # update screen pygame.display.flip() self.clock.tick(30) - def gameOver(self,score): + def game_over(self, score): """Game over screen.""" # main event loop - while 1: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - sys.exit() + while True: + if pygame.QUIT in {event.type for event in pygame.event.get()}: + sys.exit() # check keyboard for space key to restart game pressed = pygame.key.get_pressed() if pressed[pygame.K_SPACE]: - self.mainLoop() + self.main_loop() + if pressed[pygame.K_v]: + self.start_menu() # display game over screen self.screen.fill(colors['BLACK']) - font = pygame.font.SysFont("comicsansms", 28) - text = font.render("Player 1 recived a score of " + str(score), True, (255,255,255)) - self.screen.blit(text,[50,140]) - text = font.render("Press Space Bar to play again", True, (255,255,255)) - self.screen.blit(text,[50,178]) + font = pygame.font.SysFont("comicsansms", int(self.width/16)) + text = font.render("Score: " + str(score), True, colors['WHITE']) + text_rect = text.get_rect(center=(self.width/2, self.height*1/3)) + self.screen.blit(text,text_rect) + text = font.render("Press Space Bar to play again", True, colors['WHITE']) + text_rect = text.get_rect(center=(self.width/2, self.height*1/2)) + self.screen.blit(text,text_rect) + text = font.render("Press V to go to home screen", True, colors['WHITE']) + text_rect = text.get_rect(center=(self.width/2, self.height*2/3)) + self.screen.blit(text,text_rect) # update screen pygame.display.flip() + def button(self, msg, x, y, color, oneplayer, action=None): + "Button for start screen." + mouse = pygame.mouse.get_pos() + click = pygame.mouse.get_pressed() + font = pygame.font.SysFont("comicsansms", int(self.width/20)) + text = font.render(msg, True, colors['WHITE']) + w = self.width/3 + h = self.width/12 + + if x+w > mouse[0] > x and y+h > mouse[1] > y: + pygame.draw.rect(self.screen, color, (x,y,w,h)) + + if click[0] == 1 and action != None: + self.oneplayer = oneplayer + action() + else: + pygame.draw.rect(self.screen, colors['BLACK'], (x,y,w,h)) + + self.screen.blit(text,[x+20,y]) + + if __name__ == "__main__": - Game4Main().mainLoop() + Game4Main().start_menu() diff --git a/Old Files/gameover.png b/Old Files/gameover.png new file mode 100644 index 0000000..ef7e113 Binary files /dev/null and b/Old Files/gameover.png differ diff --git a/playermoves.py b/Old Files/playermoves.py similarity index 94% rename from playermoves.py rename to Old Files/playermoves.py index 6121815..75b681d 100644 --- a/playermoves.py +++ b/Old Files/playermoves.py @@ -1,25 +1,25 @@ -import pygame -from pygame.locals import * -import time -from sys import exit -pygame.init() -def jump(ctime, startloc): - """ - Changes the y position up one frame - #for i in range(21): - - #print(jump(i,0)[1]) - """ - over = False - h = 100 - t = 20 - b = startloc - c = t/2 - a = h/((t/2)**2) - x = (ctime%20) - recty = (a*(x - c)**2)+b - - - if (x == 0): - over = True - return [recty, over] +import pygame +from pygame.locals import * +import time +from sys import exit +pygame.init() +def jump(ctime, startloc): + """ + Changes the y position up one frame + #for i in range(21): + + #print(jump(i,0)[1]) + """ + over = False + h = 100 + t = 20 + b = startloc + c = t/2 + a = h/((t/2)**2) + x = (ctime%20) + recty = (a*(x - c)**2)+b + + + if (x == 0): + over = True + return [recty, over] diff --git a/pygame_base_template.py b/Old Files/pygame_base_template.py similarity index 95% rename from pygame_base_template.py rename to Old Files/pygame_base_template.py index 94b378f..5eb8bcc 100644 --- a/pygame_base_template.py +++ b/Old Files/pygame_base_template.py @@ -1,115 +1,115 @@ -""" - Pygame base template for opening a window - - Sample Python/Pygame Programs - Simpson College Computer Science - http://programarcadegames.com/ - http://simpson.edu/computer-science/ - - Explanation video: http://youtu.be/vRB_983kUMc -""" - - - -import pygame -from playermoves import * - - -# Define some colors -BLACK = (0, 0, 0) -WHITE = (255, 255, 255) -GREEN = (0, 255, 0) -RED = (255, 0, 0) -jumping = False -pygame.init() - -# Set the width and height of the screen [width, height] -size = (700, 500) -screen = pygame.display.set_mode(size) - -pygame.display.set_caption("My Game") - -# Loop until the user clicks the close button. -done = False - -# Used to manage how fast the screen updates -clock = pygame.time.Clock() -frames = 0; -startjump = 0 -x_min = 0 -x_max = 200 -rectx = 100 -recty = 400 - -# -------- Main Program Loop ----------- -while not done: - - # --- Main event loop - - for event in pygame.event.get(): - if event.type == pygame.QUIT: - done = True - #if event.type == pygame.KEYDOWN: -# - # if event.key == pygame.K_SPACE: - # if frames - startjump > 20: - # jumping = True - # startjump = frames - - pressed = pygame.key.get_pressed() - if pressed[pygame.K_UP]: - if frames - startjump > 20: - jumping = True - startjump = frames - if pressed[pygame.K_LEFT]: - if rectx > x_min: - rectx -= 5 - if pressed[pygame.K_RIGHT]: - if rectx < x_max: - rectx += 5 - - - - - - # --- Game logic should go here - - # --- Screen-clearing code goes here - - # Here, we clear the screen to white. Don't put other drawing commands - # above this, or they will be erased with this command. - - # If you want a background image, replace this clear with blit'ing the - # background image. - screen.fill(BLACK) - pygame.draw.rect(screen, RED, [0,425,700,100]) - jumpclock = frames%21 - - # --- Drawing code should go here - # --- Drawing code should go here - - jumpover = False - - #if False:#if detect_key_press() == 'space': - # jumping = True #if the spacebar is pressed start the jump - # print("boing") - #else: - # print(detect_key_press()) - if jumping == True: - recty = jump(frames-startjump+1,300)[0] - jumpover = jump(frames-startjump+1,300)[1] - if jumpover == True: - - jumping = False - - pygame.draw.rect(screen, WHITE, [rectx,recty,25,25]) - # --- Go ahead and update the screen with what we've drawn - pygame.display.flip() - frames+=1 # increments frame count - - # --- Limit to 60 frames per second - clock.tick(60) - - -# Close the window and quit. -pygame.quit() +""" + Pygame base template for opening a window + + Sample Python/Pygame Programs + Simpson College Computer Science + http://programarcadegames.com/ + http://simpson.edu/computer-science/ + + Explanation video: http://youtu.be/vRB_983kUMc +""" + + + +import pygame +from playermoves import * + + +# Define some colors +BLACK = (0, 0, 0) +WHITE = (255, 255, 255) +GREEN = (0, 255, 0) +RED = (255, 0, 0) +jumping = False +pygame.init() + +# Set the width and height of the screen [width, height] +size = (700, 500) +screen = pygame.display.set_mode(size) + +pygame.display.set_caption("My Game") + +# Loop until the user clicks the close button. +done = False + +# Used to manage how fast the screen updates +clock = pygame.time.Clock() +frames = 0; +startjump = 0 +x_min = 0 +x_max = 200 +rectx = 100 +recty = 400 + +# -------- Main Program Loop ----------- +while not done: + + # --- Main event loop + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + done = True + #if event.type == pygame.KEYDOWN: +# + # if event.key == pygame.K_SPACE: + # if frames - startjump > 20: + # jumping = True + # startjump = frames + + pressed = pygame.key.get_pressed() + if pressed[pygame.K_UP]: + if frames - startjump > 20: + jumping = True + startjump = frames + if pressed[pygame.K_LEFT]: + if rectx > x_min: + rectx -= 5 + if pressed[pygame.K_RIGHT]: + if rectx < x_max: + rectx += 5 + + + + + + # --- Game logic should go here + + # --- Screen-clearing code goes here + + # Here, we clear the screen to white. Don't put other drawing commands + # above this, or they will be erased with this command. + + # If you want a background image, replace this clear with blit'ing the + # background image. + screen.fill(BLACK) + pygame.draw.rect(screen, RED, [0,425,700,100]) + jumpclock = frames%21 + + # --- Drawing code should go here + # --- Drawing code should go here + + jumpover = False + + #if False:#if detect_key_press() == 'space': + # jumping = True #if the spacebar is pressed start the jump + # print("boing") + #else: + # print(detect_key_press()) + if jumping == True: + recty = jump(frames-startjump+1,300)[0] + jumpover = jump(frames-startjump+1,300)[1] + if jumpover == True: + + jumping = False + + pygame.draw.rect(screen, WHITE, [rectx,recty,25,25]) + # --- Go ahead and update the screen with what we've drawn + pygame.display.flip() + frames+=1 # increments frame count + + # --- Limit to 60 frames per second + clock.tick(60) + + +# Close the window and quit. +pygame.quit() diff --git a/config.py b/config.py new file mode 100644 index 0000000..6190651 --- /dev/null +++ b/config.py @@ -0,0 +1,21 @@ +colors = {'BLACK': (0, 0, 0), + 'WHITE' : (255, 255, 255), + 'GREEN' : (0, 255, 0), + 'RED' : (255, 0, 0), + 'BLUE' : (0, 0, 255), + } + +PLAY_LEN = 25 +PLAY_X = 100 + +P1_STAMINA_BAR_OFFSET = 25 +P2_STAMINA_BAR_OFFSET = 125 +JUMP_COST = 33 +OBSTACLE_COST = 33 + +OBS_LEN = 25 + +LEVEL_OFFSETS = {'ground': 0, + 'first': 25, + 'second': 50, + } diff --git a/gameover.png b/gameover.png deleted file mode 100644 index 24035b8..0000000 Binary files a/gameover.png and /dev/null differ diff --git a/misc.py b/models.py similarity index 87% rename from misc.py rename to models.py index a48d400..1f16a25 100644 --- a/misc.py +++ b/models.py @@ -1,13 +1,7 @@ import os, sys import pygame - -colors = {'BLACK': (0, 0, 0), - 'WHITE' : (255, 255, 255), - 'GREEN' : (0, 255, 0), - 'RED' : (255, 0, 0), - 'BLUE' : (0, 0, 255), - } +from config import * class Obstacle: @@ -24,12 +18,15 @@ def __init__(self, obs_x, obs_y, obs_len, screen, color): def __repr__(self): return 'Obstacle({}, {}, {}, {})'.format(self.obs_x, self.obs_y, self.obs_len, self.screen) - def moveForward(self): - """Update horizontal location and draw obstacle.""" - self.obs_x -= 20 + def draw(self): + """Draw osbstacle based on top left hand coordinate and length.""" pygame.draw.rect(self.screen, colors[self.color], [self.obs_x, self.obs_y, self.obs_len, self.obs_len]) - def isGone(self): + def move_forward(self): + """Update horizontal location of obstacle.""" + self.obs_x -= 20 + + def is_gone(self): """Check if obstacle is completely off screen.""" return self.obs_x < -self.obs_len @@ -48,18 +45,17 @@ def __init__(self, play_x, play_y, play_len, screen): self.v = 7.5 # "velocity" for jump self.m = 2.5 # "mass" for jump self.floor = play_y # location of player before jump, used for comparison - self.jumpcost = 30 def draw(self): """Draw player based on top left hand coordinate and length.""" pygame.draw.rect(self.screen, colors['WHITE'], [self.play_x, self.play_y, self.play_len, self.play_len]) - def moveRight(self): + def move_right(self): """Update horizontal location of player after moving right.""" if self.play_x < 300: self.play_x += self.speed - def moveLeft(self): + def move_left(self): """Update horizontal location of player after moving left.""" if self.play_x > 0: self.play_x -= self.speed @@ -88,7 +84,7 @@ def update(self): # reset velocity self.v = 7.5 - def isCollide(self, obs_x, obs_y, obs_len): + def is_collide(self, obs_x, obs_y, obs_len): """Check collision of player with obstacle.""" # set coordinates for top left hand corner (0) and bottom right hand corner (1) of obstacle obs_x0 = obs_x @@ -101,7 +97,7 @@ def isCollide(self, obs_x, obs_y, obs_len): play_y0 = self.play_y play_y1 = self.play_y + self.play_len # check if player coordinates within obstacle coordinates - if (play_x0 in range(obs_x0, obs_x1) or play_x1 in range(obs_x0, obs_x1)) and (int(play_y0) in range(obs_y0, obs_y1) or int(play_y1) in range(obs_y0, obs_y1)): + if (obs_x0 <= play_x0 <= obs_x1 or obs_x0 <= play_x1 <= obs_x1) and (obs_y0 <= play_y0 < obs_y1 or obs_y0 < play_y1 <= obs_y1): return True @@ -118,11 +114,11 @@ def draw(self): """Draw stamina bar based on color, starting location, and number of health bars.""" pygame.draw.rect(self.screen, colors[self.color], [self.start, 20, self.bars, 10]) - def decreaseBar(self, num_bars): + def decrease_bar(self, num_bars): """Decrease health bar by num_bars.""" self.bars -= num_bars - def increaseBar(self, speed = 1): + def increase_bar(self, speed = 1): """Increase health bar continuously if number of bars is lower than 100.""" if self.bars < 100: self.bars += 1 * speed