博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用Python写个超级小恐龙跑酷游戏,上班摸鱼我能玩一天
阅读量:2108 次
发布时间:2019-04-29

本文共 14203 字,大约阅读时间需要 47 分钟。

目录


啥也不多说,先来一个效果图展示 

工具使用

开发环境:win10、python3.7 开发工具:pycharm 工具包:pygame

游戏思路解析

准备相对应的游戏图片 准备相对应的音频数据

项目整体的框架搭建

创建小恐龙对象

import pygame'''小恐龙'''class Dinosaur(pygame.sprite.Sprite):    def __init__(self, imagepaths, position=(40, 147), size=[(44, 47), (59, 47)], **kwargs):        pygame.sprite.Sprite.__init__(self)        # 导入所有图片        self.images = []        image = pygame.image.load(imagepaths[0])        for i in range(5):            self.images.append(pygame.transform.scale(image.subsurface((i*88, 0), (88, 95)), size[0]))        image = pygame.image.load(imagepaths[1])        for i in range(2):            self.images.append(pygame.transform.scale(image.subsurface((i*118, 0), (118, 95)), size[1]))        self.image_idx = 0        self.image = self.images[self.image_idx]        self.rect = self.image.get_rect()        self.rect.left, self.rect.bottom = position        self.mask = pygame.mask.from_surface(self.image)        # 定义一些必要的变量        self.init_position = position        self.refresh_rate = 5        self.refresh_counter = 0        self.speed = 11.5        self.gravity = 0.6        self.is_jumping = False        self.is_ducking = False        self.is_dead = False        self.movement = [0, 0]    '''跳跃'''    def jump(self, sounds):        if self.is_dead or self.is_jumping:            return        sounds['jump'].play()        self.is_jumping = True        self.movement[1] = -1 * self.speed    '''低头'''    def duck(self):        if self.is_jumping or self.is_dead:            return        self.is_ducking = True    '''不低头'''    def unduck(self):        self.is_ducking = False    '''死掉了'''    def die(self, sounds):        if self.is_dead:            return        sounds['die'].play()        self.is_dead = True    '''将恐龙画到屏幕'''    def draw(self, screen):        screen.blit(self.image, self.rect)    '''载入当前状态的图片'''    def loadImage(self):        self.image = self.images[self.image_idx]        rect = self.image.get_rect()        rect.left, rect.top = self.rect.left, self.rect.top        self.rect = rect        self.mask = pygame.mask.from_surface(self.image)    '''更新小恐龙'''    def update(self):        if self.is_dead:            self.image_idx = 4            self.loadImage()            return        if self.is_jumping:            self.movement[1] += self.gravity            self.image_idx = 0            self.loadImage()            self.rect = self.rect.move(self.movement)            if self.rect.bottom >= self.init_position[1]:                self.rect.bottom = self.init_position[1]                self.is_jumping = False        elif self.is_ducking:            if self.refresh_counter % self.refresh_rate == 0:                self.refresh_counter = 0                self.image_idx = 5 if self.image_idx == 6 else 6                self.loadImage()        else:            if self.refresh_counter % self.refresh_rate == 0:                self.refresh_counter = 0                if self.image_idx == 1:                    self.image_idx = 2                elif self.image_idx == 2:                    self.image_idx = 3                else:                    self.image_idx = 1                self.loadImage()        self.refresh_counter += 1

创建障碍物对象

  • 仙人掌

  • 飞龙

import randomimport pygame'''仙人掌'''class Cactus(pygame.sprite.Sprite):    def __init__(self, imagepaths, position=(600, 147), sizes=[(40, 40), (40, 40)], **kwargs):        pygame.sprite.Sprite.__init__(self)        # 导入图片        self.images = []        image = pygame.image.load(imagepaths[0])        for i in range(3):            self.images.append(pygame.transform.scale(image.subsurface((i*101, 0), (101, 101)), sizes[0]))        image = pygame.image.load(imagepaths[1])        for i in range(3):            self.images.append(pygame.transform.scale(image.subsurface((i*68, 0), (68, 70)), sizes[1]))        self.image = random.choice(self.images)        self.rect = self.image.get_rect()        self.rect.left, self.rect.bottom = position        self.mask = pygame.mask.from_surface(self.image)        # 定义一些必要的变量        self.speed = -10    '''画到屏幕上'''    def draw(self, screen):        screen.blit(self.image, self.rect)    '''更新'''    def update(self):        self.rect = self.rect.move([self.speed, 0])        if self.rect.right < 0:            self.kill()'''飞龙'''class Ptera(pygame.sprite.Sprite):    def __init__(self, imagepath, position, size=(46, 40), **kwargs):        pygame.sprite.Sprite.__init__(self)        # 导入图片        self.images = []        image = pygame.image.load(imagepath)        for i in range(2):            self.images.append(pygame.transform.scale(image.subsurface((i*92, 0), (92, 81)), size))        self.image_idx = 0        self.image = self.images[self.image_idx]        self.rect = self.image.get_rect()        self.rect.left, self.rect.centery = position        self.mask = pygame.mask.from_surface(self.image)        # 定义一些必要的变量        self.speed = -10        self.refresh_rate = 10        self.refresh_counter = 0    '''画到屏幕上'''    def draw(self, screen):        screen.blit(self.image, self.rect)    '''更新'''    def update(self):        if self.refresh_counter % self.refresh_rate == 0:            self.refresh_counter = 0            self.image_idx = (self.image_idx + 1) % len(self.images)            self.loadImage()        self.rect = self.rect.move([self.speed, 0])        if self.rect.right < 0:            self.kill()        self.refresh_counter += 1    '''载入当前状态的图片'''    def loadImage(self):        self.image = self.images[self.image_idx]        rect = self.image.get_rect()        rect.left, rect.top = self.rect.left, self.rect.top        self.rect = rect        self.mask = pygame.mask.from_surface(self.image)

创建地板对象

import pygame'''地板'''class Ground(pygame.sprite.Sprite):    def __init__(self, imagepath, position, **kwargs):        pygame.sprite.Sprite.__init__(self)        # 导入图片        self.image_0 = pygame.image.load(imagepath)        self.rect_0 = self.image_0.get_rect()        self.rect_0.left, self.rect_0.bottom = position        self.image_1 = pygame.image.load(imagepath)        self.rect_1 = self.image_1.get_rect()        self.rect_1.left, self.rect_1.bottom = self.rect_0.right, self.rect_0.bottom        # 定义一些必要的参数        self.speed = -10    '''更新地板'''    def update(self):        self.rect_0.left += self.speed        self.rect_1.left += self.speed        if self.rect_0.right < 0:            self.rect_0.left = self.rect_1.right        if self.rect_1.right < 0:            self.rect_1.left = self.rect_0.right    '''将地板画到屏幕'''    def draw(self, screen):        screen.blit(self.image_0, self.rect_0)        screen.blit(self.image_1, self.rect_1)

游戏的基本配置信息

'''配置文件'''import os'''屏幕大小'''SCREENSIZE = (600, 150)'''FPS'''FPS = 60'''音频素材路径'''AUDIO_PATHS = {    'die': os.path.join(os.getcwd(), 'resources/audios/die.wav'),    'jump': os.path.join(os.getcwd(), 'resources/audios/jump.wav'),    'point': os.path.join(os.getcwd(), 'resources/audios/point.wav')}'''图片素材路径'''IMAGE_PATHS = {    'cacti': [        os.path.join(os.getcwd(), 'resources/images/cacti-big.png'),        os.path.join(os.getcwd(), 'resources/images/cacti-small.png')    ],    'cloud': os.path.join(os.getcwd(), 'resources/images/cloud.png'),    'dino': [        os.path.join(os.getcwd(), 'resources/images/dino.png'),        os.path.join(os.getcwd(), 'resources/images/dino_ducking.png')    ],    'gameover': os.path.join(os.getcwd(), 'resources/images/gameover.png'),    'ground': os.path.join(os.getcwd(), 'resources/images/ground.png'),    'numbers': os.path.join(os.getcwd(), 'resources/images/numbers.png'),    'ptera': os.path.join(os.getcwd(), 'resources/images/ptera.png'),    'replay': os.path.join(os.getcwd(), 'resources/images/replay.png')}'''背景颜色'''BACKGROUND_COLOR = (235, 235, 235)BLACK = (0, 0, 0)WHITE = (255, 255, 255)```设定游戏开始界面```pythonimport sysimport pygamefrom modules.sprites.dinosaur import Dinosaur'''游戏开始界面'''def GameStartInterface(screen, sounds, cfg):    dino = Dinosaur(cfg.IMAGE_PATHS['dino'])    ground = pygame.image.load(cfg.IMAGE_PATHS['ground']).subsurface((0, 0), (83, 19))    rect = ground.get_rect()    rect.left, rect.bottom = cfg.SCREENSIZE[0]/20, cfg.SCREENSIZE[1]    clock = pygame.time.Clock()    press_flag = False    while True:        for event in pygame.event.get():            if event.type == pygame.QUIT:                pygame.quit()                sys.exit()            elif event.type == pygame.KEYDOWN:                if event.key == pygame.K_SPACE or event.key == pygame.K_UP:                    press_flag = True                    dino.jump(sounds)        dino.update()        screen.fill(cfg.BACKGROUND_COLOR)        screen.blit(ground, rect)        dino.draw(screen)        pygame.display.update()        clock.tick(cfg.FPS)        if (not dino.is_jumping) and press_flag:            return True```游戏结束界面```pythonimport sysimport pygame'''游戏结束界面'''def GameEndInterface(screen, cfg):    replay_image = pygame.image.load(cfg.IMAGE_PATHS['replay'])    replay_image = pygame.transform.scale(replay_image, (35, 31))    replay_image_rect = replay_image.get_rect()    replay_image_rect.centerx = cfg.SCREENSIZE[0] / 2    replay_image_rect.top = cfg.SCREENSIZE[1] * 0.52    gameover_image = pygame.image.load(cfg.IMAGE_PATHS['gameover'])    gameover_image = pygame.transform.scale(gameover_image, (190, 11))    gameover_image_rect = gameover_image.get_rect()    gameover_image_rect.centerx = cfg.SCREENSIZE[0] / 2    gameover_image_rect.centery = cfg.SCREENSIZE[1] * 0.35    clock = pygame.time.Clock()    while True:        for event in pygame.event.get():            if event.type == pygame.QUIT:                pygame.quit()                sys.exit()            elif event.type == pygame.KEYDOWN:                if event.key == pygame.K_SPACE or event.key == pygame.K_UP:                    return True            elif event.type == pygame.MOUSEBUTTONDOWN:                mouse_pos = pygame.mouse.get_pos()                if replay_image_rect.collidepoint(mouse_pos):                    return True        screen.blit(replay_image, replay_image_rect)        screen.blit(gameover_image, gameover_image_rect)        pygame.display.update()        clock.tick(cfg.FPS)```项目运行文件```pythonimport cfgimport sysimport randomimport pygamefrom modules.interfaces.gameend import GameEndInterfacefrom modules.interfaces.gamestart import GameStartInterfacefrom modules.sprites.dinosaur import Dinosaurfrom modules.sprites.obstacle import Cactus, Pterafrom modules.sprites.scene import Ground'''main'''def main(highest_score):    # 游戏初始化    pygame.init()    screen = pygame.display.set_mode(cfg.SCREENSIZE)    pygame.display.set_caption('九歌')    # 导入所有声音文件    sounds = {}    for key, value in cfg.AUDIO_PATHS.items():        sounds[key] = pygame.mixer.Sound(value)    # 游戏开始界面    GameStartInterface(screen, sounds, cfg)    # 定义一些游戏中必要的元素和变量    score = 0    # score_board = Scoreboard(cfg.IMAGE_PATHS['numbers'], position=(534, 15), bg_color=cfg.BACKGROUND_COLOR)    highest_score = highest_score    # highest_score_board = Scoreboard(cfg.IMAGE_PATHS['numbers'], position=(435, 15), bg_color=cfg.BACKGROUND_COLOR, is_highest=True)    dino = Dinosaur(cfg.IMAGE_PATHS['dino'])    ground = Ground(cfg.IMAGE_PATHS['ground'], position=(0, cfg.SCREENSIZE[1]))    cloud_sprites_group = pygame.sprite.Group()    cactus_sprites_group = pygame.sprite.Group()    ptera_sprites_group = pygame.sprite.Group()    add_obstacle_timer = 0    score_timer = 0    # 游戏主循环    clock = pygame.time.Clock()    while True:        for event in pygame.event.get():            if event.type == pygame.QUIT:                pygame.quit()                sys.exit()            elif event.type == pygame.KEYDOWN:                if event.key == pygame.K_SPACE or event.key == pygame.K_UP:                    dino.jump(sounds)                elif event.key == pygame.K_DOWN:                    dino.duck()            elif event.type == pygame.KEYUP and event.key == pygame.K_DOWN:                dino.unduck()        screen.fill(cfg.BACKGROUND_COLOR)        # --随机添加仙人掌/飞龙        add_obstacle_timer += 1        if add_obstacle_timer > random.randrange(50, 150):            add_obstacle_timer = 0            random_value = random.randrange(0, 10)            if random_value >= 5 and random_value <= 7:                cactus_sprites_group.add(Cactus(cfg.IMAGE_PATHS['cacti']))            else:                position_ys = [cfg.SCREENSIZE[1]*0.82, cfg.SCREENSIZE[1]*0.75, cfg.SCREENSIZE[1]*0.60, cfg.SCREENSIZE[1]*0.20]                ptera_sprites_group.add(Ptera(cfg.IMAGE_PATHS['ptera'], position=(600, random.choice(position_ys))))        # --更新游戏元素        dino.update()        ground.update()        cloud_sprites_group.update()        cactus_sprites_group.update()        ptera_sprites_group.update()        score_timer += 1        if score_timer > (cfg.FPS//12):            score_timer = 0            score += 1            score = min(score, 99999)            if score > highest_score:                highest_score = score            if score % 100 == 0:                sounds['point'].play()            if score % 1000 == 0:                ground.speed -= 1                for item in cloud_sprites_group:                    item.speed -= 1                for item in cactus_sprites_group:                    item.speed -= 1                for item in ptera_sprites_group:                    item.speed -= 1        # --碰撞检测        for item in cactus_sprites_group:            if pygame.sprite.collide_mask(dino, item):                dino.die(sounds)        for item in ptera_sprites_group:            if pygame.sprite.collide_mask(dino, item):                dino.die(sounds)        # --将游戏元素画到屏幕上        dino.draw(screen)        ground.draw(screen)        cloud_sprites_group.draw(screen)        cactus_sprites_group.draw(screen)        ptera_sprites_group.draw(screen)        # --更新屏幕        pygame.display.update()        clock.tick(cfg.FPS)        # --游戏是否结束        if dino.is_dead:            break    # 游戏结束界面    return GameEndInterface(screen, cfg), highest_score'''run'''if __name__ == '__main__':    highest_score = 0    while True:        flag, highest_score = main(highest_score)        if not flag: break```

❀微信扫一扫关注公众号加入学习交流技术解答小天地+q裙:881744585

转载地址:http://wxuef.baihongyu.com/

你可能感兴趣的文章
高可用架构-- MySQL主从复制的配置
查看>>
jvm调优-从eclipse开始
查看>>
构建微服务:Spring boot 入门篇
查看>>
jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)
查看>>
Spring boot Myibatis
查看>>
spring boot(七):springboot+mybatis多数据源最简解决方案
查看>>
Spring Boot 笔记
查看>>
maven下手动导入ojdbc6.jar
查看>>
SpringBoot、MyBatis配置多数据源XML方法
查看>>
SpringBoot配置属性之MQ
查看>>
SpringBoot集成mybatis
查看>>
Shell文本处理三剑客之grep
查看>>
linux查看进程启动时间
查看>>
Linux 基础命令
查看>>
35 个 Java 代码性能优化总结
查看>>
Linux Sed 命令
查看>>
StandardContext 错误
查看>>
如何添加网站favicon.ico图标
查看>>
cvs no such repository 问题
查看>>
MySQL中REGEXP正则表达式
查看>>