I’m creating flap by the pygame and the animation is not working well

Asked

Viewed 99 times

0

So following as I said in the title I am creates a flap Bird , I have not yet implemented physics and the tubes however my problem is being with his animation , What’s happening is that it only animates the bird when I hover on the screen and I have no idea what’s going on. Noting that I am still beginner in programming can be a silly mistake.

import pygame

import neat

import time

import os

import random


WIN_WIDTH = 500

WIN_HEIGTH = 800

BIRD_IMG = [pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','bird1.png'))),pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','bird2.png'))),pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','bird3.png')))]

PIPE_IMG = pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','pipe.png')))

BASE_IMG = pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','base.png')))

BG_IMG = pygame.transform.scale2x(pygame.image.load(os.path.join('imgs','bg.png')))


class Bird:
    IMGS = BIRD_IMG

    MAX_RATATION = 25

    ROT_VEL = 20

    ANIMATION_TIME = 5


    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.tilt = 0
        self.tick_count = 0
        self.vel = 0
        self.height = self.y
        self.img_count = 0
        self.img = self.IMGS[0]

    def Jump(self):
        self.vel = -10.5
        self.tick_count = 0
        self.height = self.y

    def move(self):
        self.tick_count += 1

        d = self.vel*self.tick_count + 1.5*self.tick_count**2

        if d >= 16:
            d = 16
        if d < 0:
            d -= 2
        self.y = self.y + d
        if d < 0 or self.y < self.height + 50:
            if self.tilt < self.MAX_RATATION:
                self.tilt = self.MAX_RATATION
        else:
            if self.tilt > -90:
                self.tilt -= self.ROT_VEL

    def draw(self,win):

        self.img_count += 1

        if self.img_count < self.ANIMATION_TIME:
            self.img = self.IMGS[0]
        elif self.img_count < self.ANIMATION_TIME*2:
            self.img = self.IMGS[1]
        elif self.img_count < self.ANIMATION_TIME*3:
            self.img = self.IMGS[2]
        elif self.img_count < self.ANIMATION_TIME*4:
            self.img = self.IMGS[1]
        elif self.img_count == self.ANIMATION_TIME*4 + 1:
            self.img = self.IMGS[0]
            self.img_count = 0
        if self.tilt <= -80:
            self.img = self.IMGS[1]
            self.img_count = self.ANIMATION_TIME*2

        rotated_image =  pygame.transform.rotate(self.img, self.tilt)

        bew_rect = rotated_image.get_rect(center=self.img.get_rect(topleft= (self.x, self.y)).center)

        win.blit(rotated_image, bew_rect.topleft)



    def get_mask(self):

        return pygame.mask.from_surface(self.img)

def draw_window(win, bird):

    win.blit(BG_IMG,(0,0))

    bird.draw(win)

    pygame.display.update()




def main():

    bird = Bird(200,200)

    win = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGTH))

    clock = pygame.time.Clock()


    run = True
    while run:
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = false
            bird.move()
            draw_window(win,bird)


    pygame.quit()
    quit()
main()
  • I updated the answer as per @jsbueno’s tip!

1 answer

1


First of all, let’s understand how things work in Python.

Definition of code blocks

As you may already know (but it costs nothing to remember), in Python, the code blocks for certain structures (if, else, for, while etc.) are defined, "delimited", with so-called indentations, which may consist of tabs (tabulations), or spaces, at the beginning of the line. When spaces, generally, it goes from 2 to 4 spaces. So:

print("Antes do 'if'")
n = int(input("Digite um número: "))

if n > 5:
    print("Dentro do 'if'")
    print(n)

print("Fora do 'if'")

All that’s after if n > 5: and has the so-called indentation (which I explained above) is considered within the if. And all that’s after if n > 5: and does not have the indentation is considered outside the if. That is to say:

if n > 5:
    # só executa se 'n' for maior que 5
    print("Dentro do 'if'")
    print(n)

# vai executar independente de 
# 'n' ser maior que 5, ou não
print("Fora do 'if'")

This is how it works in structures for, as well as while:

print("Antes do 'for'")

for i in range(10):
    if i % 2 == 0: # se for par
        print("Par:", i)
    elif i % 2 == 1: # se for ímpar
        print("Ímpar:", i)

    print("Analisado o {}º número".format(i+1))

print("Fora do 'for'")

What is after for i in range(10) and is indented, is considered part of the for. And what is not indented is considered outside the for. And on the block if-elif the same thing applies.

Once that review is done, let’s get to the problem.

Why only refreshes the animation when I place the (mouse) cursor on the screen?

What is happening is that you are only updating the screen when some event (either mouse or keyboard) happens:

for event in pygame.event.get():

That is to say: for every event that has occurred, do this. What if there’s no event? So, it doesn’t!

That’s why:

    # essas linhas
    bird.move()
    draw_window(win, bird)

They have to be out of of for, that is to say:

run = True
while run:
     clock.tick(30)
     for event in pygame.event.get():
         if event.type == pygame.QUIT:
             run = false

     # fora do 'for', porém dentro do 'while' (loop de execução)
     # executando assim, independente de ter
     # ocorrido um evento, ou não
     bird.move()
     draw_window(win,bird)

pygame.quit()

I hope I’ve helped!

  • 1

    have to take out the bird.move of for event... also. You can fix it there?

  • 1

    In case, I had been a bit in doubt regarding that line! But, yes, I correct! Thanks for the @jsbueno tip!

  • Thank you very much Gustavo, your explanation helped me to clear some doubts that I’ve always had , I’m learning python half self-taught paid for a basic python course but it was boring because I’m the kind of person who learns more doing than reading the theory (yes, I know theory is important for programming) but I’m learning more trying to make the Bird flap than doing a course on logic. because in practice it makes much more sense and once again thank you for having taught me

Browser other questions tagged

You are not signed in. Login or sign up in order to post.