Learning Python's Pygame Development Contra (3)

Continue writing Contra

In the last blog Learning Python: Pygame Development Contra (2) , we completed the creation and update of the character, now let’s implement the character state function in the update function

The following is the material of the picture

Link: https://pan.baidu.com/s/1X7tESkes_O6nbPxfpHD6hQ?pwd=hdly
Extraction code: hdly

1. The character stands

When writing the character standing function, first annotate other state functions to facilitate testing
insert image description here

In the character standing function, first set the state of the current character

When standing, other states are False, onlyisStanding = True

# 设置角色状态
self.isStanding = True
self.isWalking = False
self.isJumping = False
self.isSquating = False
self.isUp = False
self.isDown = False
self.isFiring = False

Secondly, modify the speed of the character, the speed is 0 when standing

# 设置速度
self.ySpeed = 0
self.xSpeed = 0

Again, we set the key response event

# 按下A键
if keys[pygame.K_a]:
    # A按下,角色方向向左
    self.direction = Direction.LEFT
    # 改变角色的状态,角色进入移动状态
    self.state = State.WALK
    # 设置站立状态为False,移动状态为True
    self.isStanding = False
    self.isWalking = True
    # 向左移动,速度为负数,这样玩家的x坐标是减小的
    self.xSpeed = -PLAYER_X_SPEED
# 按下D键
elif keys[pygame.K_d]:
    # D按下,角色方向向右
    self.direction = Direction.RIGHT
    # 改变角色的状态,角色进入移动状态
    self.state = State.WALK
    # 设置站立状态为False,移动状态为True
    self.isStanding = False
    self.isWalking = True
    # 向右移动,速度为正数
    self.xSpeed = PLAYER_X_SPEED
# 按下k键
elif keys[pygame.K_k]:
    # K按下,角色进入跳跃状态,但是不会改变方向
    self.state = State.JUMP
    # 设置站立状态为False,跳跃状态为True
    # 不改变移动状态,因为移动的时候也可以跳跃
    self.isStanding = False
    self.isJumping = True
    # 设置速度,速度为负数,因为角色跳起后,要下落
    self.ySpeed = self.jumpSpeed
# 没有按下按键
else:
    # 没有按下按键,角色依然是站立状态
    self.state = State.STAND
    self.isStanding = True

# 按下w键
if keys[pygame.K_w]:
    # W按下,角色向上,改变方向状态
    self.isUp = True
    self.isStanding = True
    self.isDown = False
    self.isSquating = False
# 按下s键
elif keys[pygame.K_s]:
    # S按下,角色蹲下,改变方向状态,并且蹲下状态设置为True
    self.isUp = False
    self.isStanding = False
    self.isDown = True
    self.isSquating = True

full character class

import pygame
from Constants import *


class PlayerOne(pygame.sprite.Sprite):

    def __init__(self, currentTime):
        pygame.sprite.Sprite.__init__(self)
        # 加载角色图片
        self.standRightImage = loadImage('../Image/Player/Player1/Right/stand.png')
        self.standLeftImage = loadImage('../Image/Player/Player1/Left/stand.png')
        self.upRightImage = loadImage('../Image/Player/Player1/Up/upRight(small).png')
        self.upLeftImage = loadImage('../Image/Player/Player1/Up/upLeft(small).png')
        self.downRightImage = loadImage('../Image/Player/Player1/Down/down.png')
        self.downLeftImage = loadImage('../Image/Player/Player1/Down/down.png', True)
        self.obliqueUpRightImages = [
            loadImage('../Image/Player/Player1/Up/rightUp1.png'),
            loadImage('../Image/Player/Player1/Up/rightUp2.png'),
            loadImage('../Image/Player/Player1/Up/rightUp3.png'),
        ]
        self.obliqueUpLeftImages = [
            loadImage('../Image/Player/Player1/Up/rightUp1.png', True),
            loadImage('../Image/Player/Player1/Up/rightUp2.png', True),
            loadImage('../Image/Player/Player1/Up/rightUp3.png', True),
        ]
        self.obliqueDownRightImages = [
            loadImage('../Image/Player/Player1/ObliqueDown/1.png'),
            loadImage('../Image/Player/Player1/ObliqueDown/2.png'),
            loadImage('../Image/Player/Player1/ObliqueDown/3.png'),
        ]
        self.obliqueDownLeftImages = [
            loadImage('../Image/Player/Player1/ObliqueDown/1.png', True),
            loadImage('../Image/Player/Player1/ObliqueDown/2.png', True),
            loadImage('../Image/Player/Player1/ObliqueDown/3.png', True),
        ]
        # 角色向右的全部图片
        self.rightImages = [
            loadImage('../Image/Player/Player1/Right/run1.png'),
            loadImage('../Image/Player/Player1/Right/run2.png'),
            loadImage('../Image/Player/Player1/Right/run3.png')
        ]
        # 角色向左的全部图片
        self.leftImages = [
            loadImage('../Image/Player/Player1/Left/run1.png'),
            loadImage('../Image/Player/Player1/Left/run2.png'),
            loadImage('../Image/Player/Player1/Left/run3.png')
        ]
        # 角色跳跃的全部图片
        self.upRightImages = [
            loadImage('../Image/Player/Player1/Jump/jump1.png'),
            loadImage('../Image/Player/Player1/Jump/jump2.png'),
            loadImage('../Image/Player/Player1/Jump/jump3.png'),
            loadImage('../Image/Player/Player1/Jump/jump4.png'),
        ]
        self.upLeftImages = [
            loadImage('../Image/Player/Player1/Jump/jump1.png', True),
            loadImage('../Image/Player/Player1/Jump/jump2.png', True),
            loadImage('../Image/Player/Player1/Jump/jump3.png', True),
            loadImage('../Image/Player/Player1/Jump/jump4.png', True),
        ]
        self.rightFireImages = [
            loadImage('../Image/Player/Player1/Right/fire1.png'),
            loadImage('../Image/Player/Player1/Right/fire2.png'),
            loadImage('../Image/Player/Player1/Right/fire3.png'),
        ]
        self.leftFireImages = [
            loadImage('../Image/Player/Player1/Right/fire1.png', True),
            loadImage('../Image/Player/Player1/Right/fire2.png', True),
            loadImage('../Image/Player/Player1/Right/fire3.png', True),
        ]
        # 角色左右移动下标
        self.imageIndex = 0
        # 角色跳跃下标
        self.upImageIndex = 0
        # 角色斜射下标
        self.obliqueImageIndex = 0
        # 上一次显示图片的时间
        self.runLastTimer = currentTime
        self.fireLastTimer = currentTime

        # 选择当前要显示的图片
        self.image = self.standRightImage
        # 获取图片的rect
        self.rect = self.image.get_rect()
        # 设置角色的状态
        self.state = State.STAND
        # 角色的方向
        self.direction = Direction.RIGHT
        # 速度
        self.xSpeed = PLAYER_X_SPEED
        self.ySpeed = 0
        self.jumpSpeed = -11
        # 人物当前的状态标志
        self.isStanding = False
        self.isWalking = False
        self.isJumping = True
        self.isSquating = False
        self.isFiring = False
        # 重力加速度
        self.gravity = 0.7

        self.isUp = False
        self.isDown = False

    def update(self, keys, currentTime):
        # 更新站或者走的状态
        # 根据状态响应按键
        if self.state == State.STAND:
            self.standing(keys, currentTime)
        # elif self.state == State.WALK:
        #   self.walking(keys, currentTime)
        # elif self.state == State.JUMP:
        #     self.jumping(keys, currentTime)
        # elif self.state == State.FALL:
        #     self.falling(keys, currentTime)

        # 更新位置
        # 记录前一次的位置坐标
        pre = self.rect.x
        self.rect.x += self.xSpeed
        self.rect.y += self.ySpeed
        # 如果x位置小于0了,就不能移动,防止人物跑到屏幕左边
        if self.rect.x <= 0:
            self.rect.x = pre

        # 更新动画
        # 跳跃状态
        if self.isJumping:
            # 根据方向
            if self.direction == Direction.RIGHT:
                # 方向向右,角色加载向右跳起的图片
                self.image = self.upRightImages[self.upImageIndex]
            else:
                # 否则,方向向左,角色加载向左跳起的图片
                self.image = self.upLeftImages[self.upImageIndex]

        # 角色蹲下
        if self.isSquating:
            if self.direction == Direction.RIGHT:
                # 加载向右蹲下的图片
                self.image = self.downRightImage
            else:
                # 加载向左蹲下的图片
                self.image = self.downLeftImage

        # 角色站着
        if self.isStanding:
            if self.direction == Direction.RIGHT:
                if self.isUp:
                    # 加载向右朝上的图片
                    self.image = self.upRightImage
                elif self.isDown:
                    # 加载向右蹲下的图片
                    self.image = self.downRightImage
                else:
                    # 加载向右站着的图片
                    self.image = self.standRightImage
            else:
                # 向左也是同样的效果
                if self.isUp:
                    self.image = self.upLeftImage
                elif self.isDown:
                    self.image = self.downLeftImage
                else:
                    self.image = self.standLeftImage

        # 角色移动
        if self.isWalking:
            if self.direction == Direction.RIGHT:
                if self.isUp:
                    # 加载斜右上的图片
                    self.image = self.obliqueUpRightImages[self.obliqueImageIndex]
                elif self.isDown:
                    # 加载斜右下的图片
                    self.image = self.obliqueDownRightImages[self.obliqueImageIndex]
                else:
                    # 加载向右移动的图片,根据开火状态是否加载向右开火移动的图片
                    if self.isFiring:
                        self.image = self.rightFireImages[self.imageIndex]
                    else:
                        self.image = self.rightImages[self.imageIndex]
            else:
                if self.isUp:
                    self.image = self.obliqueUpLeftImages[self.obliqueImageIndex]
                elif self.isDown:
                    self.image = self.obliqueDownLeftImages[self.obliqueImageIndex]
                else:
                    if self.isFiring:
                        self.image = self.leftFireImages[self.imageIndex]
                    else:
                        self.image = self.leftImages[self.imageIndex]

    def standing(self, keys, currentTime):
        """角色站立"""

        # 设置角色状态
        self.isStanding = True
        self.isWalking = False
        self.isJumping = False
        self.isSquating = False
        self.isUp = False
        self.isDown = False
        self.isFiring = False

        # 设置速度
        self.ySpeed = 0
        self.xSpeed = 0

        # 按下A键
        if keys[pygame.K_a]:
            # A按下,角色方向向左
            self.direction = Direction.LEFT
            # 改变角色的状态,角色进入移动状态
            self.state = State.WALK
            # 设置站立状态为False,移动状态为True
            self.isStanding = False
            self.isWalking = True
            # 向左移动,速度为负数,这样玩家的x坐标是减小的
            self.xSpeed = -PLAYER_X_SPEED
        # 按下D键
        elif keys[pygame.K_d]:
            # D按下,角色方向向右
            self.direction = Direction.RIGHT
            # 改变角色的状态,角色进入移动状态
            self.state = State.WALK
            # 设置站立状态为False,移动状态为True
            self.isStanding = False
            self.isWalking = True
            # 向右移动,速度为正数
            self.xSpeed = PLAYER_X_SPEED
        # 按下k键
        elif keys[pygame.K_k]:
            # K按下,角色进入跳跃状态,但是不会改变方向
            self.state = State.JUMP
            # 设置站立状态为False,跳跃状态为True
            # 不改变移动状态,因为移动的时候也可以跳跃
            self.isStanding = False
            self.isJumping = True
            # 设置速度,速度为负数,因为角色跳起后,要下落
            self.ySpeed = self.jumpSpeed
        # 没有按下按键
        else:
            # 没有按下按键,角色依然是站立状态
            self.state = State.STAND
            self.isStanding = True

        # 按下w键
        if keys[pygame.K_w]:
            # W按下,角色向上,改变方向状态
            self.isUp = True
            self.isStanding = True
            self.isDown = False
            self.isSquating = False
        # 按下s键
        elif keys[pygame.K_s]:
            # S按下,角色蹲下,改变方向状态,并且蹲下状态设置为True
            self.isUp = False
            self.isStanding = False
            self.isDown = True
            self.isSquating = True

After finishing the character standing, let's try to see how it works

Create character in main class and put in pygame.sprite.Group

class MainGame:

    player1 = None
    allSprites = None

Add code in the __init__() function

# 初始化角色
MainGame.player1 = PlayerOne(pygame.time.get_ticks())
# 设置角色的初始位置
# 这里设置为(0,80),可以实现一开始玩家掉下来的动画,目前没有实现掉落,所以直接设置为(80,300)
# MainGame.player1.rect.x = 80
# MainGame.player1.rect.bottom = 0
MainGame.player1.rect.x = 80
MainGame.player1.rect.bottom = 300

# 把角色放入组中,方便统一管理
MainGame.allSprites = pygame.sprite.Group(MainGame.player1)

Then call the update function of the role in the loop

For convenience, I put the update of the object all together and create an update() function

add function in main class

def update(self, window):
    # 更新物体
    currentTime = pygame.time.get_ticks()
    MainGame.allSprites.update(self.keys, currentTime)
    # 显示物体
    MainGame.allSprites.draw(window)

pygame.sprite.Group()Objects in can be updated uniformly, which is its convenience

Because when the player moves in Contra, the objects in the scene also have to move, so the map is a long strip. When the player moves to the right, the map actually moves to the left, the player does not move, and the objects being created Move to the left, if you don’t put all the objects in the group, it’s not easy to manage them uniformly

complete main class code

import sys
import pygame
from Constants import *
from PlayerOne import PlayerOne


class MainGame:

    player1 = None
    allSprites = None

    window = None

    def __init__(self):
        # 初始化展示模块
        pygame.display.init()

        SCREEN_SIZE = (SCREEN_WIDTH, SCREEN_HEIGHT)
        # 初始化窗口
        MainGame.window = pygame.display.set_mode(SCREEN_SIZE)
        # 设置窗口标题
        pygame.display.set_caption('魂斗罗角色')
        # 是否结束游戏
        self.isEnd = False
        # 获取按键
        self.keys = pygame.key.get_pressed()
        # 帧率
        self.fps = 60
        self.clock = pygame.time.Clock()

        # 初始化角色
        MainGame.player1 = PlayerOne(pygame.time.get_ticks())
        # 设置角色的初始位置
        # 这里设置为(0,80),可以实现一开始玩家掉下来的动画
        MainGame.player1.rect.x = 80
        MainGame.player1.rect.bottom = 300

        # 把角色放入组中,方便统一管理
        MainGame.allSprites = pygame.sprite.Group(MainGame.player1)

    def run(self):
        while not self.isEnd:

            # 设置背景颜色
            pygame.display.get_surface().fill((0, 0, 0))

            # 游戏场景和景物更新函数
            self.update(MainGame.window)

            # 获取窗口中的事件
            self.getPlayingModeEvent()

            # 更新窗口
            pygame.display.update()

            # 设置帧率
            self.clock.tick(self.fps)
            fps = self.clock.get_fps()
            caption = '魂斗罗 - {:.2f}'.format(fps)
            pygame.display.set_caption(caption)
        else:
            sys.exit()

    def getPlayingModeEvent(self):
        # 获取事件列表
        for event in pygame.event.get():
            # 点击窗口关闭按钮
            if event.type == pygame.QUIT:
                self.isEnd = True
            # 键盘按键按下
            elif event.type == pygame.KEYDOWN:
                self.keys = pygame.key.get_pressed()
            # 键盘按键抬起
            elif event.type == pygame.KEYUP:
                self.keys = pygame.key.get_pressed()

    def update(self, window):
        # 更新物体
        currentTime = pygame.time.get_ticks()
        MainGame.allSprites.update(self.keys, currentTime)
        # 显示物体
        MainGame.allSprites.draw(window)


if __name__ == '__main__':
    MainGame().run()

Let's run it now and see the effect

insert image description here
We found that the character is jumping and moving forward, which is not what we expected, the expectation should be standing there

The reason is that the state of the character when it was first created is wrong.
insert image description here
Currently, the falling() function is not implemented, so there is no way to display the falling state, so let’s modify it and modify the __init__() function in the character class

# 设置角色的状态
self.state = State.FALL 改为 self.state = State.STAND

insert image description here
After changing it, run it to see the result

insert image description here
Pressing the a and d keys will keep the player moving without stopping

insert image description here
At this point, we have written the player standing function, and now we will write the player movement function

Complete player class __init__() function code

def __init__(self, currentTime):
    pygame.sprite.Sprite.__init__(self)
    # 加载角色图片
    self.standRightImage = loadImage('../Image/Player/Player1/Right/stand.png')
    self.standLeftImage = loadImage('../Image/Player/Player1/Left/stand.png')
    self.upRightImage = loadImage('../Image/Player/Player1/Up/upRight(small).png')
    self.upLeftImage = loadImage('../Image/Player/Player1/Up/upLeft(small).png')
    self.downRightImage = loadImage('../Image/Player/Player1/Down/down.png')
    self.downLeftImage = loadImage('../Image/Player/Player1/Down/down.png', True)
    self.obliqueUpRightImages = [
        loadImage('../Image/Player/Player1/Up/rightUp1.png'),
        loadImage('../Image/Player/Player1/Up/rightUp2.png'),
        loadImage('../Image/Player/Player1/Up/rightUp3.png'),
    ]
    self.obliqueUpLeftImages = [
        loadImage('../Image/Player/Player1/Up/rightUp1.png', True),
        loadImage('../Image/Player/Player1/Up/rightUp2.png', True),
        loadImage('../Image/Player/Player1/Up/rightUp3.png', True),
    ]
    self.obliqueDownRightImages = [
        loadImage('../Image/Player/Player1/ObliqueDown/1.png'),
        loadImage('../Image/Player/Player1/ObliqueDown/2.png'),
        loadImage('../Image/Player/Player1/ObliqueDown/3.png'),
    ]
    self.obliqueDownLeftImages = [
        loadImage('../Image/Player/Player1/ObliqueDown/1.png', True),
        loadImage('../Image/Player/Player1/ObliqueDown/2.png', True),
        loadImage('../Image/Player/Player1/ObliqueDown/3.png', True),
    ]
    # 角色向右的全部图片
    self.rightImages = [
        loadImage('../Image/Player/Player1/Right/run1.png'),
        loadImage('../Image/Player/Player1/Right/run2.png'),
        loadImage('../Image/Player/Player1/Right/run3.png')
    ]
    # 角色向左的全部图片
    self.leftImages = [
        loadImage('../Image/Player/Player1/Left/run1.png'),
        loadImage('../Image/Player/Player1/Left/run2.png'),
        loadImage('../Image/Player/Player1/Left/run3.png')
    ]
    # 角色跳跃的全部图片
    self.upRightImages = [
        loadImage('../Image/Player/Player1/Jump/jump1.png'),
        loadImage('../Image/Player/Player1/Jump/jump2.png'),
        loadImage('../Image/Player/Player1/Jump/jump3.png'),
        loadImage('../Image/Player/Player1/Jump/jump4.png'),
    ]
    self.upLeftImages = [
        loadImage('../Image/Player/Player1/Jump/jump1.png', True),
        loadImage('../Image/Player/Player1/Jump/jump2.png', True),
        loadImage('../Image/Player/Player1/Jump/jump3.png', True),
        loadImage('../Image/Player/Player1/Jump/jump4.png', True),
    ]
    self.rightFireImages = [
        loadImage('../Image/Player/Player1/Right/fire1.png'),
        loadImage('../Image/Player/Player1/Right/fire2.png'),
        loadImage('../Image/Player/Player1/Right/fire3.png'),
    ]
    self.leftFireImages = [
        loadImage('../Image/Player/Player1/Right/fire1.png', True),
        loadImage('../Image/Player/Player1/Right/fire2.png', True),
        loadImage('../Image/Player/Player1/Right/fire3.png', True),
    ]
    # 角色左右移动下标
    self.imageIndex = 0
    # 角色跳跃下标
    self.upImageIndex = 0
    # 角色斜射下标
    self.obliqueImageIndex = 0
    # 上一次显示图片的时间
    self.runLastTimer = currentTime
    self.fireLastTimer = currentTime

    # 选择当前要显示的图片
    self.image = self.standRightImage
    # 获取图片的rect
    self.rect = self.image.get_rect()
    # 设置角色的状态
    self.state = State.STAND
    # 角色的方向
    self.direction = Direction.RIGHT
    # 速度
    self.xSpeed = PLAYER_X_SPEED
    self.ySpeed = 0
    self.jumpSpeed = -11
    # 人物当前的状态标志
    self.isStanding = False
    self.isWalking = False
    self.isJumping = True
    self.isSquating = False
    self.isFiring = False
    # 重力加速度
    self.gravity = 0.7

    self.isUp = False
    self.isDown = False

2. Character movement

Open the comment and start writing the character movement function
insert image description here
. Similarly, first set the state of the character, because it is the character movement, so only isWalking is true, and the others are false

self.isStanding = False
self.isWalking = True
self.isJumping = False
self.isSquating = False
self.isFiring = False

set speed

self.ySpeed = 0
self.xSpeed = PLAYER_X_SPEED

Judge the current state and prepare the picture of the next state according to the current state

# 如果当前是站立的图片
if self.isStanding:
    # 方向向右,方向向上
    if self.direction == Direction.RIGHT and self.isUp:
        # 设置为向右朝上的图片
        self.image = self.upRightImage
    # 方向向右
    elif self.direction == Direction.RIGHT and not self.isUp:
        # 设置为向右站立的图片
        self.image = self.standRightImage
    elif self.direction == Direction.LEFT and self.isUp:
        self.image = self.upLeftImage
    elif self.direction == Direction.LEFT and not self.isUp:
        self.image = self.standLeftImage
    # 记下当前时间
    self.runLastTimer = currentTime
else:
    # 如果是走动的图片,先判断方向
    if self.direction == Direction.RIGHT:
        # 设置速度
        self.xSpeed = PLAYER_X_SPEED
        # 根据上下方向觉得是否角色要加载斜射的图片
        if self.isUp or self.isDown:
            # isUp == True表示向上斜射
            # isDown == True表示向下斜射
            # 计算上一次加载图片到这次的时间,如果大于115,即11.5帧,即上次加载图片到这次加载图片之间,已经加载了11张图片
            if currentTime - self.runLastTimer > 115:
                # 那么就可以加载斜着奔跑的图片
                # 如果角色加载的图片不是第三张,则加载下一张就行
                if self.obliqueImageIndex < 2:
                    self.obliqueImageIndex += 1
                # 否则就加载第一张图片
                else:
                    self.obliqueImageIndex = 0
                # 记录变换图片的时间,为下次变换图片做准备
                self.runLastTimer = currentTime
        # 不是斜射
        else:
            # 加载正常向右奔跑的图片
            if currentTime - self.runLastTimer > 115:
                if self.imageIndex < 2:
                    self.imageIndex += 1
                else:
                    self.imageIndex = 0
                self.runLastTimer = currentTime
    else:
        self.xSpeed = -PLAYER_X_SPEED
        if self.isUp or self.isDown:
            if currentTime - self.runLastTimer > 115:
                if self.obliqueImageIndex < 2:
                    self.obliqueImageIndex += 1
                else:
                    self.obliqueImageIndex = 0
                self.runLastTimer = currentTime
        else:
            if currentTime - self.runLastTimer > 115:
                if self.imageIndex < 2:
                    self.imageIndex += 1
                else:
                    self.imageIndex = 0
                self.runLastTimer = currentTime

After the picture is loaded, handle the key response

# 按下D键
if keys[pygame.K_d]:
    self.direction = Direction.RIGHT
    self.xSpeed = PLAYER_X_SPEED
# 按下A键
elif keys[pygame.K_a]:
    self.direction = Direction.LEFT
    self.xSpeed = -PLAYER_X_SPEED
 # 按下S键
elif keys[pygame.K_s]:
    self.isStanding = False
    self.isDown = True

# 按下W键
if keys[pygame.K_w]:
    self.isUp = True
    self.isDown = False
# 没有按键按下
else:
    self.state = State.STAND

# 移动时按下K键
if keys[pygame.K_k]:
    # 角色状态变为跳跃
    self.state = State.JUMP
    self.ySpeed = self.jumpSpeed
    self.isJumping = True
    self.isStanding = False

Complete walking() function code

    def walking(self, keys, currentTime):
        """角色行走,每10帧变换一次图片"""
        self.isStanding = False
        self.isWalking = True
        self.isJumping = False
        self.isSquating = False
        self.isFiring = False
        self.ySpeed = 0
        self.xSpeed = PLAYER_X_SPEED

        # 如果当前是站立的图片
        if self.isStanding:
            # 方向向右,方向向上
            if self.direction == Direction.RIGHT and self.isUp:
                # 设置为向右朝上的图片
                self.image = self.upRightImage
            # 方向向右
            elif self.direction == Direction.RIGHT and not self.isUp:
                # 设置为向右站立的图片
                self.image = self.standRightImage
            elif self.direction == Direction.LEFT and self.isUp:
                self.image = self.upLeftImage
            elif self.direction == Direction.LEFT and not self.isUp:
                self.image = self.standLeftImage
            # 记下当前时间
            self.runLastTimer = currentTime
        else:
            # 如果是走动的图片,先判断方向
            if self.direction == Direction.RIGHT:
                # 设置速度
                self.xSpeed = PLAYER_X_SPEED
                # 根据上下方向觉得是否角色要加载斜射的图片
                if self.isUp or self.isDown:
                    # isUp == True表示向上斜射
                    # isDown == True表示向下斜射
                    # 计算上一次加载图片到这次的时间,如果大于115,即11.5帧,即上次加载图片到这次加载图片之间,已经加载了11张图片
                    if currentTime - self.runLastTimer > 115:
                        # 那么就可以加载斜着奔跑的图片
                        # 如果角色加载的图片不是第三张,则加载下一张就行
                        if self.obliqueImageIndex < 2:
                            self.obliqueImageIndex += 1
                        # 否则就加载第一张图片
                        else:
                            self.obliqueImageIndex = 0
                        # 记录变换图片的时间,为下次变换图片做准备
                        self.runLastTimer = currentTime
                # 不是斜射
                else:
                    # 加载正常向右奔跑的图片
                    if currentTime - self.runLastTimer > 115:
                        if self.imageIndex < 2:
                            self.imageIndex += 1
                        else:
                            self.imageIndex = 0
                        self.runLastTimer = currentTime
            else:
                self.xSpeed = -PLAYER_X_SPEED
                if self.isUp or self.isDown:
                    if currentTime - self.runLastTimer > 115:
                        if self.obliqueImageIndex < 2:
                            self.obliqueImageIndex += 1
                        else:
                            self.obliqueImageIndex = 0
                        self.runLastTimer = currentTime
                else:
                    if currentTime - self.runLastTimer > 115:
                        if self.imageIndex < 2:
                            self.imageIndex += 1
                        else:
                            self.imageIndex = 0
                        self.runLastTimer = currentTime

        # 按下D键
        if keys[pygame.K_d]:
            self.direction = Direction.RIGHT
            self.xSpeed = PLAYER_X_SPEED
        # 按下A键
        elif keys[pygame.K_a]:
            self.direction = Direction.LEFT
            self.xSpeed = -PLAYER_X_SPEED
         # 按下S键
        elif keys[pygame.K_s]:
            self.isStanding = False
            self.isDown = True

        # 按下W键
        if keys[pygame.K_w]:
            self.isUp = True
            self.isDown = False
        # 没有按键按下
        else:
            self.state = State.STAND

        # 移动时按下K键
        if keys[pygame.K_k]:
            # 角色状态变为跳跃
            self.state = State.JUMP
            self.ySpeed = self.jumpSpeed
            self.isJumping = True
            self.isStanding = False

Run it and see the effect

insert image description here
Wow, that's done, we're done with character movement

3. Character Jump

First set the status flag

# 设置标志
self.isJumping = True
self.isStanding = False
self.isDown = False
self.isSquating = False
self.isFiring = False

Update Speed

self.ySpeed += self.gravity

After jumping, the y coordinate of the character is reduced, so the speed is originally a negative number, because the speed has been decreasing from the jump to the highest point, so here we set the gravity to ensure that the speed slowly decreases to 0

Decide whether to show the next picture according to the time

if currentTime - self.runLastTimer > 115:
    if self.upImageIndex < 3:
        self.upImageIndex += 1
    else:
        self.upImageIndex = 0
    # 记录变换图片的时间,为下次变换图片做准备
    self.runLastTimer = currentTime

Set button response event

if keys[pygame.K_d]:
    self.direction = Direction.RIGHT

elif keys[pygame.K_a]:
    self.direction = Direction.LEFT

# 按下W键
if keys[pygame.K_w]:
    self.isUp = True
    self.isDown = False
elif keys[pygame.K_s]:
    self.isUp = False
    self.isDown = True

# 当速度变为正数,玩家进入下落状态
if self.ySpeed >= 0:
    self.state = State.FALL

if not keys[pygame.K_k]:
    self.state = State.FALL

Complete jumping() function code

def jumping(self, keys, currentTime):
    """跳跃"""
    # 设置标志
    self.isJumping = True
    self.isStanding = False
    self.isDown = False
    self.isSquating = False
    self.isFiring = False
    # 更新速度
    self.ySpeed += self.gravity
    if currentTime - self.runLastTimer > 115:
        if self.upImageIndex < 3:
            self.upImageIndex += 1
        else:
            self.upImageIndex = 0
        # 记录变换图片的时间,为下次变换图片做准备
        self.runLastTimer = currentTime

    if keys[pygame.K_d]:
        self.direction = Direction.RIGHT

    elif keys[pygame.K_a]:
        self.direction = Direction.LEFT

    # 按下W键
    if keys[pygame.K_w]:
        self.isUp = True
        self.isDown = False
    elif keys[pygame.K_s]:
        self.isUp = False
        self.isDown = True

    if self.ySpeed >= 0:
        self.state = State.FALL

    if not keys[pygame.K_k]:
        self.state = State.FALL

4. Whereabouts of characters

def falling(self, keys, currentTime):
    # 下落时速度越来越快,所以速度需要一直增加
    self.ySpeed += self.gravity
    if currentTime - self.runLastTimer > 115:
        if self.upImageIndex < 3:
            self.upImageIndex += 1
        else:
            self.upImageIndex = 0
        self.runLastTimer = currentTime

    # 防止落到窗口外面,当落到一定高度时,就不会再掉落了
    if self.rect.bottom > SCREEN_HEIGHT - GROUND_HEIGHT:
        self.state = State.WALK
        self.ySpeed = 0
        self.rect.bottom = SCREEN_HEIGHT - GROUND_HEIGHT
        self.isJumping = False

    if keys[pygame.K_d]:
        self.direction = Direction.RIGHT
        self.isWalking = False

    elif keys[pygame.K_a]:
        self.direction = Direction.LEFT
        self.isWalking = False

Let's see the effect now, run it

Don't forget to turn on comments

insert image description here

insert image description here
Up to now, we have realized the character movement and jumping, and the next step is to shoot bullets

Guess you like

Origin blog.csdn.net/qq_37354060/article/details/129214623