pygame:invalid destination position for blit
Question
The wrong info is:
Traceback (most recent call last):
File "C:\Documents and Settings\Administrator.MICRO-C17310A13\桌面\pygame例子\vectorfish.py", line 24, in <module>
screen.blit(sprite, position)
TypeError: invalid destination position for blit
The code is:
background_image_filename = 'sushiplate.jpg'
sprite_image_filename = 'fugu.bmp'
import pygame
from pygame.locals import *
from sys import exit
from vector2 import Vector2
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
background = pygame.image.load(background_image_filename).convert()
sprite = pygame.image.load(sprite_image_filename).convert_alpha()
clock = pygame.time.Clock()
position = Vector2(100.0, 100.0)
speed = 250.0
heading = Vector2()
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == MOUSEBUTTONDOWN:
destination = Vector2(*event.pos) - Vector2(*sprite.get_size())/2.
heading = Vector2.from_points(position, destination)
heading.normalize()
screen.blit(background, (0,0))
screen.blit(sprite, position)
time_passed = clock.tick()
time_passed_seconds = time_passed / 1000.0
distance_moved = time_passed_seconds * speed
position += heading * distance_moved
pygame.display.update()
The code of vector2 is:
import math
class Vector2(object):
def __init__(self, x=0.0, y=0.0):
self.x = x
self.y = y
def __str__(self):
return "(%s, %s)"%(self.x, self.y)
@staticmethod
def from_points(P1, P2):
return Vector2( P2[0] - P1[0], P2[1] - P1[1] )
def get_magnitude(self):
return math.sqrt( self.x**2 + self.y**2 )
def normalize(self):
magnitude = self.get_magnitude()
self.x /= magnitude
self.y /= magnitude
Not only this code,but all the codes that needs vector2 met this question: invalid destination position for blit
am I doing something wrong ?
Any help is much needed.
Gilbert chan
Solution
Surface.blit
expects a tuple
as dest
parameter. if you want to work with your own vector class, change it to this:
class Vector2(tuple):
def __new__(typ, x=1.0, y=1.0):
n = tuple.__new__(typ, (int(x), int(y)))
n.x = x
n.y = y
return n
def __mul__(self, other):
return self.__new__(type(self), self.x*other, self.y*other)
def __add__(self, other):
return self.__new__(type(self), self.x+other.x, self.y+other.y)
def __str__(self):
return "(%s, %s)"%(self.x, self.y)
@staticmethod
def from_points(P1, P2):
return Vector2( P2[0] - P1[0], P2[1] - P1[1] )
def get_magnitude(self):
return math.sqrt( self.x**2 + self.y**2 )
def normalize(self):
magnitude = self.get_magnitude()
self.x /= magnitude
self.y /= magnitude
Now, it's subclassed from tuple
and you can pass it to the blit
function. (Also note that the tuple must contains int
s).
I also added __add__
and __mul__
to have it support addition and multiplication.
This way, no further modifications to your code are required, and you can use your vector class as intended.
OTHER TIPS
Try the following:
screen.blit(sprite, (position.x, position.y))
The problem is that your Vector2 does not have an overload for __iter__
which is an iterator so you can call tuple
on your object. This means that it cannot be converted to a tuple by the blit
function call and thus the parameter is invalid.
Your Vector2 would then contain:
def __iter__(self):
return [self.x, self.y].__iter__()
And your blit would be:
screen.blit(sprite, tuple(position))