九、小白如何用Pygame制作一款跑酷类游戏(添加前进小动物作为动态障碍物)

九、小白如何用Pygame制作一款跑酷类游戏(添加前进小动物作为动态障碍物)


文章目录


前言

本篇文章主要分享如何添加向前移动的小动物作为动态的障碍物,一个是飞行障碍物主角可以通过滑行躲避,另一个是爬行障碍物可以通过跳跃躲避。


一、添加小动物素材

1. 在根目录的图片文件夹下新建两个目录分别存放爬行障碍物和飞行障碍物。

2. 图片示例


二、代码部分

1.创建飞行小动物的精灵类

python 复制代码
import pygame.sprite
class Badman(pygame.sprite.Sprite):
    def __init__(self):
        super(Badman,self).__init__()
        self.image=pygame.image.load('material/image/badman/badman3.1.PNG').convert_alpha()
        self.images=[pygame.image.load('material/image/badman/badman3.{:d}.png'.format(i)).convert_alpha() for i in range(1,6)]
        self.rect = self.images[0].get_rect()
        self.loc = 500
        self.speed = 1

    def update(self, *args):
        if args[0] % 10 == 0:
            i = int(args[0] / 10)
            self.image = self.images[i % len(self.images)]
        if self.rect.left < 0:
            self.kill()
        else:
            self.rect.left -= self.speed

1.创建爬行小动物的精灵类

代码如下:

python 复制代码
# -*- codeing = utf-8 -*-
# @Time : 2023/2/24 10:30
# @Author : 小马
# @File: enemy.py
# @Software : PyCharm
import pygame.sprite
class mantis(pygame.sprite.Sprite):
    def __init__(self):
        super(mantis,self).__init__()
        self.image=pygame.image.load('material/image/mantis/b5.1.PNG').convert_alpha()
        self.images=[pygame.image.load('material/image/mantis/b5.{:d}.png'.format(i)).convert_alpha() for i in range(1,16)]
        self.rect = self.images[0].get_rect()
        self.loc=500
        self.speed = 1
        self.rect.left = 770
    def update(self, *args):
         if args[0] % 10 == 0:
             i = int(args[0] / 10)
             self.image=self.images[i%len(self.images)]
         if self.rect.left<0:
            self.kill()
         else:
            self.rect.left -= self.speed

3.在左半部分按随机数添加飞行或者爬行

代码如下:

c 复制代码
        if left<=-1080:
            left=left+2160
            random_number = random.randint(1, 2)
            if random_number == 1:
                badman=Badman()
                badman.rect.top = 360
                enemyGroup.add(badman)
            if random_number == 2:
                enemyone = mantis()
                enemyone.rect.top = 440
                enemyGroup.add(enemyone)
        if -1080<left<1080:
            for sprite in enemyGroup:
                sprite.rect.left=sprite.loc+left*1.5
                if pygame.sprite.collide_mask(sprite, myself):
                    injure = pygame.mixer.Sound('material/music/injure1.mp3')
                    pygame.mixer.Sound.play(injure)
                    myself.life -= 1
                    sprite.kill()

            enemyGroup.draw(screen)
            enemyGroup.update(index)

4.runner_main的全部代码

python 复制代码
import pygame

from Badman import Badman
from Gold import Gold
import random
from Myself import Myself
import os

from mantis import mantis


pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((1080, 600))
pygame.display.set_caption('跑酷游戏')
#背景图
bg_image_path1 = 'material/image/background4.jpg'
bg_img_obj1 = pygame.image.load(bg_image_path1).convert_alpha()
#道路图
road_image_path= 'material/image/road1.png'
road_img_obj=pygame.image.load(road_image_path).convert_alpha()
#距离图
km_image_path= 'material/image/km.png'
km_img_obj=pygame.image.load(km_image_path).convert_alpha()
#按键图
keyUp_image_path= 'material/image/keyboardUpUp.png'
keyUp_img_obj=pygame.image.load(keyUp_image_path).convert_alpha()
keyLeft_image_path= 'material/image/keyboardLEFT.png'
keyLeft_img_obj=pygame.image.load(keyLeft_image_path).convert_alpha()
keyDown_image_path= 'material/image/keyboardDown.png'
keyDown_img_obj=pygame.image.load(keyDown_image_path).convert_alpha()
font_path = 'material/ziti/AlimamaFangYuanTiVF-Thin-2.ttf'  # 例如 'SimSun.ttf'
chinese_font = pygame.font.Font(font_path, 30)
text_surface = chinese_font.render('跳跃', True, (0, 0, 255))
text1_surface = chinese_font.render('疾跑', True, (0, 0, 255))
text2_surface = chinese_font.render('滑行', True, (0, 0, 255))
#创建两个存放障碍图片对象的数组
#存放向上的
uplist=[]
#存放向下的
downlist=[]
upadress=['up1.png','up2.png','up3.png','up4.png']
downadress=['platform1.png','platform2.png','platform3.png','platform4.png','platform5.png']
#根据图像的位置加入到相应的数组当中
for i in range(len(downadress)):
         stone_image_path= 'material/image/stone/'+downadress[i]
         stone_img_obj=pygame.image.load(stone_image_path).convert_alpha()
         downlist.append(stone_img_obj)
for i in range(len(upadress)):
         stone_image_path= 'material/image/stone/'+upadress[i]
         stone_img_obj=pygame.image.load(stone_image_path).convert_alpha()
         uplist.append(stone_img_obj)
#因为金币不唯一,所以创建一个精灵族来存放所有的金币精灵
goldGroup = pygame.sprite.Group()
enemyGroup = pygame.sprite.Group()
barriarMargin=290
#图片初始化
heart_image_path= 'material/image/heart.png'
heart_img_obj=pygame.image.load(heart_image_path).convert_alpha()
gold_image_path= 'material/image/gold.png'
gold_img_obj=pygame.image.load(gold_image_path).convert_alpha()
def init():
    global badman
    fps = 60
    running = True
    index = 0
    left = 0
    right = 1080
    margin = 3
    myself = Myself()
    pygame.mixer.music.load(os.path.join('material/music', 'bgm1.mp3'))
    pygame.mixer.music.play(-1)
    km = '0'
    goldnum = '0'
    #标志位是否暂停
    isPause = False
    barrier = []
    while running:
        # 获取键盘的按下事件,与抬起不同
        keys = pygame.key.get_pressed()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            #空格键作为暂停键 当空格键抬起时触发暂停动作
            #如果当前是运动状态,抬起空格变为暂停
            #如果当前是暂停状态,抬起空格变为运动
            elif event.type == pygame.KEYUP:
                if not isPause:
                    if event.key == pygame.K_SPACE:
                        isPause = True
                else:
                    if event.key == pygame.K_SPACE:
                        isPause = False
        #暂停状态下,道路不会向左滑动
        if isPause:
            margin=0
        else:
            margin=3

        #通过提升道路的滑动效果体现出疾跑的效果
        if keys[pygame.K_RIGHT]:
            margin=8
        screen.blit(bg_img_obj1, (0, 0))
        screen.blit(road_img_obj, (left, 465))
        screen.blit(road_img_obj, (right, 465))
        #键位介绍
        screen.blit(keyUp_img_obj, (900, 5))
        screen.blit(text_surface, (980, 23))
        screen.blit(keyLeft_img_obj, (900, 70))
        screen.blit(text1_surface, (980, 88))
        screen.blit(keyDown_img_obj, (900, 135))
        screen.blit(text2_surface, (980, 148))
        #根据生命值绘制血量
        for i in range(0,myself.life):
            screen.blit(heart_img_obj,(10+i*70,5))
        if left<=-1080:
            left=left+2160
            random_number = random.randint(1, 2)
            if random_number == 1:
                badman=Badman()
                badman.rect.top = 360
                enemyGroup.add(badman)
            if random_number == 2:
                enemyone = mantis()
                enemyone.rect.top = 440
                enemyGroup.add(enemyone)
        if -1080<left<1080:
            for sprite in enemyGroup:
                sprite.rect.left=sprite.loc+left*1.5
                if pygame.sprite.collide_mask(sprite, myself):
                    injure = pygame.mixer.Sound('material/music/injure1.mp3')
                    pygame.mixer.Sound.play(injure)
                    myself.life -= 1
                    sprite.kill()

            enemyGroup.draw(screen)
            enemyGroup.update(index)


        if right<=-1080:
            right=right+2160
            #计划在右半边的时候加入静态的障碍,所以要在某一时刻确定要加入的对象
            #于是在当右半边移动到左边尽头的时候确定下来接下来的对象
            #这里采用随机数的方法
            barrier = []
            for i in range(0,4):
                random_number = random.randint(1, 15)
                if 10 <= random_number <= 15:
                        gold1=Gold()
                        gold2=Gold()
                        gold3=Gold()
                        gold1.loc=i*barriarMargin
                        gold2.loc=i*barriarMargin+1*70
                        gold3.loc=i*barriarMargin+2*70
                        goldGroup.add(gold1)
                        goldGroup.add(gold2)
                        goldGroup.add(gold3)
                        barrier.append(1)
                elif random_number == 1:
                    barrier.append(2)
                elif random_number == 2:
                    barrier.append(3)
                elif random_number == 3:
                    barrier.append(4)
                elif random_number == 4:
                    barrier.append(5)
                elif random_number == 5:
                    barrier.append(6)
                elif random_number == 6:
                    barrier.append(7)
                elif random_number == 7:
                    barrier.append(8)
                elif random_number == 8:
                    barrier.append(9)
                elif random_number == 9:
                    barrier.append(10)
        if -1080<right<1080:
            for sprite in goldGroup:
                sprite.rect.left=sprite.loc+right
            goldGroup.draw(screen)
            goldGroup.update(index)
            for i in range(len(barrier)):
                if barrier[i]==2:
                    a = uplist[0]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 465)
                elif barrier[i]==1:
                    continue
                elif barrier[i]==3:
                    a = uplist[1]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 460)
                elif barrier[i]==4:
                    a = uplist[2]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 455)
                elif barrier[i]==5:
                    a = uplist[3]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 460)
                elif barrier[i]==6:
                    a = downlist[0]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 330)
                elif barrier[i]==7:
                    a = downlist[1]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 350)
                elif barrier[i]==8:
                    a = downlist[2]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 365)
                elif barrier[i]==9:
                    a = downlist[3]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 350)
                elif barrier[i]==10:
                    a = downlist[4]
                    arect = a.get_rect()
                    arect.topleft = (right + i*barriarMargin, 210)
                start_x = arect.width // 3
                middle_third_width = arect.width // 3
                # 提取中间三分之一区域
                middle_third_rect = (start_x, 0, middle_third_width, arect.height)
                middle_third_surface = a.subsurface(middle_third_rect)
                mrect = middle_third_surface.get_rect()
                mrect.topleft = (arect.left + arect.width // 3, arect.top)
                if mrect.colliderect(myself.rect):
                    injure = pygame.mixer.Sound('material/music/injure1.mp3')
                    pygame.mixer.Sound.play(injure)
                    barrier[i] = 1
                    myself.life -= 1
                else:
                    screen.blit(a, arect)


        #及时从金币精灵族移除不需要的金币精灵
        for goldsprite in goldGroup:
            # 人与金币碰撞检测 发生碰撞之后 金币增加

            if pygame.sprite.collide_mask(goldsprite, myself):
                    # 响一下音效
                    nosun = pygame.mixer.Sound('material/music/gold.mp3')
                    pygame.mixer.Sound.play(nosun)
                    goldGroup.remove(goldsprite)
                    goldnum = str(int(goldnum) + 10)

            if goldsprite.rect.right<=0:
                goldGroup.remove(goldsprite)



        # 暂停状态下,主角也要保持静止,也就是说主角直保持一个动作,因此要传递一个参数给主角精灵
        # 通过按下键盘的事件更改主角的状态,因此也需传递一个参数给主角来决定状态比如奔跑、跳跃以及滑行
        screen.blit(myself.image, myself.rect)
        myself.update(index,keys,isPause)

        screen.blit(km_img_obj, (10, 70))
        km_font = pygame.font.SysFont('arial', 30)
        km_num_surface = km_font.render(km, True, (0, 0, 255))
        screen.blit(km_num_surface, (80, 88))
        # 金币数量金币图片
        screen.blit(gold_img_obj, (10, 135))
        sun_font = pygame.font.SysFont('arial', 30)
        sun_num_surface = sun_font.render(goldnum, True, (180, 0, 255))
        screen.blit(sun_num_surface, (80, 148))

        if myself.life<4 and int(goldnum)>=100:
            myself.life+=1
            goldnum = str(int(goldnum) - 100)


        if index%6==0:
           km = str(int(km) + margin)
        index += 1
        pygame.display.update()
        clock.tick(fps)
        left -= margin
        right -= margin
if __name__=="__main__":
    init()

三、效果展示


相关推荐
拾忆-eleven29 分钟前
C语言实战:用Pygame打造高难度水果消消乐游戏
c语言·python·pygame
旦莫1 小时前
Python 教程:我们可以给 Python 文件起中文名吗?
开发语言·python
豌豆花下猫1 小时前
Python 潮流周刊#99:如何在生产环境中运行 Python?(摘要)
后端·python·ai
小杨4041 小时前
python入门系列二十(peewee)
人工智能·python·pycharm
弧襪1 小时前
FlaskRestfulAPI接口的初步认识
python·flaskrestfulapi
船长@Quant1 小时前
文档构建:Sphinx全面使用指南 — 进阶篇
python·markdown·sphinx·文档构建
二狗哈1 小时前
制作一款打飞机游戏21:自定义工具
游戏
cloudy4911 小时前
强化学习:历史基金净产值,学习最大化长期收益
python·强化学习
Bruce_Liuxiaowei2 小时前
使用Python脚本在Mac上彻底清除Chrome浏览历史:开发实战与隐私保护指南
chrome·python·macos
ruyingcai6666662 小时前
用python进行OCR识别
开发语言·python·ocr