Learning Python's Pygame Development Contra (4)

Continue writing Contra

In the last blog Learning Python Pygame Development Contra (3) , we completed the movement and jumping of the character, let's continue to write Contra.

The following is the material of the picture

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

1. Create the bullet class

To launch a bullet, we must first have a bullet class.
Let's create it

import pygame
from Constants import *

class Bullet(pygame.sprite.Sprite):

    def __init__(self, person):
        pygame.sprite.Sprite.__init__(self)
        self.images = [
            loadImage('../Image/Bullet/bullet1.png')
        ]
        self.index = 0
        self.image = self.images[self.index]
        # 速度
        self.xSpeed = 1
        self.ySpeed = 1
        self.rect = pygame.Rect(person.rect)

        # 销毁开关
        self.isDestroy = False

    def move(self):
        self.rect.x += self.xSpeed
        self.rect.y += self.ySpeed
        self.checkBullet()

    def draw(self, window):
        window.blit(self.image, self.rect)

    def checkBullet(self):
        toDestroy = False
        if self.rect.top < 0 or self.rect.top > 600:
            toDestroy = True
        if self.rect.left < 0 or self.rect.right > 900:
            toDestroy = True
        if toDestroy:
            self.isDestroy = True

2. Set the position of the bullet launch according to the player's direction and state

Since the direction and state of the player are different, the position of the bullet is also different after the player fires.

Let's take a look at the character status and the position where the bullet is fired

(1). Stand and fire bullets to the right

(x,y) is the position of the picture, we calculated that in this state, the position of the bullet launch is (x+24,y+11)

insert image description here
Let's set it up

self.rect.x += 24 * 2.5
self.rect.y += 11 * 2.5
self.ySpeed = 0
self.xSpeed = 7

2.5 is the magnification of the character. When loading the image, the image is magnified by 2.5 times, so when setting the bullet firing position, it must also be multiplied by 2.5

if person.isStanding:
	# 判断方向
	# 方向向右
    if person.direction == Direction.RIGHT:
    	# 向上
        if person.isUp:
            pass
        # 向右
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    # 方向向左
    else:
        if person.isUp:
            pass
        else:
            pass

elif person.isSquating and not person.isWalking:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

elif person.isWalking:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass
    else:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

(2). Stand and fire bullets to the left

insert image description here

self.rect.y += 11 * 2.5
self.ySpeed = 0
self.xSpeed = -7
# 根据角色的方向和状态设置子弹发射的位置
# 角色站着
if person.isStanding:
	# 判断方向
    if person.direction == Direction.RIGHT:
    	# 向上
        if person.isUp:
            pass
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    else:
        if person.isUp:
            pass
        else:
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = -7

elif person.isSquating and not person.isWalking:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

elif person.isWalking:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass
    else:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

(3). Stand up and fire bullets

Stand right and shoot bullets upwards
insert image description here

self.rect.x += 10 * 2.5
self.rect.y += -1 * 2.5
self.ySpeed = -7
self.xSpeed = 0

Here I slightly adjusted the value of y, the direction is upward, so the y of the bullet is gradually reduced, so the y speed is negative

# 根据角色的方向和状态设置子弹发射的位置
# 角色站着
if person.isStanding:
	# 判断方向
    if person.direction == Direction.RIGHT:
    	# 向上
        if person.isUp:
            self.rect.x += 10 * 2.5
			self.rect.y += -1 * 2.5
			self.ySpeed = -7
			self.xSpeed = 0
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    else:
        if person.isUp:
            pass
        else:
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = -7

elif person.isSquating and not person.isWalking:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

elif person.isWalking:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass
    else:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

Standing up and shooting bullets to the left is the same calculation method

self.rect.x += 10 * 2.5
self.rect.y += -1 * 2.5
self.ySpeed = -7
self.xSpeed = 0
# 根据角色的方向和状态设置子弹发射的位置
# 角色站着
if person.isStanding:
	# 判断方向
    if person.direction == Direction.RIGHT:
    	# 向上
        if person.isUp:
            self.rect.x += 10 * 2.5
			self.rect.y += -1 * 2.5
			self.ySpeed = -7
			self.xSpeed = 0
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    else:
        if person.isUp:
            self.rect.x += 10 * 2.5
            self.rect.y += -1 * 2.5
            self.ySpeed = -7
            self.xSpeed = 0
        else:
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = -7

elif person.isSquating and not person.isWalking:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

elif person.isWalking:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass
    else:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

(4). Crouch down and fire bullets

Schematic diagram to the right

insert image description here

self.rect.x += 34 * 2.5
self.rect.y += 25 * 2.5
self.ySpeed = 0
self.xSpeed = 7
# 根据角色的方向和状态设置子弹发射的位置
# 角色站着
if person.isStanding:
	# 判断方向
    if person.direction == Direction.RIGHT:
    	# 向上
        if person.isUp:
            self.rect.x += 10 * 2.5
			self.rect.y += -1 * 2.5
			self.ySpeed = -7
			self.xSpeed = 0
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    else:
        if person.isUp:
            self.rect.x += 10 * 2.5
            self.rect.y += -1 * 2.5
            self.ySpeed = -7
            self.xSpeed = 0
        else:
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = -7

elif person.isSquating and not person.isWalking:
    if person.direction == Direction.RIGHT:
        self.rect.x += 34 * 2.5
		self.rect.y += 25 * 2.5
		self.ySpeed = 0
		self.xSpeed = 7
    else:
        pass

elif person.isWalking:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass
    else:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

Similarly, set the launch position to the left

self.rect.y += 25 * 2.5
self.ySpeed = 0
self.xSpeed = -7
# 根据角色的方向和状态设置子弹发射的位置
# 角色站着
if person.isStanding:
	# 判断方向
    if person.direction == Direction.RIGHT:
    	# 向上
        if person.isUp:
            self.rect.x += 10 * 2.5
			self.rect.y += -1 * 2.5
			self.ySpeed = -7
			self.xSpeed = 0
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    else:
        if person.isUp:
            self.rect.x += 10 * 2.5
            self.rect.y += -1 * 2.5
            self.ySpeed = -7
            self.xSpeed = 0
        else:
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = -7

elif person.isSquating and not person.isWalking:
    if person.direction == Direction.RIGHT:
        self.rect.x += 34 * 2.5
		self.rect.y += 25 * 2.5
		self.ySpeed = 0
		self.xSpeed = 7
    else:
        self.rect.y += 25 * 2.5
		self.ySpeed = 0
		self.xSpeed = -7

elif person.isWalking:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass
    else:
        if person.isUp:
            pass
        elif person.isDown:
            pass
        else:
            pass

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

(5). Shoot bullets diagonally

Schematic diagram of firing bullets to the upper right
insert image description here

self.rect.x += 20 * 2.5
self.rect.y += -1 * 2.5
self.ySpeed = -7
self.xSpeed = 7

Bullet position when firing a bullet to the upper left

self.rect.x += -3 * 2.5
self.rect.y += -1 * 2.5
self.ySpeed = -7
self.xSpeed = -7

Schematic diagram of firing bullets to the lower right
insert image description here

self.rect.x += 21 * 2.5
self.rect.y += 20 * 2.5
self.ySpeed = 7
self.xSpeed = 7

The position of the bullet when firing the bullet to the lower left

self.rect.x += -3 * 2.5
self.rect.y += 20 * 2.5
self.ySpeed = 7
self.xSpeed = -7

(6). Fire bullets while running

Shooting bullets while running is the same as firing bullets while standing

To the right

self.rect.x += 24 * 2.5
self.rect.y += 11 * 2.5
self.ySpeed = 0
self.xSpeed = 7

left

self.rect.y += 11 * 2.5
self.ySpeed = 0
self.xSpeed = -7

complete code

if person.isStanding:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            self.rect.x += 10 * 2.5
            self.rect.y += -1 * 2.5
            self.ySpeed = -7
            self.xSpeed = 0
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    else:
        if person.isUp:
            self.rect.x += 10 * 2.5
            self.rect.y += -1 * 2.5
            self.ySpeed = -7
            self.xSpeed = 0
        else:
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = -7

elif person.isSquating and not person.isWalking:
    if person.direction == Direction.RIGHT:
        self.rect.x += 34 * 2.5
        self.rect.y += 25 * 2.5
        self.ySpeed = 0
        self.xSpeed = 7
    else:
        self.rect.y += 25 * 2.5
        self.ySpeed = 0
        self.xSpeed = -7

elif person.isWalking:
    if person.direction == Direction.RIGHT:
        if person.isUp:
            self.rect.x += 20 * 2.5
            self.rect.y += -1 * 2.5
            self.ySpeed = -7
            self.xSpeed = 7
        elif person.isDown:
            self.rect.x += 21 * 2.5
            self.rect.y += 20 * 2.5
            self.ySpeed = 7
            self.xSpeed = 7
        else:
            self.rect.x += 24 * 2.5
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = 7
    else:
        if person.isUp:
            self.rect.x += -3 * 2.5
            self.rect.y += -1 * 2.5
            self.ySpeed = -7
            self.xSpeed = -7
        elif person.isDown:
            self.rect.x += -3 * 2.5
            self.rect.y += 20 * 2.5
            self.ySpeed = 7
            self.xSpeed = -7
        else:
            self.rect.y += 11 * 2.5
            self.ySpeed = 0
            self.xSpeed = -7

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        pass
    else:
        pass

(7). Fire bullets when jumping

insert image description here

elif person.isJumping or person.state == State.FALL:
    if person.direction == Direction.RIGHT:
        self.rect.x += 16 * 2.5
        self.rect.y += 8 * 2.5
        self.ySpeed = 0
        self.xSpeed = 7
    else:
        self.rect.x += -2 * 2.5
        self.rect.y += 8 * 2.5
        self.ySpeed = 0
        self.xSpeed = -7

Complete bullet class code

import pygame
from Constants import *

class Bullet(pygame.sprite.Sprite):

    def __init__(self, person):
        pygame.sprite.Sprite.__init__(self)
        self.images = [
            loadImage('../Image/Bullet/bullet1.png')
        ]
        self.index = 0
        self.image = self.images[self.index]
        # 速度
        self.xSpeed = 1
        self.ySpeed = 1
        self.rect = pygame.Rect(person.rect)

        if person.isStanding:
            if person.direction == Direction.RIGHT:
                if person.isUp:
                    self.rect.x += 10 * 2.5
                    self.rect.y += -1 * 2.5
                    self.ySpeed = -7
                    self.xSpeed = 0
                else:
                    self.rect.x += 24 * 2.5
                    self.rect.y += 11 * 2.5
                    self.ySpeed = 0
                    self.xSpeed = 7
            else:
                if person.isUp:
                    self.rect.x += 10 * 2.5
                    self.rect.y += -1 * 2.5
                    self.ySpeed = -7
                    self.xSpeed = 0
                else:
                    self.rect.y += 11 * 2.5
                    self.ySpeed = 0
                    self.xSpeed = -7

        elif person.isSquating and not person.isWalking:
            if person.direction == Direction.RIGHT:
                self.rect.x += 34 * 2.5
                self.rect.y += 25 * 2.5
                self.ySpeed = 0
                self.xSpeed = 7
            else:
                self.rect.y += 25 * 2.5
                self.ySpeed = 0
                self.xSpeed = -7

        elif person.isWalking:
            if person.direction == Direction.RIGHT:
                if person.isUp:
                    self.rect.x += 20 * 2.5
                    self.rect.y += -1 * 2.5
                    self.ySpeed = -7
                    self.xSpeed = 7
                elif person.isDown:
                    self.rect.x += 21 * 2.5
                    self.rect.y += 20 * 2.5
                    self.ySpeed = 7
                    self.xSpeed = 7
                else:
                    self.rect.x += 24 * 2.5
                    self.rect.y += 11 * 2.5
                    self.ySpeed = 0
                    self.xSpeed = 7
            else:
                if person.isUp:
                    self.rect.x += -3 * 2.5
                    self.rect.y += -1 * 2.5
                    self.ySpeed = -7
                    self.xSpeed = -7
                elif person.isDown:
                    self.rect.x += -3 * 2.5
                    self.rect.y += 20 * 2.5
                    self.ySpeed = 7
                    self.xSpeed = -7
                else:
                    self.rect.y += 11 * 2.5
                    self.ySpeed = 0
                    self.xSpeed = -7

        elif person.isJumping or person.state == State.FALL:
            if person.direction == Direction.RIGHT:
                self.rect.x += 16 * 2.5
                self.rect.y += 8 * 2.5
                self.ySpeed = 0
                self.xSpeed = 7
            else:
                self.rect.x += -2 * 2.5
                self.rect.y += 8 * 2.5
                self.ySpeed = 0
                self.xSpeed = -7

        # 销毁开关
        self.isDestroy = False

    def move(self):
        self.rect.x += self.xSpeed
        self.rect.y += self.ySpeed
        self.checkBullet()

    def draw(self, window):
        window.blit(self.image, self.rect)

    def checkBullet(self):
        toDestroy = False
        if self.rect.top < 0 or self.rect.top > 600:
            toDestroy = True
        if self.rect.left < 0 or self.rect.right > 900:
            toDestroy = True
        if toDestroy:
            self.isDestroy = True

3. Add fire to the player class

Set the bullet cap in the constants file

# 设置玩家子弹上限
PLAYER_BULLET_NUMBER = 15

Add the launch code to the four state functions of the player class

if keys[pygame.K_j]:
    self.isFiring = True
    if len(playerBulletList) < PLAYER_BULLET_NUMBER:
    	# 设置子弹发射的间隔为150
        if currentTime - self.fireLastTimer  > 150:
            playerBulletList.append(Bullet(self))
            self.fireLastTimer = currentTime

complete player class

import pygame
from Constants import *
from Bullet import Bullet


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, playerBulletList):
        # 更新站或者走的状态
        # 根据状态响应按键
        if self.state == State.STAND:
            self.standing(keys, currentTime, playerBulletList)
        elif self.state == State.WALK:
            self.walking(keys, currentTime, playerBulletList)
        elif self.state == State.JUMP:
            self.jumping(keys, currentTime, playerBulletList)
        elif self.state == State.FALL:
            self.falling(keys, currentTime, playerBulletList)

        # 更新位置
        # 记录前一次的位置坐标
        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, playerBulletList):
        """角色站立"""

        # 设置角色状态
        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
            
        if keys[pygame.K_j]:
            self.isFiring = True
            if len(playerBulletList) < PLAYER_BULLET_NUMBER:
                if currentTime - self.fireLastTimer  > 150:
                    playerBulletList.append(Bullet(self))
                    self.fireLastTimer = currentTime


    def walking(self, keys, currentTime, playerBulletList):
        """角色行走,每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
            
        if keys[pygame.K_j]:
            self.isFiring = True
            if len(playerBulletList) < PLAYER_BULLET_NUMBER:
                if currentTime - self.fireLastTimer  > 150:
                    playerBulletList.append(Bullet(self))
                    self.fireLastTimer = currentTime

    def jumping(self, keys, currentTime, playerBulletList):
        """跳跃"""
        # 设置标志
        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
            
        if keys[pygame.K_j]:
            self.isFiring = True
            if len(playerBulletList) < PLAYER_BULLET_NUMBER:
                if currentTime - self.fireLastTimer  > 150:
                    playerBulletList.append(Bullet(self))
                    self.fireLastTimer = currentTime

    def falling(self, keys, currentTime, playerBulletList):
        # 下落时速度越来越快,所以速度需要一直增加
        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
            
        if keys[pygame.K_j]:
            self.isFiring = True
            if len(playerBulletList) < PLAYER_BULLET_NUMBER:
                if currentTime - self.fireLastTimer  > 150:
                    playerBulletList.append(Bullet(self))
                    self.fireLastTimer = currentTime


4. Modify the main class to enable the player to fire

Since the update() method in the player class has an additional parameter of the bullet list, now we need to modify the main class

Add bullet list to main class

# 子弹
player1BulletList = []

insert image description here
Modify the run() function and pass the bullet list into the update() function

def run(self):

    while not self.isEnd:

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

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

        # 更新窗口
        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()

Modify the update() function

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

Create a display bullet function, created outside the class

def drawPlayerOneBullet(player1BulletList):
    for bullet in player1BulletList:
        if bullet.isDestroy:
            player1BulletList.remove(bullet)
        else:
            bullet.draw(MainGame.window)
            bullet.move()

complete main class code

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


def drawPlayerOneBullet(player1BulletList):
    for bullet in player1BulletList:
        if bullet.isDestroy:
            player1BulletList.remove(bullet)
        else:
            bullet.draw(MainGame.window)
            bullet.move()

class MainGame:

    player1 = None
    allSprites = None

    window = None

    # 子弹
    player1BulletList = []

    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, MainGame.player1BulletList)

            # 获取窗口中的事件
            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, player1BulletList):
        # 更新物体
        currentTime = pygame.time.get_ticks()
        MainGame.allSprites.update(self.keys, currentTime, player1BulletList)
        drawPlayerOneBullet(player1BulletList)
        # 显示物体
        MainGame.allSprites.draw(window)


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

Run it and see the effect
insert image description here
Haha, it’s done

Guess you like

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