学习 Python 之 Pygame 开发魂斗罗(十四)
Posted _DiMinisH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习 Python 之 Pygame 开发魂斗罗(十四)相关的知识,希望对你有一定的参考价值。
学习 Python 之 Pygame 开发魂斗罗(十四)
继续编写魂斗罗
在上次的博客学习 Python 之 Pygame 开发魂斗罗(十三)中,我们加入了敌人2的类,创建了新的敌人,这次我们加入桥。
下面是图片的素材
链接:https://pan.baidu.com/s/1X7tESkes_O6nbPxfpHD6hQ?pwd=hdly
提取码:hdly
1. 创建桥类
import pygame
from Constants import *
class Bridge:
def __init__(self, x, y, typeInfo):
if typeInfo == BridgeType.ON:
self.image = loadImage('../Image/Map/1/Bridge/bridgeOn.png')
elif typeInfo == BridgeType.BODY:
self.image = loadImage('../Image/Map/1/Bridge/bridgeBody.png')
else:
self.image = loadImage('../Image/Map/1/Bridge/bridgeDown.png')
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.isDestroy = False
def draw(self, window: pygame.Surface):
window.blit(self.image, self.rect)
这里会有报错,因为在Constants.py中没有定义BridgeType.ON
BridgeType是桥的类型,魂斗罗中桥的图片有三种,所以对应三个类型
我们在Constants.py中定义一下
class BridgeType(Enum):
ON = 1
BODY = 2
DOWN = 3
2. 在主类中加入一些类变量
加入一个列表,用来存放桥
加入一个通用碰撞体组,存放敌人和玩家都可以碰的碰撞体
commonColliderGroup = None
bridgeList = []
有了列表和碰撞体组后,现在就可以创建桥了
魂斗罗的第一关有两座桥,下面是创建桥的函数
def initBridge():
bridge1_1 = Bridge(1920, int(113 * MAP_SCALE), BridgeType.ON)
bridge1_2 = Bridge(1980, int(113 * MAP_SCALE), BridgeType.BODY)
bridge1_3 = Bridge(2040, int(113 * MAP_SCALE), BridgeType.BODY)
bridge1_4 = Bridge(2100, int(113 * MAP_SCALE), BridgeType.BODY)
bridge1_5 = Bridge(2160, int(113 * MAP_SCALE), BridgeType.BODY)
bridge1_6 = Bridge(2180, int(113 * MAP_SCALE), BridgeType.DOWN)
bridge2_1 = Bridge(2640, int(113 * MAP_SCALE), BridgeType.ON)
bridge2_2 = Bridge(2700, int(113 * MAP_SCALE), BridgeType.BODY)
bridge2_3 = Bridge(2760, int(113 * MAP_SCALE), BridgeType.BODY)
bridge2_4 = Bridge(2820, int(113 * MAP_SCALE), BridgeType.BODY)
bridge2_5 = Bridge(2880, int(113 * MAP_SCALE), BridgeType.BODY)
bridge2_6 = Bridge(2900, int(113 * MAP_SCALE), BridgeType.DOWN)
# 桥的碰撞体,设置为绿色
bridgeCollide1_1 = Collider(1920, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide1_2 = Collider(1980, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide1_3 = Collider(2040, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide1_4 = Collider(2100, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide1_5 = Collider(2160, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide1_6 = Collider(2180, 119 * MAP_SCALE, 0.8 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide2_1 = Collider(2640, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide2_2 = Collider(2700, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide2_3 = Collider(2760, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide2_4 = Collider(2820, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide2_5 = Collider(2880, 119 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
bridgeCollide2_6 = Collider(2900, 119 * MAP_SCALE, 0.8 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE, (0, 255, 0))
# 把桥加入列表
MainGame.bridgeList.append(bridge1_1)
MainGame.bridgeList.append(bridge1_2)
MainGame.bridgeList.append(bridge1_3)
MainGame.bridgeList.append(bridge1_4)
MainGame.bridgeList.append(bridge1_5)
MainGame.bridgeList.append(bridge1_6)
MainGame.bridgeList.append(bridge2_1)
MainGame.bridgeList.append(bridge2_2)
MainGame.bridgeList.append(bridge2_3)
MainGame.bridgeList.append(bridge2_4)
MainGame.bridgeList.append(bridge2_5)
MainGame.bridgeList.append(bridge2_6)
# 把桥碰撞体加入通用碰撞体组
MainGame.commonColliderGroup = pygame.sprite.Group(
bridgeCollide1_1, bridgeCollide1_2, bridgeCollide1_3, bridgeCollide1_4, bridgeCollide1_5, bridgeCollide1_6,
bridgeCollide2_1, bridgeCollide2_2, bridgeCollide2_3, bridgeCollide2_4, bridgeCollide2_5, bridgeCollide2_6,
)
有了创建桥的函数,下面要调用一下,在主类的__init__
函数中调用
接下来修改主类的mapObjectMove
函数,让桥也随着玩家的镜头移动
def mapObjectMove(self):
for sprite in MainGame.allSprites:
sprite.rect.x -= self.cameraAdaption
for collider in MainGame.playerColliderGroup:
collider.rect.x -= self.cameraAdaption
for collider in MainGame.colliderStack:
collider.rect.x -= self.cameraAdaption
for collider in MainGame.enemyColliderGroup:
collider.rect.x -= self.cameraAdaption
for collider in MainGame.commonColliderGroup:
collider.rect.x -= self.cameraAdaption
for bridge in MainGame.bridgeList:
bridge.rect.x -= self.cameraAdaption
for explode in MainGame.explodeList:
explode.rect.x -= self.cameraAdaption
for bullet in MainGame.enemyBulletList:
bullet.rect.x -= self.cameraAdaption
3. 显示桥
在主类的update
函数中,写一个显示桥的函数
def drawBridge(bridgeList):
for b in bridgeList:
if b.isDestroy:
bridgeList.remove(b)
else:
b.draw(MainGame.window)
这是一个全局函数,写在主类外面
现在,运行一下程序,看看效果
桥就出现了,但是碰撞体没有起作用,玩家还是会从桥上掉下来,下面就来解决一下这个问题
4. 解决玩家与桥的碰撞体问题
首先在update
函数中加入如下代码,让桥的碰撞体的绿线显示出来
此时运行游戏就看到了绿线了
接下来需要增加一些变量,用来出来桥的行为
self.bridgeExploding = False
这个变量用来记录当前桥是否处于爆炸的状态
在__init__
函数的最后加入如下代码
该列表的作用是,记录下来哪一个桥发生了碰撞
处理桥的总体逻辑思路是这样的:当玩家碰到桥时,记录下来发生碰撞的桥,让self.bridgeExploding=True,表示有桥发生了碰撞,然后把发生碰撞的桥加入hasCollidedBridge列表,这个列表用于记录上一个玩家发生碰撞的是哪一个桥,之后在一个函数中,处理爆炸的桥。
下面修改一下玩家与物体碰撞的逻辑
来到updatePlayerPosition
函数,在下面的位置加入逻辑
加入玩家与桥发生碰撞的逻辑
# 玩家与桥碰撞的逻辑
if c := pygame.sprite.spritecollideany(tempPlayer, MainGame.commonColliderGroup):
MainGame.player1.isInWater = False
# 玩家碰到桥
if not self.bridgeExploding:
self.bridgeExploding = True
# 把碰到的桥放到列表里
self.hasCollidedBridge.append(c)
# MainGame.commonColliderGroup.remove(c)
else:
# 获取玩家中心
center = MainGame.player1.getCenter()
# 遍历桥列表,看看玩家中心当前在哪一个桥的范围内
for bridge in MainGame.bridgeList:
# 计算位置,是不是当前的桥(桥有好几块,判断当前块)走到了2/3
if bridge.rect.x + bridge.rect.width * 2 / 3 < center[0] < bridge.rect.x + bridge.rect.width:
# 找到了,那么就让这个桥爆炸
self.bridgeExploding = True
# 删除碰撞体
for collider in MainGame.commonColliderGroup:
if collider.rect.x < center[0] < collider.rect.x + collider.rect.width:
MainGame.commonColliderGroup.remove(collider)
这个的逻辑分为两个,一个是玩家走到桥上,桥要爆炸,还有一个是玩家走到桥的位置,桥要爆炸
在“玩家走到桥的位置,桥要爆炸”的逻辑里,我设置了一个范围,当玩家走到桥的三分之二的位置时,那么当前的这个位置的桥就要发生爆炸
接下来写一下处理桥爆炸的逻辑
def bridgeExplode(self):
if self.bridgeExploding:
self.bridgeExploding = False
if len(MainGame.bridgeList) > 0:
# 取出第一个, 创建爆炸,放入爆炸列表
bridge = MainGame.bridgeList[0]
# 把该桥移除
MainGame.bridgeList.remove(bridge)
# 创建爆炸,指定爆炸类型,并且是按照时间来显示爆炸图片
explode = Explode(bridge, ExplodeVariety.BRIDGE, True)
# 设置时间
explode.lastTime = pygame.time.get_ticks()
MainGame.explodeList.append(explode)
# 检查列表中是不是有元素
if len(self.hasCollidedBridge) > 0:
# 把第一个元素取出来,并且删除这个元素,这里是碰撞的桥会被放到列表里,所以删除的是碰到的桥
c = self.hasCollidedBridge.pop()
MainGame.commonColliderGroup.remove(c)
之后在update
函数中调用一下
ok,现在就应该实现了桥爆炸了
可以看到玩家经过,桥就会爆炸了
此时敌人踩到桥上,会落下去,我们把这个问题解决一下
5. 解决敌人与桥的碰撞体问题
来到主类的全局函数updateEnemyPosition
修改一下其中的逻辑
因为敌人分为两种,一个可以移动,一个不能移动
在类型1的敌人里,加入如下代码,让它可以与通用类碰撞体进行碰撞检测
好了,我们运行一下游戏,看看情况
成功实现敌人可以在桥上走动
下面是完整的代码
完整的主类代码
import copy
import sys
import pygame
from Constants import *
from PlayerOne import PlayerOne
from Collider import Collider
from Enemy1 import Enemy1
from Explode import Explode
from Enemy2 import Enemy2
from Bridge import Bridge
def drawPlayerOneBullet(player1BulletList):
for bullet in player1BulletList:
if bullet.isDestroy:
player1BulletList.remove(bullet)
else:
bullet.draw(MainGame.window)
bullet.move()
bullet.collideEnemy(MainGame.enemyList, MainGame.explodeList)
def enemyUpdate(enemyList, enemyBulletList):
# 遍历整个敌人列表
for enemy in enemyList:
if enemy.type == 1:
if enemy.isDestroy:
enemyList.remove(enemy)
MainGame.allSprites.remove(enemy)
MainGame.enemyGroup.remove(enemy)
else:
enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y)
enemy.draw(pygame.time.get_ticks())
enemy.move(pygame.time.get_ticks())
enemy.fire(enemyBulletList)
elif enemy.type == 2:
if enemy.isDestroy:
enemyList.remove(enemy)
MainGame.allSprites.remove(enemy)
MainGame.enemyGroup.remove(enemy)
else:
enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y)
enemy.draw(MainGame.window, MainGame.player1, pygame.time.get_ticks())
enemy.fire(enemyBulletList, MainGame.player1)
def updateEnemyPosition():
# 遍历全部敌人列表
for enemy in MainGame.enemyList:
if enemy.type == 1:
# 创建一个复制
t = copy.copy(enemy)
t.rect.y += 1
# 让复制的y加1,看看有没有发生碰撞,这里看的碰撞是enemyColliderGroup和commonColliderGroup中的碰撞
collide = pygame.sprite.spritecollideany(t, MainGame.enemyColliderGroup) \\
or pygame.sprite.spritecollideany(t, MainGame.commonColliderGroup)
# 没有发生碰撞,让敌人下落
if not collide:
enemy.rect.y += 4
enemy.isFalling = True
# 改变下落时的图片
enemy.image = enemy.rightFallImage if enemy.direction == Direction.RIGHT else enemy.leftFallImage
else:
enemy.isFalling = False
# 如果与河发生碰撞,表示敌人落到了水中,那么敌人直接死亡
if collide in MainGame.enemyRiverGroup:
enemy.isDestroy = True
MainGame.explodeList.append(Explode(enemy))
t.rect.y -= 1
elif enemy.type == 2:
t = copy.copy(enemy)
t.rect.y += 1
collide = pygame.sprite.spritecollideany(t, MainGame.enemyColliderGroup)
if not collide:
enemy.rect.y += 1
t.rect.y -= 1
def drawEnemyBullet(enemyBulletList):
for bullet in enemyBulletList:
if bullet.isDestroy:
enemyBulletList.remove(bullet)
else:
bullet.draw(MainGame.window)
bullet.move()
if bullet.collidePlayer(MainGame.player1, MainGame.explodeList):
initPlayer1(MainGame.player1.life)
def initLand():
land1 = Collider(81, 119 * MAP_SCALE, 737 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
# land1 = Collider(81, 119 * MAP_SCALE, 8000 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land2 = Collider(400, 151 * MAP_SCALE, 96 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land3 = Collider(640, 183 * MAP_SCALE, 33 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land4 = Collider(880, 183 * MAP_SCALE, 33 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land5 = Collider(720, 215 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land6 = Collider(1040, 154 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land7 = Collider(1600, 166 * MAP_SCALE, 3 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land8 = Collider(1120 * RATIO, 215 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land9 = Collider(1650 * RATIO, 119 * MAP_SCALE, 5 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE)
land10 = Collider(2185 * RATIO, 119 * MAP_SCALE, 8 * LAND_LENGTH * MAP_SCALE学习 Python 之 Pygame 开发魂斗罗
学习 Python 之 Pygame 开发魂斗罗(一)
Pygame
回忆Pygame
在之前的学习中,咱们使用Pygame开发出了坦克大战,这次再使用Pygame开发魂斗罗,如果有想学习开发坦克大战的小伙伴,可以看看下面的博客
下面再回顾一下Pygame创建窗口、播放音乐等操作
函数名称 作用 返回值 pygame.display.init() 初始化展示模块 None pygame.display.set_mode(size = (0, 0)) 初始化窗口(窗口就是一个Surface对象) Surface pygame.display.set_caption(title, icontitle = None) 设置窗口标题和图标 None pygame.Surface.fill(color, rect = None) 用纯色填充表面Surface对象 None pygame.Color(b, g, r) 创建用于颜色表示的Pygame对象 Color pygame.display.update() 更新屏幕 None pygame.event.get() 获取事件队列 Eventlist pygame.image.load(filename) 从文件加载图片(图片跟窗口一样,也是Surface对象) Surface pygame.Surface.get_rect() 获取Surface对象的rect属性 Rect pygame.Surface.blit(source, dest, area = None) 在一个Surface对象上显示另一个Surface对象 Rect pygame.font.init() 初始化字体模块 None pygame.font.SysFont(name, size, bold = False, italic = False) 从系统字体创建字体对象 Font pygame.font.render(text, antialias, color, background = None) 创建一个带有指定字体的Surface对象 Surface pygame.mixer.init() 初始化混合器模块 None pygame.mixer.Sound(filename) 从文件创建声音对象 Sound pygame.mixer.Sound.play(loops = 0, maxtime = 0) 播放音乐,loops参数控制播放次数,播放次数为loops + 1次。默认为0,表示声音不会重复,只播放一次。如果loops为-1,声音将无限循环 Channel pygame.mixer.Sound.stop() 声音停止播放 None pygame.mixer.Sound.set_volume(value) 设置音量 None pygame.transform.flip(surface, flip_x, flip_y) 图片翻转 Surface pygame.transform.scale(surface, size) 将图片(Surface对象)调整为大小为(width, height)的新图片 Surface pygame.time.Clock() 用于帮助跟踪时间以及控制游戏帧速率的类 Clock pygame.time.Clock.tick(framerate = 0) 设置游戏运行的帧率 milliseconds pygame.time.Clockget_fps() 计算游戏的帧速率(以帧每秒为单位) float
1. 使用pygame创建窗口
import pygame
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Contra')
创建结果
窗口一闪而过
2. 设置窗口背景颜色
# 设置窗口背景颜色
blue = 255
green = 0
red = 255
BACKGROUND_COLOR = pygame.Color(blue, green, red)
window.fill(BACKGROUND_COLOR)
# 更新窗口
pygame.display.update()
完整代码
import pygame
import time
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 1100
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Tank Battle')
# 设置窗口背景颜色
blue = 255
green = 0
red = 255
BACKGROUND_COLOR = pygame.Color(blue, green, red)
window.fill(BACKGROUND_COLOR)
# 更新窗口
pygame.display.update()
# 让程序休眠200秒,方便观察窗口的变化
time.sleep(200)
不要忘记更新窗口
,否则不会显示颜色的
实际上,颜色可以不用使用 pygame.Color(blue, green, red) 来创建,直接使用元组的方式
WHITE = (255, 255, 255)
这样的方式传入
window.fill(WHITE)
也是可以生效的,为了方便直接用红绿蓝序列即可
3. 获取窗口中的事件
def getWindowEvent():
for event in pygame.event.get():
# 点击窗口右上角的关闭触发的事件
if event.type == pygame.QUIT:
sys.exit()
# 鼠标按下事件
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = event.pos
print('鼠标按下, 鼠标位置(x, y)'.format(x = x, y = y))
# 鼠标抬起事件
elif event.type == pygame.MOUSEBUTTONUP:
print('鼠标抬起')
# 键盘按键按下事件
elif event.type == pygame.KEYDOWN:
print('键盘按键按下')
# 具体键盘事件触发
if event.key == pygame.K_j:
print('按下键盘 j 键')
# 键盘按键抬起事件
elif event.type == pygame.KEYUP:
print('键盘按键抬起')
完整代码
import pygame
import sys
def getWindowEvent():
for event in pygame.event.get():
# 点击窗口右上角的关闭触发的事件
if event.type == pygame.QUIT:
sys.exit()
# 鼠标按下事件
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = event.pos
print('鼠标按下, 鼠标位置(x, y)'.format(x = x, y = y))
# 鼠标抬起事件
elif event.type == pygame.MOUSEBUTTONUP:
print('鼠标抬起')
# 键盘按键按下事件
elif event.type == pygame.KEYDOWN:
print('键盘按键按下')
# 具体键盘事件触发
if event.key == pygame.K_j:
print('按下键盘 j 键')
# 键盘按键抬起事件
elif event.type == pygame.KEYUP:
print('键盘按键抬起')
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 1100
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Contra')
# 设置窗口背景颜色
blue = 255
green = 0
red = 255
BACKGROUND_COLOR = pygame.Color(blue, green, red)
window.fill(BACKGROUND_COLOR)
while 1:
# 获取键盘事件
getWindowEvent()
# 更新窗口
pygame.display.update()
运行后按下鼠标左键,键盘s键,键盘w键
结果
鼠标按下, 鼠标位置(355, 170)
鼠标抬起
键盘按键按下
键盘按键抬起
键盘按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
W按键按下
键盘按键抬起
系统的事件都具有一组成员属性。下面是事件类型及其特定属性的列表图(图片来源链接)
在 学习 Python 之 Pygame 开坦克大战(一)中,我们使用的是另一种形式,这两种差别不大,大家仔细对比一下
在上面的结果中,“W按键按下”打印的次数与窗口的帧率有关系,在下面我们会说到
4. 在窗口中展示图片
(1). pygame中的直角坐标系
(2). 展示图片
import pygame
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 1100
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Contra')
# 设置图片路径
path = '../Image/Map/第一关BG.png'
# 加载图片
image = pygame.image.load(path)
# 获取直角坐标
rect = image.get_rect()
# 设置图片的位置,在(0,0)处加载图片
rect.left = 0
rect.top = 0
# 在窗口显示
window.blit(image, rect)
while 1:
# 更新窗口
pygame.display.update()
(3). 给部分区域设置颜色
import pygame
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Contra')
# 设置窗口背景颜色
blue = 255
green = 0
red = 255
BACKGROUND_COLOR = pygame.Color(blue, green, red)
window.fill(BACKGROUND_COLOR)
# 给部分区域设置颜色
rect = pygame.Rect(200, 200, 200, 300)
REGION_COLOR = pygame.Color(50, 50, 150)
window.fill(REGION_COLOR, rect)
while 1:
# 更新窗口
pygame.display.update()
5. 在窗口中显示文字
import pygame
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Contra')
# 设置文字内容
text = 'Hello Pygame'
# 初始化字体
pygame.font.init()
# 设置文字字体和大小
fontSize = 16
font = pygame.font.SysFont('georgia', fontSize)
# 加载文字并设置颜色
fontColor = pygame.Color(255, 255, 255)
fontObject = font.render(text, True, fontColor)
# 设置展示位置
position = (50, 50)
# 展示文字
window.blit(fontObject, position)
while 1:
# 更新窗口
pygame.display.update()
运行结果
6. 播放音乐
import pygame
# 初始化混合器模块
pygame.mixer.init()
# 加载音乐
sound = pygame.mixer.Sound('./star.wav')
# 播放音乐
sound.play()
7. 图片翻转与缩放
import time
import pygame
def enlarge(image: pygame.Surface, scale):
"""
缩放图片
:param image: 要缩放的图片
:param scale: 图片缩放尺寸
:return: 缩放后的图片
"""
# 获取图片大小
rect = image.get_rect()
# 长宽扩大 scale 倍
largeSize = (int(rect.width * scale), int(rect.height * scale))
# 对图片缩放
large = pygame.transform.scale(origin, largeSize)
return large
def flip(image: pygame.Surface, h, v):
"""
图片翻转
:param image: 要翻转的图片
:param h: 是否水平翻转
:param v: 是否上下翻转
:return: 翻转后的图片
"""
return pygame.transform.flip(image, h, v)
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Contra')
# 加载原图
origin = pygame.image.load('../Image/Map/第一关BG.png')
# 显示原图
rect = origin.get_rect()
rect.x = 0
rect.y = 0
window.blit(origin, rect)
# 更新窗口
pygame.display.update()
time.sleep(2)
# 图片缩放2.5倍
large = enlarge(origin, 2.5)
# 显示原图
rect = large.get_rect()
rect.x = 0
rect.y = 0
window.blit(large, rect)
# 更新窗口
pygame.display.update()
time.sleep(2)
# 图片翻转
img = flip(large, True, False)
# 显示原图
rect = img.get_rect()
rect.x = 0
rect.y = 0
window.blit(img, rect)
# 更新窗口
pygame.display.update()
time.sleep(2)
先看看原图
放大2.5倍的图
翻转图片,这里是左右翻转,图片的最后是BOSS关,翻转过来就先显示BOSS关卡啦
水平翻转大家可以自己试一试
自己封装的图片缩放函数
def enlarge(image: pygame.Surface, scale):
"""
缩放图片
:param image: 要缩放的图片
:param scale: 图片缩放尺寸
:return: 缩放后的图片
"""
# 获取图片大小
rect = image.get_rect()
# 长宽扩大 scale 倍
largeSize = (int(rect.width * scale), int(rect.height * scale))
# 对图片缩放
large = pygame.transform.scale(origin, largeSize)
return large
自己封装的图片翻转函数
def flip(image: pygame.Surface, h, v):
"""
图片翻转
:param image: 要翻转的图片
:param h: 是否水平翻转
:param v: 是否上下翻转
:return: 翻转后的图片
"""
return pygame.transform.flip(image, h, v)
8. 设置游戏帧率
创建一个对象来帮助跟踪时间,并设置帧率
clock = pygame.time.Clock()
fps = 60
在循环中设置帧率,并把帧率显示在标题上
while 1:
# 设置帧率
clock.tick(fps)
r = clock.get_fps()
caption = 'Contra - :.2f'.format(r)
pygame.display.set_caption(caption)
# 更新窗口
pygame.display.update()
完整代码
import pygame
# 初始化展示模块
pygame.display.init()
# 设置窗口大小
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
size = (SCREEN_WIDTH, SCREEN_HEIGHT)
# 初始化窗口
window = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption('Contra')
clock = pygame.time.Clock()
fps = 60
while 1:
# 设置帧率
clock.tick(fps)
r = clock.get_fps()
caption = 'Contra - :.2f'.format(r)
pygame.display.set_caption(caption)
# 更新窗口
pygame.display.update()
看看结果,可以看到窗口上有帧率显示了,60表示 1秒窗口要刷新60次
以上是关于学习 Python 之 Pygame 开发魂斗罗(十四)的主要内容,如果未能解决你的问题,请参考以下文章