Reputation: 1017
I am having trouble updating the mouse position and checking for entity collisions (between the mouse and entity) due to my level scrolling. I have used the camera function from this question: How to add scrolling to platformer in pygame
I have tried to use the camera function on the mouse like this:
def update(self, target, target_type, mouse):
if target_type != "mouse":
self.state = self.camera_func(self.state, target.rect)
else:
new_pos = self.camera_func(mouse.rect, target.rect)
mouse.update((new_pos[0], new_pos[1]))
print mouse.rect
but the mouse.rect is consistently set to 608, 0
. Can someone help me with this? The mouse class looks like this:
class Mouse(Entity):
def __init__(self, pos):
Entity.__init__(self)
self.x = pos[0]
self.y = pos[1]
self.rect = Rect(pos[0], pos[1], 32, 32)
def update(self, pos, check=False):
self.x = pos[0]
self.y = pos[1]
self.rect.top = pos[1]
self.rect.left = pos[0]
if check:
print "Mouse Pos: %s" %(self.rect)
print self.x, self.y
Everytime I click the screen, and pass it through a collision test, it always uses the point on the screen, however I need the point on the map (if that makes sense). For example, the screen size is 640x640
. If I click in the top left corner, the mouse position will always be 0,0
however, the actual map coordinates may 320,180
in the top corner of the screen. I have attempted to update everything with the camera and the mouse, and the only real results are when I apply the camera.update
function to the mouse, but this stop the player being the cause of the scrolling, so I therefore attempted to update the mouse.rect
with this function.
Attempted code:
mouse_pos = pygame.mouse.get_pos()
mouse_offset = camera.apply(mouse)
pos = mouse_pos[0] + mouse_offset.left, mouse_pos[1] + mouse_offset.top
mouse.update(mouse_pos)
if hit_block:
print "Mouse Screen Pos: ", mouse_pos
print "Mouse Pos With Offset: ", pos
print "Mouse Offset: ", mouse_offset
replace_block(pos)
Upvotes: 1
Views: 1254
Reputation: 101122
The camera calculates the screen coordinate by a given world coordinate.
Since the mouse position is already a screen coordinate, if you want to get the tile under the mouse, you have to substract the offset, not add it.
You can add the following method to the Camera
class:
def reverse(self, pos):
"""Gets the world coordinates by screen coordinates"""
return (pos[0] - self.state.left, pos[1] - self.state.top)
and use it like this:
mouse_pos = camera.reverse(pygame.mouse.get_pos())
if hit_block:
replace_block(mouse_pos)
Upvotes: 1
Reputation: 7511
When you read the mouse that's screen coordinates. Since you're scrolling, you need world coordinates to check the collisions.
Your render loop simplifies to
# draw: x+offset
for e in self.entities:
screen.draw(e.sprite, e.rect.move(offset))
which is the same as draw( world_to_screen( e.rect ))
Your click would be collidepoint( screen_to_world( pos ))
# mouseclick
pos = event.pos[0] + offset.left, event.pos[1] + offset.top
for e in self.entities:
if e.collidepoint(pos):
print("click:", pos)
Upvotes: 2