学习 Python 之 Pygame 开发魂斗罗(二)

news2024/11/17 19:50:54

学习 Python 之 Pygame 开发魂斗罗(二)

    • 魂斗罗的需求
    • 开始编写魂斗罗
      • 1. 搭建主类框架
      • 2. 设置游戏运行遍历和创建窗口
      • 3. 获取窗口中的事件
      • 4. 创建角色
      • 5. 完成角色更新函数

魂斗罗的需求

魂斗罗游戏中包含很多个物体,现在要对这些物体进行总结

类名包含的操作包含的属性
玩家1类跳跃、行走、落下、更新生命,速度,伤害,方向,类型
玩家2类跳跃、行走、落下、更新生命,速度,伤害,方向,类型
敌人类跳跃、行走、落下、更新生命,速度,伤害,方向,类型
子弹类移动,显示方向,伤害,发射源,速度
桥类、陷阱类、奖励类、BOSS类
音效类播放,停止,设置音乐-
爆炸效果类显示是否可以摧毁
主类

物体总结完毕后,规划一下窗口的大小,下面是我设置的窗口大小

由于地图素材的大小限制,下面这个窗口的大小刚刚合适
在这里插入图片描述

开始编写魂斗罗

那么我们开始来编写魂斗罗吧

1. 搭建主类框架

同样地,先写主类,主类是整个游戏运作的类,我们也可以不用这样的方式,可以使用函数代替

import pygame


class MainGame:

    window = None

    def __init__(self):
        pass

    def run(self):
        pass

if __name__ == '__main__':
    pass

2. 设置游戏运行遍历和创建窗口

魂斗罗游戏不像坦克大战,坦克大战中坦克移动是把图片放到不同的位置,而魂斗罗中,人物移动有移动的动画,跳跃也有跳跃的动画,我们需要设置帧率,通过控制帧率来实现动画效果

首先创建一个常量Constants.py文件,用于存放游戏中使用的常量

from enum import Enum

# 玩家的四种状态
class State(Enum):
    STAND = 1
    WALK = 2
    JUMP = 3
    FALL = 4

# 玩家的方向
class Direction(Enum):
    RIGHT = 1
    LEFT = 2


# 设置窗口大小
SCREEN_HEIGHT = 600
SCREEN_WIDTH = 800
GROUND_HEIGHT = 63

# 玩家x方向速度
PLAYER_X_SPEED = 3

设置遍历和创建窗口

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()

修改一下run()函数

def run(self):
   while not self.isEnd:
       
       # 设置背景颜色
       pygame.display.get_surface().fill((0, 0, 0))

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

完整主类代码

import sys
import pygame
from Constants import *

class MainGame:

    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()

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

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

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

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

运行一下,看看窗口

在这里插入图片描述

3. 获取窗口中的事件

在魂斗罗中,玩家移动是必不可少的操作,因此键盘事件响应是必不可少的

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()

获取窗口中的事件,用于玩家角色移动、发射子弹等操作

在这个游戏中,我规定aswd操控玩家移动,j攻击,k跳跃

import sys
import pygame
from Constants import *

class MainGame:

    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()

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

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

            # 获取窗口中的事件
            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()

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

4. 创建角色

创建一个玩家类,实现玩家的移动和射击,玩家类需要继承
pygame.sprite.Sprite类,用来实现物体的碰撞检测

import pygame
from Constants import *


class PlayerOne(pygame.sprite.Sprite):

    def __init__(self, currentTime):
        pygame.sprite.Sprite.__init__(self)
        pass

    def update(self, playerBulletList, keys, currentTime):
        pass

创建玩家类后,先把玩家图片加载进来,这里需要写一个函数,用来处理图片

在常量Constants.py文件中,写一个函数,用来加载图片

def loadImage(filename, hReverse = False):
    image = pygame.image.load(filename)
    if hReverse:
        image = pygame.transform.flip(image, True, False)
    rect = image.get_rect()
    image = pygame.transform.scale(
        image,
        (int(rect.width * 2.5), int(rect.height * 2.5))
    )
    image = image.convert_alpha()
    return image

这个函数用来设置图片放缩和水平翻转

因为素材中大多数图片都是向右的,如果要得到向左的,必须要进行翻转,为了方便,我就没有处理素材,直接使用了翻转

文件中翻转和缩放代码,在学习 Python 之 Pygame 开发魂斗罗(一)中已经见过了

完整的常量文件

from enum import Enum
import pygame

class State(Enum):
    STAND = 1
    WALK = 2
    JUMP = 3
    FALL = 4
    SQUAT = 5

class Direction(Enum):
    RIGHT = 1
    LEFT = 2

def loadImage(filename, hReverse = False):
    image = pygame.image.load(filename)
    if hReverse:
        image = pygame.transform.flip(image, True, False)
    rect = image.get_rect()
    image = pygame.transform.scale(
        image,
        (int(rect.width * 2.5), int(rect.height * 2.5))
    )
    image = image.convert_alpha()
    return image

# 设置窗口大小
SCREEN_HEIGHT = 600
SCREEN_WIDTH = 800
GROUND_HEIGHT = 63

# 玩家x方向速度
PLAYER_X_SPEED = 3

这里需要注意一点,由于玩家移动时有动画效果,所有我们载入的图片是连续的好几张

下面是图片的素材

链接:https://pan.baidu.com/s/1X7tESkes_O6nbPxfpHD6hQ?pwd=hdly
提取码:hdly

有了素材,开始读取图片吧,修改玩家类的__init__()函数

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),
    ]

图片读取好后,我们需要设置一些索引,用来记录当前应该加载哪一张图片

举个简单的例子,人物向右行走的图片有三张,如下图

在这里插入图片描述
我们需要在人物跑动的时候,循环加载这三张图片,所以要设置一个索引,用来记录当前加载到了哪一张,如果是第三张,那么把索引再变为0,这样下次就又开始加载第一张图片了,循环下去,就可以看到人物跑动的动画了

好,那我们就来设置索引

def __init__(self, currentTime):
	...
    # 角色左右移动下标
    self.imageIndex = 0
    # 角色跳跃下标
    self.upImageIndex = 0
    # 角色斜射下标
    self.obliqueImageIndex = 0
    ...

有了下标还要考虑加载图片的间隔,这个游戏中,在前面我们已经设置了游戏的帧率,为60,就是一秒加载60张图片,如果不设置时间间隔,玩家移动的时候,加载的图片是闪的,因为太快了,看不清楚,所以要设置间隔

首先记录下上次加载的图片的时间,然后在显示玩家图片时,用当前的时间减去上次加载图片的时间,如果相差一定的间隔,那么就让索引+1,超过图片个数就把索引置为0

下面是设置上一次加载图片的时间变量

def __init__(self, currentTime):
	...
    # 上一次显示图片的时间
    self.runLastTimer = currentTime
    self.fireLastTimer = currentTime
    ...

这里要区分一下,因为玩家移动的时候也可以射击,所以移动射击的图片和移动不射击的图片要分开索引,防止混淆

之后设置一下玩家的其他属性

	# 选择当前要显示的图片
    self.image = self.standRightImage
    # 获取图片的rect
    self.rect = self.image.get_rect()
    # 设置角色的状态
    self.state = State.FALL
    # 角色的方向
    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

角色一开始是降落的状态,是因为开始的时候角色从天而降

# 人物当前的状态标志
self.isStanding = False
self.isWalking = False
self.isJumping = True
self.isSquating = False
self.isFiring = False

# 玩家上下的朝向
self.isUp = False
self.isDown = False

这两组属性,用来画出当前角色的图片

完整的角色类代码

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.FALL
        # 角色的方向
        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, playerBulletList, keys, currentTime):
        pass

5. 完成角色更新函数

先根据状态读取下一次操作,再更新玩家位置,再根据方向和状态标志觉得玩家显示的图片

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]

完整的update()函数

def update(self, playerBulletList, keys, currentTime):
    # 更新站或者走的状态
    # 根据状态响应按键
    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]

之后就是对四个状态函数进行完善啦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/370692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【RabbitMQ笔记02】消息队列RabbitMQ七种模式之最简单的模式

这篇文章&#xff0c;主要介绍RabbitMQ消息队列中七种模式里面最简单的使用模式。 目录 一、消息队列的使用 1.1、消息队列七种模式 1.2、最简单的模式使用 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;编写生产者 &#xff08;3&#xff09;编写消费者…

Enhanced ShockBurst (ESB)原文翻译

自我学习为主&#xff0c;同时也为所需要的提供一份资料 官方地址 增强型ShockBurst&#xff08;ESB&#xff09;是一种支持双向数据包通信的基本协议&#xff0c;包括数据包缓冲、数据包确认和丢失数据包的自动重传。ESB以低功耗提供无线通信&#xff0c;并且实现的代码量小且…

数据集市与数据仓库的区别

数据仓库是企业级的&#xff0c;能为整个企业各个部门的运作提供决策支持&#xff1b;而数据集市则是部门级的&#xff0c;一般只能为某个局部范围内的管理人员服务&#xff0c;因此也称之为部门级数据仓库。 1、两种数据集市结构 数据集市按数据的来源分为以下两种 &#x…

MATLAB算法实战应用案例精讲-【数模应用】多元线性回归(MLR)(附Java、python和matlab代码实现)

前言 在回归分析中,如果有两个或两个以上的自变量,就称为多元回归。事实上,一种现象常常是与多个因素相联系的,由多个自变量的最优组合共同来预测或估计因变量,比只用一个自变量进行预测或估计更有效,更符合实际。因此多元线性回归比一元线性回归的实用意义更大。 知识…

Chatgpt 编程 工作实战使用 (国内 镜像)

又到周末&#xff0c;时间像是乘着光阴的箭, 一去不返 &#xff0c; 时间的流逝 似乎没有直觉 &#xff0c;就像哪一座座大山&#xff0c;斗转星移 之间 便拔地而起了&#xff0c; 日复一日年复一年&#xff0c; 的工作使人麻木 &#xff0c;今天不写技术文&#xff0c;写一些有…

Leetcode.1247 交换字符使得字符串相同

题目链接 Leetcode.1247 交换字符使得字符串相同 Rating &#xff1a; 1597 题目描述 有两个长度相同的字符串 s1和 s2&#xff0c;且它们其中 只含有 字符 "x"和 "y"&#xff0c;你需要通过「交换字符」的方式使这两个字符串相同。 每次「交换字符」的时…

C++设计模式(21)——中介者模式

亦称&#xff1a; 调解人、控制器、Intermediary、Controller、Mediator 意图 中介者模式是一种行为设计模式&#xff0c; 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互&#xff0c; 迫使它们通过一个中介者对象进行合作。 问题 假如你有一个创建…

蓄水池抽样算法

蓄水池抽样&#xff0c;也称水塘抽样&#xff0c;是随机抽样算法的一种。基本抽样问题有一批数据&#xff08;假设为一个数组&#xff0c;可以逐个读取&#xff09;&#xff0c;要从中随机抽取一个数字&#xff0c;求抽得的数字下标。常规的抽样方法是&#xff0c;先读取所有的…

Spring IoC 和 Spring AOP

Spring IoC Ioc&#xff08;Inversion of control&#xff1a;即控制反转&#xff09;是一种设计思想&#xff0c;而不是一种具体的技术实现。IoC的思想就是将原本在程序中手动创建对象的控制权交给Spring框架来管理。 不过&#xff0c; IoC 并非 Spring 特有&#xff0c;在其…

蓝桥杯C/C++VIP试题每日一练之龟兔赛跑预测

&#x1f49b;作者主页&#xff1a;静Yu &#x1f9e1;简介&#xff1a;CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家&#xff0c;前端知识交流社区创建者 &#x1f49b;社区地址&#xff1a;前端知识交流社区 &#x1f9e1;博主的个人博客&#xff1a;静Yu的个人博客…

python的类如何使用?兔c同学一篇关于python类的博文概述

本章内容如目录 所示&#xff1a; 文章目录1. 创建和使用类1.1 创建第一个python 类1.2 版本差异1.3 根据类创建实例1. 访问属性2. 调用方法3. 创建多个实例2. 使用类和实例2.1 给属性指定默认值2.2 修改属性的值3. 继承3.1 子类的 __init __()3.2 给子类定义属性和方法3.3 重写…

《如何有效阅读》藤原和博 读书笔记

感想 1、整本书内容零散&#xff1a; 主旨是如何有效阅读&#xff0c;但是阅读方法不成系统&#xff0c;更像是零散的想法&#xff0c;或者说是作者想到什么就写什么。第一遍读完以后&#xff0c;大脑里没有什么整体思路&#xff0c;觉得作者说的有道理&#xff0c;但是没有实…

Django 模型层及ORM介绍二

数据库迁移文件混乱的解决方法 数据库中django_migrations表记录了migrate的‘全过程’&#xff0c;项目各应用中的migrate文件与之对应&#xff0c;否则migrate会报错解决方案&#xff1a; 1、删除所有migrations里所有的000?_xxxx.py&#xff08;__init__.py除外&#xff09…

【模拟集成电路】环路滤波器(LPF)设计

环路滤波器 LPF 设计 前言环路滤波器设计仿真结果各部分链接链接&#xff1a;前言 本文主要内容是对环路滤波器 模块设计设计进行阐述&#xff0c;LPF在电荷泵频率综合器中&#xff0c;主要作用是进行滤波&#xff0c;消除毛刺&#xff0c;因此一个简单的RC就可以起到很好的效果…

软件设计的“SOLID”五大原则

一、单一职责 1、定义 单一职责原则&#xff08;single Responsibility Principle,SRP&#xff09;规定&#xff0c;每一个软件单元&#xff0c;其中包括组件、类和函数&#xff0c;应该只有一个单一且明确定义的职责。 2、特点 一个类应该仅有一个引起它变化的原因&#x…

JavaScript HTML DOM 改变 HTML

文章目录JavaScript HTML DOM 改变 HTML改变 HTML 输出流改变 HTML 内容改变 HTML 属性JavaScript HTML DOM 改变 HTML HTML DOM 允许 JavaScript 改变 HTML 元素的内容。 改变 HTML 输出流 JavaScript 能够创建动态的 HTML 内容&#xff1a; 今天的日期是&#xff1a; Thu …

JDBC-API详解、SQL注入演示、连接池

文章目录JDBC1&#xff0c;JDBC概述1.1 JDBC概念1.2 JDBC本质1.3 JDBC好处2&#xff0c;JDBC快速入门2.1 编写代码步骤2.2 具体操作3&#xff0c;JDBC API详解3.1 DriverManager3.2 Connection &#xff08;事务归我管&#xff09;3.2.1 获取执行对象3.2.2 事务管理3.3 Stateme…

SQL语句 -非空约束 - 唯一约束 - 主键约束 - 默认约束 -外键约束

文章目录约束约束介绍和分类非空约束唯一约束主键约束默认约束案例练习外键约束约束 约束介绍和分类 约束的概念: 约束是作用于表中列上的规则&#xff0c;用于限制加入表的数据 约束的存在保证了数据库中数据的正确性、有效性和完整性 约束的分类如下: 约束名称描述关键字非…

代码随想录【Day25】| 216. 组合总和 III、17. 电话号码的字母组合

216. 组合总和 III 题目链接 题目描述&#xff1a; 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数&#xff0c;并且每种组合中不存在重复的数字。 说明&#xff1a; 所有数字都是正整数。 解集不能包含重复的组合。 示例 1: 输入: k 3, n 7 输…

从中国文化看面试挑人标准

文章目录标准一、面相1. 1 四白眼1.2 浓眉二、讲话2.1 言多与气虚总结本文结合中国面相&#xff0c;是个概率性问题&#xff0c;对于个体无效。 标准 正直&#xff0c;三观正&#xff0c;沟通好&#xff0c;技术。从概率上讲&#xff1a; 正直且三观正的人----有恒心&#x…