Alec Smith
Alec Smith

Reputation: 33

Flappy Bird won't rotate when falling and flaps to quickly

I'm trying to make a flappy bird AI using OOP, so far everything seem to be working fine except for two problems. First my bird is flapping way to quickly. I created a user event and in the timer I put 200 milliseconds:

birdflap = pygame.USEREVENT
pygame.time.set_timer(birdflap, 200)

but for some reason, the wings are still flapping like crazy and I can't seem to understand what's causing it to do so. Secondly I had a problem with the bird rotating when it falls down. I made a function in my bird class called 'move' that creates gravity for the bird and causes it to turn using rotozoom in pygame to make it turn as it falls down.

def move(self):
        self.bird_movement = 8
        self.bird_movement += self.gravity
        self.bird_rect.centery += self.bird_movement

        pygame.transform.rotozoom(self.img[self.bird_index], -self.bird_movement * 3, 1)
        

The problem is that once the game starts, it falls but doesn't turn. I honestly don't know where to start with solving both of these issues. My full code is down below if anybody wanted to see what I have so far.

import pygame
import neat
import time
import os
import random
import sys

pygame.init()
clock = pygame.time.Clock()
# VARIABLES THAT DEFINE SCREEN SIZE
screen_width = 500
screen_height = 800

# CLOCK TO SET FRAME RATE
clock = pygame.time.Clock()

# VARIABLES THAT CONTAIN GAME IMAGES
bird_imgs = [pygame.transform.scale2x(pygame.image.load(os.path.join('assets', 'yellowbird-upflap.png'))), pygame.transform.scale2x(pygame.image.load(
    os.path.join('assets', 'yellowbird-midflap.png'))), pygame.transform.scale2x(pygame.image.load(os.path.join('assets', 'yellowbird-downflap.png')))]
bg_img = pygame.transform.scale2x(pygame.image.load(os.path.join('assets', 'background-day.png' )))

# TIMER FOR BIRD FLAP IMAGES
birdflap = pygame.USEREVENT
pygame.time.set_timer(birdflap, 200)

class Bird:
    img = bird_imgs
    gravity = 0.25

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.bird_movement = 0
        self.bird_index = 0
        self.bird_rect = self.img[self.bird_index].get_rect(center = (self.x, self.y))

    def bird_animation(self, win):
        if self.bird_index < 2:
            self.bird_index += 1
        else:
            self.bird_index = 0

        win.blit(self.img[self.bird_index], self.bird_rect)
        
    def move(self):
        self.bird_movement = 8
        self.bird_movement += self.gravity
        self.bird_rect.centery += self.bird_movement

        pygame.transform.rotozoom(self.img[self.bird_index], -self.bird_movement * 3, 1)


# FUNCTION TO DRAW THE WINDOW
def draw_window(win, bird):
    win.blit(bg_img, (0,0))
    bird.bird_animation(win)
    pygame.display.update()

# MAIN FUNCTION OF OUR GAME
def main():
    win = pygame.display.set_mode((screen_width, screen_height))
    bird = Bird(200, 200)
    run = True

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

            if event.type == birdflap:
                bird.bird_animation(win)

        bird.move()
        draw_window(win, bird)

    clock.tick(60)
    pygame.quit()
    sys.exit()  

main()

I tried using other modules in pygame, but that doesn't seem to solve my issue either. Right now I'm really lost.

Upvotes: 1

Views: 173

Answers (1)

Rabbid76
Rabbid76

Reputation: 211230

The 1st problem is that bird_animation is called in draw_window so the bird is animated all over the time. The 2nd problem is that pygame.transform.rotozoom returns a new but rotated surface (see How do I rotate an image around its center using PyGame?). The method move has to create an image, that is used in an draw method:

class Bird:
    img = bird_imgs
    gravity = 0.25

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.bird_movement = 0
        self.bird_index = 0
        self.image = self.img[self.bird_index]
        self.rect = self.image.get_rect(center = (self.x, self.y))

    def bird_animation(self):
        if self.bird_index < 2:
            self.bird_index += 1
        else:
            self.bird_index = 0
        
    def move(self):
        self.bird_movement = 8
        self.bird_movement += self.gravity
        self.y += self.bird_movement

        self.image = pygame.transform.rotozoom(self.img[self.bird_index], -self.bird_movement * 3, 1)
        self.rect = self.image.get_rect(center = (self.x, self.y))

    def draw(self, win)
        win.blit(self.img[self.bird_index], self.bird_rect)


# FUNCTION TO DRAW THE WINDOW
def draw_window(win, bird):
    win.blit(bg_img, (0,0))
    bird.draw(win)
    pygame.display.update()

def main():
    win = pygame.display.set_mode((screen_width, screen_height))
    bird = Bird(200, 200)
    run = True

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

            if event.type == birdflap:
                bird.bird_animation()

        bird.move()
        draw_window(win, bird)

    clock.tick(60)
    pygame.quit()
    sys.exit()  

main()

Upvotes: 1

Related Questions