Sean
Sean

Reputation: 23

I am getting an attribute error for an attribute defined inside the class. How can I fix this?

This is the error I'm getting:

 File "/home/ore/PycharmProjects/testing grounds/venv/Moses and the Snakes.py", line 209, in <module>
    if stick.y - stick.radius < snake.the_hitbox[1] + snake.the_hitbox[3] and stick.y + stick.radius > snake.the_hitbox[1]:
AttributeError: type object 'snake' has no attribute 'the_hitbox'

This is my all my relevant code:

class snake(object):
    rle_slither = [pygame.image.load(os.path.join(path, 'pixil-frame-2(3).png')),
                   pygame.image.load(os.path.join(path, 'pixil-frame-1(3).png')),
                   pygame.image.load(os.path.join(path, 'pixil-frame-0(4).png'))]
    lle_slither = [pygame.transform.flip(pygame.image.load(os.path.join(path, 'pixil-frame-2(3).png')), True, False),
                   pygame.transform.flip(pygame.image.load(os.path.join(path, 'pixil-frame-1(3).png')), True, False),
                   pygame.transform.flip(pygame.image.load(os.path.join(path, 'pixil-frame-0(4).png')), True, False)]

    def __init__(self, x, y, wid, len, end):
        self.x = x
        self.y = y
        self.wid = wid
        self.len = len
        self.end = end
        self.path = [self.x, self.end]
        self.walk_count = 0
        self.speed = 15
        self.the_hitbox = (self.x, self.y + 5, 78, 25)

    def movement(self):
        if self.speed > 0:
            if self.x + self.speed < self.path[1]:
                self.x += self.speed
            else:
                self.speed = self.speed * -1
                self.walk_count = 0
        else:
            if self.x - self.speed > self.path[0]:
                self.x += self.speed
            else:
                self.speed = self.speed * -1
                self.walk_count = 0

    def animate(self, screen):
        self.movement()
        if self.walk_count + 1 >= 9:
            self.walk_count = 0
        if self.speed > 0:
            screen.blit(self.rle_slither[self.walk_count // 3], (self.x, self.y))
            self.walk_count += 1
        else:
            screen.blit(self.lle_slither[self.walk_count // 3], (self.x, self.y))
            self.walk_count += 1
        self.the_hitbox = (self.x, self.y + 5, 78, 25)
        pygame.draw.rect(screen, (150, 0, 0), self.the_hitbox, 2)

    def got_hit(self):
        print("Snake was hit!")
    for stick in staff_list:
        if stick.y - stick.radius < snake.the_hitbox[1] + snake.the_hitbox[3] and stick.y + stick.radius > snake.the_hitbox[1]:
            if stick.x + stick.radius > snake.the_hitbox[0] and stick.x - stick.radius < snake.the_hitbox[0] - snake.the_hitbox[2]:
                snake.got_hit()
                staff_list.reomve(stick)

Upvotes: 0

Views: 43

Answers (1)

adrianp
adrianp

Reputation: 1019

Replace snake with self. snake is the name of the class, while self is the reference to instances of that class.

Three things wrong with this code:

  1. You are trying to use the snake class in its own definition block (because of the indents in your for loop at the very bottom)
  2. You are trying to use the name of the class as an instance of that class. Doing so will replace the class definition after you just instantiate one instant.
  3. You never created an instance of snake. As a rule of thumb, you should name classes using PascalCase in order to easily differentiate them from class instances.

See below for fix:

# Pascal case
class Snake(object):
    rle_slither = [pygame.image.load(os.path.join(path, 'pixil-frame-2(3).png')),
                   pygame.image.load(os.path.join(path, 'pixil-frame-1(3).png')),
                   pygame.image.load(os.path.join(path, 'pixil-frame-0(4).png'))]
    lle_slither = [pygame.transform.flip(pygame.image.load(os.path.join(path, 'pixil-frame-2(3).png')), True, False),
                   pygame.transform.flip(pygame.image.load(os.path.join(path, 'pixil-frame-1(3).png')), True, False),
                   pygame.transform.flip(pygame.image.load(os.path.join(path, 'pixil-frame-0(4).png')), True, False)]

    def __init__(self, x, y, wid, len, end):
        self.x = x
        self.y = y
        self.wid = wid
        self.len = len
        self.end = end
        self.path = [self.x, self.end]
        self.walk_count = 0
        self.speed = 15
        self.the_hitbox = (self.x, self.y + 5, 78, 25)

    def movement(self):
        if self.speed > 0:
            if self.x + self.speed < self.path[1]:
                self.x += self.speed
            else:
                self.speed = self.speed * -1
                self.walk_count = 0
        else:
            if self.x - self.speed > self.path[0]:
                self.x += self.speed
            else:
                self.speed = self.speed * -1
                self.walk_count = 0

    def animate(self, screen):
        self.movement()
        if self.walk_count + 1 >= 9:
            self.walk_count = 0
        if self.speed > 0:
            screen.blit(self.rle_slither[self.walk_count // 3], (self.x, self.y))
            self.walk_count += 1
        else:
            screen.blit(self.lle_slither[self.walk_count // 3], (self.x, self.y))
            self.walk_count += 1
        self.the_hitbox = (self.x, self.y + 5, 78, 25)
        pygame.draw.rect(screen, (150, 0, 0), self.the_hitbox, 2)

    def got_hit(self):
        print("Snake was hit!")

# Assuming staff_list is defined

# Instantiate a new Snake() instance and call it `snake`
snake = Snake()

for stick in staff_list:
    if stick.y - stick.radius < snake.the_hitbox[1] + snake.the_hitbox[3] and stick.y + stick.radius > snake.the_hitbox[1]:
        if stick.x + stick.radius > snake.the_hitbox[0] and stick.x - stick.radius < snake.the_hitbox[0] - snake.the_hitbox[2]:
            snake.got_hit()
            staff_list.reomve(stick)

Upvotes: 2

Related Questions