# -*- coding: utf-8 -*-
"""
Created on Sun Nov 17 16:32:23 2019
@author: admin

Priya Bannur: Simple game using Pygame
"""

import pygame
pygame.init()
                                                  #coordinate of object is at its top left point
                                                  #initializing

screenw=800
screenh=500
win = pygame.display.set_mode((screenw,screenh))  #window width=600, height=300
pygame.display.set_caption("My-Game")
clock = pygame.time.Clock()

walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'), pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'), pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'), pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
bg = pygame.image.load('bg.png')
char = pygame.image.load('standing.png')

clock = pygame.time.Clock()
#bulletSound = pygame.mixer.Sound("bullet.wav")
#hitSound = pygame.mixer.Sound("hit.wav")
music = pygame.mixer.music.load("music.mp3")
pygame.mixer.music.play(-1)                       # -1 will ensure the song keeps playing
score = 0 

class player(object):
    def __init__(self,x,y,width,height):          #attributes of player
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5
        self.isJump = False
        self.left = False
        self.right = True
        self.walkCount = 0
        self.jumpCount = 10
        self.standing = True
        self.hitbox = (self.x + 17, self.y + 11, 29, 52)
                                                  #the elements in the hitbox are (top left x, top left y, width, height)

    def draw(self, win):
                                                  #9 images for our walking animation, to show the same image for 3 frames
                                                  #number 27 as an upper bound for walkCount because 27 / 3 = 9. 
                                                  #9 images shown 3 times each animation.
        if self.walkCount + 1 >= 27:
            self.walkCount = 0
        
        if not(self.standing):
            if self.left:                         #facing left
                win.blit(walkLeft[self.walkCount//3], (self.x,self.y))
                self.walkCount += 1
            elif self.right:                      #facing right
                win.blit(walkRight[self.walkCount//3], (self.x,self.y))
                self.walkCount +=1
        else:                                     #standing still facing either side
           if self.right:
                win.blit(walkRight[0], (self.x, self.y))
           else:
                win.blit(walkLeft[0], (self.x, self.y))
        
                                                  #draw hit box around the player
        self.hitbox = (self.x + 17, self.y + 11, 29, 52)
        #pygame.draw.rect(win, (255,0,0), self.hitbox,2)    
        
    def hit(self):
        self.isJump = False
        self.jumpCount = 10 
        self.x = 60                               #resetting the player position
        self.y = 380
        self.walkCount = 0
        font1 = pygame.font.SysFont('comicsans', 100)
        text = font1.render('-5', 1, (255,0,0))
        win.blit(text, (400,20))
        pygame.display.update()
        i = 0
        while i < 300:
            pygame.time.delay(10)
            i += 1
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    i = 301
                    pygame.quit()
                                                  #msg when hit for a certain period of time

class projectile(object):                         #bullet class
    def __init__(self,x,y,radius,color,facing):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.facing = facing                      #left or right
        self.vel = 8 * facing
    
    def draw(self,win):
        pygame.draw.circle(win, self.color, (self.x,self.y), self.radius)


class enemy(object):
    walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
    walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]
    
    def __init__(self, x, y, width, height, end):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.path = [x, end]                      #where the enemy starts and finishes its path
        self.walkCount = 0
        self.vel = 3
        self.hitbox = (self.x + 17, self.y + 2, 31, 57)
        self.health = 10 
        self.visible = True
    
    def draw(self, win):
        self.move()
        if self.visible:
            if self.walkCount + 1 >= 33:          #11 images for each animtion, upper bound = 33. 
                self.walkCount = 0
            
            if self.vel > 0:                      #moving to the right
                win.blit(self.walkRight[self.walkCount//3], (self.x,self.y))
                self.walkCount += 1
            else:                                 #else Left
                win.blit(self.walkLeft[self.walkCount//3], (self.x,self.y))
                self.walkCount += 1
                
            pygame.draw.rect(win, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 50, 10))
            pygame.draw.rect(win, (0,128,0), (self.hitbox[0], self.hitbox[1] - 20, 50 - (5 * (10 - self.health)), 10))    
                                                  #draw hit box around the enemy
            self.hitbox = (self.x + 17, self.y + 2, 31, 57)
            #pygame.draw.rect(win, (255,0,0), self.hitbox,2)    
        
    def move(self):
        if self.vel > 0:                          #moving right
            if self.x < self.path[1] + self.vel:  #if not right end of path
                self.x += self.vel
            else:                                 #if end reached
                self.vel = self.vel * -1
                self.x += self.vel
                self.walkCount = 0
        else:                                     #moving left
            if self.x > self.path[0] - self.vel:  #if not left end of path
                self.x += self.vel
            else:                                 #if end reached
                self.vel = self.vel * -1
                self.x += self.vel
                self.walkCount = 0   
    
    def hit(self):                                #when enemy is hit
        #hitSound.play()
        if self.health > 0:
            self.health -= 1
        else:
            self.visible = False
        print('hit')  

def redrawGameWindow():
    win.blit(bg, (0,0))
    text = font.render("Score: " + str(score), 1, (0,0,0)) 
                                                  #text, anti-aliasing, color
    win.blit(text, (680, 10))
    man.draw(win)
    goblin.draw(win)
    for bullet in bullets:
        bullet.draw(win)
    pygame.display.update()
         
#################################################################################################        
                                                  #mainloop
font = pygame.font.SysFont("comicsans", 30, True)
                                                  #Bold set True
man = player(10, 380, 64, 64)                     #creating instances
goblin = enemy(100, 380, 64, 64, 600)
shootLoop=0
run = True
bullets = [] 
while run:
    clock.tick(27)
    
    if goblin.visible == True:
        if man.hitbox[1] < goblin.hitbox[1] + goblin.hitbox[3] and man.hitbox[1] + man.hitbox[3] > goblin.hitbox[1]:
            if man.hitbox[0] + man.hitbox[2] > goblin.hitbox[0] and man.hitbox[0] < goblin.hitbox[0] + goblin.hitbox[2]:
                man.hit()
                score -= 5                        #reducing score if enemy hits player

    if shootLoop > 0:
        shootLoop += 1
    if shootLoop > 3:
        shootLoop = 0
        
    for event in pygame.event.get():              #loop through key actions
        if event.type == pygame.QUIT:             #game exit
            run = False
    
    for bullet in bullets:                        #checks x & y coords
        if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > goblin.hitbox[1]:
            if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + goblin.hitbox[2]:
                if goblin.visible == True:
                    goblin.hit()                  #calls enemy hit method
                    score += 1
                    bullets.pop(bullets.index(bullet))
                                                  #remove bullet from bullet list
        
        if bullet.x < screenw and bullet.x > 0:
            bullet.x += bullet.vel                #moves the bullet by its vel
        else:
            bullets.pop(bullets.index(bullet))    #remove the bullet if it is off the screen

    keys = pygame.key.get_pressed()               #returns a dictonary where 1= key pressed and 0= key not pressed.

    if keys[pygame.K_SPACE] and shootLoop==0:     #code to shoot bullets
        #bulletSound.play()
        if man.left:
            facing = -1
        else:
            facing = 1
    
        if len(bullets) < 5:                      #make sure we cannot exceed 5 bullets on the screen at once
            bullets.append(projectile(round(man.x+man.width//2), round(man.y + man.height//2), 6, (0,0,0), facing)) 
                                                  #create a bullet starting at the middle of the character
        shootLoop = 1
        
        
    if keys[pygame.K_LEFT] and man.x > man.vel:
        man.x -= man.vel
        man.left = True
        man.right = False
        man.standing = False
    elif keys[pygame.K_RIGHT] and man.x < screenw - man.width - man.vel:
        man.x += man.vel
        man.right = True
        man.left = False
        man.standing = False
    else:
        man.standing = True
        man.walkCount = 0
        
    if not(man.isJump):
        if keys[pygame.K_UP]:                                 
            man.isJump = True
            man.right = True
            man.left = False
            man.walkCount = 0
    else:                                                        
        if man.jumpCount >= -10:                   #code to jump
            neg = 1
            if man.jumpCount < 0:
                neg = -1
            man.y -= (man.jumpCount ** 2) * 0.5 * neg
            man.jumpCount -= 1
        else:
            man.isJump = False
            man.jumpCount = 10
            
    redrawGameWindow()

pygame.quit()                                      #game closed when while loop exited