九、小白如何用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()

三、效果展示


相关推荐
胡耀超29 分钟前
霍夫圆变换全面解析(OpenCV)
人工智能·python·opencv·算法·计算机视觉·数据挖掘·数据安全
doupoa40 分钟前
Fabric 服务端插件开发简述与聊天事件监听转发
运维·python·fabric
How_doyou_do1 小时前
备战菊厂笔试4
python·算法·leetcode
(・Д・)ノ2 小时前
python打卡day27
开发语言·python
小oo呆3 小时前
【学习心得】Jupyter 如何在conda的base环境中其他虚拟环境内核
python·jupyter·conda
小白学大数据3 小时前
Scrapy框架下地图爬虫的进度监控与优化策略
开发语言·爬虫·python·scrapy·数据分析
浊酒南街3 小时前
TensorFlow之微分求导
人工智能·python·tensorflow
立秋67894 小时前
用Python绘制梦幻星空
开发语言·python·pygame
alpszero4 小时前
YOLO11解决方案之对象裁剪探索
人工智能·python·计算机视觉·yolo11
白云千载尽4 小时前
相机、雷达标定工具,以及雷达自动标定的思路
python·自动驾驶·ros