Python利用3D引擎写一个Pong游戏

目录
  • 前言
  • 实现方法
  • 完整代码

前言

之前,我们用pygame做了一个2D的Pong游戏,今天我们做一个3D的,游戏画面如下:

用ad和←→操作,双人对战

实现该效果我们使用Python强大的3D引擎Ursina,基础的使用方法见这篇文章:详解Python 3D引擎Ursina如何绘制立体图形

接下来开始写代码吧!

实现方法

首先,导入ursina和随机库

from ursina import *
import random as rd

定义两个玩家的分数

scorea=scoreb=0

然后,我们创建app

app=Ursina()

ursina自带window参数,代表窗口,它还自带color参数,代表各种颜色,我们直接修改窗口的颜色

window.color=color.cyan

我们创建一个桌子,它是一个长方体,所以model为cube,颜色是橙色,然后进行缩放操作,并设置位置,还有它的材质(普通材质)

table=Entity(model="cube",color=color.orange,scale=(10,0.5,14),position=(0,0,0),texture="white_cube")

照样子,创建一个板子

paddle_A=Entity(parent=table,color=color.black,model="cube",scale=(0.2,0.03,0.05),position=(0,3.7,0.22),collider="box")

因为第二个板子和第一个板子差不多,我们只需要用duplicate函数进行实体复制,然后修改部分参数即可

paddle_B=duplicate(paddle_A,z=-0.62)

然后,把分数显示,显示文字用到了Text类,参数差不多

t=Text(text=f"Player A : Player B  {scorea} : {scoreb}", position=(-0.85, 0.45), scale=2,color=color.orange)

这样运行程序,我们只看到了桌子的侧面,调整视角,改变ursina自带的camera的属性即可,设置它的倾斜度和位置

camera.position=(0,15,-26)
camera.rotation_x=30

绘制两个玩家的名字

Text(text="Player A",scale=2,position=(-0.1,0.32),color=color.orange)
Text(text="Player B",scale=2,position=(-0.1,-0.4),color=color.orange)

接下来,绘制桌子中间的分割线和球

line=Entity(parent=table,model="quad",scale=(0.88,0.2,0.1),position=(0,3.5,-0.2))
ball=Entity(parent=table,model="sphere",color=color.gold,scale=.05,position=(0,3.7,-0.2),collider="box")

设置初始x和z的速度

dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)

然后进入主循环

app.run()

我们在创建app前添加update函数,注意,这里名字一定要用update,然后自己无需调用,由ursina自动调用

创建函数并引入全局变量

def update():
    global dx,dz,scorea,scoreb

然后判断按下了按键就对板子进行移动操作,按下按键的信息存储于held_keys中,并限制板子的移动范围

    paddle_B.x-=held_keys["left arrow"]*time.dt
    paddle_B.x+=held_keys["right arrow"]*time.dt
    paddle_A.x-=held_keys["a"]*time.dt
    paddle_A.x+=held_keys["d"]*time.dt
    if paddle_A.x>0.35:
        paddle_A.x=0.35
    elif paddle_A.x<-0.35:
        paddle_A.x=-0.35
    if paddle_B.x>0.35:
        paddle_B.x=0.35
    elif paddle_B.x<-0.35:
        paddle_B.x=-0.35

移动小球

    ball.x+=dx*time.dt
    ball.z+=dz*time.dt

更新比分显示

    t.text=f"Player A : Player B  {scorea} : {scoreb}"

进行板子和球的碰撞检测,先用intersects获取触碰到的实体列表,然后对碰到实体为两个板子的时候进行反弹、加速或减速的操作

    hit_info=ball.intersects()
    if hit_info.hit:
        if hit_info.entity==paddle_A:
            dz=-dz
            if dz>-0.05:
                dz-=rd.uniform(0.1,0.3)
            else:
                dz-=rd.uniform(-0.05,0.2)
        if hit_info.entity==paddle_B:
            dz=-dz
            if dz<0.05:
                dz+=rd.uniform(0.1,0.3)
            else:
                dz+=rd.uniform(-0.05,0.2)

限制球在桌子中间移动,如果一方没有接到球,就对另一方进行加分的操作

    if abs(ball.x)>0.4:
        dx=-dx
    if ball.z>0.25:
        scoreb+=1
        ball.x=0
        ball.z=-0.2
        dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
        dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
    if ball.z<-0.65:
        scorea+=1
        ball.x=0
        ball.z=-0.2
        dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
        dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)

我们用了不到100行代码,就实现了以下效果~

完整代码

这里附上最终代码:

from ursina import *
import random as rd

scorea=scoreb=0

def update():
    global dx,dz,scorea,scoreb
    paddle_B.x-=held_keys["left arrow"]*time.dt
    paddle_B.x+=held_keys["right arrow"]*time.dt
    paddle_A.x-=held_keys["a"]*time.dt
    paddle_A.x+=held_keys["d"]*time.dt
    if paddle_A.x>0.35:
        paddle_A.x=0.35
    elif paddle_A.x<-0.35:
        paddle_A.x=-0.35
    if paddle_B.x>0.35:
        paddle_B.x=0.35
    elif paddle_B.x<-0.35:
        paddle_B.x=-0.35
    ball.x+=dx*time.dt
    ball.z+=dz*time.dt
    t.text=f"Player A : Player B  {scorea} : {scoreb}"
    hit_info=ball.intersects()
    if hit_info.hit:
        if hit_info.entity==paddle_A:
            dz=-dz
            if dz>-0.05:
                dz-=rd.uniform(0.1,0.3)
            else:
                dz-=rd.uniform(-0.05,0.2)
        if hit_info.entity==paddle_B:
            dz=-dz
            if dz<0.05:
                dz+=rd.uniform(0.1,0.3)
            else:
                dz+=rd.uniform(-0.05,0.2)
    if abs(ball.x)>0.4:
        dx=-dx
    if ball.z>0.25:
        scoreb+=1
        ball.x=0
        ball.z=-0.2
        dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
        dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)
    if ball.z<-0.65:
        scorea+=1
        ball.x=0
        ball.z=-0.2
        dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
        dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)

app=Ursina()

window.color=color.cyan

table=Entity(model="cube",color=color.orange,scale=(10,0.5,14),position=(0,0,0),texture="white_cube")

paddle_A=Entity(parent=table,color=color.black,model="cube",scale=(0.2,0.03,0.05),position=(0,3.7,0.22),collider="box")
paddle_B=duplicate(paddle_A,z=-0.62)

t=Text(text=f"Player A : Player B  {scorea} : {scoreb}", position=(-0.85, 0.45), scale=2,color=color.orange)

camera.position=(0,15,-26)
camera.rotation_x=30

Text(text="Player A",scale=2,position=(-0.1,0.32),color=color.orange)
Text(text="Player B",scale=2,position=(-0.1,-0.4),color=color.orange)

line=Entity(parent=table,model="quad",scale=(0.88,0.2,0.1),position=(0,3.5,-0.2))
ball=Entity(parent=table,model="sphere",color=color.gold,scale=.05,position=(0,3.7,-0.2),collider="box")

dx=rd.uniform(-0.4,0.15) if rd.randint(0,1)==0 else rd.uniform(0.15,0.4)
dz=rd.uniform(-0.5,0.2) if rd.randint(0,1)==0 else rd.uniform(0.2,0.5)

app.run()

到此这篇关于Python利用3D引擎写一个Pong游戏的文章就介绍到这了,更多相关Python Pong游戏内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python实现生命游戏的示例代码(tkinter版)

    目录 生命游戏(Game of Life) 游戏概述 生存定律 图形结构 代码实现 运行界面 使用简介 后续改进 生命游戏(Game of Life) 由剑桥大学约翰·何顿·康威设计的计算机程序.美国趣味数学大师马丁·加德纳(Martin Gardner,1914-2010)通过<科学美国人>杂志,将康威的生命游戏介绍给学术界之外的广大渎者,一时吸引了各行各业一大批人的兴趣,这时细胞自动机课题才吸引了科学家的注意. 游戏概述 用一个二维表格表示“生存空间”,空间的每个方格中都可放置一个生命细胞

  • Python+Pygame编写一个Pong游戏

    目录 前言 代码教学 最终代码 前言 这次,我们要用Pygame写一个Pong游戏 先看看效果: 需要的模块:Pygame 在python文件同目录下新建resources文件夹,在文件夹中新建Pong文件夹,文件夹中放入两个音频文件 代码教学 导入需要的模块 import pygame from pygame.locals import * import random import sys 定义常量 COUNTDOWN=USEREVENT+1 path="resources/Pong/&quo

  • Python利用物理引擎Pymunk编写一个解压小游戏

    用鼠标创建小球,一个蹦来蹦去的解压小游戏…… 本次需要的外置包:pygame,pymunk,cmd运行该命令安装: pip install pygame pip install pymunk 首先,导入 import pymunk import pygame from pygame.locals import * import sys import random as rd 结合pygame,创建若干障碍,并设置重力.弹跳力等参数  class Demo: WIDTH=800 HEIGHT=80

  • python实现一个简单的贪吃蛇游戏附代码

    前言: 不知道有多少同学跟我一样,最初接触编程的动机就是为了自己做个游戏玩? 今天要给大家分享的是一个 pygame 写的“贪吃蛇”小游戏: “贪吃蛇”这个小游戏在编程学习中的常客,因为: 简单,最基本的游戏元素只需要蛇和食物两个就可以进行了.(打飞机还需要三个元素呢,想想分别是什么?)方向的话只要上下左右4个固定方向就可以了.有基本的数据结构和面向对象的思想在其中.游戏开发本身就会用到很多面向对象的概念,而蛇的身体又是一个天然的“链表”结构,太适合用来练习数据结构了.另外比较有趣的一点是,Py

  • Python利用3D引擎写一个Pong游戏

    目录 前言 实现方法 完整代码 前言 之前,我们用pygame做了一个2D的Pong游戏,今天我们做一个3D的,游戏画面如下: 用ad和←→操作,双人对战 实现该效果我们使用Python强大的3D引擎Ursina,基础的使用方法见这篇文章:详解Python 3D引擎Ursina如何绘制立体图形 接下来开始写代码吧! 实现方法 首先,导入ursina和随机库 from ursina import * import random as rd 定义两个玩家的分数 scorea=scoreb=0 然后,

  • Python利用3D引擎做一个太阳系行星模拟器

    这次,我们再来用Ursina引擎来做一个太阳系行星模拟器吧! 想要了解Ursina 3D引擎的基本使用方法的话,查看我的另一篇文章:详解Python 3D引擎Ursina如何绘制立体图形 这一次,我们要实现的效果如下 首先,送上本次需要用到的资源 Earth.jpg Jupiter.jpg Mars.jpg Mercury.jpg Neptune.jpg Saturn.jpg Sun.jpg Uranus.jpg Venus.jpg 现在,就开始写代码吧! 首先,导入我们需要的模块,导入3D引擎

  • 使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下其中的有趣之处.本次开发的游戏叫做alien invasion. 安装pygame并创建能左右移动的飞船 安装pygame 本人电脑是windows 10.python3.6,pygame下载地址: 传送门 请自行下载对应python版本的pygame 运行以下命令 $ pip install wh

  • Python利用Turtle库绘制一个小老虎

    目录 导语 1.定义库以及初始化界面 2.画出左右两只耳朵 3.画出小老虎头部轮廓 4. 画出老虎的两只眼睛 5.画出老虎的鼻子和嘴巴 6.画出小老虎的左右肢体和脚趾 7.在需要的位置写上我们的新年祝福 8. 显示倒数3,2,1 9.显示我们需要的文字 10.设定代码运行入口,调用目标函数 成果展示 导语 哈喽铁汁们好久不见吖~小编已经复工了于是马不停蹄赶来给大家准备新年礼物算开工礼物吧! 海龟来作图 虎年就是要画老虎 2022不用纸和笔~ 今晚画老虎~ 一二三四五 老虎宝宝示意图 虎年怎么能少

  • Python利用字典树实现猎词游戏

    目录 解决策略 什么是 Trie? 创建 Trie 字典树 单词测试 总结 猎词(word hunt)是一类很常见的游戏,给你一张字母组成的表,然后让你在这些字母中尽可能多的去寻找单词.这类游戏有不同的变体,一类是你可以多次重复使用这些字母(这类游戏叫做猎词),或者你只能使用一次每个字母(这类游戏叫做字母重组).你组出来的单词越长就得分越高,使用了所有字母就可以获得最高分. 这类游戏对计算机而言是很「容易」去完成的,而且要强调一个相当有用的数据结构叫做 “Trie”. 解决策略 让我们先拿出一个

  • Python实战之手写一个搜索引擎

    一.前言 这篇文章,我们将会尝试从零搭建一个简单的新闻搜索引擎 当然,一个完整的搜索引擎十分复杂,这里我们只介绍其中最为核心的几个模块 分别是数据模块.排序模块和搜索模块,下面我们会逐一讲解,这里先从宏观上看一下它们之间的工作流程 二.工作流程 三.数据模块 数据模块的主要作用是爬取网络上的数据,然后对数据进行清洗并保存到本地存储 一般来说,数据模块会采用非定向爬虫技术广泛爬取网络上的数据,以保证充足的数据源 但是由于本文只是演示,所以这里我们仅会采取定向爬虫爬取中国社会科学网上的部分文章素材

  • Python Tornado框架轻松写一个Web应用的全过程

    目录 Tornado是什么 安装 试试看使用tornado框架来写一个web application 总结 Tornado是什么 学委之前在看Jupyter组件的源码的时候,发现了tornado这个web框架. 不仅仅做一个web框架, 通过使用非阻塞网络I/O,Tornado可以扩展到数万个开放连接. 这样非常适合long polling, WebSockets以及其他需要与每个用户建立长期连接的应用程序. 好,下面安装试用一下. 安装 pip install tornado pip 不会用的

  • 利用Java代码写一个并行调用模板

    目录 前言: 1. 一个串行调用的例子 2. CompletionService实现并行调用 3. 抽取通用的并行调用方法 4. 代码思考以及设计模式应用 5. 思考总结 前言: 本文主要介绍内容有: 一个串行调用的例子(App首页信息查询) CompletionService实现并行调用 抽取通用的并行调用方法 代码思考以及设计模式应用 思考总结 1. 一个串行调用的例子 如果让你设计一个APP首页查询的接口,它需要查用户信息.需要查banner信息.需要查标签信息等等. 一般情况,小伙伴会实

  • 利用Java手写一个简易的lombok的示例代码

    目录 1.概述 2.lombok使用方法 3.lombok原理解析 4.手写简易lombok 1.概述 在面向对象编程中,必不可少的需要在代码中定义对象模型,而在基于Java的业务平台开发实践中尤其如此.相信大家在平时开发中也深有感触,本来是没有多少代码开发量的,但是因为定义的业务模型对象比较多,而需要重复写Getter/Setter.构造器方法.字符串输出的ToString方法.Equals/HashCode方法等.我们都知道Lombok能够替大家完成这些繁琐的操作,但是其背后的原理很少有人会

随机推荐