0
\$\begingroup\$

I am working one the movement for a tactical turn-based pygame. I'm stumped as to how to get a selected object to move one tile at a time up to it's max movement to the mouse's pos. Right now this is what I have. I'm not sure how to proceed.

def move_toward(self, new_location):
def do_calculations():
# ... code ...
return dx, dy
# ----
# you have the current x,y for the player.
# each click of the clock you want to move the player
# closer to the end location.
delta = .01 # or whatever
# get <delta> amount closer to the end corrds. <-- do this each tick of the clock.
new_x, new_y = do_calculations()
self.move(dx=new_x, dy=new_y)

Sprites.py

import pygame as pg
from settings import *

class Player(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.image = pg.Surface((TILESIZE, TILESIZE))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect()
        self.x = x
        self.y = y

    def move(self, dx=0, dy=0):
        if not self.collide_with_walls(dx, dy):
            self.x = dx
            self.y = dy
            self.rect = self.rect.move(dx * TILESIZE, dy * TILESIZE)

main.py

    def events(self):
    # catch all events here
    for event in pg.event.get():
        if event.type == pg.QUIT:
            self.quit()
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_ESCAPE:
                self.quit()
        if event.type == pg.MOUSEBUTTONDOWN:
            x = pg.mouse.get_pos()[0] // TILESIZE
            y = pg.mouse.get_pos()[1] // TILESIZE
            print(x, y)

            self.player.move(dx=x, dy=y)
\$\endgroup\$
2
  • 2
    \$\begingroup\$ I read TTRPG as "Table Top RPG" which confused me a bit. Actually the "RPG" part seems unnecessary, because any RPG mechanics you might have don't seem relevant to this problem. I changed the title accordingly. \$\endgroup\$
    – Philipp
    Jun 30 at 10:14
  • \$\begingroup\$ Can you clarify if you are looking for a path finding algorithm? As in, you want the character to move along the grid? Try searching for A* pathfinding. \$\endgroup\$ Jul 4 at 19:14
0
\$\begingroup\$

When developing a turn-based game, then it can be useful to design the basic architecture of the game in form of a finite state machine.

That means that your game can be in one of a number of states. Depending on the state the game is currently in, it looks and behaves differently.

  • First, your game is in the "pick unit" state. In this state, the game waits for player clicks and when such a click happens on a unit they control, that unit becomes selected and the game changes into the "pick destination" state.

  • In the "pick destination" state, the game still waits for player clicks, but they now do something different: When the square the player clicked is a valid movement destination for the selected unit, then the game switches to the "execute move" state.

  • The "execute move" state is purely automatic without player input. The unit slowly moves from one square to the next until it reached the destination. Then the game progresses to the next state automatically.

Optionally, you might want to add some additional state transitions. For example, a transition from "pick destination" back to "pick unit" when the player signals that they changed their mind and would like to move a different unit.

OK, but how do you implement this?

One good way to do that is to implement each state as a separate class which all inherit from the same base class. The methods defined by that state base class would be methods for any kinds of situations where states would behave differently. Examples would be "handle_click" or "tick_update".

The regular functions in your game which handle such events would then check the state machine for the currently active state object and call the respective method in that state object so it can do whatever it wants. That way you have all the functionality which is specific to each state in one place.

That makes it easy to avoid bugs where a functionality which is supposed to only be active in one state is active in a different state. You will also notice that it will become very easy to add additional states to the game. For example, the state of being in some form of menu, waiting for the opponent to make a move, visualizing the move of the opponent, displaying the "You Win" / "You Lose" banner or even watching a cutscene. All you need to do for each of those things is to create yet another State class and to write the code which causes the transition to that state.

\$\endgroup\$
1
  • \$\begingroup\$ yeah I plan on doing this down the line but I want to get one unit to function properly before proceeding. Start_screen, menu, etc are being passed. I have been struggling for more than a week trying to figure out the algorithm that works. Thanks for the advice. \$\endgroup\$ Jul 2 at 8:56

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.