import pygame, copy, random, math, data from euclid import * from pygame.locals import * BGCOLOR=[50,100,200] GREEN=[50,150,50] ################ Function ########################### ########################################################## def rect(c,r): """Takes a center and offset and returns a list of points for that rectangle.""" return [Point2(c[0]+r[0],c[1]+r[1]), Point2(c[0]+r[0],c[1]-r[1]), Point2(c[0]-r[0],c[1]-r[1]), Point2(c[0]-r[0],c[1]+r[1])] def triangle(c,bh): """Take a center, anf a base-height tuple and makes the poins for a triangle)""" return [Point2(c[0]-bh[0]/2,c[1]+bh[1]/2), Point2(c[0] ,c[1]-bh[1] ), Point2(c[0]+bh[0]/2,c[1]+bh[1]/2)] def lerp(a,b,p=0.7): """Blend two colors with a certain percentage of the old""" newcolor=[0,0,0] for i in range(3): newcolor[i]=int(a[i]*p+b[i]*(1-p)) return newcolor def fcenter(points): """ Takes the average of x and y to find the center point or something close """ return Point2(sum([p[0]/len(points) for p in points]), sum([p[1]/len(points) for p in points])) def collision(player,wall,truefalse=True): """Detects if there is a collison. Optionally returns a vector""" vlist=[] if truefalse: return player.rect.colliderect(wall) else: if player.rect.colliderect(wall): if player.vel.x>0 and player.rect.top+2>wall.rect.top and player.oldrect.left < wall.rect.left: vlist.append(Vector2(wall.rect.left-player.rect.right,0)) if player.vel.x<0 and player.rect.top+2>wall.rect.top and player.oldrect.right > wall.rect.right: vlist.append(Vector2(wall.rect.right-player.rect.left,0)) if player.vel.y>0 and player.oldrect.top0: if abs(vlist[0].y)==0: player.upped=True return vlist[0] else: return Vector2(0,0) else: return Vector2(0,0) def logadd(y=0,x=0): """Formula to making a log""" return log( rect( [1700+random.randint(-2,2),400], [75+random.randint(-10,10)+x, 20+random.randint(0,10)+y] ), [150+random.randint(-10,10), 75+random.randint(-10,10),random.randint(0,10)] ) def moveup(d,e): return [[d[0][0],d[0][1]-e], [d[1][0],d[1][1]], [d[2][0],d[2][1]], [d[3][0],d[3][1]-e]] ################ Classes ######################### ######################################################## class polygon(object): """Basic polygon object""" def __init__(self,points,color=[200,200,100]): self.color=color self.points=[Point2(*x) for x in points] self.center=fcenter(points) self.vel=Vector2(0,0) self.acc=Vector2(0,0) self.width=0 self.rect=pygame.Rect(20,20,20,20) self.oldrect=copy.copy(self.rect) self.oldpoints=self.points[:] self.blend=GREEN ##person stuff i'm to lazy to make into a new init. self.upped=False self.lives=5 def draw(self,screen): """Draws a polygon based on the points and an outline that blends in with the background""" self.rect=pygame.draw.polygon( screen, self.color, [map(math.floor,x[:]) for x in self.points], self.width) pygame.draw.lines( screen, lerp(self.color,self.blend), 1, [map(math.floor,x[:]) for x in self.points], 1) def update(self): """adds accell to velocity and moves based on the velocity""" self.vel+=self.acc fvel=copy.deepcopy(self.vel) fvel.x=math.floor(fvel.x) fvel.y=math.floor(fvel.y) self.moverel(fvel) def moverel(self,v): """Takes a vector and moves the outer points and the fcenter based on those""" for i in self.points+[self.center]: i.x+=v.x i.y+=v.y def old(self): self.oldpoints=self.points[:] self.oldrect=copy.copy(self.rect) #-------------- person -------------------------------------- class person(polygon): def adjust(self,walls): for wall in walls: self.vel+=0.4*collision(self,wall,False) #--------------- log --------------------------------- class log(polygon): def update(self,player): self.vel+=self.acc self.moverel(self.vel) if collision(player,self): player.upped=False player.moverel(self.vel) def draw(self,screen): self.rect=pygame.draw.polygon( screen, lerp(self.color,BGCOLOR), [x[:] for x in self.points], self.width) pygame.draw.polygon( screen, self.color, moveup(self.points[:],self.rect.height/2), self.width) pygame.draw.lines( screen, lerp(self.color,BGCOLOR,0.5), 1, [x[:] for x in self.points], 1) pygame.draw.lines( screen, lerp(self.color,GREEN,0.6), 0, moveup(self.points[:],self.rect.height/2), 1) #-----------circle------------------------------------- class circle(object): def __init__(self,center,radius,color,width=0): self.center=center self.radius=radius self.color=color self.width=width self.vel=Vector2(0,0) self.acc=Vector2(0,0) self.rect=pygame.rect.Rect([self.center[0]-radius,self.center[1]-radius],[radius*2,radius*2]) def moverel(self,v): self.center.x+=v.x self.center.y+=v.y def draw(self,screen): self.rect=pygame.draw.circle(screen, self.color, self.center, self.radius, self.width) def update(self): """adds accell to velocity and moves based on the velocity""" self.vel+=self.acc fvel=copy.deepcopy(self.vel) fvel.x=math.floor(fvel.x) fvel.y=math.floor(fvel.y) self.moverel(fvel) ############## combined objects ############################ #------------ mount ---------------------------------------- class mount(object): """A mountain""" def __init__(self,center,bh=[120,75]): self.base=polygon(triangle([center[0],center[1]],bh),[200,150,200]) self.tip=polygon(triangle([center[0],center[1]-bh[1]*4/5],[bh[0]/5,bh[1]/5]),[230,230,230]) def moverel(self,v): self.base.moverel(v) self.tip.moverel(v) def draw(self,screen): self.base.draw(screen) self.tip.draw(screen) #---------------------- fish -------------------------- class fish(object): def __init__(self,center,bh=[32,20]): self.body=polygon([ [center[0]-bh[0]/2,center[1]], [center[0] ,center[1]+bh[1]/2], [center[0]+bh[0]/2,center[1]], [center[0] ,center[1]-bh[1]/2]], lerp([200,200,200],BGCOLOR)) self.tail=polygon( [ [center[0],center[1]], [center[0]-bh[0]/2,center[1]+bh[1]/2 ], [center[0]-bh[0]/2,center[1]-bh[1]/2 ]], lerp([200,200,200],BGCOLOR)) self.eye=circle( Vector2(center[0]+bh[0]/4-2,center[1]-bh[1]/4+3) ,2 ,[0,0,0]) self.body.acc.x=0 self.body.blend=BGCOLOR self.tail.acc.x=0 self.tail.blend=BGCOLOR self.eye.acc.x=0 def draw(self,screen): self.tail.draw(screen) self.body.draw(screen) self.eye.draw(screen) def update(self,player): self.tail.update() self.body.update() self.eye.update() self.rect=self.tail.rect.unionall((self.body.rect,self.eye.rect)) if (player.center - self.body.center).magnitude_squared() < 400: self.moverel(Vector2(500,0)) player.lives+=2 if (player.center.x - self.body.center.x) < 20: self.moverel(Vector2(2,0)) def moverel(self,v): self.tail.moverel(v) self.body.moverel(v) self.eye.moverel(v) ################ Font ############################3 class text: def __init__(self,text,center=(0,0),color=(200,100,50)): self.font=pygame.font.Font(data.load("aerial.ttf"),72) self.text=text self.center=center self.color=color self.image=self.font.render(self.text,0,self.color).convert() self.rect=pygame.rect.Rect(center,(200,100)) self.active=False self.change=False def draw(self,screen): if self.change: self.color=[255-x for x in self.color] self.image=self.font.render(self.text, 0, self.color).convert() self.change = False self.rect=screen.blit(self.image,self.center) def update(self,x,y): if self.rect.collidepoint(x,y)!=self.active: self.active= not self.active self.change=True ################ Game function ###################### ################################################### def game(screen,clock,jump,fall): #Initialize pygame.mouse.set_visible(0) screen.fill(BGCOLOR) pygame.display.update() end = False score=0 counter=0 ## Makes the players and logs grass=polygon(rect([320,280],[320,120]),GREEN) water=polygon(rect([320,440],[320,40]),BGCOLOR) player=person(rect([430,320],[15,15])) loglist=[log(rect([500+i+random.randint(-5,5),400],[80+random.randint(-15,15),20]),[150,75,0]) for i in range(0,300*6,300)] for logy in loglist: logy.vel.x+=-3 mrange=range(20) random.shuffle(mrange) mountainlist=[] for i in range(len(mrange)): mountainlist.append(mount([mrange[i]*50+random.randint(-8,10),150-2.5*i/2],[120+i*2.5,75+i*2.5])) random.shuffle(mountainlist) fishy=fish([900,440]) ############### Game loop ################################# while not end: clock.tick(60) counter+=1 screen.fill([150,200,250]) water.draw(screen) grass.draw(screen) for m in mountainlist: if m.base.center.x<-80: m.moverel(Vector2(920+random.randint(-20,20),0)) m.draw(screen) fishy.update(player) fishy.draw(screen) if fishy.eye.center.x > 700: fishy.moverel(Vector2(-fishy.body.center.x - 30,0)) fishy.body.vel.x=3 fishy.tail.vel.x=3 fishy.eye.vel.x=3 loglist=[l for l in loglist if l.center.x>-100] if len([l for l in loglist if l.vel.x==-3])<6: score+=1 randlog=random.randint(-24-3*int(math.sqrt(score)),24+3*int(math.sqrt(score))) if randlog<-21: loglist.append(logadd(5)) loglist[-1].vel.x=-3 loglist.append(logadd(50,-10)) loglist[-1].vel.x=-8 elif randlog>21: loglist.append(logadd(-5,-28)) loglist[-1].vel.x=-3 else : loglist.append(logadd()) loglist[-1].vel.x=-3 for l in loglist: l.old() l.update(player) l.draw(screen) player.old() player.update() player.adjust(loglist) player.draw(screen) [pygame.draw.polygon(screen,[220,220,110], rect([620-i*40,20],[7.5,7.5]),0) for i in range(player.lives)] player.vel.x*=0.82 player.vel.y*=0.85 player.vel.y+=0.8 if player.center.y>500 or player.center.x<-15: player.lives-=1 fall.play() if player.lives<0: end=True print "score = " + str(score) else: player.moverel(Vector2(loglist[1].center.x-player.center.x,loglist[1].rect.top-player.center.y)) player.vel.y=-10 ## Player input for e in pygame.event.get(): if e.type == QUIT: end = True if e.type == KEYDOWN: if e.key==K_UP and player.upped==False: player.vel.y+=-14 player.upped=True jump.play() if e.key==K_DOWN: player.acc.y=0.5 if e.key==K_LEFT: player.acc.x=-0.4 if e.key==K_RIGHT: player.acc.x=0.75 if e.key==K_ESCAPE: end = True if e.type == KEYUP: if e.key==K_UP: player.acc.y=0 if e.key==K_DOWN and player.acc.y>0: player.acc.y=0 if e.key==K_LEFT and player.acc.x<0: player.acc.x=0 if e.key==K_RIGHT and player.acc.x>0: player.acc.x=0 for i in loglist + mountainlist +[player]: i.moverel(Vector2(-1,0)) player.upped=True pygame.display.update() pygame.mouse.set_visible(1) return score #################### main function ############################### ################################################################ def main(): pygame.init() pygame.display.set_icon(pygame.image.load(data.load("favicon.png"))) screen = pygame.display.set_mode((640, 480)) pygame.display.set_caption("Rolling on the river") clock = pygame.time.Clock() screen.fill([150,200,250]) thickarrow_strings = ( #sized 24x24 "........................", "........................", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "..XXXXXXXXXXXXXXXXXXXX..", "........................", "........................",) cdata,cmask=pygame.cursors.compile(thickarrow_strings) pygame.mouse.set_cursor((24,24),(7,7),cdata,cmask) try: pygame.mixer.init() except pygame.error: class nonesound: def play(self): pass jump=nonesound() fall=nonesound() else: jump=pygame.mixer.Sound(data.load("jump.wav")) fall=pygame.mixer.Sound(data.load("fall.wav")) menu=[text("Play",(100,200)),text("Quit",(300,350),(250,250,250))] quitting = False #----------------------- main while loop ----------------------- while not quitting: clock.tick(30) screen.fill((150,200,250)) for m in menu: m.draw(screen) m.update(*pygame.mouse.get_pos()) for e in pygame.event.get(): #Goes through each of the events if e.type == QUIT: quitting = True if e.type == KEYDOWN: if e.key == K_ESCAPE: quitting = True if e.type == MOUSEBUTTONDOWN: if menu[0].rect.collidepoint(e.pos): game(screen,clock,jump,fall) if menu[1].rect.collidepoint(e.pos): quitting = True pygame.display.update() pygame.quit() if __name__ == "__main__": main()