Jak to w piosence Van Halen - skaczemy! ­čśâ

Tak jak pisa┼éem w poprzednim wpisie - musia┼éem zmieni─ç my┼Ťlenie o ruchu w grze. Ruch nie mo┼╝e odbywa─ç si─Ö ju┼╝ ÔÇ×na zawo┼éanieÔÇŁ - musi chodzi─ç timer kt├│ry b─Ödzie ogarnia┼é bardziej zaawansowany ruch ni┼╝ proste wci┼Ťni─Öcie przycisku :arrow_left: czy :arrow_right:.

Doda┼éem do aplikacji timer kt├│ry tyka sobie co 50 ms. Wrzuci┼éem tam odpowiedzialno┼Ť─ç za od┼Ťwie┼╝enie widoku.

def tick(self):
     self.update()

I dla ruchu lewo-prawo wszystko ┼Ťmiga jak trzeba. Akcja ruchu na graczu si─Ö wykonuje (czyli w uproszczeniu zmienia si─Ö jego po┼éo┼╝enie na osi x). No ale nie ruszy┼éo to tematu skoku kt├│ry sk┼éada si─Ö w┼éa┼Ťciwie z serii ruch├│w (je┼Ťli za ruch uznamy aktualizacj─Ö pozycji gracza na osiach xi y).

I tutaj dozna┼éem ol┼Ťnienia! Skoro mam timer kt├│ry tyka co jaki┼Ť czas to czemu nie zrzuci─ç na niego podejmowania decyzji czy ruch ju┼╝ si─Ö zako┼äczy┼é czy te┼╝ jeszcze trwa? Znowu dla ruchu lewo-prawo wszystko jest proste - w self.tick() trzeba tylko wykona─ç raz funkcj─Ö odpowiedzialn─ů za ruch i tyle, przy skoku za┼Ť mam informacj─Ö z klasy Player m├│wi─ůc─ů w jakim stanie jest skok u┼╝ytkownika player.jump_started.

Technicznie za┼éatwi┼éem to przenosz─ůc wykonanie funkcji z metody def keyPressEvent(self, e) na ustawianie w niej aktualnej akcji. Aktualn─ů akcj─Ö przechowuj─Ö w zmiennej self.tick_action musz─Ö wi─Öc tylko przy ka┼╝dorazowym wci┼Ťni─Öciu klawisza ustawia─ç poprawn─ů funkcj─Ö do wykonania. W Pythonie jest to proste - wystarczy zapisa─ç do zmiennej metod─Ö tak, jakby j─ů si─Ö wykonywa┼éo - z t─ů r├│┼╝nic─ů, ┼╝e nie dodajemy nawias├│w po nazwie metody. Powoduje to zapisanie do zmiennej funkcji a nie wykonanie jej - wykonanie realizowane jest w┼éa┼Ťnie przez nawiasy.

W pewnym uproszczeniu (dla ruchu w lewo) wygl─ůda to tak:

def keyPressEvent(self, e):
        key = e.key()

        if key == QtCore.Qt.Key_Left:
            self.tick_action = self.player_move_backward # [1]

def tick(self):
        if self.tick_action is None: # [2]
            return

        self.tick_action() # [3]
        self.update()

        self.tick_action = None # [4]

Id─ůc po numerach dziej─ů si─Ö nast─Öpuj─ůce rzeczy:
[1] po wykryciu wci┼Ťni─Öcia strza┼éki w lewo zmienne tick_action ustawiana jest na self.player_move_backward (ale ta si─Ö nie wykonuje, bo nie ma nawias├│w)
[2] w metodzie tick sprawdzamy czy mamy w og├│le ustawion─ů jak─ů┼Ť metod─Ö
[3] metoda jest wykonywana
[4] akcja ustawiana jest na None aby zakończyć ruch

┼╗eby ogra─ç skakanie musia┼éem tylko doda─ç przy [4] sprawdzenie czy player jest w trakcie skoku, tak┼╝e w tej chwili [4] wygl─ůda tak:

if self.player.jump_started:
    self.tick_action = self.player_jump
else:
    self.tick_action = None

Na teraz to wszystko, w nast─Öpnym wpisie zajm─Ö si─Ö ogarni─Öciem wciskania kilku klawiszy jednocze┼Ťnie aby ruch i skok mog┼éy odbywa─ç si─Ö jednocze┼Ťnie. Stay tuned!

Na koniec ma┼ée demo skoku ­čśâ