0

I am attempting to create a game in which a block moves back and forth until the player presses space. Upon which, the block jumps to the next line up and stops.

Currently i am having problems with the collision code.

The error being thrown up by the shell is:

    if doRectsOverlap(j['rect'], floors['line']):
TypeError: list indices must be integers, not str

I am stuck with understanding where my code has gone wrong. My knowledge of how python works is very limited.

There is also code i have commented out to do with the floor moving dowards when the player jumps. it has been commented out until i can get the collisions working, but still included

Code Below:

import pygame, sys, time
from pygame.locals import *


def doRectsOverlap(rect1, rect2):
    for a, b in [(rect1, rect2), (rect2, rect1)]:
        # Check if a's corners are inside b
        if ((isPointInsideRect(a.left, a.top, b)) or
            (isPointInsideRect(a.left, a.bottom, b)) or
            (isPointInsideRect(a.right, a.top, b)) or
            (isPointInsideRect(a.right, a.bottom, b))):
            return True

    return False

def isPointInsideRect(x, y, rect):
    if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom):
        return True
    else:
        return False

# set up pygame
pygame.init()
mainClock = pygame.time.Clock()

# set up the window
WINDOWWIDTH = 480
WINDOWHEIGHT = 800
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Jumper')

#Directions
LEFT = 4
RIGHT = 6
UP = 8
DOWN = 2
STILL = 5

#blocks location for jumping
#BLOCKLOCY = 700

#Binary for stopping movement
#STOPPER = 0

MOVESPEED = 1

# set up the colors
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)


j = {'rect':pygame.Rect(240, 700, 20, 20), 'color':GREEN, 'dir':LEFT, 'jump':STILL}


f1 = {'line':pygame.Rect(0,720,480,2), 'color':GREEN, 'dir':STILL}
f2 = {'line':pygame.Rect(0,650,480,2), 'color':GREEN, 'dir':STILL}
floors = [f1,f2]

# run the game loop
while True:
    # check for the QUIT event
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()



    # draw the black background onto the surface
    windowSurface.fill(BLACK)


        # move the block data structure
    if j['dir'] == LEFT:
        j['rect'].left -= MOVESPEED
    if j['dir'] == RIGHT:
        j['rect'].left += MOVESPEED

    if j['jump'] == UP:
        j['rect'].bottom -= MOVESPEED
        #BLOCKLOCY -= MOVESPEED

    if j['rect'].left < 0:
        j['dir'] = RIGHT
    if j['rect'].left > WINDOWWIDTH-j['rect'].width:
        j['dir'] = LEFT

    if event.type == KEYDOWN:
        if event.key == K_SPACE:
            j['jump'] = UP

    if doRectsOverlap(j['rect'], floors['line']):
        j['jump'] = STILL



#Floor controll code for moving level - not working currently
   # for f in floors:
        #if f['dir'] == DOWN:
          #  f['line'].y += MOVESPEED

      #  if event.type == KEYDOWN:
          #  if event.key == K_SPACE:
              # f['dir'] = DOWN

     #   if f['line'].top == BLOCKLOCY:
      #      f['dir'] = STILL
       #     STOPPER = 1

        #if f['line'].bottom == BLOCKLOCY:
         #   f['dir'] = STILL
          #  STOPPER = 1




        # draw the block onto the surface
        pygame.draw.rect(windowSurface, j['color'], j['rect'])

        pygame.draw.rect(windowSurface, f['color'], f['line'])


    # draw the window onto the screen
    pygame.display.update()
    mainClock.tick(40)
2
  • Are you sure about the if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom): condition ? I think it should be rather y < rect.top and y > rect.bottom. Commented Apr 29, 2015 at 15:12
  • A lot of it is because it's code i am using from inventwithpython.com to learn Python. Once i can get it to work, am going to skim down the code as needed Commented Apr 29, 2015 at 15:23

1 Answer 1

1

You are creating floors as a list:

f1 = {'line':pygame.Rect(0,720,480,2), 'color':GREEN, 'dir':STILL}
f2 = {'line':pygame.Rect(0,650,480,2), 'color':GREEN, 'dir':STILL}
floors = [f1,f2]

So when you call:

if doRectsOverlap(j['rect'], floors['line']):
    j['jump'] = STILL

You're message is telling you that you need an index as an int:

for n in range(len(floors)):
    if doRectsOverlap(j['rect'], floors[n]['line']):
       j['jump'] = STILL
Sign up to request clarification or add additional context in comments.

7 Comments

doRectsOverlap(j['rect'], floors[n]['line']), doRectsOverlap expects 2 rectangles.
sorry, do i need to replace the [n] with a each of the numbers in a list like how Tijko had originally?
if you iterate over a range of length of the floors - for n in range(len(floors)): you can use n just as above.
okay, now it's throwing a new error which i don't understand at all. pygame.draw.rect(windowSurface, f['color'], f['line']) NameError: name 'f' is not defined
Well, I understand what it is saying, but i don't understand why it's been thrown. Surely f was defined back when i made the list?
|

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.