1

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)
Community
  • 1
  • 1
GoodPie
  • 967
  • 3
  • 23
  • 41

2 Answers2

2

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)
ninMonkey
  • 7,211
  • 8
  • 37
  • 66
  • I added my code to the actual answer and there seems to be an issue where the offset begins decreasing as it goes past the screen height or width – GoodPie Jul 17 '13 at 14:33
  • 1
    If you paste your full code to pastebin (So I can run it) I can take a look. – ninMonkey Jul 17 '13 at 17:01
  • 1
    @ReallyGoodPie Instead of just posting the code, maybe you want to check-in the code into a public repository (on GitHub/BitBucket/etc.) with images included, so it would be easy for others to just check-out and run your code. If you don't use source control, better start using it now. – sloth Jul 18 '13 at 11:23
  • I meant to add the link, but must have got caught up :/ my bad :/ – GoodPie Jul 18 '13 at 11:33
1

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)
sloth
  • 99,095
  • 21
  • 171
  • 219