Python Forum
How to get continuous movement whilst using State Machine
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to get continuous movement whilst using State Machine
#1
I am having an issue getting continuous movement whilst using metulburr's state machine code.
As of now, holding down a key will not cause continuous and fluid movement. Only each key press is registered.

Here is his code, with a sprite added.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import pygame as pg
import sys
from spritez import MainChar
 
BLACK = (0,0,0)
 
pg.init()
 
# This is positioning the sprite at x and y coordinates 100.
main_char = MainChar(BLACK, 100, 100)
 
sprite_list = pg.sprite.Group()
sprite_list.add(main_char)
sprite_list.update()
 
 
   
class States(object):
    def __init__(self):
        self.done = False
        self.next = None
        self.quit = False
        self.previous = None
   
class Menu(States):
    def __init__(self):
        States.__init__(self)
        self.next = 'game'
    def cleanup(self):
        print('cleaning up Menu state stuff')
    def startup(self):
        print('starting Menu state stuff')
    def get_event(self, event):
        if event.type == pg.KEYDOWN:
            print('Menu State keydown')
        elif event.type == pg.MOUSEBUTTONDOWN:
            self.done = True
    def update(self, screen, dt):
        self.draw(screen)
    def draw(self, screen):
        screen.fill((255,0,0))
   
class Game(States):
    def __init__(self):
        States.__init__(self)
        self.next = 'menu'
    def cleanup(self):
        print('cleaning up Game state stuff')
    def startup(self):
        print('starting Game state stuff')
    def get_event(self, event):
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT:
                main_char.moveLeft(5)
            elif event.key == pg.K_RIGHT:
                main_char.moveRight(5)
        elif event.type == pg.MOUSEBUTTONDOWN:
            self.done = True
 
 
    def update(self, screen, dt):
        self.draw(screen)
    def draw(self, screen):
        screen.fill((0,0,255))
        sprite_list.draw(screen)
   
class Control:
    def __init__(self, **settings):
        self.__dict__.update(settings)
        self.done = False
        self.screen = pg.display.set_mode(self.size)
        self.clock = pg.time.Clock()
    def setup_states(self, state_dict, start_state):
        self.state_dict = state_dict
        self.state_name = start_state
        self.state = self.state_dict[self.state_name]
    def flip_state(self):
        self.state.done = False
        previous,self.state_name = self.state_name, self.state.next
        self.state.cleanup()
        self.state = self.state_dict[self.state_name]
        self.state.startup()
        self.state.previous = previous
    def update(self, dt):
        if self.state.quit:
            self.done = True
        elif self.state.done:
            self.flip_state()
        self.state.update(self.screen, dt)
    def event_loop(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.done = True
            self.state.get_event(event)
    def main_game_loop(self):
        while not self.done:
            delta_time = self.clock.tick(self.fps)/1000.0
            self.event_loop()
            self.update(delta_time)
            pg.display.update()
 
 
 
   
settings = {
    'size':(600,400),
    'fps' :60
}
   
app = Control(**settings)
state_dict = {
    'menu': Menu(),
    'game': Game()
}
 
app.setup_states(state_dict, 'menu')
app.main_game_loop()
pg.quit()
sys.exit()
The sprites method for movement:

1
2
3
4
5
def moveLeft(self, px):
    self.rect.x -= px
 
def moveRight(self, px):
    self.rect.x += px
I understand that typically one would use a boolean, such as:

1
2
if left:
    main_char.moveLeft(5)
Then, the event handler would be:

1
2
if event.key == pg.K_LEFT:
    left = True
Despite trying this many times and reformatting many times, I cannot implement it properly. Any ideas on how to fix this and get it working?
Reply
#2
The simplest way is to use pygame's KEYUP event type.


1
2
3
4
5
6
7
if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT:
                main_char.moveLeft = True
 
if event.type == pg.KEYUP:
            if event.key == pg.K_LEFT:
                main_char.moveLeft = False
Then in your characters's update section:
1
2
if self.moveLeft == True:
    self.rect.x -=5
Then if the key is down the player moves left, and if the key is up it does nothing. I'm sure there is a million ways, this is just one.
Reply
#3
Thanks a lot.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  ValueError: Unknown label type: 'continuous-multioutput' hobbyist 7 3,332 Sep-13-2023, 05:41 PM
Last Post: deanhystad
  how to make the movement humanized isv 4 2,978 Jul-29-2022, 07:14 PM
Last Post: XavierPlatinum
  Extract continuous numeric characters from a string in Python Robotguy 2 3,828 Jan-16-2021, 12:44 AM
Last Post: snippsat
  Using Metulburr's state machine, having a lag issue with events cjoe1993 4 3,340 Dec-09-2020, 08:04 PM
Last Post: cjoe1993
  Moving mouse so that games can detect movement SheeppOSU 2 2,785 Jun-09-2020, 07:23 PM
Last Post: SheeppOSU
  need help on solving and movement Tankey2630 1 2,348 Jan-09-2020, 11:04 AM
Last Post: Tankey2630
  State graph Kaluss 1 2,976 Mar-18-2019, 05:29 PM
Last Post: nilamo
  Count to movement according to the time pressed button noartist 1 3,293 Feb-27-2019, 01:33 PM
Last Post: noartist
  movement in a zigzag in a 2d array ShakeDat53 1 3,536 Aug-17-2018, 08:22 PM
Last Post: ichabod801
  Can't change Right to left id spawning/ movement to top to bottom Kingrocket10 3 4,717 Dec-14-2017, 11:05 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

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