-4

I have a school project for Pygame over the winter break, as a summative. I made the basis of the game (Flappy Bird), but the problem is that the collisions aren't working properly. The problem is that it counts going through the pipes as a collision.

Could you guys please check my code and fix it up?

import pygame
import sys
import math
import random
from pygame.locals import *
a=320

b=240
da=1
db=0
x=25
y=25
e=50
da2=0
c=200
d=10
c_change=0
d_change=0
clock = pygame.time.Clock()
bg=(36,38,82)
wood=(253,197,136)
green=(79, 255, 101)
pipe=(152,228,86)
end=(137, 226, 57)
bg1=(40,42,86)
gold=(219,178,58)
golden=(254, 197, 34)
golder=(255, 206, 63)
black=(0,0,0)
red=(255, 47, 47)
white=(255,255,255)
pygame.init()
screen = pygame.display.set_mode((1400,700))
class Wall(pygame.sprite.Sprite):

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


        self.image = pygame.Surface([width, height])
        self.image.fill(GREY)


        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x

crashFlag=0

done = False
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type==pygame.KEYDOWN:
            if event.key==pygame.K_SPACE:
                c_change=-1
                d_change=1
        if event.type==pygame.KEYUP:
            if event.key==pygame.K_SPACE:
                c_change=1
        if event.type==pygame.KEYDOWN:
            crashFlag==0


    c+=c_change
    d+=d_change

    screen.fill(bg)
    pygame.draw.rect(screen,bg1, (0,350,1400,350), 0)


    pygame.draw.circle(screen,white, (d,c),5)
    #for f in range(195, 390 ,5):
    if d>200 and d<275:
        if c>340:
            crashFlag=1

    pygame.draw.rect(screen,end, (195,300,80,40), 0)
    pygame.draw.rect(screen,pipe, (200,0,70,300), 0)
    pygame.draw.rect(screen,pipe, (350,0,70,450), 0)
    pygame.draw.rect(screen,end, (345,420,80,40), 0)
    pygame.draw.rect(screen,pipe, (490,0,70,480), 0)
    pygame.draw.rect(screen,end, (485,480,80,40), 0)
    pygame.draw.rect(screen,pipe, (630,0,70,450), 0)
    pygame.draw.rect(screen,end, (625,450,80,40), 0)
    pygame.draw.rect(screen,pipe, (770,0,70,430), 0)
    pygame.draw.rect(screen,end, (765,420,80,40), 0)
    pygame.draw.rect(screen,pipe, (910,0,70,400), 0)
    pygame.draw.rect(screen,end, (905,400,80,40), 0)
    pygame.draw.rect(screen,pipe, (1050,0,70,470), 0)
    pygame.draw.rect(screen,end, (1045,470,80,40), 0)
    pygame.draw.rect(screen,pipe, (1190,0,70,430), 0)
    pygame.draw.rect(screen,end, (1185,430,80,40), 0)
    pygame.draw.rect(screen,gold, (1330,0,70,410), 0)
    pygame.draw.rect(screen,golder, (1350,0,70,410), 0)
    pygame.draw.rect(screen,golden, (1325,410,80,40), 0)
    pygame.draw.rect(screen,pipe, (200,400,70,240), 0)
    #lower pipes
    pygame.draw.rect(screen,end, (195,400,80,40), 0)
    pygame.draw.rect(screen,pipe, (350,520,70,500), 0)
    pygame.draw.rect(screen,end, (345,515,80,40), 0)
    pygame.draw.rect(screen,pipe, (490,570,70,100), 0)
    pygame.draw.rect(screen,end, (485,570,80,40), 0)
    pygame.draw.rect(screen,pipe, (630,570,70,100), 0)
    pygame.draw.rect(screen,end, (625,540,80,40), 0)
    pygame.draw.rect(screen,pipe, (770,550,70,120), 0)
    pygame.draw.rect(screen,end, (765,510,80,40), 0)
    pygame.draw.rect(screen,pipe, (910,530,70,220), 0)
    pygame.draw.rect(screen,end, (905,490,80,40), 0)
    pygame.draw.rect(screen,pipe, (1050,560,70,220), 0)
    pygame.draw.rect(screen,end, (1045,560,80,40), 0)
    pygame.draw.rect(screen,pipe, (1190,530,70,220), 0)
    pygame.draw.rect(screen,end, (1185,530,80,40), 0)
    pygame.draw.rect(screen,gold, (1330,530,70,220), 0)
    pygame.draw.rect(screen,golder, (1350,530,70,220), 0)
    pygame.draw.rect(screen,golden, (1325,510,80,40), 0)
    pygame.draw.rect(screen, wood, (0,650,1400,50), 0)
    pygame.draw.rect(screen,green, (0,640,1400,10), 0)

    if crashFlag==1:
        pygame.draw.rect(screen,white, (0,0,1400,700), 0)
        font = pygame.font.SysFont("Berlin Sans FB Demi", 100, True, False)

        text = font.render("You Lost", True, black)
        screen.blit(text, (500, 100))
        pygame.draw.rect(screen,green, (600,400,190,60), 0)
        font = pygame.font.SysFont("Aharoni", 50, True, False)

        text = font.render("RESET", True, white)
        screen.blit(text, (630, 410))



    pygame.display.update()
    clock.tick(150)
pygame.quit()
halfer
  • 19,824
  • 17
  • 99
  • 186
  • 3
    "Check my code and fix it up" isn't something that SO is for. Ask a specific question and someone will help you debug it. – David Hoelzer Dec 26 '17 at 23:45
  • 1
    use `print()` to display values in variables and messages which shows which part of code is executed - it is called "print debugging" - and it helps to see what is going on in code. Sometimes code doesn't do what you expect or has different values in variables.. – furas Dec 27 '17 at 00:35
  • you could use list or dictionary to keep all pipes' position and size and then you can use `for` loop to draw them and to check collisions. Python has even [pygame.Rect()](http://pygame.org/docs/ref/rect.html) to keep position and size - and it has method `colliderect`, `collidepoint`, etc. Currently I don't see where do you check collisions - so they doesn't work. – furas Dec 27 '17 at 00:37
  • what means `a`, `b`, ect. Use names which means something. Now code is unreadable. – furas Dec 27 '17 at 00:41
  • if you doesn't use `Wall` in code then remove it - don't keep unused elements. It makes code unreadable. – furas Dec 27 '17 at 00:50

1 Answers1

1

There is too many changes to describe them all.

I keep all pipes on list all_pipes as (END, pygame.Rect(195,300,80,40)) and then I can use for loop to draw them

    for pipe_color, pipe_rect in all_pipes:
        pygame.draw.rect(screen, pipe_color, pipe_rect, 0)

and to check collision with player.

    for pipe_color, pipe_rect in all_pipes:
        if pipe_rect.collidepoint(player_x, player_y):
            state = STATE_GAMEOVER
            break # no need to check other

Full code

import pygame

# --- constants --- (UPPER_CASE_NAMES)

# - colors -

BACKGROUND_0 = (36, 38, 82)
BACKGROUND_1 = (40, 42, 86)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 47, 47)
GREEN = (79, 255, 101)

WOOD = (253, 197, 136)
PIPE = (152, 228, 86)
END = (137, 226, 57)
GOLD = (219, 178, 58)
GOLDEN = (254, 197, 34)
GOLDER = (255, 206, 63)

# - states -

STATE_INTRO    = 1
STATE_GAME     = 2
STATE_GAMEOVER = 3

# --- classes --- (CamelCaseNames)

#class Wall(pygame.sprite.Sprite):
#
#   def __init__(self, x, y, width, height):
#        super().__init__()
#
#        self.image = pygame.Surface((width, height))
#        self.image.fill(GREY)
#
#        self.rect = self.image.get_rect()
#        self.rect.y = y
#        self.rect.x = x

# --- functions --- (lower_case_names)

# empty

# --- main ---

# - init -

pygame.init()
screen = pygame.display.set_mode((1400,700))

font1 = pygame.font.SysFont("Berlin Sans FB Demi", 100, True, False)
text1 = font1.render("You Lost", True, BLACK)
font2 = pygame.font.SysFont("Aharoni", 50, True, False)
text2 = font2.render("RESET", True, WHITE)

# - objects -

player_y = 200
player_x = 10

x_change = 5
y_change = 0

all_pipes = [
    #upper pipes
    (END, pygame.Rect(195,300,80,40)), 
    (PIPE, pygame.Rect(200,0,70,300)), 
    (PIPE, pygame.Rect(350,0,70,450)), 
    (END, pygame.Rect(345,420,80,40)), 
    (PIPE, pygame.Rect(490,0,70,480)), 
    (END, pygame.Rect(485,480,80,40)), 
    (PIPE, pygame.Rect(630,0,70,450)), 
    (END, pygame.Rect(625,450,80,40)), 
    (PIPE, pygame.Rect(770,0,70,430)), 
    (END, pygame.Rect(765,420,80,40)), 
    (PIPE, pygame.Rect(910,0,70,400)), 
    (END, pygame.Rect(905,400,80,40)), 
    (PIPE, pygame.Rect(1050,0,70,470)), 
    (END, pygame.Rect(1045,470,80,40)), 
    (PIPE, pygame.Rect(1190,0,70,430)), 
    (END, pygame.Rect(1185,430,80,40)), 
    (GOLD, pygame.Rect(1330,0,70,410)), 
    (GOLDER, pygame.Rect(1350,0,70,410)), 
    (GOLDEN, pygame.Rect(1325,410,80,40)), 
    (PIPE, pygame.Rect(200,400,70,240)), 
    #lower pipes
    (END, pygame.Rect(195,400,80,40)), 
    (PIPE, pygame.Rect(350,520,70,500)), 
    (END, pygame.Rect(345,515,80,40)), 
    (PIPE, pygame.Rect(490,570,70,100)), 
    (END, pygame.Rect(485,570,80,40)), 
    (PIPE, pygame.Rect(630,570,70,100)), 
    (END, pygame.Rect(625,540,80,40)), 
    (PIPE, pygame.Rect(770,550,70,120)), 
    (END, pygame.Rect(765,510,80,40)), 
    (PIPE, pygame.Rect(910,530,70,220)), 
    (END, pygame.Rect(905,490,80,40)), 
    (PIPE, pygame.Rect(1050,560,70,220)), 
    (END, pygame.Rect(1045,560,80,40)), 
    (PIPE, pygame.Rect(1190,530,70,220)), 
    (END, pygame.Rect(1185,530,80,40)), 
    (GOLD, pygame.Rect(1330,530,70,220)), 
    (GOLDER, pygame.Rect(1350,530,70,220)), 
    (GOLDEN, pygame.Rect(1325,510,80,40)), 
    (WOOD, pygame.Rect(0,650,1400,50)), 
    (GREEN, pygame.Rect(0,640,1400,10)), 
]

# - mainloop -

state = STATE_INTRO # STATE_GAME, STATE_GAMEOVER

clock = pygame.time.Clock()
done = False

while not done:

    # - events -

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

        if state == STATE_INTRO:
            if event.type == pygame.KEYDOWN:
               state = STATE_GAME

        elif state == STATE_GAME:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    y_change = -5
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_SPACE:
                    y_change = 5

        elif state == STATE_GAMEOVER:
            if event.type == pygame.KEYDOWN:
               state = STATE_INTRO
               player_y = 200
               player_x = 10

    # - updates (without draws) -

    if state == STATE_GAME:
        player_x += x_change
        player_y += y_change

        # check collisions with all pipes

        for pipe_color, pipe_rect in all_pipes:
            if pipe_rect.collidepoint(player_x, player_y):
                state = STATE_GAMEOVER
                break # no need to check other

    # - draws (without updates) -

    if state in (STATE_INTRO, STATE_GAME):
        screen.fill(BACKGROUND_0)
        pygame.draw.rect(screen, BACKGROUND_1, (0, 350, 1400, 350), 0)

        # draw all pipes

        for pipe_color, pipe_rect in all_pipes:
            pygame.draw.rect(screen, pipe_color, pipe_rect, 0)

        pygame.draw.circle(screen, WHITE, (player_x, player_y), 5)

    if state == STATE_GAMEOVER:
        screen.fill(WHITE)
        screen.blit(text1, (500, 100))
        pygame.draw.rect(screen, GREEN, (600, 400, 190, 60), 0)
        screen.blit(text2, (630, 410))

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

# - end -

pygame.quit()
furas
  • 134,197
  • 12
  • 106
  • 148
  • thanks for fixing my problem and code you have no idea how this has helped me –  Dec 27 '17 at 01:25
  • BTW: Stackoverflow has portal [Code Review](https://codereview.stackexchange.com/) and most of those changes should be done on this portal. – furas Dec 27 '17 at 01:31
  • Stackoverflow has also portal [Game Development](https://gamedev.stackexchange.com/) – furas Dec 27 '17 at 01:33