Python int object is not subscriptable

2.9k Views Asked by At

I'm currently trying to implement my own SAT (separating axis theorem) collision detection system but have run into an issue. On line 34 I'm getting this error message:

line 34, in collision axis = (v[1], -v[0]) TypeError: 'int' object is not subscriptable

The weird thing is that v is not an int, it's a tuple.

Here's the code

import math
import pygame

WIDTH = 900
HEIGHT = 700

pygame.init()

screen = pygame.display.set_mode((WIDTH, HEIGHT))

clock = pygame.time.Clock()

def dot(v1, v2):
    return v1[0]*v2[0] + v1[1]*v2[1]

polygons = []

class Polygon():
    def __init__(self, points):
        self.points = points
        self.vectors = []
        for p1 in range(len(self.points)):
            p2 = p1 + 1
            if p2 > len(self.points) - 1:
                p2 = 0
            v = (self.points[p2][0] - self.points[p1][0], self.points[p2][1] - self.points[p1][1])#int object not subscriptable
            self.vectors.append(v)
        polygons.append(self)
    def collision(self):
        for p in polygons:
            collision = True
            if p.points != self.points:
                for v in range(len(p.vectors)):
                    axis = (v[1], -v[0])
                    selfFirst = True
                    pFirst = True
                    for point in self.points:
                        if selfFirst == True:
                            selfFirst = False
                            projection = dot(point, axis)
                            selfMin = projection
                            selfMax = projection
                        else:
                            projection = dot(point, axis)
                            if projection < selfMin:
                                selfMin = projection
                            elif projection > selfMax:
                                selfMax = projection
                    for point in p.points:
                        if pFirst == True:
                            pFirst = False
                            projection = dot(point, axis)
                            pMin = projection
                            pMax = projection
                        else:
                            projection = dot(point, axis)
                            if projection < pMin:
                                pMin = projection
                            elif projection > pMax:
                                pMax = projection
                    if (selfMin > pMin and selfMin < pMax) or (selfMax > pMin and selfMax < pMax):
                        collision = True
                    else:
                        collision = False
                        return collision

polygon1 = Polygon([(0, 0), (100, 100), (0, 100)])
polygon2 = Polygon([(300, 300), (150, 0), (0, 150)])

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill((0,0,0))

for polygon in polygons:
    polygon.collision()
    pygame.draw.polygon(screen, (0, 255, 0), polygon.points, 1)

        pygame.display.flip()
        clock.tick(60)


    pygame.display.quit()

The problem is on line 34

2

There are 2 best solutions below

0
hipoglucido On

So the v inside your loop is an integer, and it doesnt make sense to access to the first/second position of an integer (thats what you do when the v[1], -v[0] thing) hence you get that error about subscriptable things.

In:

for v in range(len(p.vectors)):
        axis = (v[1], -v[0])

the range returns a list of integers, because you passed another integer as parameter to it (len(p.vectors)). Don't really know what p.vectors is, I assume is a list of obects v that may have positions 0 and 1 on them, so then maybe this will work:

for v in p.vectors:
        axis = (v[1], -v[0])
0
Mark On

This is an object lesson in variable naming.

In line 27 you assign v in __init__() to: v = (self.points[p2][0] - self.points[p1][0], self.points[p2][1] - self.points[p1][1])

Then in the loop you reassign it and clobber you previous assignment: for v in range(len(p.vectors)):

len() returns an integer and range() returns a list of integers. So with each loop v is assigned an integer from that range. Hence v is now an integer and not subscriptable.

Maybe something like: for v in p.vectors: would work better for you.