0

I have been trying to make a Fangame for Undertale with pygame but i am stuck. This is my first project. I want to replay the main loop with a few changes, for example i want the knife movement to be different, but i dont know how to do it. I have tried with attack2 to replay everything but it doesnt work, for example the player can't move and the knife is also not moving. I also tried defining the main loop but then i can't change anything. Please comment if you can help me. This is the code i have:

import math
import pygame
from pygame import mixer

pygame.init()
screen = pygame.display.set_mode((1000, 800))

# FPS
FPS = 60
clock = pygame.time.Clock()

# Title and icon
pygame.display.set_caption("CharaFight")
icon = pygame.image.load('Chara.png')
pygame.display.set_icon(icon)

# images
fight_button = pygame.image.load('Fight.png')
fight_button2 = pygame.image.load('Fight2.png')
hp_bar1 = pygame.image.load('hp_bar.png')
hp_bar2 = pygame.image.load('hp_bar2.png')

# music and sounds
background_muziek = mixer.music
damage_sound = mixer.Sound('Undertale Sound Effect - Taking Damage.wav')
background_muziek.load('Prepare for Battle!.wav')
background_muziek.set_volume(0.4)
background_muziek.play(-1)

# backgrounds
background = pygame.image.load("Background1.png")
background2 = pygame.image.load("Background2.png")

# Player
playerImg = pygame.image.load("Soul.png")
PlayerX = 450
PlayerY = 550
PlayerX_change = 0
PlayerY_change = 0
HP = 0

# Enemy
enemyImg = pygame.image.load("Chara2.png")
charaImg = pygame.image.load("Chara3.png")
EnemyX = 390
EnemyY = 50
EnemyX_change = 0
EnemyY_change = 0

# Knife
knifeImg = pygame.image.load("knife.png")
KnifeX = 350
KnifeY = 580
KnifeX_change = 5
KnifeY_change = 0
Knife_state = "ready"

# Game over text
over_font = pygame.font.Font('8-BIT WONDER.TTF', 64)
det_font = pygame.font.Font('8-BIT WONDER.TTF', 30)
emy_font = pygame.font.Font('Determination_text.ttf', 45)


def game_over_text():
    over_text = over_font.render("GAME OVER", True, (255, 255, 255))
    det_text = det_font.render(" Stay Determined ", True, (255, 255, 255))
    screen.blit(over_text, (230, 250))
    screen.blit(det_text, (280, 400))


def enemy_text():
    chara_text = emy_font.render(" * Give me your SOUL! ", True, (255, 255, 255))
    screen.blit(chara_text, (150, 500))


def fade(width, height):
    fade1 = pygame.Surface((width, height))
    fade1.fill((0, 0, 0))
    for alpha in range(0, 150):
        fade1.set_alpha(alpha)
        screen.blit(fade1, (0, 0))
        pygame.display.update()
        pygame.time.delay(5)


def player(x, y):
    screen.blit(playerImg, (x, y))


def enemy(x, y):
    screen.blit(enemyImg, (x, y))


def fire_knife(x, y):
    global Knife_state
    Knife_state = "fire"
    screen.blit(knifeImg, (x, y))


def isCollision(PlayerX, PlayerY, KnifeX, KnifeY):
    distance = math.sqrt(math.pow(PlayerX - KnifeX, 2) + (math.pow(PlayerY - 37 - KnifeY, 2)))

    if distance < 27:
        return True
    else:
        return False

# Here is my attempt to replay the main loop
def attack2():
    screen.fill((0, 0, 0))
    player(PlayerX, PlayerY)
    enemy(EnemyX, EnemyY)
    fire_knife(KnifeY, KnifeX)
    screen.blit(background, (100, 300))
    pygame.display.flip()


# main loop
running = True

while running:

    screen.fill((0, 0, 0))

    screen.blit(background, (100, 300))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        # Movement
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                PlayerX_change = -2.5
            if event.key == pygame.K_RIGHT:
                PlayerX_change = 2.5
            if event.key == pygame.K_UP:
                PlayerY_change = -2.5
            if event.key == pygame.K_DOWN:
                PlayerY_change = 2.5

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                PlayerX_change = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                PlayerY_change = 0

    # Boundaries for player
    PlayerY += PlayerY_change

    if PlayerY >= 700:
        PlayerY = 700
    elif PlayerY <= 520:
        PlayerY = 520

    PlayerX += PlayerX_change

    if PlayerX <= 370:
        PlayerX = 370
    elif PlayerX >= 570:
        PlayerX = 570

    # Knife movement
    if KnifeX >= 550:
        KnifeX = 340
        KnifeY += 20
        Knife_state = "ready"

    if KnifeY >= 680:
        KnifeY = 480
        Knife_state = "ready"

    if Knife_state == "fire":
        fire_knife(KnifeX, KnifeY)
        KnifeX += KnifeX_change

    # collision and game over screen
    collision = isCollision(PlayerX, PlayerY, KnifeX, KnifeY)
    if collision:
        Knife_state = "ready"
        damage_sound.set_volume(1.5)
        damage_sound.play()
        HP += 1
        if HP > 100:
            fade(1000, 800)
            screen.fill((0, 0, 0))
            game_over_text()
            background_muziek.stop()
            game_over_sound = mixer.music
            game_over_sound.load('Undertale Game Over Theme.wav')
            game_over_sound.play(-1)
            pygame.display.flip()
            pygame.time.wait(5000)

            while True:
                if pygame.key.get_pressed():
                    running = True
                    pygame.quit()

    # Fight screen
    if pygame.time.get_ticks() > 21700:
        fade(1000, 800)
        screen.fill((0, 0, 0))
        enemy_text()
        screen.blit(background2, (140, 250))
        screen.blit(charaImg, (390, 50))
        screen.blit(fight_button, (330, 630))
        screen.blit(hp_bar1, (440, 350))
        pygame.display.flip()

        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = True

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        screen.blit(fight_button2, (330, 630))
                        screen.blit(hp_bar2, (440, 350))
                        damage_sound.set_volume(10)
                        damage_sound.play()
                        pygame.display.flip()
                        pygame.time.wait(5000)
                        attack2()------------------> here i try to replay the main loop but i cant move and the knife is also not moving.

            if pygame.key.get_pressed():
                running = True

    clock.tick(FPS)
    player(PlayerX, PlayerY)
    enemy(EnemyX, EnemyY)
    fire_knife(KnifeX, KnifeY)
    pygame.display.update()

1 Answers1

0

You can use a class like this to animate stuff:

import pygame
from os import listdir, path


def load_animations(folder_path: str) -> tuple:
    animation = listdir(folder_path)
    animation = tuple(pygame.image.load(path.join(folder_path, frame)).convert_alpha() for frame in animation)

    return animation


class Animation:
    def __init__(self, FPS: int, animation_folder: str, speed: float, pos: tuple):
        self.animation = load_animations(animation_folder)

        self.speed = speed
        self.FPS = FPS

        self.current_frame = 0

        self.image = None
        self.rect = None

        self.pos = pos

    def get_frame(self) -> pygame.Surface:
        self.current_frame += self.speed * 10 / self.FPS

        if self.current_frame >= len(self.animation):
            return

        return self.animation[int(self.current_frame)]

    def play(self, screen: pygame.Surface):
        self.image = self.get_frame()

        if not self.image:
            return

        self.rect = self.image.get_rect(center=self.pos)

        screen.blit(self.image, self.rect)

And to use this you would do something like:

animation = Animation(60, "path to the folder", 1, (100, 100))

# Put this inside the main loop.
animation.play(# Put the display surface in here)

And you should make a draw function for your whole game and put this code inside of the draw function (This function should handle all the graphics of your game).

CozyCode
  • 484
  • 4
  • 13