3
\$\begingroup\$

Based on my understanding of Verlet integration I tryed to use it over my Euler method to move my character in a 2D space. I will put only the neccessery code, but if anything else is needed I will edit my post.

This is my Character class (which I probably need to rename to Charactor)

class PlayerData(object):
    def __init__(self):
        self.applied_force = Vector(0, 0)
        self.mass = 70 /killograms
        self.position = Vector(15, 200)
        self.old_position = Vector(self.position.x, self.position.y)
        self.acceleration = Vector(self.applied_force.x / self.mass, 0)

    # These methods seems smelly
    def on_left_key_pressed(self):
        self.applied_force.x = -200
        self.old_position.x = self.position.x + 3
    def on_right_key_pressed(self):
        self.applied_force.x = 200
        self.old_position.x = self.position.x - 3
    def on_left_key_released(self):
        self.applied_force.x = 0
        self.old_position.x = self.position.x
    def on_right_key_released(self):
        self.applied_force.x = 0
        self.old_position.x = self.position.x
    def keys_up(self):
        self.applied_force = Vector(0, 0)
        self.old_position = Vector(self.position.x, self.position.y)

    def verlet(self, dt):
        self.acceleration = Vector(self.applied_force.x / self.mass, 0)
        temp = Vector(self.position.x, self.position.y)

        self.position.x += self.position.x - self.old_position.x + \
                           self.acceleration.x * dt * dt

        self.old_position = Vector(temp.x, temp.y)

    def update(self, dt):
        self.verlet(dt)
        // here be a collision detection method which I need to write
        self.rect.left = self.position.x
        self.rect.top = self.position.y

And this is the Event class which has 2 main methods - listener and handler

class EventManager(object):
    def __init__(self, player):
        self.player = player
        # few bools to indicate key states, the listener method toggles them

    def handler(self):
        ''' Calls Player on_x_key_pressed(), on_x_key_released()
        methods according to event bools set from the listener method.
        '''
        # Moving
        if self.left:
            self.player.on_left_key_pressed()
        elif self.right:
            self.player.on_right_key_pressed()
        else:
            self.player.on_keys_up()

I have jumping but I'm still trying to understand the right aproach to writing a proper verlet integration method. I can controll how fast my object is moving by setting the self.old_position.x = self.position.x + 3 to self.old_position.x = self.position.x + 20 for example. This also stops the movement, but I truly suspect that this is incorect or simply a very bad aproach.

EDIT: Redesigned the event handler method and shortened the bool names for simplicity. I have no problems running the code, it is working as intented. The thing I dont like is how my on_x_key_pressed() methods look, you can find them in PlayerData class. I have the feeling that, to stop my character from continues move in some direction I have to set old_position.x = position.x. Is this the right aproach to stop character movement? And to control how fast the object is moving (the velocity), I have to manually set old_position to some value bigger/lower than position.x as seen in on_left_key_pressed() and on_right_key_pressed(). I wonder if there is better aproach to control the velocity?

\$\endgroup\$
  • \$\begingroup\$ Hello! Does your code work? The question is currently unclear. We cannot really help with the integration method per se, but can help to get cleaner code. For example, simplifying your ifs in the EventManager class. \$\endgroup\$ – Quentin Pradet Feb 26 '14 at 8:52
  • \$\begingroup\$ @QuentinPradet My biggest issue is that I'm not sure how to start/end the movement of my character, through on_key_press methods in the Player class. Thank's for the heads up for the Event class, I will look into it! \$\endgroup\$ – dragons Feb 26 '14 at 9:34
  • \$\begingroup\$ The question you face is 'how can I apply the verlet integration method?'. We can only answer to 'how can I make this working code better?' \$\endgroup\$ – Quentin Pradet Feb 26 '14 at 9:55
  • \$\begingroup\$ @QuentinPradet Currently my code is functioning and the real question was how can I make this working code better, as you said it. Excuse my english. I know that pos - old_pos is actualy acting like a velocity. In my previous attempt with Euler method I did set velocity values inside on_key_pressed methods, so I did something similliar here. I think it's not the right aproach even if the code is working. Im kind of perfectionist person and I'm struggling to write a good method for moving in space and time. \$\endgroup\$ – dragons Feb 26 '14 at 11:25
1
\$\begingroup\$
    def handler(self):
        '''
        Calls Player on_x_key_pressed(), on_x_key_released()
        methods according to event bools set from the listener method.
        '''
        # Moving
        if self.left_key_pressed and self.right_key_pressed:
            self.player.keys_up()

From this point, you know that both keys cannot be pressed at the same time, so you can continue with:

        elif self.left_key_pressed:
            self.player.on_left_key_pressed()
        elif self.right_key_pressed:
            self.player.on_right_key_pressed()
        else:
            self.player.keys_up()

It's up to you to see if you find it more easy to read.

I'm afraid I can't help much with the way you use verlet integration. Last comment: Try to avoid passing the key events around too much, or try to be more 'semantic', eg. send move_left to self.player instead of on_left_key_pressed.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.