python newbie
python newbie

Reputation: 275

How do I create an attack mechanism in my turn based game in Pygame?

so im making a turn based game where the player has 3 attacks to chose from, the way I tried to do it was creating a boolean for each attack and setting it to false and when its set to true the opponents health bar would have a white rect drawn onto it to create the effect of damage and an animation would play but I can't figure out how do I make it so that this "attack" boolean is reusable, meaning every time the player uses it the rect would get longer by a certain amount. right now the attack can be used only once and it draws a single rect also the animation keeps playing on repeat since the boolean is set to true and if I set it to false then the rect would disappear, I also tried to set a variable for rect width that increases every time the attack is used but that for some reason gives the rectangle a border. How would I go about adding this attacking system? ive attached the necessary part of the code below and the entire code with prerequisite files is here

Hit = [pygame.image.load('Hit1.png'), pygame.image.load('Hit2.png'), pygame.image.load('Hit3.png')]
hitcount = 0

def attack():
    global FlareonX
    global FlareonY
    global hitcount
    f = 0
    Ax = 70
    Ay = 0
    scr_shake = False
    quick_attack = False
    click = False
    cursorX = 230
    cursorY = 540
    A1 = font.render('Thundershock', True, black)
    A2 = font.render('Quick Attack', True, black)
    A3 = font.render('Growl', True, black)
    A4 = font2.render('Electric', True, yellow)
    A5 = font2.render('Normal', True, grey)
    drawA4 = False
    drawA5 = False
    back_black = pygame.image.load('black_back.png')
    back_white = pygame.image.load('white_back.png')
    button_back = pygame.Rect(75, 200, 50, 50)

    running = True
         while running:
         scr.fill(black)
        if scr_shake:
            for Ay in [0, 0, 0, 0, 0, 0, -20, -20, -20, -20, -20, -20, 20, 20, 20, 20, 20, 20,]:
                scr.fill(black)
                scr.blit(attack_scr, (70, Ay))
                f += 1
                if f >= 9:
                    break
        scr.blit(attack_scr, (Ax, Ay))
        scr.blit(Flareon, (470, 0))
        scr.blit(A1, (270, 435))
        scr.blit(A2, (270, 470))
        scr.blit(A3, (270, 505))
        scr.blit(Cursor, (cursorX, cursorY))
        scr.blit(back_white, (70, 200))

        mx, my = pygame.mouse.get_pos()

        if button_back.collidepoint((mx, my)):
            scr.blit(back_black, (70, 200))
            if click:
                return
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    click = True
            if event.type == pygame.KEYDOWN:
                if cursorY <= 535 and event.key == pygame.K_DOWN:
                    cursorY += 35
                if cursorY >= 470 and event.key == pygame.K_UP:
                    cursorY += -35
                if cursorY == 435:
                    drawA5 = False
                    drawA4 = True
                elif cursorY == 470:
                    drawA4 = False
                    drawA5 = True
                elif cursorY == 505:
                    drawA4 = False
                    drawA5 = True
                elif cursorY >= 505:
                    drawA4 = False
                    drawA5 = False

                # ATTACK MECHANISM
                if cursorY == 470 and event.key == pygame.K_RETURN:
                    quick_attack = True

        if drawA4:
            scr.blit(A4, (265, 310))

        if drawA5:
            scr.blit(A5, (265, 310))

        if hitcount + 2 >= 22:
            hitcount = 0

        if quick_attack:
            scr.blit(Hit[hitcount // 7], (FlareonX, FlareonY))
            scr_shake = True
            hitcount += 2
            pygame.draw.rect(scr, white, (373, 79, 30, 8))
        pygame.display.update()

Upvotes: 2

Views: 931

Answers (1)

dario
dario

Reputation: 111

class Character:
    def __init__(self):
        self.HP = 100

    def setHP(self,HP):
        self.HP -= HP

    def getHP(self):
        return self.HP
    
def attack():
    global FlareonX
    global FlareonY
    global hitcount
    me = Character()
    enemy = Character()
    f = 0
    Ax = 70
    Ay = 0
    scr_shake = False
    quick_attack = False
    click = False
    cursorX = 230
    cursorY = 540
    A1 = font.render('Thundershock', True, black)
    A2 = font.render('Quick Attack', True, black)
    A3 = font.render('Growl', True, black)
    A4 = font2.render('Electric', True, yellow)
    A5 = font2.render('Normal', True, grey)
    drawA4 = False
    drawA5 = False
    back_black = pygame.image.load('black_back.png')
    back_white = pygame.image.load('white_back.png')
    button_back = pygame.Rect(75, 200, 50, 50)
    running = True
    while running:
        pygame.display.update()
        scr.fill(black)
        if scr_shake:
            scr_shake = False
            f = 0
            for Ay in [0, 20, 0, -20, 0, 20, 0, -20, 0]:
                scr.fill(black)
                scr.blit(attack_scr, (70, Ay))
                scr.blit(Flareon, (470, Ay))
                scr.blit(Hit[f//3], (FlareonX, FlareonY))
                f += 1
                pygame.display.update()
                time.sleep(0.05)
    scr.blit(attack_scr, (Ax, Ay))
    print(enemy.getHP())
    if enemy.getHP() != 100:
        pygame.draw.rect(scr, white, (203+enemy.getHP()*2, 80, (100-enemy.getHP())*2, 8))
    scr.blit(Flareon, (470, 0))
    scr.blit(A1, (270, 435))
    scr.blit(A2, (270, 470))
    scr.blit(A3, (270, 505))
    scr.blit(Cursor, (cursorX, cursorY))
    scr.blit(back_white, (70, 200))

    mx, my = pygame.mouse.get_pos()

    # removed button_back and event for shorter code, copy them back

    if drawA4:
        scr.blit(A4, (265, 310))

    if drawA5:
        scr.blit(A5, (265, 310))

    if hitcount + 2 >= 22:
        hitcount = 0
        running = False

    if quick_attack:
        scr_shake = True
        enemy.setHP(20)
        quick_attack = False

Import time for this to work. The problem was you were drawing your rectangles based on fixed values. I defined length and starting point of the rectangle based on HP. Also i would suggest to change HP bar from black to white in attack.png and then draw a gray HP bar instead of drawing a white rectangle over full HP. You would need to draw the gray rectangle with something like this: pygame.draw.rect(scr, gray, (203, 80, 200-enemy.getHP()*2, 8)). My most important suggestion would be to create classes for your pokemon and the enemy's pokemon that would contain HP and other needed information. Then create methods inside to change and return the information. This would also be done for attacks that you put inside pokemon object and your character to contain list of Pokemon objects. The code above is just a start to expand upon. Hope this helps and good luck! :)

Upvotes: 3

Related Questions