Untitled

mail@pastecode.io avatar
unknown
plain_text
2 months ago
19 kB
3
Indexable
Never
from PIL import Image
import time
import pygame
import pydoc

from PIL import Image
import sqlite3    
import shelve

# Loading models into the game
background = pygame.image.load('background.jpg')
character1 = pygame.image.load('standingreversed.png')  #
character2 = pygame.image.load('standing.png')
player1dead = pygame.image.load('player2dead.png')  #
player2dead = pygame.image.load('player1dead.png')

daynight = pygame.image.load('daynight.png')

blocking1 = pygame.image.load('blocking.png')
blocking2 = pygame.image.load('blockingreversed.png')  #

attack1 = pygame.image.load('attackreversed.png')  #
attack2 = pygame.image.load('attack.png')

icon = pygame.image.load('icon.png')
new_icon = pygame.transform.scale(icon, (32,32))
pygame.display.set_icon(new_icon)

# Initializing the game, setting the screen, caption, and frames per second/clock
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Sword Slice")
clock = pygame.time.Clock()

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
RED = (255,0,0)

text_font = pygame.font.SysFont("Impact", 50)
text_fontSmall = pygame.font.SysFont("Impact", 25)
text_font2 = pygame.font.SysFont("cooperblackstditalicopentype", 30, bold=False)

# GLOBALS
gameOverScreenDuration = 30


class Player:
    def __init__(self,x,y):
        self.rect = pygame.Rect(x, y, character1.get_width(),
                                character1.get_height())  # rectangle properties: x,y, width,height
        self.starting_x = x
        self.starting_y = y
        self.health = 100
        self.cooldown = 5
        self.attack_duration = 0
        self.invulnerable = False
        self.attacking = False
        self.blocking = False
        self.invulnerability_duration = 0
        self.block_duration = 0
        self.block_cooldown = 0
        self.jumping = False
        self.jumping_duration = 10
        self.jump_velocity = -10
        self.gravity = 0.5        

    def reset_state(self):
        self.health = 100
        self.cooldown = 5
        self.attack_duration = 0
        self.invulnerable = False
        self.attacking = False
        self.blocking = False
        self.block_cooldown = 0
        self.block_duration = 0
        self.invulnerability_duration = 0

    def tick_player(self):
        self.shield()
        self.playerMovement()
        self.cooldown_timer()
        self.attack_timer()
        self.invulnerability_timer()
        self.abilities()
        self.render_player()
        self.detection()
        self.blocking_timer()
        self.blocking_cooldown_timer()

    def blocking_cooldown_timer(self):
        if self.block_cooldown > 0:
            self.block_cooldown -= 1

    def blocking_timer(self):
        if self.block_duration > 0:
            self.block_duration -= 1
        if self.block_duration == 0:
            self.blocking = False

    def attack_timer(self):
        if self.attack_duration > 0:
            self.attack_duration -= 1
        if self.attack_duration == 0:
            self.attacking = False

    def invulnerability_timer(self):
        if self.invulnerability_duration > 0:
            self.invulnerability_duration -= 1
        if self.invulnerability_duration == 0:
            self.invulnerable = False

    def cooldown_timer(self):
        if self.cooldown > 0:
            self.cooldown -= 1
            
    def jump(self):
        if self.jumping:
            self.rect.y += self.jump_velocity  # Move the player up or down
            self.jump_velocity += self.gravity  # Apply gravity
            self.jumping = False

        # Reset when the player reaches the ground level
        if self.rect.y >= self.starting_y:
            self.rect.y = 293
            self.jumping = False
            self.jump_velocity = -10  # Reset the jump velocity

# Player class for Player 1
class Player1(Player):

    def __init__(self, x, y):
        super().__init__(x,y)

    def reset_statep1(self):
        self.rect = pygame.Rect(self.starting_x, self.starting_y, character1.get_width(), character1.get_height())
    def detection(self):
        #  print("Detection function was called")
        if self.attacking and player1.rect.colliderect(player2.rect):
            distance = player1.rect.x - player2.rect.x
            if distance < 115:
                self.player_hurt()

    # call player_hurt -> see if players blocking

    def player_hurt(self):
        if not self.invulnerable:
            multiplier = 1
            damage = 10
            if player2.blocking:
                multiplier = 0.66
            self.health -= (damage * multiplier)
            self.invulnerable = True
            self.invulnerability_duration = 50
            print(f'P1 HP: {self.health} blocking: {player2.blocking}')


    def playerMovement(self):

        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] and self.rect.x > 0:
            self.rect.x -= 10

        if keys[pygame.K_RIGHT] and self.rect.x < 590:
            self.rect.x += 10

        # screen.blit(character2, self.rect.topleft)  # draws characters from top left of corner of rectangle (sprite)

    def render_player(self):
        if self.attacking:
            screen.blit(attack1, (self.rect.x, self.rect.y))
        elif self.blocking:
            screen.blit(blocking2, (self.rect.x, self.rect.y))
        else:
            screen.blit(character1, self.rect.topleft)

    def shield(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RCTRL] and self.block_cooldown == 0:
            self.blocking = True
            print("P2 blocked!")
            self.block_duration = 60
            self.block_cooldown = 120

    def abilities(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_RSHIFT] and self.cooldown == 0 and self.attack_duration == 0:
            self.attacking = True
            self.attack_duration = 40
            self.cooldown = 60
        
        if keys[pygame.K_UP] and not self.jumping:

            self.jumping = True
            self.jump()
            print(self.rect.y)
        else:
            if self.rect.y < 293:
                self.rect.y += 10
    

# Player class for Player 2
class Player2(Player):
    def __init__(self, x, y):
        super().__init__(x,y)
        self.rect = pygame.Rect(x, y, character2.get_width(),
                                character2.get_height())  # rectangle properties: x,y, width,height
        
    def reset_statep2(self):
        self.rect = pygame.Rect(self.starting_x, self.starting_y, character2.get_width(), character2.get_height())
    def detection(self):
        #  print("Detection function was called")
        if self.attacking and player2.rect.colliderect(player1.rect):
            distance = player1.rect.x - player2.rect.x
            if distance < 115:
                self.player_hurt()

    # call player_hurt -> see if players blocking
    def shield(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_q] and self.block_cooldown == 0:
            print("P1 blocked!")
            self.blocking = True
            self.block_duration = 60
            self.block_cooldown = 120

    def player_hurt(self):
        if not self.invulnerable:
            multiplier = 1
            damage = 10
            if player1.blocking:
                multiplier = 0.66
            self.health -= (damage * multiplier)
            self.invulnerable = True
            self.invulnerability_duration = 50
            print(f'P2 HP: {self.health} blocking: {player1.blocking}')
    def playerMovement(self):

        keys = pygame.key.get_pressed()

        if keys[pygame.K_a] and self.rect.x > 0:
            self.rect.x -= 10

        if keys[pygame.K_d] and self.rect.x < 590:
            self.rect.x += 10

        # screen.blit(character2, self.rect.topleft)  # draws characters from top left of corner of rectangle (sprite)

    def render_player(self):
        if self.attacking:
            screen.blit(attack2, (self.rect.x, self.rect.y))
        elif self.blocking:
            screen.blit(blocking1, (self.rect.x, self.rect.y))
        else:
            screen.blit(character2, self.rect.topleft)

    def abilities(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_e] and self.cooldown == 0 and self.attack_duration == 0:
            self.attacking = True
            self.attack_duration = 40  # previous value was 50
            self.cooldown = 60
            
        if keys[pygame.K_w] and not self.jumping:

            self.jumping = True
            self.jump()
            print(self.rect.y)
        else:
            if self.rect.y < 293:
                self.rect.y += 10
    


x1 = 495
y1 = 293  # Starting coordinates and health for Player 1

x2 = 0
y2 = 293  # Starting coordinates and health for Player 2

p1wins = 0
p2wins = 0

screen.blit(background, (0, 0))
screen.blit(character1, (x1, y1))
screen.blit(character2, (x2, y2))

player1 = Player1(x1, y1)
player2 = Player2(x2, y2)


class GameOver:
    def __init__(self, p1hp, p2hp):
        self.p1hp = p1hp
        self.p2hp = p2hp


    def gameOverChecker(self):
        if round(self.p2hp) <= 0:
            player2health_bar.hp = 0
            screen.fill('black')
            global background
            screen.blit(background, (0, 0))
            screen.blit(player2dead, (player2.rect.x, player2.rect.y + 40))
            screen.blit(character1, (player1.rect.x, player1.rect.y))
            draw_text("GAME OVER! PLAYER 2 WINS", text_font, (255, 0, 0), 140, 147)
            with shelve.open("leaderboard") as lb:
                lastvalue = lb["player2"]
                lb["player2"] +=1
                if lb["player2"] == 30:
                    if lastvalue == 29:
                        lb["player2"] = 1
                
            draw_text("Returning to main menu...", text_fontSmall, (255, 0, 0), 270, 240)              
            return True


        elif round(self.p1hp) <= 0:
            player1health_bar.hp = 0
            screen.fill('blue')
            screen.fill('black')
            screen.blit(background, (0, 0))
            screen.blit(player1dead, (player1.rect.x, player1.rect.y + 40))
            screen.blit(character2, (player2.rect.x - 60, player2.rect.y))
            draw_text("GAME OVER! PLAYER 1 WINS", text_font, (0, 0, 255), 140, 147)
            
            with shelve.open("leaderboard") as lb:
                lastvalue = lb["player1"]
                lb["player1"] +=1
                if lb["player1"] == 30:
                    if lastvalue == 29:
                        lb["player1"] = 1
            
            
            draw_text("Returning to main menu...", text_fontSmall, (0, 0, 255), 270, 240)   
            return True

        elif self.p1hp < 0 and self.p2hp < 0:
            time.sleep(0.5)
            screen.fill('black')
            draw_text("DRAW. AWKWARD....", text_font, (255, 255, 255), 140, 147)
            return True
        return False


class HealthBar():
    def __init__(self, x, y, w, h, max_hp):
        #
        # super.__init__()
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.hp = max_hp
        self.max_hp = max_hp

    def draw(self, surface):
        # calculate health ratio
        ratio = self.hp / self.max_hp
        pygame.draw.rect(surface, "red", (self.x, self.y, self.w, self.h))
        pygame.draw.rect(surface, "green", (self.x, self.y, self.w * ratio, self.h))


##


def draw_text(text, font, text_col, x, y):
    img = font.render(text, True, text_col)
    screen.blit(img, (x, y))


class MainMenu:
    def __init__(self):
        pass

    def display_menu(self):
        screen.fill(BLACK)
        # draw_text("Sword Slice", text_font, WHITE, 280, 50)
        draw_text("SWORD SLICE", text_font, WHITE, 270, 100)
        button_game = pygame.Rect(300, 250, 200, 50)
        button_keybinds = pygame.Rect(300, 350, 200, 50)
        button_leaderboard = pygame.Rect(300, 450, 200, 50)        
        pygame.draw.rect(screen, BLUE, button_game)
        pygame.draw.rect(screen, BLUE, button_keybinds)
        pygame.draw.rect(screen, BLUE, button_leaderboard)
        draw_text("Play Game", text_font2, WHITE, 320, 260)
        draw_text("Keybinds", text_font2, WHITE, 330, 360)
        draw_text("Leaderboard", text_font2, WHITE, 302, 460)

        return button_game, button_keybinds, button_leaderboard
    
    def leaderboards(self):

        screen.fill(BLACK)
        draw_text("Leaderboard", text_font, WHITE, 300, 100)
        draw_text("PLAYER 1 WINS", text_font2, BLUE, 80, 200)
        with shelve.open("leaderboard") as lb:
            for player1 in lb:
                draw_text(str(lb["player1"]), text_font2, BLUE, 45, 250)  
        #draw_text(str(p1wins), text_font2, BLUE, 45, 250)  
        
        draw_text("PLAYER 2 WINS", text_font2, RED, 500, 200)
        with shelve.open("leaderboard") as lb:
            for player2 in lb:
                draw_text(str(lb["player2"]), text_font2, RED, 450, 250)          
        #draw_text(str(p2wins), text_font2, RED, 450, 250)
        
    def keybinds_screen(self):
        screen.fill(BLACK)
        draw_text("KEYBINDS", text_font, WHITE, 300, 100)
        draw_text("PLAYER 1", text_font2, BLUE, 80, 200)
        draw_text("A to move left", text_font2, BLUE, 45, 250)
        draw_text("D to move right", text_font2, BLUE, 35, 300)
        draw_text("Q to block", text_font2, BLUE, 70, 350)
        draw_text("E to attack", text_font2, BLUE, 70, 400)

        draw_text("PLAYER 2", text_font2, RED, 500, 200)
        draw_text("<- to move left", text_font2, RED, 450, 250)
        draw_text("-> to move right", text_font2, RED, 440, 300)
        draw_text("Right CTRL to block", text_font2, RED, 410, 400)
        draw_text("Right SHIFT to attack", text_font2, RED, 400, 350)
                        
        draw_text("Press 'Esc' to go back", text_fontSmall, WHITE, 280, 500)
        return pygame.Rect(250, 400, 300, 50)


player1health_bar = HealthBar(485, 70, 300, 40, 100)
player1health_bar.hp = player2.health  # This is health points inflicted to player 1
player2health_bar = HealthBar(10, 70, 300, 40, 100)
player2health_bar.hp = player1.health  # This is health points inflicted to player 1


def game():
    p1wins=0
    p2wins=0
    global gameOverScreenDuration
    screen.blit(background, (0, 0))


    # Tick players
    player1.tick_player()
    player2.tick_player()

    # Check for player collisions
    if player1.rect.colliderect(player2.rect):  # Player 1 is the right player, player 2 is the left player
        if player1.rect.right > player2.rect.left:
            distance = player1.rect.x - player2.rect.x  # they should be 60px to touch, -160 px to touch from behind
            if 60 >= distance > 160:  # this means that the players are facing head to head
                player1.rect.x -= 10
                player2.rect.x += 10
            elif -160 <= distance < 60:  # this means players are facing back to back
                player1.rect.x += 10
                player2.rect.x -= 10
    # draw health bar
    player1health_bar = HealthBar(485, 70, 300, 40, 100)
    player1health_bar.hp = player2.health  # This is health points inflicted to player 1
    player1health_bar.draw(screen)
    draw_text("PLAYER 1", text_font2, (0, 0, 255), 55, 30)
    player2health_bar = HealthBar(10, 70, 300, 40, 100)

    player2health_bar.hp = player1.health  # This is health points inflicted to player 1
    player2health_bar.draw(screen)
    draw_text("PLAYER 2", text_font2, (210, 4, 45), 560, 30)

    draw_text(str(round(player2health_bar.hp)), text_font2, (0, 0, 0), 130, 75)
    draw_text(str(round(player1health_bar.hp)), text_font2, (0, 0, 0), 605, 75)
            
    

    gameover = GameOver(player1health_bar.hp, player2health_bar.hp)
    isGameOver = gameover.gameOverChecker()

    if isGameOver:
        if gameOverScreenDuration > 0:
            gameOverScreenDuration -= 1
        if gameOverScreenDuration == 0:
            return False
    return True






def main():
    running = True
    in_menu = True
    in_game = False
    in_keybinds = False
    in_leaderboard = False
    menu = MainMenu()

    while running:
        if in_game:
            isGameRunning = game()
            if not isGameRunning:
                in_game = False
                in_menu = True
                player1.reset_state()
                player1.reset_statep1()
                player2.reset_state()
                player2.reset_statep2()

        else:
            screen.fill(BLACK)

        if in_menu:
            btn_game, btn_keybinds, btn_leaderboard = menu.display_menu()

        if in_keybinds:
            back_button = menu.keybinds_screen()

        if in_leaderboard:
            back_b = menu.leaderboards()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if in_menu:
                if event.type == pygame.MOUSEBUTTONDOWN:
                    mouse_pos = event.pos
                    if btn_game.collidepoint(mouse_pos):
                        in_menu = False
                        in_game = True
                        if in_game:
                            game()
                            pygame.display.update()
                    elif btn_keybinds.collidepoint(mouse_pos):
                        in_keybinds = True
                        in_menu = False
                    elif btn_leaderboard.collidepoint(mouse_pos):
                        in_leaderboard = True
                        in_menu = False
            if in_keybinds:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        in_keybinds = False
                        in_menu = True
            if in_leaderboard:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        in_leaderboard = False
                        in_menu = True

        global p1wins
        global p2wins
        if p1wins == 30:
            p1wins = 1
        if p2wins == 30:
            p2wins = 1

        pygame.display.update()
        clock.tick(60)

    pygame.quit()


if __name__ == "__main__":
    main()
Leave a Comment