python--谷歌恐龙快跑小项目

news2025/7/9 17:07:17

用300行代码左右实现谷歌休闲的恐龙快跑游戏!

主函数:

import sys
import math
import time
import random
import pygame
from pygame.locals import *
from Scene import Scene
from Obstacle import Plant, Ptera
from Dinosaur import Dinosaur

# 定义背景填充色,画布宽和高
BACKGROUND = (250, 250, 250)
WIDTH = 800
HEIGHT = 400

#定义游戏结束界面是的样式,即对两张图片的位置显示
def show_gameover(screen):
    screen.fill(BACKGROUND)
    gameover_img = pygame.image.load('./images/others/gameover.png').convert_alpha()
    gameover_rect = gameover_img.get_rect()
    gameover_rect.left, gameover_rect.top = WIDTH//3, int(HEIGHT/2.4)
    screen.blit(gameover_img, gameover_rect)
    restart_img = pygame.image.load('./images/others/restart.png').convert_alpha()
    restart_rect = restart_img.get_rect()
    restart_rect.left, restart_rect.top = int(WIDTH/2.25), int(HEIGHT/2)
    screen.blit(restart_img, restart_rect)
    pygame.display.update()
    # 鼠标精准点击重新开始图标以执行重新开始游戏功能
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
                pygame.quit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                if mouse_pos[0] < restart_rect.right and mouse_pos[0] > restart_rect.left and\
                    mouse_pos[1] < restart_rect.bottom and mouse_pos[1] > restart_rect.top:
                    return True

#将Score转为生成障碍物的概率,e的-score次幂
def sigmoid(score):
    probability = 1 / (1 + math.exp(-score))
    return min(probability, 0.6)

#主函数
def main():
    # 初始化
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("dragon running")
    clock = pygame.time.Clock()
    # 得分
    score = 0
    # 加载一些素材
    jump_sound = pygame.mixer.Sound("./music/jump.wav")
    jump_sound.set_volume(6)
    die_sound = pygame.mixer.Sound("./music/die.wav")
    die_sound.set_volume(6)
    pygame.mixer.init()
    pygame.mixer.music.load("./music/bg_music.mp3")
    pygame.mixer.music.set_volume(0.6)
    pygame.mixer.music.play(-1)
    font = pygame.font.Font('./font/font1.ttf', 20)
    # 实例化
    dinosaur = Dinosaur(WIDTH, HEIGHT)
    scene = Scene(WIDTH, HEIGHT)
    plants = pygame.sprite.Group()
    pteras = pygame.sprite.Group()
    # 产生障碍物事件
    # 设置的定时器常量第一个用pygame.USEREVENT第二个用pygame.USEREVENT+1
    GenPlantEvent = pygame.constants.USEREVENT + 0
    pygame.time.set_timer(GenPlantEvent, 1500)
    GenPteraEvent = pygame.constants.USEREVENT + 1
    pygame.time.set_timer(GenPteraEvent, 5000)
    # 游戏是否结束了
    running = True
    # 是否可以产生障碍物flag
    flag_plant = False
    flag_ptera = False
    t0 = time.time()
    # 主循环
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
                pygame.quit()
            if event.type == GenPlantEvent:
                flag_plant = True
            if event.type == GenPteraEvent:
                if score > 10:
                    flag_ptera = True
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_SPACE]:
            dinosaur.is_jumping = True
            jump_sound.play()
        screen.fill(BACKGROUND)
        time_passed = time.time() - t0
        t0 = time.time()
        # 场景
        scene.move()
        scene.draw(screen)
        # 小恐龙
        dinosaur.is_running = True
        if dinosaur.is_jumping:
            dinosaur.be_afraid()
            dinosaur.jump(time_passed)
        dinosaur.draw(screen)
        # 障碍物-植物
        if random.random() < sigmoid(score) and flag_plant:
            plant = Plant(WIDTH, HEIGHT)
            plants.add(plant)
            flag_plant = False
        for plant in plants:
            plant.move()
            if dinosaur.rect.left > plant.rect.right and not plant.added_score:
                score += 1
                plant.added_score = True
            if plant.rect.right < 0:
                plants.remove(plant)
                continue
            plant.draw(screen)
        # 障碍物-飞龙
        if random.random() < sigmoid(score) and flag_ptera:
            if len(pteras) > 1:
                continue
            ptera = Ptera(WIDTH, HEIGHT)
            pteras.add(ptera)
            flag_ptera = False
        for ptera in pteras:
            ptera.move()
            if dinosaur.rect.left > ptera.rect.right and not ptera.added_score:
                score += 5
                ptera.added_score = True
            if ptera.rect.right < 0:
                pteras.remove(ptera)
                continue
            ptera.draw(screen)
        # 碰撞检测
        if pygame.sprite.spritecollide(dinosaur, plants, False) or pygame.sprite.spritecollide(dinosaur, pteras, False):
            die_sound.play()
            running = False
        # 显示得分
        score_text = font.render("熊百涛的Score: "+str(score), 1, (0, 0, 0))
        screen.blit(score_text, [10, 10])
        pygame.display.flip()
        clock.tick(60)
    res = show_gameover(screen)
    return res


#run
if __name__ == '__main__':
    res = True
    while res:
        res = main()

实现主要事件,恐龙的跳跃,奔跑,表情的变换,地图背景的滑动,障碍物的出现(仙人掌和飞鸟),音乐和音效的设置等等

恐龙类:


import pygame


'''恐龙类'''
class Dinosaur(pygame.sprite.Sprite):
	def __init__(self, WIDTH=640, HEIGHT=500):
		pygame.sprite.Sprite.__init__(self)
		self.HEIGHT = HEIGHT
		self.WIDTH = WIDTH
		# self.imgs = ['./images/dinosaur/wait.png', './images/dinosaur/afraid.png', './images/dinosaur/running.png', './images/dinosaur/flying.png']
		self.imgs = ['./images/dinosaur/dino.png', './images/dinosaur/dino_ducking.png']
		self.reset()
	'''跳跃'''
	def jump(self, time_passed):
		# time_passed很小时,可近似为匀速运动
		if self.is_jumping_up:
			self.rect.top -= self.jump_v * time_passed
			self.jump_v = max(0, self.jump_v - self.jump_a_up * time_passed)
			if self.jump_v == 0:
				self.is_jumping_up = False
		else:
			self.rect.top = min(self.initial_top, self.rect.top + self.jump_v * time_passed)
			self.jump_v += self.jump_a_down * time_passed
			if self.rect.top == self.initial_top:
				self.is_jumping = False
				self.is_jumping_up = True
				self.jump_v = self.jump_v0
	'''跳跃时变为感到恐惧的表情'''
	def be_afraid(self):
		self.dinosaur = self.dinosaurs.subsurface((352, 0), (88, 95))
	'''把自己画到屏幕上去'''
	def draw(self, screen):
		if self.is_running and not self.is_jumping:
			self.running_count += 1
			if self.running_count == 6:
				self.running_count = 0
				self.running_flag = not self.running_flag
			if self.running_flag:
				self.dinosaur = self.dinosaurs.subsurface((176, 0), (88, 95))
			else:
				self.dinosaur = self.dinosaurs.subsurface((264, 0), (88, 95))
		screen.blit(self.dinosaur, self.rect)
	'''重置'''
	def reset(self):
		# 恐龙是否在奔跑
		self.is_running = False
		# 为了奔跑特效
		self.running_flag = False
		self.running_count = 0
		# 恐龙是否在跳跃
		self.is_jumping = False
		# 恐龙是否在向上跳跃
		self.is_jumping_up = True
		# 跳跃初始速度
		self.jump_v0 = 500
		# 跳跃瞬时速度
		self.jump_v = self.jump_v0
		# 跳跃加速度
		self.jump_a_up = 1000
		self.jump_a_down = 800
		# 小恐龙初始位置
		self.initial_left = 40
		self.initial_top = int(self.HEIGHT/2.3)
		self.dinosaurs = pygame.image.load(self.imgs[0]).convert_alpha()
		self.dinosaur = self.dinosaurs.subsurface((0, 0), (88, 95))
		self.rect = self.dinosaur.get_rect()
		self.rect.left, self.rect.top = self.initial_left, self.initial_top

背景画布:

import pygame
import random

'''场景类'''
class Scene(pygame.sprite.Sprite):
	def __init__(self, WIDTH=640, HEIGHT=500):
		pygame.sprite.Sprite.__init__(self)
		self.WIDTH = WIDTH
		self.HEIGHT = HEIGHT
		self.speed = 5
		self.imgs = ['./images/bg/bg1.png', './images/bg/bg2.png', './images/bg/bg3.png']
		self.reset()
	'''不停向左移动'''
	def move(self):
		self.x = self.x - self.speed
	'''把自己画到屏幕上去'''
	def draw(self, screen):
		if self.bg1_rect.right < 0:
			self.x = 0
			self.bg1 = self.bg2
			self.bg1_rect = self.bg2_rect
			self.bg2 = self.bg3
			self.bg2_rect = self.bg3_rect
			self.bg3 = pygame.image.load(self.imgs[random.randint(0, 2)]).convert_alpha()
			self.bg3_rect = self.bg3.get_rect()
		self.bg1_rect.left, self.bg1_rect.top = self.x, int(self.HEIGHT/2.3)
		self.bg2_rect.left, self.bg2_rect.top = self.bg1_rect.right, int(self.HEIGHT/2.3)
		self.bg3_rect.left, self.bg3_rect.top = self.bg2_rect.right, int(self.HEIGHT/2.3)
		screen.blit(self.bg1, self.bg1_rect)
		screen.blit(self.bg2, self.bg2_rect)
		screen.blit(self.bg3, self.bg3_rect)
	'''重置'''
	def reset(self):
		self.x = 0
		self.bg1 = pygame.image.load(self.imgs[0]).convert_alpha()
		self.bg2 = pygame.image.load(self.imgs[1]).convert_alpha()
		self.bg3 = pygame.image.load(self.imgs[2]).convert_alpha()
		self.bg1_rect = self.bg1.get_rect()
		self.bg2_rect = self.bg2.get_rect()
		self.bg3_rect = self.bg3.get_rect()
		self.bg1_rect.left, self.bg1_rect.top = self.x, int(self.HEIGHT/2.3)
		self.bg2_rect.left, self.bg2_rect.top = self.bg1_rect.right, int(self.HEIGHT/2.3)
		self.bg3_rect.left, self.bg3_rect.top = self.bg2_rect.right, int(self.HEIGHT/2.3)

障碍物类:


import random
import pygame


'''植物'''
class Plant(pygame.sprite.Sprite):
	def __init__(self, WIDTH=640, HEIGHT=500):
		pygame.sprite.Sprite.__init__(self)
		self.WIDTH = WIDTH
		self.HEIGHT = HEIGHT
		# 统计分数时用的
		self.added_score = False
		self.speed = 5
		# self.imgs = ['./images/obstacles/plant1.png', './images/obstacles/plant2.png', './images/obstacles/plant3.png', './images/obstacles/plant4.png']
		self.imgs = ['./images/obstacles/plant_big.png', './images/obstacles/plant_small.png']
		self.generate_random()
	'''随机生成障碍物'''
	def generate_random(self):
		idx = random.randint(0, 1)
		temp = pygame.image.load(self.imgs[idx]).convert_alpha()
		if idx == 0:
			self.plant = temp.subsurface((101*random.randint(0, 2), 0), (101, 101))
		else:
			self.plant = temp.subsurface((68*random.randint(0, 2), 0), (68, 70))
		self.rect = self.plant.get_rect()
		self.rect.left, self.rect.top = self.WIDTH+60, int(self.HEIGHT/2)
	'''不停往左移动'''
	def move(self):
		self.rect.left = self.rect.left-self.speed
	'''把自己画到屏幕上去'''
	def draw(self, screen):
		screen.blit(self.plant, self.rect)


'''飞龙'''
class Ptera(pygame.sprite.Sprite):
	def __init__(self, WIDTH=640, HEIGHT=500):
		pygame.sprite.Sprite.__init__(self)
		self.WIDTH = WIDTH
		self.HEIGHT = HEIGHT
		# 统计分数时用的
		self.added_score = False
		self.imgs = ['./images/obstacles/ptera.png']
		# 为了飞行特效
		self.flying_count = 0
		self.flying_flag = True
		# 统计分数时用的
		self.speed = 7
		self.generate()
	'''生成飞龙'''
	def generate(self):
		self.ptera = pygame.image.load(self.imgs[0]).convert_alpha()
		self.ptera_0 = self.ptera.subsurface((0, 0), (92, 81))
		self.ptera_1 = self.ptera.subsurface((92, 0), (92, 81))
		self.rect = self.ptera_0.get_rect()
		self.rect.left, self.rect.top = self.WIDTH+30, int(self.HEIGHT/20)
	'''不停往左移动'''
	def move(self):
		self.rect.left = self.rect.left-self.speed
	'''把自己画到屏幕上去'''
	def draw(self, screen):
		self.flying_count += 1
		if self.flying_count % 6 == 0:
			self.flying_flag = not self.flying_flag
		if self.flying_flag:
			screen.blit(self.ptera_0, self.rect)
		else:
			screen.blit(self.ptera_1, self.rect)

截图如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/6805.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式开发:当用微控制器构建嵌入式GUI时,有哪些注意事项

在嵌入式开发中&#xff0c;借助基于MCU的设计&#xff0c;你可以消除额外的RAM和闪存芯片&#xff0c;并使用板载外设而不是板外逻辑&#xff0c;所有这些都将随着当今功能强大的芯片而变得更加简单。当然&#xff0c;与成熟的微处理器相比&#xff0c;MCU本身也提供了额外的成…

【校内篇】如何安装一台虚拟机

咱们的微机老师要求上微机课用的电脑必须要用 Windows7Windows\ 7Windows 7&#xff0c;但是很多同学的电脑也许并不匹配&#xff0c;造成了诸多不便。 作为班长&#xff0c;我觉得有必要把自己的一些技术共享给大家&#xff0c;方便大家使用。 文章目录一、准备材料&#x1f6…

如何扩大电脑c盘分区,c盘空间不足怎么扩容

当电脑使用一段时间后&#xff0c;C盘会存储一定的数据&#xff0c;包括操作系统以及其他的文件。在实际的运用中&#xff0c;许多应用程序的默认下载路径就是C盘&#xff0c;如果用户没有更改为其他磁盘&#xff0c;会导致C盘的空间越来越小&#xff0c;电脑越来越卡顿。从根源…

【C版本】静态通讯录与动态通讯录的实现,以及各自所存在的缺陷对比。(含所有原码)

目录静态版本通讯录前期思路具体实现1、框架2、初始化通讯录3、增加联系人4、显示已有联系人5、查找联系人6、删除指定联系人7、排序联系人8、修改联系人信息9、清空联系人静态版本通讯录存在的缺陷动态版本通讯录&#xff08;静态版本的部分功能发生改动&#xff09;初始化增加…

优雅的使用Webstack打造个人网址导航

原文链接&#xff1a;优雅的使用Webstack打造个人网址导航 前言 一款基于 WebStackPage 的 Hexo 主题。本人选择的是 hexo-theme-webstack。 效果预览 具体效果请移步 个人网址导航。 步骤 在目标路径&#xff08;我这里选的路径为【D:/studytype/My_Blog】&#xff09;打开…

基于C#制作一个桌面宠物

此文主要基于C#制作一个桌面宠物&#xff0c;可自定义宠物素材图片及打开外部exe的快捷菜单。 实现流程1.1、创建项目1.2、准备素材1.3、控件设置&#xff08;1&#xff09;PictureBox控件&#xff08;2&#xff09;timer控件&#xff08;3&#xff09;contextMenuStrip控件1.4…

学习MySQL必须掌握的13个关键字,你get了吗?

1、三范式 第一范式&#xff1a;每个表的每一列都要保持它的原子性&#xff0c;也就是表的每一列是不可分割的&#xff1b;第二范式&#xff1a;在满足第一范式的基础上&#xff0c;每个表都要保持唯一性&#xff0c;也就是表的非主键字段完全依赖于主键字段&#xff1b;第三范…

【微服务】Nacos2.x服务发现?RPC调用?重试机制?

&#x1f496;Spring家族及微服务系列文章 ✨【微服务】Nacos通知客户端服务变更以及重试机制 【微服务】SpringBoot监听器机制以及在Nacos中的应用 ✨【微服务】Nacos服务端完成微服务注册以及健康检查流程 ✨【微服务】Nacos客户端微服务注册原理流程 ✨【微服务】SpringClou…

Vue 和 React 比,React 好在哪里?

​ 这两个设计理念上就有所区别&#xff0c;类比过来就是&#xff1a;Vue 是自动挡汽车&#xff0c;React 是手动挡汽车。 在 Vue 中&#xff0c;不需要去注意视图和数据的一致性&#xff0c;因为有双向绑定看帮你处理&#xff0c;响应式的。还有一些很方便的 v-if、v-model 之…

软考 - 面向对象开发

⭐设计模式UML详解&#xff1a;https://blog.csdn.net/qq_40274514/article/details/124047443 面向对象基础 面向对象的程序设计 和 面向对象设计区别 面向对象的程序设计涉及到具体的编程语言 面向对象设计只从系统逻辑结构设计解决方案 常见的机制 动态绑定&#xff1a;过…

ESXi5.5远程升级到ESXi6.7 (VMware Hypervisor)

1、ESXi的介质分为两类&#xff0c;以6.7为例&#xff1a; VMware vSphere Hypervisor (ESXi ISO) image (Includes VMware Tools)&#xff08;ISO包&#xff09; VMware vSphere Hypervisor (ESXi) Offline Bundle &#xff08;ZIP包&#xff09; 如果要升级&#xff0c;需要Z…

【畅购商城】详情页详情之商品详情

1.构建详情页 步骤0&#xff1a;确定访问路径 http://localhost:3000/Goods?id1 步骤二&#xff1a;复制 ~/static/goods.html 内容&#xff0c;导入第三方资源&#xff08;css、js&#xff09; head: {title: 列表页面,link: [{rel:stylesheet,href: /style/goods.css},{re…

Sysweld笔记:利用稳态算法加速算法模拟焊接过程的残余应力

作者&#xff1a;贾亚波博士&#xff0c;仿真秀专栏作者 在进行热力耦合的仿真过程中&#xff0c;如果模型足够的长并且热源速度恒定&#xff0c;通常其热学&#xff0c;相变以及热力耦合都会达到稳态的过程&#xff0c;因此如何直接计算稳态问题成为了大家研究的热点问题。 …

【C++笔试强训】第二十四天

&#x1f387;C笔试强训 博客主页&#xff1a;一起去看日落吗分享博主的C刷题日常&#xff0c;大家一起学习博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a;夜色难免微凉&#xff0c;前方必有曙光 &#x1f31e;。 &#x1f4a6;&a…

【数据结构】栈基本操作的实现(C语言)

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f40c; 个人主页&#xff1a;蜗牛牛啊 &#x1f525; 系列专栏&#xff1a;&#x1f6f9;初出茅庐C语言、&#x1f6f4;数据结构 &#x1f4d5; 学习格言&#xff1a;博…

SpringBoot项目打包时配置文件区分日常、测试、预发、正式环境

前言&#x1f34a; 在我们开发项目的时候&#xff0c;一般有四套环境&#xff1a;日常、测试、预发、正式。日常环境作为我们开发环境&#xff1b;测试环境给测试同学测试功能&#xff1b;预发环境给正式环境发布时提供准备&#xff1b;正式环境则是稳定的生产环境。 这四套环…

面试官问我new Vue阶段做了什么?

前言 本篇录入吊打面试官专栏&#xff0c;希望能祝君拿下Offer一臂之力&#xff0c;各位看官感兴趣可移步&#x1f6b6;。这段时间面了很多家公司&#xff0c;被问到的题我感觉不重复不止100道&#xff0c;将会挑选觉得常见且有意义的题目进行分析及回答。有人说面试造火箭&am…

Redis字符串、hash、列表方法使用以及Redis管道与Django集成Redis

目录标题一、Redis字符串操作二、Redis-hash操作三、Redis列表操作四、Redis管道五、Redis其他操作六、Django中集成Redis七、Celery介绍一、Redis字符串操作 名称属性setex:过期时间&#xff08;秒&#xff09;px:过期时间(毫秒) nx:如果设置为True&#xff0c;则只有name不存…

毕业设计:SpringBoot+Vue+Element的校内跑腿平台

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 文末获取源码 项目编号&#xff1a;BS-XX-…

MySQL基础总结

一.sql数据及语言基本类型: 1.语言的分类 DDL:数据定义语言,用来定义数据库对象:数据库,表,列等。关键字:create,alter,drop等 DML:数据操作语言,用来对数据库中表的记录进行操作。关键字:insert,delete,update等 DQL:数据库查询语言,用来查询数据库中表的记录。关键字:select,…