1

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.

6
  • 2
    shirtPosition starts off as a list, but you reassign it to a tuple in your onGame loop. Commented Apr 9, 2018 at 9:56
  • @DanielRoseman I see. So once I assign with a tupple it doesn't transform back? But why doesn't that equally happen with chestPosition? Commented Apr 9, 2018 at 9:58
  • visit this stackoverflow.com/questions/7687510/… Commented Apr 9, 2018 at 9:58
  • Visit codereview.stackexchange.com to get tips and suggestions for improvements. Commented Apr 9, 2018 at 10:14
  • 1
    I don't understand why you think it should transform into anything. The reason why you don't have this problem with chestPosition is that you don't have an equivalent method to resetShirtPosition that attempts to mutate it. Commented Apr 9, 2018 at 10:47

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.