前言
逮——小恐龍——哪里跑!!!

有段時間沒發過文章啦~
我估摸著一直給大家更新小白的案例,知識點,大家都看膩歪了,
今天栗子同學給大家安利一款新奇的簡單的小恐龍游戲案例,讓大家結合案例來學習嘛!
這不——隔壁的小表弟發來一系列小恐龍表情包祝賀:






正文
這里是Pygame游戲模塊寫的彩色版本的小恐龍游戲哦!
1)游戲規則:
只需按一下空格鍵(或者向上鍵),小恐龍就跑起來了,沿途遇到障礙(比如仙人掌🌵、飛鳥🐦)的時候,按一下向上鍵,幫助小恐龍跨越障礙,
堅持玩的時間越長,小恐龍就跑得越快,如果小恐龍撞上障礙,游戲就結束啦,你需要開啟下一輪
游戲(分數也會重置),按一下空格鍵,就可以重新開始游戲,
2)環境安裝
本文環境:Python3.7、Pycharm2021社區版、Pygame模塊,其他自帶的不介紹,
安裝庫:pip install pygame
3)素材圖片+音樂背景


4)組態檔cfg.py

'''組態檔'''
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)
5)主程式Game小恐龍.py

import cfg
import sys
import random
import pygame
from modules import *
'''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)
# --隨機添加云
if len(cloud_sprites_group) < 5 and random.randrange(0, 300) == 10:
cloud_sprites_group.add(Cloud(cfg.IMAGE_PATHS['cloud'], position=(cfg.SCREENSIZE[0], random.randrange(30, 75))))
# --隨機添加仙人掌/飛龍
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)
score_board.set(score)
highest_score_board.set(highest_score)
score_board.draw(screen)
highest_score_board.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
6)游戲開始界面gamestart.py

import sys
import pygame
from ..sprites 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
7)游戲結束界面gameend.py

import sys
import 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)
8)小恐龍類dinosaur.py(比如小恐龍影像繪制更新跳躍等)

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
9)定義障礙物obstacle.py(比如仙人掌,飛鳥等)

import random
import 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)
10)定義場景元素(比如地板、云層等)

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)
'''云'''
class Cloud(pygame.sprite.Sprite):
def __init__(self, imagepath, position, **kwargs):
pygame.sprite.Sprite.__init__(self)
# 匯入圖片
self.image = pygame.image.load(imagepath)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
# 定義一些必要的引數
self.speed = -1
'''將云畫到螢屏上'''
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 Scoreboard(pygame.sprite.Sprite):
def __init__(self, imagepath, position, size=(11, 13), is_highest=False, bg_color=None, **kwargs):
pygame.sprite.Sprite.__init__(self)
# 匯入圖片
self.images = []
image = pygame.image.load(imagepath)
for i in range(12):
self.images.append(pygame.transform.scale(image.subsurface((i*20, 0), (20, 24)), size))
if is_highest:
self.image = pygame.Surface((size[0]*8, size[1]))
else:
self.image = pygame.Surface((size[0]*5, size[1]))
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
# 一些必要的變數
self.is_highest = is_highest
self.bg_color = bg_color
self.score = '00000'
'''設定得分'''
def set(self, score):
self.score = str(score).zfill(5)
'''畫到螢屏上'''
def draw(self, screen):
self.image.fill(self.bg_color)
for idx, digital in enumerate(list(self.score)):
digital_image = self.images[int(digital)]
if self.is_highest:
self.image.blit(digital_image, ((idx+3)*digital_image.get_rect().width, 0))
else:
self.image.blit(digital_image, (idx*digital_image.get_rect().width, 0))
if self.is_highest:
self.image.blit(self.images[-2], (0, 0))
self.image.blit(self.images[-1], (digital_image.get_rect().width, 0))
screen.blit(self.image, self.rect)
11)效果展示
開始界面:

障礙物🌵:

障礙物🐦:

結束界面:

結尾

這么可愛的小恐龍, 你喜歡嗎?動手玩起來~
原始碼基地:點下面這行藍色字體即可,
原始碼基地:點擊即可加入哦!文章的一些免費代碼、解答等都可以在這里進行!
匯總文章資料
1.0 20201——已收錄文章匯總 ——持續更新!直接看這篇文章啦~

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/340559.html
標籤:其他
上一篇:c語言實作簡單的命令列掃雷游戲
