Disclaimer: I have no knowledge of PyGame.

I think your original is a lack of checking types. You are calling 
BlueCar/GreenCar/Truck.collide regardless  of the car type. If you pass a 
TruckSprite to BlueCarSprite.collide it makes sense (without knowledge of 
PyGame) that it would fail because it expects a BlueCarSprite not a TruckSprite.

You do:
crash = pygame.sprite.spritecollide(playerCar, computerSprites, False)


        if crash:
            for BlueCarSprite in crash: # This loops through crash
                redracersprites26.BlueCarSprite.collide(crash, playerCar)
            for GreenCarSprite in crash: # This loops through crash again
                redracersprites26.GreenCarSprite.collide(crash, playerCar)
            for TruckSprite in crash: # This loops through crash for the third 
time
                redracersprites26.TruckSprite.collide(crash, playerCar)


There are two other problems with this: 1) this is sending the entire list of 
collisions to each of these functions. 2) The way you are looping seems odd to 
me.
I would think you want something more like the following (UNTESTED):

crash = pygame.sprite.spritecollide(playerCar, computerSprites, False)
if crash:
    for car in crash:
        if isinstance(car, BlueCar):
            redracersprices26.BlueCarSprite.collide(car, playerCar)
        if isinstance(car, GreenCar):
            redracersprices26.GreenCarSprite.collide(car, playerCar)
        if isinstance(car, TruckCar):
            redracersprices26.TruckCarSprite.collide(car, playerCar)

If you really want to call all 3 collide statements, then just remove the 'if 
isinstance(car, \w*):' line and it will call the collide for each.


Ramit



Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

From: tutor-bounces+ramit.prasad=jpmchase....@python.org 
[mailto:tutor-bounces+ramit.prasad=jpmchase....@python.org] On Behalf Of Greg 
Nielsen
Sent: Monday, April 25, 2011 4:37 AM
To: Steven D'Aprano
Cc: tutor@python.org
Subject: Re: [Tutor] Unbound Method Error

First and foremost, thank you Steven for your quick and well written response. 
It means a lot to me that you took the time out of your day to answer my 
question, and it has really helped me better understand what it going on.

So the full trace back for my error is as follows:

Traceback (most recent call last):
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 
26\src\redracer26.py", line 19, in <module>
    main()
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 
26\src\redracer26.py", line 16, in main
    redracerstates26.game(startLives)
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 
26\src\redracerstates26.py", line 87, in game
    redracersprites26.BlueCarSprite.collide(BlueCarSprite, playerCar)
TypeError: unbound method collide() must be called with BlueCarSprite instance 
as first argument (got GreenCarSprite instance instead)
After reading through your explanation of unbound methods (and wrapping my head 
around the concept), I came up with a quick fix that lead to a new issue in my 
code. Here is what I think should work:

crash = pygame.sprite.spritecollide(playerCar, computerSprites, False)
        if crash:
            for BlueCarSprite in crash:
                redracersprites26.BlueCarSprite.collide(crash, playerCar)
            for GreenCarSprite in crash:
                redracersprites26.GreenCarSprite.collide(crash, playerCar)
            for TruckSprite in crash:
                redracersprites26.TruckSprite.collide(crash, playerCar)

However, the spritecollide method returns a list, which my collide method isn't 
expecting. The list should only contain the name of the sprite the player hit. 
In Python 3, the method would just pull the variable out of the list and work 
with it, but in Python 2, it's not expecting a list, causing an error similar 
to the one seen previously:

Traceback (most recent call last):
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 
26\src\redracer26.py", line 19, in <module>
    main()
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 
26\src\redracer26.py", line 16, in main
    redracerstates26.game(startLives)
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 
26\src\redracerstates26.py", line 87, in game
    redracersprites26.BlueCarSprite.collide(crash, playerCar)
TypeError: unbound method collide() must be called with BlueCarSprite instance 
as first argument (got list instance instead)
So what really has to happen now (I think) is that the list needs to be 
unpacked into just a simple variable containing the name of the sprite in 
question. This way the method receives the name of the instance (self) in the 
way it was expecting to receive it. In your opinion, should I unpacked the list 
before passing the data into the method, or attempt to define "self" as a list? 
Is the latter even possible? I would think it would have to be because 
otherwise Python could pick a variable type which you don't want or aren't 
expecting it to pick and need to force it to take a certain type of input.

And thank you for pointing out the fact I could just make a CarSprite class and 
have subclasses (basically just a different sprite image) work with the 
details. You just removed over 150 lines of redundant code from my program. And 
once again, thank you Steven for taking the time to help me better understand 
the whole unbound method concept.

Greg


This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.

This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.

Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to European legal entities.
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to