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.

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:

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:

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

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.


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:
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 1,193 Sep-13-2023, 05:41 PM
Last Post: deanhystad
  how to make the movement humanized isv 4 1,506 Jul-29-2022, 07:14 PM
Last Post: XavierPlatinum
  Extract continuous numeric characters from a string in Python Robotguy 2 2,584 Jan-16-2021, 12:44 AM
Last Post: snippsat
  Using Metulburr's state machine, having a lag issue with events cjoe1993 4 2,178 Dec-09-2020, 08:04 PM
Last Post: cjoe1993
  Moving mouse so that games can detect movement SheeppOSU 2 1,900 Jun-09-2020, 07:23 PM
Last Post: SheeppOSU
  need help on solving and movement Tankey2630 1 1,654 Jan-09-2020, 11:04 AM
Last Post: Tankey2630
  State graph Kaluss 1 2,197 Mar-18-2019, 05:29 PM
Last Post: nilamo
  Count to movement according to the time pressed button noartist 1 2,478 Feb-27-2019, 01:33 PM
Last Post: noartist
  movement in a zigzag in a 2d array ShakeDat53 1 2,829 Aug-17-2018, 08:22 PM
Last Post: ichabod801
  Can't change Right to left id spawning/ movement to top to bottom Kingrocket10 3 3,765 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