AttributeError: 'pygame.mask.Mask' object has no attribute 'rect' - python

I am trying to get pixel perfect collision but I keep running into this error:
Traceback (most recent call last):
File "D:\Projects\games\venv\lib\site-packages\pygame\sprite.py", line 1528, in collide_circle
xdistance = left.rect.centerx - right.rect.centerx
AttributeError: 'pygame.mask.Mask' object has no attribute 'rect'
Process finished with exit code 1
I am not sure of what's going wrong. Is it my implementation or logic or maybe both?
My code:
class AlienShooting(pygame.sprite.Sprite):
def __init__(self, w=640, h=640):
# init display
# init game state
self.spaceship_main = pygame.image.load('spacecraft_1.png').convert_alpha()
self.alien_spacecraft1 = pygame.image.load('spacecraft_alien.png').convert_alpha()
self.alien_spacecraft_rec1 = self.alien_spacecraft1.get_rect()
self.mask1 = pygame.mask.from_surface(self.alien_spacecraft1)
self.main_spaceship_mask = pygame.mask.from_surface(self.spaceship_main)
def play_step(self):
# user input
# Move the spaceship
# check if game over
game_over = False
if self._is_collision():
game_over = True
# Add new alien spaceships
# Randomly move alien spaceships
# update ui and clock
# return game over and score
return False
def _is_collision(self):
if pygame.sprite.collide_circle(self.mask1, self.main_spaceship_mask):
return True
return False
It might be because both my main space ship and my alien spaceship are in the same class, but I'm not sure.

See How do I detect collision in pygame? and Pygame mask collision. If you want to use pygame.sprite.collide_circle() or pygame.sprite.collide_mask you have to create pygame.sprite.Sprite objects.
spaceship_main and alien_spacecraft1 have to be Sprite objects. Sprite objects must have a rect and image attribute and can optionally have a mask attribute.
e.g.:
class AlienShooting():
def __init__(self, w=640, h=640):
self.spaceship_main = pygame.sprite.Sprite()
self.spaceship_main.image = pygame.image.load('spacecraft_1.png').convert_alpha()
self.spaceship_main.rect = self.spaceship_main.image.get_rect(center = (140, 140))
self.spaceship_main.mask = pygame.mask.from_surface(self.spaceship_main.image)
self.alien_spacecraft1 = pygame.sprite.Sprite()
self.alien_spacecraft1.image = pygame.image.load('spacecraft_alien.png').convert_alpha()
self.alien_spacecraft1.rect = self.alien_spacecraft1.image.get_rect(center = (160, 160))
self.alien_spacecraft1.mask = pygame.mask.from_surface(self.alien_spacecraft1.image)
def _is_collision(self):
if pygame.sprite.collide_mask(self.spaceship_main, self.alien_spacecraft1):
return True
return False

Related

function call for pong game made in python throwing AttributeError error

trying to create pong using python. i've created various parts of the code and have gotten the ball to appear and move. when i create a wall function to detect collision with the upper and lower bounds of the window i get keep getting an error.
from turtle import Turtle
import random
class Ball(Turtle):
def __init__(self):
super().__init__()
self.ball = Turtle(shape="circle")
self.ball.color("white")
self.ball.penup()
self.ball.setheading(random.randint(1, 360))
def collide(self):
current_heading = self.ball.heading()
self.ball.setheading(180 - current_heading)
def wall(self):
if self.ball.ycor() == 350 or self.ball.ycor() == -350:
self.ball.collide()
else:
pass
def move(self):
self.ball.forward(5)
self.ball.wall()
from gamescreen import GameScreen
from player import Player
import time
from ball import Ball
screen = GameScreen()
screen = screen.screen
player_1 = Player()
player_2 = Player()
player_1.left()
player_2.right()
player_1.show()
player_2.show()
ball = Ball()
screen.onkeypress(fun = player_1.up, key='w')
screen.onkeypress(fun = player_1.down, key='s')
screen.onkeypress(fun = player_2.up, key='Up')
screen.onkeypress(fun = player_2.down, key='Down')
on = True
while on:
ball.move()
screen.exitonclick()
AttributeError: 'Turtle' object has no attribute 'wall'
not sure what i'm doing wrong with regards to class inheritance and making and calling new functions. thanks.

AttributeError: 'Obstacle' object has no attribute 'image'

I tried to draw obstacle on screen but got an error in return and now im stuck :/
Here is my obstacle class :
class Obstacle(pygame.sprite.Sprite):
def __init__(self,type):
super().__init__()
if type == 'fly':
self.snail_1 = pygame.image.load("graphics\\snail1.png").convert_alpha()
self.snail_2 = pygame.image.load("graphics\\snail2.png").convert_alpha()
self.snail_frames = [self.snail_1,self.snail_2]
self.snail_index = 0
else:
self.fly_1 = pygame.image.load("graphics\\fly1.png").convert_alpha()
self.fly_2 = pygame.image.load("graphics\\fly2.png").convert_alpha()
self.fly_frames = [self.fly_1, self.fly_2]
self.fly_index = 0
self.rect = self.fly_1.get_rect(midbottom = (200,210))
Here is sprite.Group:
obstacle_group = pygame.sprite.Group()
obstacle_group.add(Obstacle('fly'))
and here is my method to draw:
obstacle_group.draw(screen)
What i'm doing wrong here ?
Traceback (most recent call last):
File "C:\Users\Marcin\PycharmProjects\tutorial\main.py", line 105, in <module>
obstacle_group.draw(screen)
File "C:\Users\Marcin\PycharmProjects\tutorial\venv\lib\site-packages\pygame\sprite.py", line 552, in draw
zip(sprites, surface.blits((spr.image, spr.rect) for spr in sprites))
File "C:\Users\Marcin\PycharmProjects\tutorial\venv\lib\site-packages\pygame\sprite.py", line 552, in <genexpr>
zip(sprites, surface.blits((spr.image, spr.rect) for spr in sprites))
AttributeError: 'Obstacle' object has no attribute 'image'
Process finished with exit code 1
pygame.sprite.Group.draw() and pygame.sprite.Group.update() is a method which is provided by pygame.sprite.Group. It uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects — you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():
Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]
Therefore the pygame.sprite.Sprite must have an image and a rect attribute which can be used to draw the object. e.g.:
class Obstacle(pygame.sprite.Sprite):
def __init__(self,type):
super().__init__()
if type == 'fly':
self.snail_1 = pygame.image.load("graphics\\snail1.png").convert_alpha()
self.snail_2 = pygame.image.load("graphics\\snail2.png").convert_alpha()
self.snail_frames = [self.snail_1,self.snail_2]
self.snail_index = 0
self.image = self.snail_1
self.rect = self.image.get_rect(midbottom = (200,210))
else:
self.fly_1 = pygame.image.load("graphics\\fly1.png").convert_alpha()
self.fly_2 = pygame.image.load("graphics\\fly2.png").convert_alpha()
self.fly_frames = [self.fly_1, self.fly_2]
self.fly_index = 0
slef.image = self.fly_1
self.rect = self.image.get_rect(midbottom = (200,210))

Pygame object has no attribute 'rect' (pygame)

I'm currently making Memory, a game for school which involves matching 8 pairs of images that are hidden underneath covers. I was successful in setting up the 4x4 grid, with a timer for score and randomizing the location of the images, but removing the cover on the tiles is giving me some issues. I end up getting the error: builtins.AttributeError: type object 'Tile' has no attribute 'rect'
The traceback is:
Traceback (most recent call last):
File "/home/user/Documents/Lab 4/memory2cover.py", line 179, in <module>
main()
File "/home/user/Documents/Lab 4/memory2cover.py", line 21, in <module>
game.play()
File "/home/user/Documents/Lab 4/memory2cover.py", line 92, in <module>
self.handle_events()
File "/home/user/Documents/Lab 4/memory2cover.py", line 117, in <module>
Tile.handle_click(Tile, event)
File "/home/user/Documents/Lab 4/memory2cover.py", line 175, in <module>
if self.rect.collidepoint(pos):
builtins.AttributeError: type object 'Tile' has no attribute 'rect'
My Tile class is:
class Tile:
# An object in this class represents a Tile
# Shared or Class Attributes
surface = None
fg_color = pygame.Color('black')
border_width = 10
cover = pygame.image.load('image0.bmp')
#classmethod
def set_surface(cls,surface_from_Game):
cls.surface = pygame.display.get_surface()
def __init__(self, x,y,width,height, image):
# Initialize a Tile.
# - self is the Tile to initialize
# - x,y top left coordinates of the rectangle
# - - width, height are the dimensions of the rectangle
# Instance Attributes or Object Attributes
self.rect = pygame.Rect(x,y,width,height)
self.image = image
self.covered = True
def draw(self):
# Draw the dot on the surface
# - self is the Tile
# then blit the tile content onto the surface
pygame.draw.rect(Tile.surface, Tile.fg_color, self.rect,Tile.border_width)
if self.covered:
Tile.surface.blit(Tile.cover, self.rect)
else:
Tile.surface.blit(self.image, self.rect)
def handle_click(self, event):
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
self.covered = False
and I am not too sure why it is saying it has no attribute 'rect'.
Here is my full code
# Memory 1
import pygame
import random
# User-defined functions
# board[row_index][col_index]
def main():
# initialize all pygame modules (some need initialization)
pygame.init()
# create a pygame display window
pygame.display.set_mode((500, 400))
# set the title of the display window
pygame.display.set_caption('Memory')
# get the display surface
w_surface = pygame.display.get_surface()
# create a game object
game = Game(w_surface)
# start the main game loop by calling the play method on the game object
game.play()
# quit pygame and clean up the pygame window
pygame.display.quit()
pygame.quit()
# User-defined classes
class Game:
# An object in this class represents a complete game.
def __init__(self, surface):
# Initialize a Game.
# - self is the Game to initialize
# - surface is the display window surface object
# === objects that are part of every game that we will discuss
self.surface = surface
self.bg_color = pygame.Color('black')
self.FPS = 70
self.game_Clock = pygame.time.Clock()
self.close_clicked = False
self.continue_game = True
# === game specific objects
Tile.set_surface(self.surface) # this is how you call a class method
self.board_size = 4
self.board = []
self.score = 0
self.load_images()
self.create_board()
self.image_index = 0
def load_images(self):
# loads a specified amount of images into a list
# that list of images is then shuffled so an images index is randomized
self.image_list = []
for self.image_index in range(1,9):
self.image_list.append(pygame.image.load('image' + str(self.image_index) + '.bmp'))
self.full_list = self.image_list + self.image_list
random.shuffle(self.full_list)
def create_board(self):
# multiple rows and columns are appended to the board with the tiles added
# utlizes the different images for each tile
index = 0
img = self.full_list[0]
width = img.get_width()
height = img.get_height()
for row_index in range(0,self.board_size):
self.row = []
for col_index in range(0,self.board_size):
#item = (row_index,col_index)
# game = Game(), dot1 = Dot(), student = Student()
image = self.full_list[index]
x = width * col_index
y = height * row_index
a_tile = Tile(x,y,width,height, image)
self.row.append(a_tile)
index = index + 1
self.board.append(self.row)
def play(self):
# Play the game until the player presses the close box.
# - self is the Game that should be continued or not.
while not self.close_clicked: # until player clicks close box
# play frame
self.handle_events()
self.draw()
if self.continue_game:
self.update()
self.game_Clock.tick(self.FPS) # run at most with FPS Frames Per Second
def draw_score(self):
fg = pygame.Color('white')
bg = pygame.Color('black')
font = pygame.font.SysFont('',70)
text_box = font.render(str(self.score),True,fg,bg)
#x = self.surface.get_width() - text_box.get_width()
#y = self.surface.get_height() - text_box.get_height()
location = (self.surface.get_width() -70,0)
self.surface.blit(text_box,location)
def handle_events(self):
# Handle each user event by changing the game state appropriately.
# - self is the Game whose events will be handled
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
self.close_clicked = True
for item in self.row:
Tile.handle_click(Tile, event)
def draw(self):
# Draw all game objects.
# - self is the Game to draw
coordinates = self.create_board()
# clear the display surface first
self.surface.fill(self.bg_color)
# drawing of the board
for row in self.board:
for tile in row:
tile.draw()
self.draw_score()
pygame.display.update() # make the updated surface appear on the display
def update(self):
# Update the game objects for the next frame.
# - self is the Game to update
self.score = pygame.time.get_ticks()//1000
class Tile:
# An object in this class represents a Tile
# Shared or Class Attributes
surface = None
fg_color = pygame.Color('black')
border_width = 10
cover = pygame.image.load('image0.bmp')
#classmethod
def set_surface(cls,surface_from_Game):
cls.surface = pygame.display.get_surface()
def __init__(self, x,y,width,height, image):
# Initialize a Tile.
# - self is the Tile to initialize
# - x,y top left coordinates of the rectangle
# - - width, height are the dimensions of the rectangle
# Instance Attributes or Object Attributes
self.rect = pygame.Rect(x,y,width,height)
self.image = image
self.covered = True
def draw(self):
# Draw the dot on the surface
# - self is the Tile
# then blit the tile content onto the surface
pygame.draw.rect(Tile.surface, Tile.fg_color, self.rect,Tile.border_width)
if self.covered:
Tile.surface.blit(Tile.cover, self.rect)
else:
Tile.surface.blit(self.image, self.rect)
def handle_click(self, event):
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
self.covered = False
main()
The problem is this:
Tile.handle_click( Tile, event )
The code is confusing the class definition of the Tile object, with an instantiated object - like a "live copy" of it ~ a_tile. So when it calls Tile.something(), the __init__() has never been called, so .rect does not exist. Of course a_tile has a .rect, because it has been instantiated.
It should probably be something like:
def handle_events(self):
# Handle each user event by changing the game state appropriately.
# - self is the Game whose events will be handled
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
self.close_clicked = True
for item in self.row:
item.handle_click( event ) # <-- HERE
Except for #classmethod functions (i.e.: what every other language calls static member functions), member functions are almost never called on the class definition. So if you find yourself writing Tile.something to call a function, you should be questioning yourself.
Unless you have an object with no internal state, it's normal to have none-to-few #classmethod functions. Sometimes you might do a class, say a unit-converter, which is in an object simply to collect a whole bunch of small functions together. These would all be called on the definition, e.g.: Units.furlongsToMetres( fur ). For your Tile, this is not the case.

Trying to shoot a projectile originating from a character in Pygame (with statement for all_sprites)

I am trying to fire a projectile from a character, with that projectile being the mudball image. I have referenced my class MUDBALL to be included in all_sprites. In my first approach I get an error saying: AttributeError: 'TRUMP' object has no attribute 'rect' when I try and include MUDBALL in all_sprites. That approach is in the code below along with the Game class definitions. In the second approach I try and code the all_sprites statement into the shoot method of the of the TRUMP class. I understand I only need one of these 2 pieces of code to work. I have tried to include the code necessary while omitting everything else to minimize confusion.
import pygame as pg
class Game:
def __init__(self):
# initialize game window, etc
pg.init()
pg.mixer.init()
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(TITLE)
self.clock = pg.time.Clock()
self.running = True
self.font_name = pg.font.match_font(FONT_NAME)
self.load_data()
def load_data(self):
# load high score
self.dir = path.dirname(__file__)
img_dir = path.join(self.dir, 'img')
with open(path.join(self.dir, HS_FILE), 'r') as f:
try:
self.highscore = int(f.read())
except:
self.highscore = 0
# load spritesheet image
self.spritesheet = Spritesheet(path.join(img_dir, SPRITESHEET))
def new(self):
# start a new game
self.score = 0
self.all_sprites = pg.sprite.Group()
self.platforms = pg.sprite.Group()
self.player = Player(self)
#ME: TRUMP added to all sprites!!!
self.trump = TRUMP(self)
self.all_sprites.add(self.trump)
#***First attempt at adding mudball to all_sprites
self.mudball = MUDBALL(TRUMP.rect.centerx, TRUMP.rect.centery)
self.all_sprites.add(self.mudball)
#game class continues...
class TRUMP(pg.sprite.Sprite):
def __init__(self, game):
pg.sprite.Sprite.__init__(self)
self.game = game
self.current_frame2 = 0
self.last_update2 = 0
self.load_images()
#TRUMP class continued etc... Second attempt with shoot def is below.
def shoot(self):
mudball = MUDBALL(self.rect.centerx, self.rect.centery)
Game.all_sprites.add(mudball)
mudballs.add(mudball)
class MUDBALL(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load("MUDBALL.png")
self.rect = self.image.get_rect()
self.rect.bottom = y
self.rect.centerx = x
self.speedx = -10
def update(self):
self.rect.x += self.speedx
# kill if moves off screen
if self.rect.centerx < 0:
self.kill
Shoot is a method of the TRUMP class! In second attempt I try and add MUDBALL to all sprites within the shoot definition of the TRUMP class. That doesn't work. again in this approach I take out the code from the previous approach. That attempt, which is just below, returns: NameError: name 'Game' is not defined. I don't know how to proceed.
The problem may be with your line
self.mudball = MUDBALL(self)
MUDBALL's __init__ method requires x, y arguments; instead, you passed it an object and nothing. That would be enough to cause the error you're seeing.
Response to OP update:
That's correct: Game is not defined. That one line is the only place in your posted code where the symbol appears. As you've coded this, you have the attachment backwards: all_sprites is an attribute (variable field) of Game. In other words, all_sprites is attached to Game, not the other way around. The only way to get to all_sprites is through Game ... except that Game isn't defined anywhere.
A friend of mine helped me. He says "TRUMP is your class ... it does not have rect as an attribute only an instance of TRUMP will have rect as an attribute." I don't understand this yet. But want to thank everyone who helped me along.
self.mudball = MUDBALL(self.trump.rect.centerx, self.trump.rect.centery)
self.all_sprites.add(self.mudball)

Python TypeError: 'int' object is not iterable despite proper assignment

When I run this program, it gives me a type error when it reaches the display_pipe method because it does not think that one of the variables is an int, when every single parameter is entered as an int, and all other variables in the method are integers.
'''This is a simple replica of flappy bird for the pc that I made to help me
understand python.'''
import random
import pygame
from pygame import *
import math
import sys
#Presets for window
size=width,height=500,500
Ag=-9.80665
clock = pygame.time.Clock()
white=(255,255,255)
blue=(0,0,255)
red=(255,0,0)
gray_bgColor=(190,193,212)
#Initialise pygame Surface as screen
pygame.init()
pygame.font.init()
#Creates icon for window
screen=pygame.display.set_mode(size)
pygame.display.set_caption("Flappy Bird Replica")
icon = pygame.image.load("images/icon.png").convert()
pygame.display.set_icon(icon)
class graphics():
#Holds the methods for loading/displaying graphics
def load_images(self):
#Loads the background and sprite images
self.background_image=pygame.image.load("images/flappy_background.png").convert()
self.bird_image=pygame.image.load("images/flappy_sprite.jpg").convert()
self.pipe_image=pygame.image.load("images/flappy_pipe.png").convert()
self.pipe_image.set_colorkey(white)
self.inverted_pipe_image=pygame.transform.flip(self.pipe_image,False,True)
self.bird_image.set_colorkey(white)
def display_pipe(self,pipe_xPos,pipe_height):
#Calculates new position of pipe
pipe_yPos=318
pipe_vX=-1
inverted_pipe_yPos=0
#Checks if there is a pre-existing velocity and xPosition
#and assigns defaults
if pipe_xPos==None or pipe_xPos<=-78:
pipe_xPos=500
pipe_height=random.randrange(0,3)
pipe_xPos+=pipe_vX
#Randomizes the height of the pipes
if pipe_height==0:
self.inverted_pipe_image=pygame.transform.scale(self.inverted_pipe_image,(self.inverted_pipe_image.get_width(),200))
elif pipe_height==1:
self.inverted_pipe_image=pygame.transform.scale(self.inverted_pipe_image,(self.inverted_pipe_image.get_width(),150))
elif pipe_height==2:
self.inverted_pipe_image=pygame.transform.scale(self.inverted_pipe_image,(self.inverted_pipe_image.get_width(),100))
screen.blit(self.pipe_image,[pipe_xPos,pipe_yPos])
screen.blit(self.inverted_pipe_image,[pipe_xPos,0])
return pipe_height
def display_loop(self,bird_vY,bird_yPos,pipe_xPos,pipe_height):
#Calculates new position of bird
bird_xPos=200
jumpspeed=-1.7
fallspeed=0.02
#Checks if there is a pre-existing velocity and yPosition
#and assigns defaults
if bird_vY==None or bird_yPos==None:
bird_vy=0
bird_yPos=200
for event in pygame.event.get():
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_UP:
bird_vY=jumpspeed
bird_vY+=fallspeed
bird_yPos+=bird_vY
#Blits all the images to the screen
screen.blit(self.background_image,[0,0])
screen.blit(self.bird_image,[bird_xPos,bird_yPos])
pipe_xPos,pipe_height=self.display_pipe(pipe_xPos,pipe_height)
pygame.display.flip()
return bird_vY,bird_yPos,pipe_xPos,pipe_height
class titleScreen():
#Holds the methods for the title screen/menu
def title(self):
#Different fonts
titleFont=pygame.font.SysFont("verdana",30,bold=True,italic=True)
startFont=pygame.font.SysFont("verdana",25,bold=False,italic=False)
quitFont=pygame.font.SysFont("verdana",25,bold=False,italic=False)
#Sets up the title
titleText="Flappy Game"
titlePos=(0,0)
renderTitle=titleFont.render(titleText,1,blue,gray_bgColor)
titlex,titley=titleFont.size(titleText)
screen.blit(renderTitle,titlePos)
#Sets up the start button
startText="Start Game"
startPos=(0,titley)
renderStart=startFont.render(startText,1,blue,gray_bgColor)
startx,starty=startFont.size(startText)
self.start_rect = pygame.Rect(startPos[0],titley,startx,starty)
screen.blit(renderStart,startPos)
#Sets up the quit button
quitText="Quit"
quitPos=(0,starty+titley)
renderQuit=quitFont.render(quitText,1,red,gray_bgColor)
quitx,quity=quitFont.size(quitText)
self.quit_rect = pygame.Rect(quitPos[0],titley+starty,quitx,quity)
screen.blit(renderQuit,quitPos)
def get_click(self):
#Gets mouse click and processes outcomes
for event in pygame.event.get():
if event.type==pygame.MOUSEBUTTONDOWN:
x,y=pygame.mouse.get_pos()
#Tests for start:
if self.start_rect.collidepoint(x,y):
print("start")
return True
elif self.quit_rect.collidepoint(x,y):
print("quit")
sys.exit()
else:
return False
#Assign objects to respective classes
titleC=titleScreen()
graphicsC=graphics()
def showTitle():
#bundles all title_screen functions
screen.blit(graphicsC.background_image,[0,0])
titleC.title()
pygame.display.flip()
def main():
graphicsC.load_images()
while True:
title=True
while title==True:
showTitle()
start=titleC.get_click()
if start==True:
title=False
bird_yPos=200
bird_vY=0
pipe_xPos=500
pipe_height=1
while title==False:
bird_vY,bird_yPos,pipe_xPos,pipe_height=graphicsC.display_loop(bird_vY,bird_yPos,pipe_xPos,pipe_height)
pygame.time.delay(3)
if bird_yPos>=height-120:
title=True
main()
Error:
Traceback (most recent call last):
File "C:\Users\Klaus\Documents\coding\python stuff\pygames\Flappy Python\flappy_bird_source.py", line 162, in <module>
main()
File "C:\Users\Klaus\Documents\coding\python stuff\pygames\Flappy Python\flappy_bird_source.py", line 158, in main
bird_vY,bird_yPos,pipe_xPos,pipe_height=graphicsC.display_loop(bird_vY,bird_yPos,pipe_xPos,pipe_height)
File "C:\Users\Klaus\Documents\coding\python stuff\pygames\Flappy Python\flappy_bird_source.py", line 85, in display_loop
pipe_xPos,pipe_height=self.display_pipe(pipe_xPos,pipe_height)
TypeError: 'int' object is not iterable
display_pipe() returns an integer.
You are trying to assign pipe_xPos,pipe_height to the return value, as if it is a tuple with two elements.
If you want to return the values of pipe_xPos and pipe_height from display_pipe(), then change your return line to:
return pipe_xPos, pipe_height

Categories