Python Forum
[PyGame] TypeError: unsupported operand type(s) for -: 'int' and 'instancemethod'
Thread Rating:
  • 2 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] TypeError: unsupported operand type(s) for -: 'int' and 'instancemethod'
#1
I'm trying to program a snake that's controlled by WASD keys and has collision detection. I also want it to turn in the direction it's moving. If you see any bugs or ways to optimize my code, please tell me. I'm getting this error:
File "C:\Users\asay_915876\Desktop\python\good\main.py", line 73, in <module>
x = width/2-snek.snek_width
TypeError: unsupported operand type(s) for -: 'int' and 'instancemethod'

Here's the code:
# -*- coding: utf-8 -*-
import pygame
from pygame.locals import *
from pygame.time import *
import os, sys
import time
import math


image_resources = "C:/Users/asay_915876/Desktop/Python/good/images/"

width,height = 680,512
size = (width,height)
FPS = 70

class GetSource:
    def snek(self,image):
        return pygame.image.load(image_resources + image).convert_alpha()
    def wall(self,image):
        return pygame.image.load(image_resources + image).convert()

class border(pygame.sprite.Sprite):
    def __init__(self,color,x,y,width,height):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((width,height))
        self.image.fill(pygame.color.Color(color))
        self.image = self.image.get_width()
        self.image = self.image.get_height()
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

class snek(pygame.sprite.Sprite):

    def __init__(self,image):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('snek.jpg')
        snek_width = get_width
        snek_height = get_height
        self.rect = self.image.get_rect()
        self.x = 340
        self.y = 256

    def snek_width(self, width):
        snek_width = get_width

    def snek_height(self, width):
        snek_height = get_height


    def handle_keys(self):
        key = pygame.key.get_pressed()
        speed = 4
        if key[pygame.K_w]:
            self.y -= speed
        if key[pygame.K_s]:
            self.y += speed
        if key[pygame.K_d]:
            self.x += speed
        if key[pygame.K_a]:
            self.x -= speed

    def draw(self, Surface):
        self.image.blit(snek, (self.x, self.y))

    def update(self, time):
        self.angle = math.atan2(-self.dx, -self.dy)/math.pi*180.0
        self.image = pygame.transform.rotozoom(self.image0,self.angle,1.0)

pygame.init()

screen = pygame.display.set_mode(size)
x = width/2-snek.snek_width
y = height/2-snek.snek_height
snek = snek()
Clock = pygame.time.Clock()
pygame.display.set_caption('lit')


running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False

    snek.handle_keys()
    screen.fill((255,255,255))
    snek(x,y)
    snek.draw(screen)
    pygame.display.update()

    pygame.display.update()
    Clock.tick(FPS)
Reply
#2
In line 38 you define the attribute sneek_width without any effect, because it's not bound to the instance nor to the class. In line 44 you define a method sneek_width of the class snek. Later you try to divide an integer with an instance method. You've forgotten to call the instance method.

But from where comes get_width? It looks for me like brute force programing with copied and pasted code.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
(Oct-05-2017, 05:45 PM)DeaD_EyE Wrote: In line 38 you define the attribute sneek_width without any effect, because it's not bound to the instance nor to the class. In line 44 you define a method sneek_width of the class snek. Later you try to divide an integer with an instance method. You've forgotten to call the instance method.

But from where comes get_width? It looks for me like brute force programing with copied and pasted code.

I'm really new to python, so I was following a tutorial about how to use collision detection, but I already had been writing my own code, so I tried to implement collision detection into my code based on the code in the tutorial. How do I bind it to the instance or class? How do I call the instance method? Sorry about the stupid questions. I'm a noob.
Reply
#4
A function defined in the class is already bound to the instance.  You call it just as you would any function, with parentheses.
>>> class Spam:
...   def __init__(self, foo):
...     self.bar = foo
...   def quz(self):
...     print("I'm an instance method!")
...     return self.bar
...
>>> thing = Spam(42)
>>> thing.quz()
I'm an instance method!
42
Reply
#5
Quote:If you see any bugs or ways to optimize my code, please tell me.
as side notes...

Quote:
class snek(pygame.sprite.Sprite):
 
    def __init__(self,image):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('snek.jpg')
In this case its fine because there is only one, but usually you do not want to load the images within the class constructor as "enemies" for example could spawn in unlimited numbers. You would only want to load the image once.

Quote:
        self.x = 340
        self.y = 256
    def draw(self, Surface):
        self.image.blit(snek, (self.x, self.y))
You should utilize pygame.Rect for the positioning as pygame Rect's have methods to handle collision detection implemented already. You do create a rect attribute (self.rect) but never use it and even bypass it by positioning your own y and x attributes when Rect already contains that.
Recommended Tutorials:
Reply
#6
(Oct-05-2017, 06:29 PM)nilamo Wrote: A function defined in the class is already bound to the instance.  You call it just as you would any function, with parentheses.
>>> class Spam:
...   def __init__(self, foo):
...     self.bar = foo
...   def quz(self):
...     print("I'm an instance method!")
...     return self.bar
...
>>> thing = Spam(42)
>>> thing.quz()
I'm an instance method!
42

Thanks, but how could I use this in my code?

(Oct-05-2017, 06:59 PM)metulburr Wrote:
Quote:If you see any bugs or ways to optimize my code, please tell me.
as side notes...

Quote:
class snek(pygame.sprite.Sprite):
 
    def __init__(self,image):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('snek.jpg')
In this case its fine because there is only one, but usually you do not want to load the images within the class constructor as "enemies" for example could spawn in unlimited numbers. You would only want to load the image once.

Quote:
        self.x = 340
        self.y = 256
    def draw(self, Surface):
        self.image.blit(snek, (self.x, self.y))
You should utilize pygame.Rect for the positioning as pygame Rect's have methods to handle collision detection implemented already. You do create a rect attribute (self.rect) but never use it and even bypass it by positioning your own y and x attributes when Rect already contains that.

Thanks. I'll do that.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] PLEASE HELP! TypeError: unsupported operand type(s) for +: 'pygame.Surface' and 'int' keyfive 1 5,242 Jun-19-2018, 01:20 PM
Last Post: volcano63

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020