This is the 10th day of my participation in the August Text Challenge.More challenges in August

First, start from control

In the previous section, we successfully changed the movement speed of the character using the buttons, and implemented the movement of the character using the Update command, as well as the looping of the animation image.

However, we judge the movement by pressing the button and releasing the button, and the following problems will occur:

1. The event is overwritten and the movement stops suddenly because the left and right switchover is too fast.

2. The steering can be realized by pressing two keys at the same time, but the action will stop immediately after one key is released (slow operation of 1).

In short, the key control is not smooth, which seriously affects the operation experience. In this regard, we will put forward an optimization scheme (the scheme summed up by individuals may not be the optimal solution) in this chapter, and then lead to the state of the characters.

Modify event listening

Our original listener was listening for key events to change state, now we make a change:

class Game:
    def __init__(self, width, height) :
        self.keys = pygame.key.get_pressed()

while True:
    if event.type == pygame.QUIT:
        pygame.display.quit()
    elif event.type == pygame.KEYDOWN:
        self.keys = pygame.key.get_pressed()
    elif event.type == pygame.KEYUP:
        self.keys = pygame.key.get_pressed()
Copy the code

Add a key to the Game class to store the currently pressed key, and call Pygame.key.get_pressed () to retrieve the array of keys.

If keys[pygame.k_d] is 1, D is pressed; if keys are 0, D is released.

3. Character status

To enable the Player to act according to the keys, we should first pass the keys to the Player:

def update(self):
    ...
    self.player.control(self.keys)
    self.player.update()
    ...
Copy the code

In Game update(), before character Update (), add a control() function and pass the keys to the player. The player will use the control() function to make the corresponding state change.

Before writing the control() function, let’s add some new fields to the Player:

class Player(pygame.sprite.Sprite) :
    def __init__(self) :. self.status ="standing"        The default standing state
        self.direction = 1              Default 1 is to the right; 1 toward the left
        
        # Delete the original walk_images
        self.images = {
            "standing": [pygame.image.load(f"./resourse/player/stand/{i+1}.png") for i in range(1)]."walking": [pygame.image.load(f"./resourse/player/walk/{i+1}.png") for i in range(8)]
        }
        self.index = 0

        self.walk_speed = 5
Copy the code
  • First, and most significantly, we added a status field, which stores the current state of the character, and then used the direction field to mark the character’s direction (why 1 and -1, more on that later).

  • Second, map is used to store groups of action pictures, which can be called by status.

  • Finally, a walk_speed is added because run_speed(´ · ·) will follow.

For the control() function, show the code:

class Player(pygame.sprite.Sprite) :
    def control(self, keys) :
        if self.status == 'standing':
            if keys[pygame.K_d]:
                self.direction = 1
                self.status = "walking"
                self.index = 0
            elif keys[pygame.K_a]:
                self.direction = -1
                self.status = "walking"
                self.index = 0
            # elif ...
        if self.status == "walking":
            if keys[pygame.K_d]:
                self.direction = 1
            elif keys[pygame.K_a]:
                self.direction = -1
            # elif ...
            else:
                self.status = "standing"
                self.index = 0
                # Keep the same direction as before
Copy the code

It’s just a bunch of if-else statements that overwrite the character’s state.

The more refined the judgment, the better the experience will be. Technically there is nothing to say, but logically it can be understood along the way (mainly to solve the problems in 1).

Note that each time the state is switched, the index must be cleared, otherwise the array will be out of bounds; And each key depending on the state of the character, the result may not be the same.

Update ();

def update(self) :
    if self.status == 'standing':
        self.speed = 0
    elif self.status == 'walking':
        self.speed = self.walk_speed * self.direction
        self.rect.left += self.speed

    self.index = (self.index + 1) % len(self.images[self.status])
    self.image = self.images[self.status][self.index]
    if self.direction == -1:
        self.image = pygame.transform.flip(self.image, True.False)
Copy the code

1. Perform different updates based on the status.

2. Directions are expressed by 1 and -1, which can be directly multiplied when calculating the speed.

3. Image update Obtain the corresponding image group from images by status.

4. When the direction is left, the image can be flipped to save art costs and resource consumption.

Four, run,