Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - PyGame - Learning vectors/animation

So, I'm not the most knowledgeable at math and was hoping to get some much needed feedback. My goal for starters is just to have an image chase my mouse. There are a few things happening that I didn't expect that I'd like feedback on.

1) The chase is very rigid, and follows the mouse in a very... "angular" way, only changes directions at what seems to be set points on the screen (middle x-axis, middle y-axis and diagonals).

2) I want the speed to be a constant, but the image moves faster as it gets closer to the mouse.

3) When the image reaches the mouse, it "slingshots" passed the mouse creating a blurry frenzy instead of reaching the mouse position and stopping.

Those are my main concerns, but if you see anything that I might be misunderstanding PLEASE tell me. I'm dying to understand this whole vector/trigonometry (to soon get into physics) thing.

def follow (self):
    mouse_pos = pygame.mouse.get_pos()
    diff = (self.xPos-mouse_pos[0], self.yPos-mouse_pos[1])
    vector = math.sqrt(diff[0]**2 + diff[1]**2)
    distance = (self.xPos/vector, self.yPos/vector)

    if (self.xPos, self.yPos) == mouse_pos:
        return
    if mouse_pos[0] >= self.xPos:
        self.xPos += distance[0]
    else:
        self.xPos -= distance[0]
    if mouse_pos[1] >= self.yPos:
        self.yPos += distance[1]
    else:
        self.yPos -= distance[1]

(The entire program can be seen here http://ideone.com/6OxWLi)

Thanks in advance for any help!

like image 375
jtsmith1287 Avatar asked Oct 21 '22 20:10

jtsmith1287


1 Answers

I don't know what you meant with your variables vector and distance, but IMO their names should be swapped. In your code, vector is the length of the diff vector, which is calculated using Pythagoras' theorem:

d^2 = dx^2 + dy^2
d = sqrt(dx^2 + dy^2)

In your code, there is the distance variable, which is the position vector, only normalized (divided by its own length). This is why I'd rather swap their names. Also, more interesting would be the diff vector in normalized form. So rather do this:

distance = math.sqrt(diff[0]**2, diff[1]**2) # instead of `vector = ...`
diff_norm = (diff[0] / distance, diff[1] / distance) # instead of `distance = ...`

From now on, every time I write distance, I am assuming you have swapped the names, and mean the distance value, not the normalized vector. Same with vector, which I will call diff_norm from now on (normalized difference vector).

Now, to your problems:

1) and 2) should be better when you use the diff_norm vector (normalized difference vector instead of normalized position vector, which really makes no sense :P).

3) It is very unlikely that your image's position (self.xPos, self.yPos) will be exactly the mouse position at any point. Because you use floating point numbers for your position (python does that for you), they will probably be never exactly on the pixel. So your image will never be exactly at the mouse position. So instead of writing (self.xPos, self.yPos) == mouse_pos, you should rather check if your image's distance to the mouse is really close, e.g. less than 1 or two pixels:

if distance <= 2: return

Also, you don't need all the if/else at the end - the diff_norm vector can have negative values, so you don't need to check if they are negative - just subtract the diff_norm vector from the position vector like so:

self.xPos -= diff[0]
self.yPos -= diff[1]
like image 178
opatut Avatar answered Nov 03 '22 06:11

opatut