diff --git a/Fall.py b/Fall.py
new file mode 100644
index 0000000..8ce4187
--- /dev/null
+++ b/Fall.py
@@ -0,0 +1,360 @@
+import pygame
+from pygame.locals import QUIT, KEYDOWN, MOUSEMOTION
+import time
+from random import choice
+
+player_speed = 2 #a value from 1 to 10
+# plank_speed = 5 #a value from 1 to 10
+
+
+white = (255, 255, 255)
+black = (0, 0, 0)
+green = (79, 191, 44)
+red = (255, 0, 0)
+blue = (13, 0, 145)
+
+clock = pygame.time.Clock()
+
+pygame.font.init()
+fontsmall = pygame.font.SysFont('UbuntuMono',40)
+fontlarge = pygame.font.SysFont('UbuntuMono',100)
+fonttiny = pygame.font.SysFont('UbuntuMono', 15)
+
+class Plank(object):
+ """ Represents a plank in our Fall game """
+ def __init__(self, left, top, width, height, plank_type):
+ self.left = left
+ self.top = top
+ self.width = width
+ self.height = height
+ self.plank_type = plank_type
+ # self.color = choice(["red", "green", "orange", "blue", "purple"])
+ if plank_type == "regular":
+ self.color=pygame.Color(178,238,238) # a teal color
+ elif plank_type == 'spike':
+ self.color=pygame.Color('red')
+ elif plank_type == 'flip':
+ self.color = pygame.Color(0, 255, 0)
+ self.rect = pygame.Rect(left, top, width, height)
+
+ def movey(self):
+ self.rect.move_ip(0,-1)
+
+class Player(object):
+ """ Represents the player in our Fall game """
+ def __init__(self, left, top, width, height):
+ """ Initialize the player with the specified geometry """
+ self.rect = pygame.Rect(left, top, width, height)
+ self.speed = (10 - player_speed)/10.0 + 0.3
+ self.dx=0
+ self.dy=0
+
+ def movex(self, dx):
+ '''Moves player side ways by an integer value of dx!
+ Checks for the walls and stops player from moving outside the walls'''
+ if self.rect.left<=20:
+ if self.dx>0:
+ self.rect.move_ip(self.dx,0)
+ elif self.rect.left>=480-self.rect.width-20:
+ if self.dx<0:
+ self.rect.move_ip(self.dx,0)
+ else:
+ self.rect.move_ip(self.dx,0)
+
+ def movey(self,dy):
+ self.rect.move_ip(0,dy)
+
+class FallModel(object):
+ """ Stores the game state for our Fall game """
+ def __init__(self):
+ self.controller = PyGameKeyboardController(self)
+ self.time_on_flip=0 #time on a flip plank
+ self.time=0 #total time since game started
+ self.make_plank_time=0 # times that new plank is made
+ self.move_plank_time=0 #Times that planks are moved
+ self.fall_time=0 #Time that a player falls down from a plank
+ # self.move_plank_speed=(10 - plank_speed)/2+1 # The smaller this is, the faster the planks move up
+ self.score=0
+ self.move_plank_speed=4 # The smaller this is, the faster the planks move up
+
+ self.WALL_THICKNESS=20
+ self.top_wall=Wall(0,0,480,self.WALL_THICKNESS)
+ self.left_wall=Wall(0,0,self.WALL_THICKNESS,640)
+ self.right_wall=Wall(480-self.WALL_THICKNESS,0,self.WALL_THICKNESS,640)
+
+ self.PLAYER_WIDTH = 20
+ self.PLAYER_HEIGHT = 20
+
+ self.planks = []
+ self.PLANK_WIDTH = 80
+ self.PLANK_HEIGHT = 20
+ first_plank=Plank(480/2, 400,self.PLANK_WIDTH, self.PLANK_HEIGHT, "regular")
+ self.planks.append(first_plank)
+
+ self.on_plank=False
+ self.beside_plank=False
+ self.current_plank = first_plank
+
+ self.life = 500
+ self.player = Player(480/2, 400 - self.PLAYER_HEIGHT, self.PLAYER_WIDTH, self.PLAYER_HEIGHT)
+
+
+ def is_dead(self):
+ return self.player.rect.top>=640 or self.player.rect.top<=0 or self.life <= 0
+
+ def make_planks(self):
+ #Make new planks from the bottom
+ # if make_new_p:
+ plank_types = ["regular", "regular", "regular", "regular", "spike", "flip"]
+ new_plank_x=choice(range(20,480-20-self.PLANK_WIDTH))
+ new_plank=Plank(new_plank_x, 640, self.PLANK_WIDTH, self.PLANK_HEIGHT, choice(plank_types))
+
+ self.planks.append(new_plank)
+
+ def move_planks(self):
+ for p in self.planks:
+ p.movey()
+
+ def check_on_plank(self):
+ for p in self.planks:
+ # if self.player.rect.colliderect(p):
+ #Check if the player is on the plank (exactly)
+ if self.player.rect.right>=p.rect.left and self.player.rect.left<=p.rect.right:
+ if self.player.rect.bottom<=p.rect.top+3 and self.player.rect.bottom>=p.rect.top:
+ self.on_plank=True
+ self.current_plank = p
+ self.fall_time=0
+ #Check if the player is beside a plank:
+ if self.player.rect.top<=p.rect.bottom and self.player.rect.bottom>=p.rect.top:
+ self.beside_plank=True
+ self.player.dx=0
+
+ def update(self):
+ #check if player is on a plank and make it fall if otherwise
+ self.score=len(self.planks)
+
+ if self.score>200:
+ self.move_plank_speed=0
+ elif self.score>140:
+ self.move_plank_speed=0.3
+ elif self.score>110:
+ self.move_plank_speed=0.8
+ elif self.score>80:
+ self.move_plank_speed=1.8
+ elif self.score>30:
+ self.move_plank_speed=2.9
+ print self.move_plank_speed
+ self.time=pygame.time.get_ticks()
+ move_plank=False
+ self.on_plank=False
+ self.player.dx=0
+ self.check_on_plank()
+ self.controller.handle_event()
+ #Move the player in the x direction
+ self.player.movex(self.player.dx)
+
+ #Move planks and player in the y direction
+ if self.time-self.move_plank_time>self.move_plank_speed:
+ self.move_planks()
+ move_plank=True
+ self.move_plank_time=self.time
+
+ if not self.on_plank:
+ self.time_on_flip=0
+ self.fall_time+=1
+ if self.life<500:
+ self.life+=.1
+ #use the following if want gravity:
+ self.player.movey(int(self.fall_time/200+1))
+ #use the following if want constant fall speed:
+ # self.player.movey(1)
+
+ if self.on_plank and move_plank:
+ self.player.movey(-1)
+ self.fall_time=0
+ if self.current_plank.plank_type == 'spike':
+ self.life -= 1
+ if self.current_plank.plank_type == 'flip':
+ self.time_on_flip += 1
+ if self.time_on_flip >= 50:
+ self.planks.remove(self.current_plank)
+ #make new planks:
+ time_interval=choice(range(int(self.move_plank_speed*10+150),int(self.move_plank_speed*30+200)))
+ if self.time-self.make_plank_time>=time_interval:
+ self.make_planks()
+ self.make_plank_time=self.time
+
+class Wall(object):
+ """ Represents the walls in our game """
+ def __init__(self, left, top, width, height):
+ """ Initializes the wall with the specified width """
+ # self.left=left
+ # self.top=top
+ # self.width = width
+ # self.height=height
+ self.rect = pygame.Rect(left, top, width, height)
+
+
+class PyGameKeyboardController(object):
+ def __init__(self, model):
+ self.model = model
+ self.move_player_time=0
+
+ def handle_event(self):
+ """ Look for left and right keypresses to
+ modify the x position of the player """
+ keys = pygame.key.get_pressed() #Returns a tuple of 0s corresponding to every key on the keyboard
+ if self.model.time-self.move_player_time>model.player.speed:
+ if keys[pygame.K_LEFT]:
+ self.model.player.dx=-1
+ if keys[pygame.K_RIGHT]:
+ self.model.player.dx=1
+ self.move_player_time=self.model.time
+
+class PyGameMouseController(object):
+ def __init__(self, model):
+ self.model = model
+
+ def handle_event(self, event):
+ """ Look for mouse movements and respond appropriately """
+ if event.type != MOUSEMOTION:
+ return
+ self.model.player.left = event.pos[0]
+
+class PygameFallView(object):
+ """ Visualizes aFall game in a pygame window """
+ def __init__(self, model, screen):
+ """ Initialize the view with the specified model
+ and screen. """
+ self.model = model
+ self.screen = screen
+ self.text_start = 140
+
+ def draw(self):
+ """ Draw the game state to the screen """
+ self.screen.fill(pygame.Color('black'))
+ # draw walls to screen
+ tw=self.model.top_wall.rect
+ lw=self.model.left_wall.rect
+ rw=self.model.right_wall.rect
+
+ pygame.draw.rect(self.screen, pygame.Color('pink'), tw)
+ pygame.draw.rect(self.screen, pygame.Color('pink'), lw)
+ pygame.draw.rect(self.screen, pygame.Color('pink'), rw)
+
+ # draw the planks to the screen
+ for plank in self.model.planks:
+ pygame.draw.rect(self.screen, plank.color, plank.rect)
+
+ # draw the player to the screen
+ p = self.model.player.rect
+ # pos=(self.model.player.left, self.model.player.top)
+ # pygame.draw.circle(self.screen, pygame.Color('red'), pos, self.model.player.radius, width=0)
+ pygame.draw.rect(self.screen, pygame.Color('white'),p)
+ # displays the life
+ myfont = pygame.font.SysFont("monospace", 15)
+
+ life_display=int(self.model.life/100)
+
+ label = myfont.render("Life " + str(life_display), 1, (255,255,0))
+ screen.blit(label, (100, 100))
+
+ score = myfont.render("Score {}".format(self.model.score), 1, (255,255,0))
+ screen.blit(score, (100, 150))
+
+ pygame.display.update()
+
+ def display_text(self, msg, font, color, x, y):
+ """Writes text on screen"""
+ text = font.render(msg, True, color)
+ self.screen.blit(text, [x, y])
+
+ def start_menu(self):
+ """Shows starting menu"""
+
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_1]: #single player mode
+ return '1'
+ if keys[pygame.K_2]: #multi player mode
+ return '2'
+ if keys[pygame.K_3]: #double player mode
+ return '3'
+ self.screen.fill(white)
+ self.display_text("FALL", fontlarge, pygame.Color(178,238,238), 100, 120)
+ self.display_text("1. Solo", fontsmall, black, self.text_start, 270)
+ self.display_text("2. Controls", fontsmall, black, self.text_start, 310)
+ self.display_text("3. Quit", fontsmall, black, self.text_start, 350)
+ clock.tick(15)
+ pygame.display.update()
+ return '0'
+
+ def instruct(self):
+ self.screen.fill(white)
+ instructions1 = "Player 1 is green snake and uses WASD to control."
+ instructions2 = "Player 2 is blue snake and uses arrow keys to control."
+ instructions3 = "Eat the apple to gain points before time runs out!"
+ instructions4 = "Press 'Q' to go back."
+ self.display_text(instructions1, fontsmall, black, self.text_start, 270)
+ self.display_text(instructions2, fontsmall, black, self.text_start, 310)
+ self.display_text(instructions3, fontsmall, black, self.text_start, 350)
+ self.display_text(instructions4, fontsmall, black, self.text_start, 390)
+ pygame.display.update()
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_q]: #single player mode
+ return '0'
+ else:
+ return '2'
+ def score(self):
+ self.screen.fill(white)
+ score_text='Score:{}'.format(scores[-1])
+ msg1='Press q to go back'
+ msg2='Press 1 to restart'
+ self.display_text(score_text,fontlarge,black, 10,230)
+ self.display_text(msg1,fontsmall,black, 10,380)
+ self.display_text(msg2,fontsmall,black, 10,480)
+
+ keys = pygame.key.get_pressed()
+ pygame.display.update()
+ if keys[pygame.K_q]: #single player mode
+ return '0'
+ elif keys[pygame.K_1]:
+ return '1'
+ else:
+ return '4'
+
+if __name__ == '__main__':
+ pygame.init()
+ size = (480, 640)
+ screen = pygame.display.set_mode(size)
+ scores=[]
+ model=FallModel()
+ view = PygameFallView(model, screen)
+ #controller = PyGameMouseController(model)
+ running = True
+ res='0'
+
+ while running:
+ for event in pygame.event.get():
+ if event.type == QUIT:
+ running = False
+ if res=='0':
+ res=view.start_menu()
+ elif res=='1':
+ #Play the game
+ view.draw()
+ model.update()
+ if model.is_dead():
+ res='4'
+ scores.append(model.score)
+ elif res=='2':
+ res=view.instruct()
+ elif res=='3':
+ running=False
+ elif res=='4':
+ res=view.score()
+ model=FallModel()
+ view=PygameFallView(model,screen)
+ print res
+
+
+
diff --git a/Fall_cupcake_theme.py b/Fall_cupcake_theme.py
new file mode 100644
index 0000000..c35336f
--- /dev/null
+++ b/Fall_cupcake_theme.py
@@ -0,0 +1,420 @@
+'''This file runs the Fall Game using the pygame module
+@author: Xiaozheng Xu, Rebecca Getto
+March 2016
+'''
+import pygame
+from pygame.locals import QUIT, KEYDOWN, MOUSEMOTION, MOUSEBUTTONDOWN
+import time
+from random import choice
+import numpy
+
+#define fonts and colors
+white = (255, 255, 255)
+black = (0, 0, 0)
+pygame.font.init()
+fontsmall = pygame.font.SysFont('UbuntuMono',20)
+fontlarge = pygame.font.SysFont('UbuntuMono',100)
+fontmedium = pygame.font.SysFont('UbuntuMono',40)
+fonttiny = pygame.font.SysFont('UbuntuMono', 15)
+
+#set up display in order to convert images
+size = (480, 640)
+screen = pygame.display.set_mode(size)
+plank_size=(120,24)
+#load images and scale them
+fast_plank = pygame.image.load('fast_plank.png').convert_alpha() #converting the image to the same pixel type as the screen- makes the game much faster!
+flip_plank = pygame.image.load('flip_plank.png').convert_alpha() #conver_alpha makes empty pixels transparent
+heart_plank = pygame.image.load('heart_plank.png').convert_alpha()
+spike_plank = pygame.image.load('spike_plank.png').convert_alpha()
+slow_plank = pygame.image.load('slow_plank.png').convert_alpha()
+regular_plank = pygame.image.load('regular_plank.png').convert_alpha()
+player_cupcake =pygame.image.load('cupcake.png').convert_alpha()
+wall_image=pygame.image.load('wall.png').convert_alpha()
+legend_image=pygame.image.load('legend.png').convert_alpha()
+
+player_cupcake=pygame.transform.scale(player_cupcake,(40,40))
+regular_plank=pygame.transform.scale(regular_plank,plank_size)
+fast_plank=pygame.transform.scale(fast_plank,plank_size)
+slow_plank=pygame.transform.scale(slow_plank,plank_size)
+flip_plank=pygame.transform.scale(flip_plank,plank_size)
+heart_plank=pygame.transform.scale(heart_plank,plank_size)
+spike_plank=pygame.transform.scale(spike_plank,(plank_size[0],plank_size[1]+4))
+legend_image=pygame.transform.scale(legend_image,(300,400))
+
+
+class Plank(object):
+ """ Represents a plank in our Fall game """
+ def __init__(self, left, top, width, height, plank_type):
+ self.rect = pygame.Rect(left, top, width, height)
+ self.plank_type = plank_type
+ if plank_type == "regular":
+ self.image=regular_plank
+ elif plank_type == 'spike':
+ self.image=spike_plank
+ self.rect.height+=4
+ elif plank_type == 'flip':
+ self.image=flip_plank
+ elif plank_type == 'heart':
+ self.image=heart_plank
+ elif plank_type == 'fast':
+ self.image=fast_plank
+ elif plank_type == 'slow':
+ self.image=slow_plank
+
+ def movey(self):
+ self.rect.move_ip(0,-1)
+
+class Player(object):
+ """ Represents the player in our Fall game """
+ def __init__(self, left, top, width, height):
+ """ Initialize the player with a rectangle, its moving speed and instantaneous velocity dx and dy """
+ self.rect = pygame.Rect(left, top, width, height)
+ self.speed = 2 # this value changes when the player lands on fast and slow planks in the model
+ self.dx=0
+ self.dy=0
+ self.image=player_cupcake
+
+ def movex(self, dx):
+ '''Moves player side ways by an integer value of dx!
+ Checks for the walls and stops player from moving outside the walls'''
+ if self.rect.left<=20:
+ if self.dx>0:
+ self.rect.move_ip(self.dx,0)
+ elif self.rect.left>=480-self.rect.width-20:
+ if self.dx<0:
+ self.rect.move_ip(self.dx,0)
+ else:
+ self.rect.move_ip(self.dx,0)
+
+ def movey(self,dy):
+ '''Moves the player up and down by integer value dy'''
+ self.rect.move_ip(0,dy)
+
+class FallModel(object):
+ """ Stores the game state for our Fall game """
+ def __init__(self,start_time):
+ '''Initialize controller, time variables, player, planks list with first plank.
+
+ Takes in start_time which is the time the model is initialized as variable.
+
+ Defines types of plank and their probablity of ocurring'''
+ self.controller = PyGameKeyboardController(self)
+ self.time_on_flip=0 #time on a flip plank
+ self.start_time=start_time
+ self.time=0
+ self.make_plank_time=0 # times that new plank is made
+ self.move_plank_time=0 #Times that planks are moved
+ self.move_player_time=0
+ self.fall_time=0 #Time that a player falls down from a plank
+ self.score=0
+ self.move_plank_speed=4 # The smaller this is, the faster the planks move up. 4 is arbituary and pretty slow
+
+ self.PLAYER_WIDTH = 40
+ self.PLAYER_HEIGHT = 40
+ self.plank_types = ['fast','slow',"spike", "flip",'heart',"regular", "regular", "regular", "regular"]
+ self.planks = []
+ self.PLANK_WIDTH = plank_size[0]
+ self.PLANK_HEIGHT = plank_size[1]
+ first_plank=Plank(480/2, 500,self.PLANK_WIDTH, self.PLANK_HEIGHT, "regular")
+ self.planks.append(first_plank)
+
+ self.on_plank=False
+ self.beside_plank=False
+ self.current_plank = first_plank
+
+ self.life = 300
+ self.player = Player(480/2+30, 500 - self.PLAYER_HEIGHT, self.PLAYER_WIDTH, self.PLAYER_HEIGHT)
+ self.color=(255,230,255)
+
+ def is_dead(self):
+ '''Return True if the player is shuffed to the top, fall through the bottom, or run out of life'''
+ return self.player.rect.top>=640 or self.player.rect.top<=0 or self.life <= 0
+
+ def make_planks(self):
+ '''Make new planks in a random x position from the bottom'''
+ new_plank_x=choice(range(20,480-20-self.PLANK_WIDTH))
+ new_plank=Plank(new_plank_x, 640, self.PLANK_WIDTH, self.PLANK_HEIGHT, choice(self.plank_types))
+ self.planks.append(new_plank)
+
+ def move_planks(self):
+ '''move planks up and removes the ones that are outside the screen from planks list'''
+ for p in self.planks:
+ p.movey()
+ if p.rect.bottom<0:
+ self.planks.remove(p)
+
+ def check_on_plank(self):
+ '''Use a costum collision logic to check if the player is on a plank or beside a plank.
+ If player is on a plank: set self.current_plank to the plank the player is on.
+ If player is beside a plank, set the player's velocity to 0 so the player doesn't collide into the plank.'''
+ for p in self.planks:
+ #Check if the player is on the plank (exactly)
+ if self.player.rect.right>=p.rect.left and self.player.rect.left<=p.rect.right:
+ if p.plank_type=='spike':
+ plank_depth=7
+ else:
+ plank_depth=0
+
+ if self.player.rect.bottom
=p.rect.top+plank_depth:
+ self.on_plank=True
+ self.current_plank = p
+ self.fall_time=0
+ #Check if the player is beside a plank:
+ if self.player.rect.top<=p.rect.bottom and self.player.rect.bottom>=p.rect.top+plank_depth+3:
+ self.beside_plank=True
+ self.player.dx=0
+
+ def update(self):
+ '''Updates the model through each time step, including what planks are on the screen,
+ the positions of planks, player, life, score and player speed.
+ '''
+ #check if player is on a plank and make it fall if otherwise
+ self.score=int(self.time/500)
+ self.time=pygame.time.get_ticks()-self.start_time
+
+ #Continuously increase game speed starting from move_plank_speed=4
+ if self.score<200:
+ self.move_plank_speed=4-self.score*4.0/200
+ # self.color=(255-self.time/500,255,255) #teal color changing
+ elif self.score>=200:
+ self.move_plank_speed=0
+
+ #continuously change color
+ if self.color[1]>=100:
+ self.color=(255,230-self.time/400,255) #pink color changing
+ else:
+ self.color=(139,0,139)
+ # self.move_plank_speed=0
+
+ move_plank=False
+ self.on_plank=False
+
+ #Move the player in the x direction
+ self.player.dx=0
+ self.controller.handle_event()
+ self.check_on_plank() # check if the player is on a plank and whether the player is beside a plank, changes the boolean self.on_plank and self.beside_plank
+ if self.time-self.move_player_time>self.player.speed:
+ self.player.movex(int(self.player.dx))
+ self.move_player_time=self.time
+
+ #Move planks and player in the y direction if time interval is reached
+ if self.time-self.move_plank_time>self.move_plank_speed:
+ self.move_planks()
+ move_plank=True
+ self.move_plank_time=self.time
+
+ #Make the player fall, recover life, increment/reset times
+ if not self.on_plank:
+ self.time_on_flip=0
+ self.fall_time+=1
+ self.player.movey(int(self.fall_time/200+1))
+ #use the following if want constant fall speed:
+ # self.player.movey(1)
+
+ #Make the player move up with plank, carry out plank effects
+ if self.on_plank and move_plank:
+ self.player.movey(-1)
+ self.fall_time=0
+ if self.current_plank.plank_type == 'spike':
+ self.life -= 0.8
+ if self.current_plank.plank_type == 'flip':
+ self.time_on_flip += 1
+ if self.time_on_flip >= 50:
+ self.planks.remove(self.current_plank)
+ if self.current_plank.plank_type == 'heart':
+ self.life+=1
+ if self.current_plank.plank_type == 'fast':
+ if self.player.speed<=0.8:
+ self.player.speed=0.8
+ else:
+ self.player.speed-=0.01
+ if self.current_plank.plank_type == 'slow':
+ if self.player.speed<2.5:
+ self.player.speed+=0.01
+ #make new planks:
+ #random interval:
+ # time_interval=choice(range(int(self.move_plank_speed*35+100),int(self.move_plank_speed*55+101)))
+ #set interval depending on move_plank_speed:
+ time_interval=(self.move_plank_speed*100)+100
+ #constant interval: (planks will become more sparse as the move_plank_speed increase)
+ # time_interval=400
+ if self.time-self.make_plank_time>=time_interval:
+ self.make_planks()
+ self.make_plank_time=self.time
+
+class PyGameKeyboardController(object):
+ def __init__(self, model):
+ self.model = model
+ def handle_event(self):
+ """ Look for left and right keypresses to
+ modify the x position of the player """
+ keys = pygame.key.get_pressed() #Returns a tuple of 0s corresponding to every key on the keyboard
+ if keys[pygame.K_LEFT]:
+ self.model.player.dx=-1
+ if keys[pygame.K_RIGHT]:
+ self.model.player.dx=1
+
+class PyGameMouseController(object):
+ def __init__(self, model):
+ self.model = model
+
+ def handle_event(self):
+ """ Look for mouse movements and respond appropriately """
+ self.model.player.dx = numpy.sign(pygame.mouse.get_pos()[0]-240.0)
+
+
+class PygameFallView(object):
+ """ Visualizes aFall game in a pygame window """
+ def __init__(self, model, screen):
+ """ Initialize the view with the specified model
+ and screen. """
+ self.model = model
+ self.screen = screen
+ self.text_start = 140
+
+ def draw(self):
+ """ Draw the game state to the screen """
+
+ self.screen.fill(self.model.color) #fills the screen with a color from model
+ self.screen.blit(wall_image,(0,0)) #displays the wall
+
+ # draw the planks to the screen
+ for plank in self.model.planks:
+ self.screen.blit(plank.image, plank.rect)
+
+ # draw the player to the screen
+ p = self.model.player
+ self.screen.blit(p.image,p.rect)
+
+ # displays the life
+ myfont = pygame.font.SysFont("monospace", 40)
+ life_display=int(self.model.life/100)
+ label = myfont.render("Life " + str(life_display), 1, (186,85,211))
+ screen.blit(label, (50, 50))
+ #display the score
+ score = myfont.render("Score {}".format(self.model.score), 1, (176,196,222))
+ screen.blit(score, (250, 50))
+ pygame.display.update()
+
+ def display_text(self, msg, font, color, x, y):
+ """Writes text on screen"""
+ text = font.render(msg, True, color)
+ self.screen.blit(text, [x, y])
+
+ def start_menu(self):
+ """Shows starting menu"""
+
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_1]: #single player mode
+ return '1'
+ if keys[pygame.K_2]: #multi player mode
+ return '2'
+ if keys[pygame.K_3]: #double player mode
+ return '3'
+ if keys[pygame.K_4]: #double player mode
+ return '4'
+ self.screen.fill((255,220,255))
+ # self.display_text("FALL", fontlarge, (178,238,238), 100, 120) #teal
+ self.display_text("FALL", fontlarge, (176,196,222), 100, 120) #light steal (blue)
+ # self.display_text("FALL", fontlarge, (189,183,107), 100, 120) #goldish color
+ self.display_text("1. Solo", fontmedium, (186,85,211), self.text_start, 270)
+ self.display_text("2. Controls", fontmedium, (186,85,211), self.text_start, 310)
+ self.display_text("3. Legend", fontmedium, (186,85,211), self.text_start, 350)
+ self.display_text("4. Quit", fontmedium, (186,85,211), self.text_start, 390)
+ pygame.display.update()
+ return '0'
+
+ def controls(self):
+ '''Shows the controls'''
+ self.screen.fill((255,220,255))
+ instructions1 = "Move the cupcake left to right to stay on "
+ instructions2='planks and survive.'
+ instructions3 = "Keyboard control: left and right keys"
+ instructions4 = "Mouse control: place mouse in left and right"
+ instructions5= "halves of the screen to move cupcake"
+ instructions6 = "Webcam control(To be implemented): move face/color from"
+ instructions7="left to right facing the camera to move cupcake"
+ instructions8 = "Press 'Q' to go back."
+
+ self.display_text(instructions1, fontsmall, (186,85,211), 30, 250)
+ self.display_text(instructions2, fontsmall, (186,85,211), 30, 270)
+ self.display_text(instructions3, fonttiny, (186,85,211), 30, 300)
+ self.display_text(instructions4, fonttiny, (186,85,211), 30, 330)
+ self.display_text(instructions5, fonttiny, (186,85,211), 30, 350)
+ self.display_text(instructions6, fonttiny, (186,85,211), 30, 380)
+ self.display_text(instructions7, fonttiny, (186,85,211), 30, 400)
+ self.display_text(instructions8, fonttiny, (186,85,211), 30, 430)
+
+ pygame.display.update()
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_q]: #single player mode
+ return '0'
+ else:
+ return '2'
+
+ def legend(self):
+ self.screen.fill((255,220,255))
+ self.screen.blit(legend_image,(85,45))
+ instructions8 = "Press 'Q' to go back."
+ self.display_text(instructions8, fontsmall,(186,85,211), 100, 500)
+ pygame.display.update()
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_q]: #single player mode
+ return '0'
+ else:
+ return '3'
+
+ def score(self):
+ '''Show the score page and allow the player to go back to menu or restart the game'''
+ self.screen.fill((255,220,255))
+ score_text='Score:{}'.format(scores[-1])
+ msg1='Press q to go back'
+ msg2='Press 1 to restart'
+ self.display_text(score_text,fontlarge,(186,85,211), 10,230) #purple color
+ self.display_text(msg1,fontmedium,(186,85,211), 10,340)
+ self.display_text(msg2,fontmedium,(186,85,211), 10,380)
+ pygame.display.update()
+ keys = pygame.key.get_pressed()
+
+ if keys[pygame.K_q] or pygame.mouse.get_pressed()[0]==True: #single player mode
+ return '0'
+ elif keys[pygame.K_1]:
+ return '1'
+ else:
+ return '5'
+
+if __name__ == '__main__':
+ pygame.init()
+ model=FallModel(pygame.time.get_ticks())
+ view=PygameFallView(model,screen)
+ scores=[]
+ #controller = PyGameMouseController(model)
+ running = True
+ res='0'
+ while running:
+ for event in pygame.event.get():
+ if event.type == QUIT:
+ running = False
+ if res=='0':
+ res=view.start_menu()
+ elif res=='1':
+ #Play the game
+ view.draw()
+ model.update()
+ if model.is_dead():
+ res='5'
+ scores.append(model.score)
+ elif res=='2':
+ res=view.controls()
+ elif res=='3':
+ res=view.legend()
+ elif res=='4':
+ running=False
+ elif res=='5':
+ res=view.score()
+ model=FallModel(pygame.time.get_ticks())
+ view=PygameFallView(model,screen)
+
+
+
+
diff --git a/Fall_cv.py b/Fall_cv.py
new file mode 100644
index 0000000..0bb1a57
--- /dev/null
+++ b/Fall_cv.py
@@ -0,0 +1,361 @@
+import pygame
+from pygame.locals import QUIT, KEYDOWN, MOUSEMOTION
+import time
+from random import choice
+import cv2
+
+player_speed = 1 #a value from 1 to 10
+# plank_speed = 5 #a value from 1 to 10
+
+
+white = (255, 255, 255)
+black = (0, 0, 0)
+green = (79, 191, 44)
+red = (255, 0, 0)
+blue = (13, 0, 145)
+
+clock = pygame.time.Clock()
+
+pygame.font.init()
+fontsmall = pygame.font.SysFont('UbuntuMono',40)
+fontlarge = pygame.font.SysFont('UbuntuMono',100)
+fonttiny = pygame.font.SysFont('UbuntuMono', 15)
+
+class Plank(object):
+ """ Represents a plank in our Fall game """
+ def __init__(self, left, top, width, height, plank_type):
+ self.left = left
+ self.top = top
+ self.width = width
+ self.height = height
+ self.plank_type = plank_type
+ # self.color = choice(["red", "green", "orange", "blue", "purple"])
+ if plank_type == "regular":
+ self.color=pygame.Color(178,238,238) # a teal color
+ elif plank_type == 'spike':
+ self.color=pygame.Color('red')
+ elif plank_type == 'flip':
+ self.color = pygame.Color(0, 255, 0)
+ self.rect = pygame.Rect(left, top, width, height)
+
+ def movey(self):
+ self.rect.move_ip(0,-1)
+
+class Player(object):
+ """ Represents the player in our Fall game """
+ def __init__(self, left, top, width, height):
+ """ Initialize the player with the specified geometry """
+ self.rect = pygame.Rect(left, top, width, height)
+ self.speed = (10 - player_speed)/10.0 + 0.3
+ self.dx=0
+ self.dy=0
+
+ def movex(self, dx):
+ '''Moves player side ways by an integer value of dx!
+ Checks for the walls and stops player from moving outside the walls'''
+ if self.rect.left<=20:
+ if self.dx>0:
+ self.rect.move_ip(self.dx,0)
+ elif self.rect.left>=480-self.rect.width-20:
+ if self.dx<0:
+ self.rect.move_ip(self.dx,0)
+ else:
+ self.rect.move_ip(self.dx,0)
+
+ def movey(self,dy):
+ self.rect.move_ip(0,dy)
+
+class FallModel(object):
+ """ Stores the game state for our Fall game """
+ def __init__(self):
+ self.controller = PyGameCvController(self)
+ self.time_on_flip=0 #time on a flip plank
+ self.time=0 #total time since game started
+ self.make_plank_time=0 # times that new plank is made
+ self.move_plank_time=0 #Times that planks are moved
+ self.fall_time=0 #Time that a player falls down from a plank
+ # self.move_plank_speed=(10 - plank_speed)/2+1 # The smaller this is, the faster the planks move up
+ self.score=0
+ self.move_plank_speed=4 # The smaller this is, the faster the planks move up
+
+ self.WALL_THICKNESS=20
+ self.top_wall=Wall(0,0,480,self.WALL_THICKNESS)
+ self.left_wall=Wall(0,0,self.WALL_THICKNESS,640)
+ self.right_wall=Wall(480-self.WALL_THICKNESS,0,self.WALL_THICKNESS,640)
+
+ self.PLAYER_WIDTH = 30
+ self.PLAYER_HEIGHT = 30
+
+ self.planks = []
+ self.PLANK_WIDTH = 100
+ self.PLANK_HEIGHT = 20
+ first_plank=Plank(480/2, 400,self.PLANK_WIDTH, self.PLANK_HEIGHT, "regular")
+ self.planks.append(first_plank)
+
+ self.on_plank=False
+ self.beside_plank=False
+ self.current_plank = first_plank
+
+ self.life = 500
+ self.player = Player(480/2, 400 - self.PLAYER_HEIGHT, self.PLAYER_WIDTH, self.PLAYER_HEIGHT)
+
+
+ def is_dead(self):
+ return self.player.rect.top>=640 or self.player.rect.top<=0 or self.life <= 0
+
+ def make_planks(self):
+ #Make new planks from the bottom
+ # if make_new_p:
+ plank_types = ["regular", "regular", "regular", "regular", "spike", "flip"]
+ new_plank_x=choice(range(20,480-20-self.PLANK_WIDTH))
+ new_plank=Plank(new_plank_x, 640, self.PLANK_WIDTH, self.PLANK_HEIGHT, choice(plank_types))
+
+ self.planks.append(new_plank)
+
+ def move_planks(self):
+ for p in self.planks:
+ p.movey()
+
+ def check_on_plank(self):
+ for p in self.planks:
+ # if self.player.rect.colliderect(p):
+ #Check if the player is on the plank (exactly)
+ if self.player.rect.right>=p.rect.left and self.player.rect.left<=p.rect.right:
+ if self.player.rect.bottom<=p.rect.top+3 and self.player.rect.bottom>=p.rect.top:
+ self.on_plank=True
+ self.current_plank = p
+ self.fall_time=0
+ #Check if the player is beside a plank:
+ if self.player.rect.top<=p.rect.bottom and self.player.rect.bottom>=p.rect.top:
+ self.beside_plank=True
+ self.player.dx=0
+
+ def update(self):
+ #check if player is on a plank and make it fall if otherwise
+ self.score=len(self.planks)
+
+ self.time=pygame.time.get_ticks()
+ move_plank=False
+ self.on_plank=False
+ self.player.dx=0
+ self.check_on_plank()
+ self.controller.handle_event()
+ #Move the player in the x direction
+ self.player.movex(self.player.dx)
+ #Move planks and player in the y direction
+ if self.time-self.move_plank_time>self.move_plank_speed:
+ self.move_planks()
+ move_plank=True
+ self.move_plank_time=self.time
+
+ if not self.on_plank:
+ self.time_on_flip=0
+ self.fall_time+=1
+ if self.life<500:
+ self.life+=.1
+ #use the following if want gravity:
+ self.player.movey(int(self.fall_time/200+1))
+ #use the following if want constant fall speed:
+ # self.player.movey(1)
+ self.controller.handle_event()
+ if self.on_plank and move_plank:
+ self.player.movey(-1)
+ self.fall_time=0
+ if self.current_plank.plank_type == 'spike':
+ self.life -= 1
+ if self.current_plank.plank_type == 'flip':
+ self.time_on_flip += 1
+ if self.time_on_flip >= 50:
+ self.planks.remove(self.current_plank)
+ #make new planks:
+ time_interval=choice(range(int(self.move_plank_speed*30+100),int(self.move_plank_speed*100+101)))
+ if self.time-self.make_plank_time>=time_interval:
+ self.make_planks()
+ self.make_plank_time=self.time
+
+class Wall(object):
+ """ Represents the walls in our game """
+ def __init__(self, left, top, width, height):
+ """ Initializes the wall with the specified width """
+ # self.left=left
+ # self.top=top
+ # self.width = width
+ # self.height=height
+ self.rect = pygame.Rect(left, top, width, height)
+
+class PyGameCvController(object):
+ def __init__(self,model):
+ self.cap = cv2.VideoCapture(0)
+ self.model=model
+ self.face_cascade = cv2.CascadeClassifier('/home/xiaozheng/Softdes/ToolBox-ComputerVision/haarcascade_frontalface_alt.xml')
+
+ def handle_event(self):
+ ret, frame = self.cap.read()
+
+ faces = self.face_cascade.detectMultiScale(frame, scaleFactor=1.2, minSize=(20,20))
+
+ for (x,y,w,h) in faces:
+ deltax=225-x
+ self.model.player.dx=deltax/100
+ # Display the resulting frame
+ cv2.imshow('frame',frame)
+ cv2.waitKey(1)
+
+ def closecv(self):
+ self.cap.release()
+ cv2.destroyAllWindows()
+
+
+class PyGameKeyboardController(object):
+ def __init__(self, model):
+ self.model = model
+ self.move_player_time=0
+
+ def handle_event(self):
+ """ Look for left and right keypresses to
+ modify the x position of the player """
+ keys = pygame.key.get_pressed() #Returns a tuple of 0s corresponding to every key on the keyboard
+ if self.model.time-self.move_player_time>model.player.speed:
+ if keys[pygame.K_LEFT]:
+ self.model.player.dx=-1
+ if keys[pygame.K_RIGHT]:
+ self.model.player.dx=1
+ self.move_player_time=self.model.time
+
+class PygameFallView(object):
+ """ Visualizes aFall game in a pygame window """
+ def __init__(self, model, screen):
+ """ Initialize the view with the specified model
+ and screen. """
+ self.model = model
+ self.screen = screen
+ self.text_start = 140
+
+ def draw(self):
+ """ Draw the game state to the screen """
+ self.screen.fill(pygame.Color('black'))
+ # draw walls to screen
+ tw=self.model.top_wall.rect
+ lw=self.model.left_wall.rect
+ rw=self.model.right_wall.rect
+
+ pygame.draw.rect(self.screen, pygame.Color('pink'), tw)
+ pygame.draw.rect(self.screen, pygame.Color('pink'), lw)
+ pygame.draw.rect(self.screen, pygame.Color('pink'), rw)
+
+ # draw the planks to the screen
+ for plank in self.model.planks:
+ pygame.draw.rect(self.screen, plank.color, plank.rect)
+
+ # draw the player to the screen
+ p = self.model.player.rect
+ # pos=(self.model.player.left, self.model.player.top)
+ # pygame.draw.circle(self.screen, pygame.Color('red'), pos, self.model.player.radius, width=0)
+ pygame.draw.rect(self.screen, pygame.Color('white'),p)
+ # displays the life
+ myfont = pygame.font.SysFont("monospace", 15)
+
+ life_display=int(self.model.life/100)
+
+ label = myfont.render("Life " + str(life_display), 1, (255,255,0))
+ screen.blit(label, (100, 100))
+
+ score = myfont.render("Score {}".format(self.model.score), 1, (255,255,0))
+ screen.blit(score, (100, 150))
+
+ pygame.display.update()
+
+ def display_text(self, msg, font, color, x, y):
+ """Writes text on screen"""
+ text = font.render(msg, True, color)
+ self.screen.blit(text, [x, y])
+
+ def start_menu(self):
+ """Shows starting menu"""
+
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_1]: #single player mode
+ return '1'
+ if keys[pygame.K_2]: #multi player mode
+ return '2'
+ if keys[pygame.K_3]: #double player mode
+ return '3'
+ self.screen.fill(white)
+ self.display_text("FALL", fontlarge, pygame.Color(178,238,238), 100, 120)
+ self.display_text("1. Solo", fontsmall, black, self.text_start, 270)
+ self.display_text("2. Controls", fontsmall, black, self.text_start, 310)
+ self.display_text("3. Quit", fontsmall, black, self.text_start, 350)
+ clock.tick(15)
+ pygame.display.update()
+ return '0'
+
+ def instruct(self):
+ self.screen.fill(white)
+ instructions1 = "Player 1 is green snake and uses WASD to control."
+ instructions2 = "Player 2 is blue snake and uses arrow keys to control."
+ instructions3 = "Eat the apple to gain points before time runs out!"
+ instructions4 = "Press 'Q' to go back."
+ self.display_text(instructions1, fontsmall, black, self.text_start, 270)
+ self.display_text(instructions2, fontsmall, black, self.text_start, 310)
+ self.display_text(instructions3, fontsmall, black, self.text_start, 350)
+ self.display_text(instructions4, fontsmall, black, self.text_start, 390)
+ pygame.display.update()
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_q]: #single player mode
+ return '0'
+ else:
+ return '2'
+ def score(self):
+ self.screen.fill(white)
+ score_text='Score:{}'.format(scores[-1])
+ msg1='Press q to go back'
+ msg2='Press 1 to restart'
+ self.display_text(score_text,fontlarge,black, 10,230)
+ self.display_text(msg1,fontsmall,black, 10,380)
+ self.display_text(msg2,fontsmall,black, 10,480)
+
+ keys = pygame.key.get_pressed()
+ pygame.display.update()
+ if keys[pygame.K_q]: #single player mode
+ return '0'
+ elif keys[pygame.K_1]:
+ return '1'
+ else:
+ return '4'
+
+if __name__ == '__main__':
+ pygame.init()
+ size = (480, 640)
+ screen = pygame.display.set_mode(size)
+ scores=[]
+ model=FallModel()
+ view = PygameFallView(model, screen)
+ running = True
+ res='0'
+
+ while running:
+ for event in pygame.event.get():
+ if event.type == QUIT:
+ running = False
+
+ if res=='0':
+ res=view.start_menu()
+ elif res=='1':
+ #Play the game
+ view.draw()
+ model.update()
+ if model.is_dead():
+ model.controller.closecv()
+ res='4'
+ scores.append(model.score)
+ elif res=='2':
+ res=view.instruct()
+ elif res=='3':
+ running=False
+ elif res=='4':
+ res=view.score()
+ model=FallModel()
+ view=PygameFallView(model,screen)
+
+
+
diff --git a/ProjectRefelction.pdf b/ProjectRefelction.pdf
new file mode 100644
index 0000000..bf7237f
Binary files /dev/null and b/ProjectRefelction.pdf differ
diff --git a/README.md b/README.md
index 61ec120..f6c1e0c 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
# InteractiveProgramming
-This is the base repo for the interactive programming project for Software Design, Spring 2016 at Olin College.
+Updated version of Fall game is in Fall_cupcake_theme.py
+
diff --git a/cupcake.png b/cupcake.png
new file mode 100644
index 0000000..a949e6c
Binary files /dev/null and b/cupcake.png differ
diff --git a/fast_plank.png b/fast_plank.png
new file mode 100644
index 0000000..e05b2e7
Binary files /dev/null and b/fast_plank.png differ
diff --git a/flip_plank.png b/flip_plank.png
new file mode 100644
index 0000000..74c5f10
Binary files /dev/null and b/flip_plank.png differ
diff --git a/heart_plank.png b/heart_plank.png
new file mode 100644
index 0000000..d541079
Binary files /dev/null and b/heart_plank.png differ
diff --git a/legend.png b/legend.png
new file mode 100644
index 0000000..d4770bb
Binary files /dev/null and b/legend.png differ
diff --git a/regular_plank.png b/regular_plank.png
new file mode 100644
index 0000000..81e20f2
Binary files /dev/null and b/regular_plank.png differ
diff --git a/slow_plank.png b/slow_plank.png
new file mode 100644
index 0000000..b203795
Binary files /dev/null and b/slow_plank.png differ
diff --git a/spike_plank.png b/spike_plank.png
new file mode 100644
index 0000000..9851a36
Binary files /dev/null and b/spike_plank.png differ
diff --git a/sprite_sheet.png b/sprite_sheet.png
new file mode 100644
index 0000000..1d03caf
Binary files /dev/null and b/sprite_sheet.png differ
diff --git a/wall.png b/wall.png
new file mode 100644
index 0000000..dcf031f
Binary files /dev/null and b/wall.png differ