Reputation: 177
I'm creating my first game using Python and Pygame. It consists on objects falling to the ground and an object controlled by the player catching them. However, It gives me an Exception when the falling object hits the ground:
Traceback (most recent call last):
File "/home/me/Chest/game.py", line 79, in <module>
resetShirtPosition()
File "/home/me/Chest/game.py", line 35, in resetShirtPosition
shirtPosition[0] = random.randint(0, DISPLAY_WIDTH - shirt_size[0])
TypeError: 'tuple' object does not support item assignment
Seems like it doesn't allow the vector to change by index. Which I find odd because I'm not assigning shirtPosition
with a tuple but with a list
. Besides that I'm changing the chestPosition
the same way and it moves without crashing.
Here is my code:
import pygame, random, os
pygame.init()
DISPLAY_WIDTH, DISPLAY_HEIGHT = 1600, 900
clock = pygame.time.Clock()
gamedisplay = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
chest_imag = pygame.image.load(os.path.join("catcher.png"))
shirt_red = pygame.image.load(os.path.join("shirt_red.png"))
background = pygame.image.load(os.path.join("background.png"))
shirt_blue = pygame.image.load(os.path.join("shirt_blue.png"))
shirt_green = pygame.image.load(os.path.join("shirt_green.png"))
shirt = shirt_blue
chest_size = chest_imag.get_size()
chestPosition = [DISPLAY_WIDTH / 2, DISPLAY_HEIGHT - chest_size[1]]
shirt_blue_size = shirt_blue.get_size()
shirt_size = shirt_blue_size
shirtPosition = [random.randint(0, DISPLAY_WIDTH - shirt_size[0]), 0]
dX, dY = 0, 20
score = 0
fallWidth = fallHeight = 100
COLLISION_LEVEL_LINE = DISPLAY_HEIGHT - chest_size[1]
onGame = True
collide = False
# **************** Exception happens here *******************
def resetShirtPosition():
shirtPosition[0] = random.randint(0, DISPLAY_WIDTH - shirt_size[0])
shirtPosition[1] = 0
def hitCollisionLevelLine():
return (shirtPosition[1] + shirt_size[1]) >= COLLISION_LEVEL_LINE
def hitGround():
return (shirtPosition[1] + shirt_size[1]) >= DISPLAY_HEIGHT
def hitHorizontalEdge():
willTouchLeftEdge = (chest_size[0] + dX) < 0
willTouchRightEdge = (chest_size[0] + dX) > (DISPLAY_WIDTH - chest_size[0])
return willTouchLeftEdge or willTouchRightEdge
def collides():
touchFromLeft = shirtPosition[0] > (chestPosition[0] - shirt_size[0])
touchFromRight = shirtPosition[0] < (chestPosition[0] + chest_size[0])
return touchFromLeft and touchFromRight
while onGame:
clock.tick(60)
# action
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
dX = -20
elif event.key == pygame.K_d:
dX = 20
elif event.type == pygame.KEYUP:
dX = 0
elif event.type == pygame.QUIT:
onGame = false
# logic
if hitCollisionLevelLine():
hasCollided = collides()
if hasCollided:
collide = False
score = score + 1
print score
resetShirtPosition()
if hitGround():
resetShirtPosition()
if hitHorizontalEdge():
dX = 0
# update positions and draw
chestPosition = (chestPosition[0] + dX, chestPosition[1])
shirtPosition = (shirtPosition[0], shirtPosition[1] + dY)
gamedisplay.blit(background , (0, 0))
gamedisplay.blit(shirt_blue, shirtPosition)
gamedisplay.blit(chest_imag, chestPosition)
pygame.display.flip()
I've posted all my code because I'd also like if you could hand me some tips to improve it, from code writting to improve-performance tricks. For example, I'm thinking about putting my images in a Dictionary and get them by its key (name). Thank you.
Upvotes: 1
Views: 80
Reputation: 660
On the following line :
shirtPosition = (shirtPosition[0], shirtPosition[1] + dY)
you have reassigned shirtPosition as a tuple, this is causing your problem. Do convert this into a list object instead and your issue will be resolved.
Upvotes: 3