Python Forum
while movinig an object how do i keep it inbounds
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
while movinig an object how do i keep it inbounds
#6
You used the relative coordinates. These instructions change the bounding box to be relative to the ship position.
x = max(-self.x ,min(x, 720 - self.x))
y = max(-self.y ,min(y, 400 - self.y))
You should not use 720 and 400. I know I did that in my post, but that was to aid the explanation. In practice you should use variables instead of literals. You already have variables for the size of your canvas (wide and high). Your code should look like this:
x = max(-self.x ,min(x, wide - self.x))
        y = max(-self.y ,min(y, high - self.y))
This code works fine for upper and left, but scrolls off on lower and right, correct? You are bounding the upper left corner of the image to remain on the canvas. You need to take the size of the image into account.
x = max(-self.x ,min(x, wide - self.x - self.imgW))
        y = max(-self.y ,min(y, high - self.y - self.imgH))
Now that I know about canvas.coords() it would be stupid for me to use self.x and self.y to keep track of the ship. The canvas is going to do that, and do a better job. The same goes for knowing about canvas.moveto() and using relative coordinates. The canvas reports the absolute position of the ship and it is easier to clip position to a static, non-relative bounding box. It only makes sense to specify the ship's position in absolute coordinates. I'd still have the x, y in Ship.move(x, y) be relative to the ship, but everything else just works easier in absolute.
def clip(x, lower, upper):
    """Clip value to be in range lower..upper"""
    return lower if x < lower else upper if x > upper else x

    def move(self, x, y):
        # Convert to absolute coordinates and clip to range
        imgx, imgy = self.canvas.coords(self.id)
        x = clip(x + imgx, 0, wide - self.imgW)
        y = clip(y + imgy, 0, high - self.imgH)
        self.canvas.moveto(self.id, x, y)
Yesterday I ran across a post talking about the fastest way to clip a value to a range in Python. The if..elif approach was fastest by far. Twice as fast as using max(..min(..)). Even after wrapping it in a function it is still faster. I also think a function named "clip" with a docstring is easier to understand than the max(..min(..)) thing.
Reply


Messages In This Thread
RE: while movinig an object how do i keep it inbounds - by deanhystad - Feb-17-2021, 11:31 PM

Forum Jump:

User Panel Messages

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