import pygame, random
pygame.init()
"""
Cheap Mario imitation - A simple mario-esque platformer!

TODO Make world scroll,
make enemies more mario like,
add sane collission mechanism,
add deaths for mario and enemies - change current sprite then turn of col. detect.,
add scenery and items classes, fix jump/elevation, add background, add music, add sounds using Audacity with .ogg's
Using full image import - change from bmp's to jpg's or png's to save space
Create levels - stop enemies random spawning - acutally map them but use minimal number of objects (respawn to nextpos offscreen maybe)
Fix Sprite overlapping world

Make mario accelerate/decelerate like jumping
fix elevation system to allow blocks
Make more OO so define all enemies in enemy froup and define nemies with type so enemies can be different sprites but act same way
change sprites to make walking more walk-like
Add lives system
Fit canvases to all sprites to prevent hitbox errors

Define functions like worldscroll, loadimage in classes

FIX enemy movespeed
Restrict movement further than pipe
Display lives left etc.
Stop goombas colliding

Animated backgrounds

Add pipe collison

Make functions

BGscroll functions aren't checking isedge etc. properly as they have no effect once started
Implement mariospeed as trhen if(mariospeed==0) can fix current problem maybe
"
""
class Pipe(pygame.sprite.Sprite):
   def __init__(self, allsprites, objects):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("pipe.bmp")
    lol=self.image.set_colorkey((255,0,255)) #CHANGE me to bright pink 255,0,255 not white
    self.image = self.image.convert()
    self.rect = self.image.get_rect()
    self.rect.centery = 450
    self.rect.centerx = 2400
    self.add(allsprites)
    self.add(objects)
   
   def update(self, mario):
      if mario.isEdge==True :
        self.scroll(mario)
   
   def scroll(self, mario):
    self.rect.centerx-=mario.curspeed

class Player(pygame.sprite.Sprite):
  #Player class loads bmp, sets transparency, loads image into given yvalue and then defines attributes
   def __init__(self, mariog):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("marioright.bmp")
        lol=self.image.set_colorkey((0,204,255)) #CHANGE me to bright pink 255,0,255 not white
        self.image = self.image.convert()
        self.rect = self.image.get_rect()
        self.rect.centery = 400
        self.jumpvel=0
        self.direction=0
        self.goright=1
        self.isjump =0
        self.jumpheight=22
        self.movspeed=8
        self.curspeed=0
        self.isDead=0
        self.isEdge=False
        self.lives=9999
        self.keysEnabled=True
        self.add(mariog)
        #self.add(allsprites)
       
   #def bgscroll(self, allsprites):
     #self.isEdge=True
     #backx -= self.movspeed
     #allsprites.sprites.scroll() #Add scroll() to all classes this *should* fix goomba speed bug
   
     
   def jump(self)#Define jump as a function
     if self.isjump == 0:
       self.isjump=1
       self.jumpvel += self.jumpheight
       
   def movright(self, backx, allsprites, event, iskeydown):
     self.direction=0
     if self.rect.centerx < 320:
        self.isEdge=False
        if self.curspeed < self.movspeed:
          self.curspeed += 1
        self.rect.centerx += self.curspeed
       
       
     if self.rect.centerx >= 320  : #Make work properly
       if backx + self.rect.centerx > -2000: #Tweak this value
         self.isEdge=True
       
       

     
     
       
   def update(self, screen):
     if self.isDead==1:
       self.lives-=1
       #Restart level etc., add code to ensure it does not take more than one life
     
     if self.lives==0:
       gameover(screen)
     
     #JUMP code
     if self.isjump == 1:
       self.rect.centery -=self.jumpvel #Could use rect.move_ip method here instead maybe
       self.jumpvel-=2
       if self.jumpvel==-self.jumpheight - 2:
         self.jumpvel=0
         self.isjump=0
       
     #print self.rect.center
     if self.direction ==self.goright:
        self.image=pygame.transform.flip(self.image, 1, 0)
        if self.goright==1:
          self.goright-=1
        elif self.goright==0:
          self.goright+=1
       
     
       
     #elif self.direction ==0 & self.goright==0:
        #self.image=pygame.transform.flip(self.image, 1, 0)
        #self.goright=1
       
      #self.rect.center = pygame.mouse.get_pos()

class Enemy(pygame.sprite.Sprite):
  def __init__(self, screen, enemies, allsprites):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("goombaright.bmp")
        self.image.set_colorkey((255,0,255))
        self.image = self.image.convert()
        self.rect = self.image.get_rect()
        self.rect.centerx = random.randrange(700, screen.get_width() + 200)
        self.rect.centery = 425
        self.goright=1
        self.isDead=0
        self.movspeed=1
        self.add(enemies)
        self.add(allsprites)
       
  def scroll(self, mario):
    if self.direction ==1:
      self.rect.centerx -= mario.curspeed
      self.goright=0
   
       
  def update(self, mario, mariog, enemies):
        #print mario.isEdge
        #if mario.isEdge==True   : #When mario is running at edge And key is held
        #  self.movspeed=6
        #elif mario.isEdge==False:
        #  self.movspeed=1
       
        if mario.isEdge==True:
          self.scroll(mario)
        if mario.rect.centerx - self.rect.centerx > 0: #CHANGE me to collidion with objects change direction for more mario-esque AI
         self.direction=0
         
        elif mario.rect.centerx - self.rect.centerx < 0:
         self.direction=1
         
        if self.direction ==self.goright:
         self.image=pygame.transform.flip(self.image, 1, 0)
         if self.goright==1:
           self.goright-=1
         elif self.goright==0:
           self.goright+=1
       
        if self.direction ==1:
         self.rect.centerx -= self.movspeed
         self.goright=0
        elif self.direction==0:
          self.rect.centerx += self.movspeed
          self.goright=1
       
        if pygame.sprite.spritecollideany(self, mariog, False) :
          if mario.rect.centery<=(self.rect.centery - 40) :
            #print self.rect.centery
            #print mario.rect.centery
            self.isDead=1
          elif mario.rect.centery>(self.rect.centery - 40) & self.isDead==0:
            mario.isDead=1
         
         
          #self.isDead=1
       
        if self.isDead==1:
          self.rect.centery+=5
        if self.rect.centery>490:
          self.rect.centery=425
          self.rect.centerx=random.randrange((mario.rect.centerx + 100), 1200)
          self.isDead=0
       

def level1(screen, enemies, allsprites, objects, mariog):
   bg = pygame.Surface(screen.get_size())
   bg = pygame.image.load("background.bmp")
   #test=bg.set_colorkey((0,204,255))
   bg=bg.convert()
   backx = 0
   
 
   mario = Player(mariog)
   goomba = Enemy(screen, enemies, allsprites)
   goomba2 = Enemy(screen, enemies, allsprites)
   pipe1= Pipe(allsprites, objects)
   #print enemies
   
   #print allsprites
   lolwut = pygame.key.set_repeat(50, 20)
   
   
   
   #basicSprites = pygame.sprite.Group(mario, goomba, goomba2, pipe1)
   #mariog = pygame.sprite.GroupSingle(mario)
   
   keepGoing = True
   clock = pygame.time.Clock()
   while keepGoing:
      clock.tick(30)
     
      #NON OOP method:
      #if mario.rect.centerx - goomba2.rect.centerx > 0:
      #  goomba2.direction=0
      #elif mario.rect.centerx - goomba2.rect.centerx < 0:
      #  goomba2.direction=1
     
      if mario.isEdge==True:
        backx-=mario.movspeed
     
      for event in pygame.event.get():
            if event.type == pygame.QUIT:
               pygame.quit()
               keepGoing = False
               
            if event.type == pygame.KEYDOWN :
               iskeydown=True
                #keyName = pygame.key.name(event.key)
                #print "key pressed:", keyName
                #print box_y
                #if event.key == pygame.K_DOWN:
                #box_y += 20
               if event.key == pygame.K_RSHIFT :
                  mario.jump()
               elif event.key == pygame.K_RIGHT: #CHANGE so world moves not mario, maybe defie in classes and then call function
                 
                 mario.movright(backx, allsprites, event, iskeydown)
                 
                 if backx < -2000:
                   mario.isEdge=False
                   mario.iskeydown=False

                    #print goomba.movspeed
                   
                   
                    #MAKE fix so all objects other than mario increase movspeed when they are right of centre
                   
                 
               elif event.key == pygame.K_LEFT:
                  if mario.rect.centerx >=50:
                   if mario.curspeed < mario.movspeed:
                    mario.curspeed -= 1
                   mario.isEdge=False
                   mario.direction=1
                   mario.rect.centerx -= mario.curspeed
                   
                 
               elif event.key == pygame.K_ESCAPE: #Quit clause
                  pygame.quit()
                  keepGoing = False
                 
            #keepGoing = True - This line breaks it.
            #print goomba.rect.center - Debug print
       #
      #if goomba.isDead ==1 & goomba2.isDead==1: WIN CONDITION
         #keepGoing = False
     
      screen.blit(bg, (backx, 0))
      mariog.clear(screen, bg)
      allsprites.clear(screen, bg)
      mariog.update(screen)
      objects.update(mario)
      enemies.update(mario, mariog, enemies)
      mariog.draw(screen)
      allsprites.draw(screen)
     
      pygame.display.flip()
             
             

def menu(screen):
   bg = pygame.Surface(screen.get_size())
   bg = pygame.image.load("background.bmp")
   bg = bg.convert()
   
   intro = pygame.image.load("splash.bmp")
   test=intro.set_colorkey((255,0,255))
   intro = intro.convert()
   
   keepGoing = True
   clock = pygame.time.Clock()
   while keepGoing:
     
     
     for event in pygame.event.get():
       if event.type == pygame.QUIT:
         pygame.quit()
         keepGoing = False
               
       if event.type == pygame.KEYDOWN:
         keepGoing = False
         clock.tick(30)
         if event.key == pygame.K_ESCAPE: #Quit clause
                  pygame.quit()
                  keepGoing = False
         
     
     screen.blit(bg, (0, 0))
     screen.blit(intro, (140, 127))
     pygame.display.flip()
     
   
 
def gameover(screen):
  bg = pygame.Surface(screen.get_size())
  bg.fill((0,0,0))
  myFont = pygame.font.SysFont(None, 36)
  label = myFont.render("Game Over!", 0, (255,0,0))
 
  keepGoing = True
  clock = pygame.time.Clock()
  while keepGoing:
     clock.tick(30)
     
     for event in pygame.event.get():
       if event.type == pygame.QUIT:
         pygame.quit()
         keepGoing = False
               
       if event.type == pygame.KEYDOWN:
         #keepGoing = False
         if event.key == pygame.K_ESCAPE: #Quit clause
                  pygame.quit()
                  keepGoing = False
         
         
         
     
     screen.blit(bg, (0, 0))
     screen.blit(label, (140, 127))
     pygame.display.flip()

def congrat(screen):
  bg = pygame.Surface(screen.get_size())
  bg.fill((0,0,0))
  myFont = pygame.font.SysFont(None, 36)
  label = myFont.render("You a winner!", 0, (0,255,0))
 
  keepGoing = True
  clock = pygame.time.Clock()
  while keepGoing:
     clock.tick(30)
     
     for event in pygame.event.get():
       if event.type == pygame.QUIT:
         pygame.quit()
         keepGoing = False
               
       if event.type == pygame.KEYDOWN:
         if event.key == pygame.K_ESCAPE: #Quit clause
                  pygame.quit()
                  keepGoing = False
         #keepGoing = False
         
         
         
     
     screen.blit(bg, (0, 0))
     screen.blit(label, (140, 127))
     pygame.display.flip()

def main():
   screen = pygame.display.set_mode((640, 480))
   #Define constants that will always be used
   allsprites = pygame.sprite.Group()
   mariog=pygame.sprite.Group()
   enemies = pygame.sprite.Group()
   objects = pygame.sprite.Group()
   pygame.display.set_caption("Cheap Mario imitation")
   menu(screen)
   level1(screen, enemies, allsprites, objects, mariog)
   congrat(screen)
   

if __name__ == "__main__":
    main()