游戏开发中的物理介绍(2)

简介: 游戏开发中的物理介绍

Area2D


区域节点提供检测和影响。它们可以检测物体何时重叠并在物体进入或离开时发出信号。区域还可以用于覆盖定义区域中的物理属性,例如重力或阻尼。


Area2D有三个主要用途:


给定区域中的替代物理参数(例如重力)。

检测其他物体何时进入或离开区域或当前区域中有哪些物体。

检查其他区域是否重叠。

默认情况下,区域还接收鼠标和触摸屏输入。


StaticBody2D


静态物体是物理引擎不会移动的物体。它参与碰撞检测,但不会响应碰撞而移动。但是,它可以利用其和属性为碰撞的物体提供运动或旋转,就好像它在运动一样。constant_linear_velocityconstant_angular_velocity


StaticBody2D 节点最常用于环境中的对象或不需要任何动态行为的对象。


示例用于StaticBody2D:


平台(包括移动平台)

输送带

墙壁和其他障碍

RigidBody2D


这是实现模拟2D物理的节点。您不能直接控制 RigidBody2D。取而代之的是,您对其施加力,然后物理引擎会计算出最终的运动,包括与其他物体的碰撞以及碰撞响应(如弹跳,旋转等)。


您可以通过“质量”,“摩擦”或“弹跳”之类的属性来修改刚体的行为,这些属性可以在检查器中设置。


人体的行为也会受到世界属性(如在“ 项目设置”->“物理”中设置的)的影响,或者受输入 覆盖全球物理属性的Area2D的影响。


当刚体处于静止状态并且一段时间未移动时,它将进入睡眠状态。睡眠物体的作用类似于静态物体,其力不是由物理引擎计算的。当通过碰撞或通过代码施加力时,身体将醒来。


刚体模式

刚体可以设置为以下四种模式之一:


刚性-身体表现为物理对象。它会与其他物体碰撞,并对其施加的力作出反应。这是默认模式。

静态-主体的行为类似于StaticBody2D,并且不会移动。

角色-与“刚性”模式相似,但身体无法旋转。

运动-身体的行为类似于KinematicBody2D,必须通过代码移动。

使用RigidBody2D

使用刚体的好处之一是无需编写任何代码即可“免费”获得许多行为。例如,如果您要制作带有下降块的“愤怒的小鸟”式游戏,则只需创建RigidBody2Ds并调整其属性。堆积,下落和弹跳将由物理引擎自动计算。


但是,如果你想有过身体有一定的控制,你应该照顾-改变position,linear_velocity,刚体的或其他物理性质可能会导致意外的行为。如果您需要更改任何与物理学相关的属性,则应使用_integrate_forces() 回调而不是_physics_process()。在此回调中,您可以访问人体的Physics2DDirectBodyState,它可以安全地更改属性并将其与物理引擎同步。


例如,以下是“小行星”式太空飞船的代码:


class Spaceship : RigidBody2D
{
    private Vector2 _thrust = new Vector2(0, 250);
    private float _torque = 20000;
    public override void _IntegrateForces(Physics2DDirectBodyState state)
    {
        if (Input.IsActionPressed("ui_up"))
            SetAppliedForce(_thrust.Rotated(Rotation));
        else
            SetAppliedForce(new Vector2());
        var rotationDir = 0;
        if (Input.IsActionPressed("ui_right"))
            rotationDir += 1;
        if (Input.IsActionPressed("ui_left"))
            rotationDir -= 1;
        SetAppliedTorque(rotationDir * _torque);
    }
}

请注意,我们不是 直接设置linear_velocity或angular_velocity属性,而是将力(thrust和torque)施加到物体上,然后让物理引擎计算出所产生的运动。


注意

当刚体进入睡眠状态时,_integrate_forces()

将不会调用该功能。要覆盖此行为,您将需要通过创建碰撞,向其施加力或禁用can_sleep

属性来使身体保持清醒状态。请注意,这可能会对性能产生负面影响。

联系人报告

默认情况下,刚体不跟踪接触,因为如果场景中有很多刚体,这可能需要大量的内存。若要启用联系人报告,请将contacts_reported 属性设置为非零值。然后可以通过Physics2DDirectBodyState.get_contact_count()和相关函数来获取联系人 。


可以通过contact_monitor 属性启用通过信号的接触监视。有关可用信号的列表,请参见RigidBody2D。


KinematicBody2D


KinematicBody2D实体可以检测与其他实体的碰撞,但不受重力或摩擦等物理属性的影响。相反,它们必须由用户通过代码控制。物理引擎不会移动运动体。


移动运动机构时,请勿position直接设置它。而是使用move_and_collide()ormove_and_slide()方法。这些方法沿着给定的矢量移动物体,如果检测到与另一个物体的碰撞,它将立即停止。身体碰撞后,任何碰撞响应都必须手动编码。


运动碰撞响应

发生碰撞后,您可能希望身体反弹,沿墙滑动或改变其撞击的对象的属性。处理碰撞响应的方式取决于您用来移动KinematicBody2D的方法。


move_and_collide

使用时move_and_collide(),该函数返回 KinematicCollision2D对象,该对象包含有关碰撞和碰撞体的信息。您可以使用此信息来确定响应。


例如,如果要查找空间中发生碰撞的点:


class Body : KinematicBody2D
{
    private Vector2 _velocity = new Vector2(250, 250);
    public override void _PhysicsProcess(float delta)
    {
        var collisionInfo = MoveAndCollide(_velocity * delta);
        if (collisionInfo != null)
        {
            var collisionPoint = collisionInfo.GetPosition();
        }
    }
}


或从碰撞对象反弹:


class Body : KinematicBody2D
{
    private Vector2 _velocity = new Vector2(250, 250);
    public override void _PhysicsProcess(float delta)
    {
        var collisionInfo = MoveAndCollide(_velocity * delta);
        if (collisionInfo != null)
            _velocity = _velocity.Bounce(collisionInfo.Normal);
    }
}
move_and_slide


滑动是一种常见的碰撞反应。想象一个玩家在自上而下的游戏中沿着墙壁移动,或者在平台游戏中在斜坡上上下移动。虽然可以使用后,自己编写这种反应move_and_collide(), move_and_slide()提供了实现滑动,而无需编写大量代码的便捷方式。


警告

move_and_slide()自动包括在计算中时间步长,所以应该没有乘法的速度矢量通过delta。

例如,使用以下代码制作一个可以在地面上行走(包括斜坡)并在站立在地面上时可以跳跃的角色:

class Body : KinematicBody2D
{
    private float _runSpeed = 350;
    private float _jumpSpeed = -1000;
    private float _gravity = 2500;
    private Vector2 _velocity = new Vector2();
    private void GetInput()
    {
        _velocity.x = 0;
        var right = Input.IsActionPressed("ui_right");
        var left = Input.IsActionPressed("ui_left");
        var jump = Input.IsActionPressed("ui_select");
        if (IsOnFloor() && jump)
            _velocity.y = _jumpSpeed;
        if (right)
            _velocity.x += _runSpeed;
        if (left)
            _velocity.x -= _runSpeed;
    }
    public override void _PhysicsProcess(float delta)
    {
        _velocity.y += _gravity * delta;
        GetInput();
        _velocity = MoveAndSlide(velocity, new Vector2(0,-1));
    }
}


有关使用的更多详细信息,请参见运动字符(2D)move_and_slide(),包括带有详细代码的演示项目。

目录
相关文章
|
Java 程序员 Android开发
apk简单介绍(组成以及打包安装流程)
apk简单介绍(组成以及打包安装流程)
737 0
|
存储 前端开发 JavaScript
【面试题】面试官问:如果有100个请求,你如何使用Promise控制并发?
【面试题】面试官问:如果有100个请求,你如何使用Promise控制并发?
400 0
|
3月前
|
人工智能 文字识别 自然语言处理
智能体来了:行政文员如何应用 AI 进行批量公文处理深度指南
本文深入解析AI智能体在批量公文处理中的核心架构与企业落地路径,涵盖智能解析、合规审查、自动排版分发等全流程。结合LLM语义理解与RPA自动化,实现效率提升超85%,合规检出率达98%。适用于政府、企业数字化转型实践,提供可复用的技术方案与实施指南。(238字)
568 6
|
3月前
|
安全 应用服务中间件 Linux
HTTPS 优化完整方案解析
本文详解HTTPS性能优化全方案,从原理到实操,涵盖硬件加速(AES-NI)、软件升级(内核与OpenSSL)及协议层优化(TLS 1.3、ECDSA、会话复用等),配合Nginx配置模板与验证方法,助你实现安全与速度双提升,显著降低访问延迟。
1225 156
|
3月前
|
数据采集 人工智能 搜索推荐
智能体来了:降本增效的终极杀手锏,销售人必看的生存指南
内容摘要:AI智能体(AI Agents)正重塑销售底层逻辑。本文深度拆解智能体如何通过自动化获客、个性化触达及全天候线索转化,协助销售人员打破内卷僵局,实现业绩呈指数级增长。
272 3
|
5月前
|
人工智能 JavaScript IDE
别用"战术勤奋"掩盖"战略懒惰":AI时代的降维竞品分析
5%的产品死于"盲视"。本文不仅是一套竞品分析AI指令,更是一次从战术勤奋到战略觉醒的认知升级。教你如何利用AI构建全天候商业情报雷达,寻找巨头缝隙中的差异化生存之道,实现商业战场的降维打击。
513 7
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
人工智能与ai有什么区别
本文探讨了“人工智能”与“AI”在语义、使用场景及技术侧重点上的差异,强调理解这些差异对把握技术发展的重要性。文中分析了两者的学术与通俗应用场景,并结合生成式人工智能认证项目(由培生于2024年推出),说明如何通过理论与实践结合,规避AI局限性,推动技术创新。最终呼吁在概念辨析中探索人工智能的未来潜力。
|
7月前
|
机器学习/深度学习 编解码 Python
Python图片上采样工具 - RealESRGANer
Real-ESRGAN基于深度学习实现图像超分辨率放大,有效改善传统PIL缩放的模糊问题。支持多种模型版本,推荐使用魔搭社区提供的预训练模型,适用于将小图高质量放大至大图,放大倍率越低效果越佳。
520 3
|
9月前
|
安全 Linux 网络安全
Python极速搭建局域网文件共享服务器:一行命令实现HTTPS安全传输
本文介绍如何利用Python的http.server模块,通过一行命令快速搭建支持HTTPS的安全文件下载服务器,无需第三方工具,3分钟部署,保障局域网文件共享的隐私与安全。
2195 0