猫史档案馆


【Python作品分享】奇遇之旅

用户:战狼3战狼3查看:0 回复:1 评论:0 创建时间:2021-07-14T12:54:34


【作品展示】

center_image

 

【作品介绍】

这个是本次作品的最终成品了。点击运行后首先会出现一个由panda3d制作的一个界面,路边有两栋房子,把鼠标放到房子上面会有一个反馈(稍微放大),并提示你即将前往的页面。点击最底下的房子,你将会前往一个叫做拯救小鸟的游戏,你可以通过点击鼠标来控制小鸟来躲过障碍物。关闭窗口后来到最右边的房子,鼠标放在上面也同样会有一个放大的反馈,点击进去后就是动物的科普了,通过点击鼠标来切换图片(同一种动物),通过点击空格来切换不同的物种简介(不同的动物,不同的简介)。素材链接在代码开头的注释(或者帖子的评论区

 

【作品源代码】

# 链接: h t t p s://pan.喵/s/1hmlkcztA7WgcENv5BOGdhg   (去掉空格)
# 密码: sdfc

# 导入库
import direct.directbase.DirectStart
from panda3d.core import *
import random
import pygame
import os 
# 导入任务功能模块
from direct.task import Task
# 导入动画功能模块
from direct.actor.Actor import Actor
# 导入GUI模块
from direct.gui.DirectGui import *

##初始化
# 创建窗体
window = WindowProperties()
window.setTitle('奇异之旅')
window.setSize(1200, 800)
base.win.requestProperties(window)
base.setBackgroundColor(100/255, 250/255, 180/255)
# 调整相机位置及其角度
cam_x, cam_y, cam_z = 450, -5850, 2000
cam_h, cam_r = 0, 0
base.cam.setPos(cam_x, cam_y, cam_z)
base.cam.setHpr(cam_h, -16, cam_r)
# 禁用鼠标
base.disableMouse()
# 定义加载模型函数
def load_model(path, pos, hpr):
    model = loader.loadModel(path)
    model.reparentTo(render)
    model.setPos(pos[0], pos[1], pos[2])
    model.setHpr(hpr[0], hpr[1], hpr[2])
    return model


# 加载字体
font = loader.loadFont('字体.TTF')
content = OnscreenText(text='',
                       pos=(0, 0.6, 0),
                       scale=0.15,
                       wordwrap=80)
content2 = OnscreenText(text='',
                        pos=(0, 0.5, 0),
                        scale=0.06,
                        wordwrap=80)
content.setFont(font)
content2.setFont(font)

# 定义坐标转换函数
pickerRay = CollisionRay()
def model_position(model):
    if base.mouseWatcherNode.hasMouse():
        mpos = base.mouseWatcherNode.getMouse()
        pickerRay.setFromLens(base.camNode, mpos)
        nearPoint = render.getRelativePoint(base.cam, pickerRay.getOrigin())
        nearVec = render.getRelativeVector(base.cam, pickerRay.getDirection())
        model.setPos(nearPoint + nearVec *
                     ((110 - nearPoint.getZ()) / nearVec.getZ()))

# 初始化数据
time = 0
is_keep = {'house1': False, 'house2': False}
car_state = {'forward': False, 'turn_left': False, }
## 加载场景
scene = load_model("scene", (0, 0, 0), (0, 0, 0))
house = load_model('house', (-650, 1300, 0), (45, 0, 0))
house.setScale(1.1)
# 一号房子
house1 = load_model('house', (800, -1550, 30), (115, 0, 0))
house1.setScale(0.6)
# 二号房子
house2 = load_model('house', (2000, -650, 80), (0, 0, 0))
house2.setScale(0.6)
# 加载太阳能汽车
# car:模型文件名,run:动画名称,car_run:模型文件名称
car = Actor('car', {'run': 'car_run'})
car.reparentTo(render)
car.setPos(340, -2300, 0)
car.setHpr(90, 0, 0)
# 鼠标
mouse = loader.loadModel('hammer')
mouse.reparentTo(render)
mouse.setScale(0.1)


## 碰撞的创建于设置
# 创建一号房子的碰撞体
sphere = CollisionSphere(0, 0, 500, 800)
sphere_node = CollisionNode('house1')
sphere_node.addSolid(sphere)
house_collision = house1.attachNewNode(sphere_node)
# house_collision.show()
# 创建二号房子的碰撞体
sphere = CollisionSphere(0, 0, 1400, 1500)
sphere_node = CollisionNode('house2')
sphere_node.addSolid(sphere)
house_collision = house2.attachNewNode(sphere_node)
# house_collision.show()
# 创建鼠标的碰撞体
sphere = CollisionSphere(0, 0, 0, 450)
sphere_node = CollisionNode('mouse')
sphere_node.addSolid(sphere)
mouse_collision = mouse.attachNewNode(sphere_node)
# mouse_collision.show()
# 添加列表碰撞处理方法
base.cTrav = CollisionTraverser()
queue_handler = CollisionHandlerQueue()
base.cTrav.addCollider(mouse_collision, queue_handler)

##定义任务函数
def whole(task):
    keep_going = False
    # 绑定鼠标
    model_position(mouse)

    # 实现触碰放大效果
    if queue_handler.getNumEntries() > 0:
        queue_handler.sortEntries()
        if queue_handler.getEntry(0).getIntoNode().getName()\
                == 'house1':
            keep_going = True
            house1.setScale(0.7)
            content2.setText('点击进入拯救小鸟游戏')
        if queue_handler.getEntry(0).getIntoNode().getName()\
                == 'house2':
            keep_going = True
            house2.setScale(0.7)
            content2.setText('点击进入长隆野生动物科普')
    if not keep_going:
        house1.setScale(0.6)
        house2.setScale(0.6)
        content2.setText('把鼠标放在路边的房子上选择场景')

    return task.cont

# 添加到任务函数
taskMgr.add(whole)

# 定义游戏类
def start_game1():
    # 初始化,设置标题,窗口等
    pygame.init()
    screen = pygame.display.set_mode((288, 512))  # 窗口
    background = pygame.image.load('bg_day.png')  # 背景图
    pygame.display.set_caption('拯救小鸟')  # 标题

    # 初始化变量
    keep_going = True
    show_notice=True
    show_over=True
    clock = pygame.time.Clock()
    cnt = 0
    # 设置字体
    font = pygame.font.SysFont('SimHei', 24)

    # 定义水管类
    class Wall():
        def __init__(self):
            # 加载素材
            self.wallDown = pygame.image.load('pipe_up.png')
            self.wallUp = pygame.image.load('pipe_down.png')
            self.wallx = 288

            self.gap = 100
            self.offset = random.randint(-50, 50)
            self.wallUpRect = self.wallUp.get_rect()
            self.wallDownRect = self.wallDown.get_rect()

            self.wallUpRect.center = (self.wallx, 0-self.gap-self.offset)
            self.wallDownRect.center = (self.wallx, 520-self.gap-self.offset)

        # 刷新
        def wallUpdate(self):
            self.wallx -= 2
            if self.wallx < -80:
                self.wallx = 280
                self.offset = random.randint(-50, 50)

            self.wallUpRect.center = (self.wallx, 0-self.gap-self.offset)
            self.wallDownRect.center = (self.wallx, 520-self.gap-self.offset)

    # 定义鸟类
    class Bird():
        def __init__(self):
            # 加载素材
            self.birdSprites = [pygame.image.load('0.png'), pygame.image.load(
                '1.png'), pygame.image.load('2.png')]
            self.a = 0
            self.birdX = 50
            self.birdY = 100
            self.jumpSpeed = 7
            self.gravity = 0.4

            self.rect = self.birdSprites[self.a].get_rect()
            self.rect.center = (self.birdX, self.birdY)

        # 刷新
        def birdUpdate(self):
            self.jumpSpeed -= self.gravity
            self.birdY -= self.jumpSpeed
            self.rect.center = (self.birdX, self.birdY)
            if self.jumpSpeed < 0:
                self.a = 1
            if self.jumpSpeed > 0:
                self.a = 2  
        
        # 碰撞检测
        def birdCush(self):
            resultU = self.rect.colliderect(newWall.wallUpRect)
            resultD = self.rect.colliderect(newWall. wallDownRect)
            if resultU or resultD or newBird.rect.top > 512:
                return True

    # 实例化
    newWall = Wall()
    newBird = Bird()
    
    # 显示告示
    while show_notice:
        for event in pygame.event.get():
            if(event.type == pygame.MOUSEBUTTONDOWN):
                show_notice=False
        # 加载素材
        notice=pygame.image.load('告示_1.png')
        
        # 加载到窗口上
        screen.blit(background, (0, 0))
        screen.blit(newWall.wallUp, newWall.wallUpRect)
        screen.blit(newWall.wallDown, newWall.wallDownRect)
        screen.blit(notice, (-22, 150))
        # 窗口刷新
        pygame.display.update()


    # pygame主程序循环
    while keep_going:
        for event in pygame.event.get():  # 判断是否按下关闭键
            if event.type == pygame.QUIT:
                keep_going = False
            if(event.type == pygame.MOUSEBUTTONDOWN):  # 判断是否按下鼠标
                newBird.jumpSpeed = 7
        if newWall.wallx == 40:
            cnt = cnt+1

        # 加载程序到窗口上
        screen.blit(background, (0, 0))
        screen.blit(newBird.birdSprites[newBird.a], (newBird.rect))
        screen.blit(newWall.wallUp, newWall.wallUpRect)
        screen.blit(newWall.wallDown, newWall.wallDownRect)
        text = font.render('得分:'+str(cnt), True, (255, 210, 0), (155, 0, 0))
        screen.blit(text, (210, 10))

        newBird.birdUpdate()  # 刷新界面
        newWall.wallUpdate()  # 刷新界面

        # 碰撞检测
        if newBird.birdCush():
            keep_going = False

        # 刷新窗口
        pygame.display.update()
        # 设置帧率
        clock.tick(60)
    
    # 显示结束标志
    while show_over:
        for event in pygame.event.get():
            if(event.type == pygame.MOUSEBUTTONDOWN):
                show_over = False
        # 加载素材
        over = pygame.image.load('game over.png')

        # 把素材绑定在窗口上
        screen.blit(background, (0, 0))
        screen.blit(newWall.wallUp, newWall.wallUpRect)
        screen.blit(newWall.wallDown, newWall.wallDownRect)
        screen.blit(over, (40, 150))
        pygame.display.update()



    # 退出游戏
    pygame.quit()

# 定义显示科普类
def start_game2():
    # 初始化
    pygame.init()
    screen = pygame.display.set_mode((900, 534))

    # 初始化参数
    animal_list = ['考拉', '山魈', '熊猫', '细尾獴', '黑叶猴']
    keep_going = True
    show_notice=True
    img_num = 0
    animal_num = 0
    while show_notice:
        for event in pygame.event.get():
            if(event.type == pygame.MOUSEBUTTONDOWN):
                show_notice = False
        notice=pygame.image.load('告示_2.png')
        screen.blit(notice,(75,0))
        pygame.display.update()

    # 循环
    while keep_going:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                keep_going = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                img_num += 1

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    animal_num += 1
                    if animal_num > 4:
                        animal_num = 0
        
        # 加载素材
        animal = pygame.image.load(
            os.path.join(animal_list[animal_num], '{}.jpg'.format(img_num % 4)))
        picture = pygame.image.load('{}.png'.format(animal_list[animal_num]))

        # 把素材绑定在窗口上
        screen.blit(animal, (0, 0))
        screen.blit(picture, (532, 0))

        # 刷新
        pygame.display.update()

    # 退出游戏
    pygame.quit()

# 触发检测
def knock(state):
    if state:
        if queue_handler.getNumEntries() > 0:
            queue_handler.sortEntries()
            if queue_handler.getEntry(0).getIntoNode().getName()\
                    == 'house1':
                messenger.send('start_game1')

        if queue_handler.getNumEntries() > 0:
            queue_handler.sortEntries()
            if queue_handler.getEntry(0).getIntoNode().getName()\
                    == 'house2':
                messenger.send('start_game2')

# 事件检测
base.accept('mouse1', knock, [True])
base.accept('start_game1',start_game1)
base.accept('start_game2',start_game2)

content.setText('欢迎来到长隆陆地世界')
content2.setText('把鼠标放在路边的房子上选择场景')

# 运行程序
base.run()

 

【提示】

部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:

https://python.codemao.cn


回复

上一页1 页 / 共 1下一页
战狼3战狼3

链接: h t t p s://pan.喵/s/1hmlkcztA7WgcENv5BOGdhg  (去掉空格)

密码: sdfc

文件是一个压缩包,请一定记得右键解压到当前文件夹而不是直接点击,里面有一个代码文件,就点击这个就行了,其它不用管,特别是文件的顺序别弄乱

点赞0


评论