0

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

5
  • 2
    for v in range(len(p.vectors)): this is a list of int's the v you are looking at is an int Commented Nov 4, 2016 at 16:35
  • 1
    which line is 34 ? Commented Nov 4, 2016 at 16:35
  • in v you have number - ie. 123 - so you try to do axis = (123[1], -123[0]). Maybe you need axis = (p.vectors[v][1], -p.vectors[v][0]) Commented Nov 4, 2016 at 16:37
  • Okay, I fixed that part, getting some bugs elsewhere but I'll try to fix those myself. thanks. Should I close this down or what? this is my first post. Commented Nov 4, 2016 at 17:33
  • Hey, I would really appreciate if you could validate my answer, if it was useful. Thanks. Commented Nov 7, 2016 at 17:13

2 Answers 2

1

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])
Sign up to request clarification or add additional context in comments.

Comments

0

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.

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.