[译]Godot系列教程六 - 简单的二维游戏-阿里云开发者社区

开发者社区> x3d> 正文

[译]Godot系列教程六 - 简单的二维游戏

简介: Pong Godot自带的Demo中有大量更复杂的示例,但这款叫“Pong”的游戏可以对2D游戏的基本特性做一个介绍。 静态资源 本文所用到的一些资源文件:http://files.cnblogs.com/files/x3d/pong_assets.zip 场景设置 考虑到兼容旧设备,该游戏的分辨率设置为 640x400像素,相关操作在项目设置中进行。
+关注继续查看

Pong

Godot自带的Demo中有大量更复杂的示例,但这款叫“Pong”的游戏可以对2D游戏的基本特性做一个介绍。

静态资源

本文所用到的一些资源文件:http://files.cnblogs.com/files/x3d/pong_assets.zip

场景设置

考虑到兼容旧设备,该游戏的分辨率设置为 640x400像素,相关操作在项目设置中进行。默认背景色为黑色:

img_a31850e1999818671e55b2a22791159b.png

在场景面板中创建一个Node2D节点作为项目的根节点。Node2D是2D引擎里的基础类型。然后,添加一些“精灵”(Sprite)节点并为之都设置相应的纹理。最终的场景布局应该类似下图(注意:球在中间!):

img_44d34002c823a6af11b03a77b534bdbe.png

场景树则应类似下图:

img_6872b5b1b8827506f08b8219cf6e6b3a.png

将该场景保存为"pong.scn"文件,并将之设置为项目主场景。

输入动作设置

视频游戏有很多种输入方法,键盘、游戏柄、鼠标、触屏(多点触摸)等。但是对于“pong”这个游戏来说,仅需实现在空格内上下移动的事件响应即可。要实现所有可能的输入方法还是很麻烦的,对应更大的编码量。而且现在的多数游戏还允许玩家对控制器进行自定义设置,这对于开发来说更麻烦。针对这种情况,Godot创建了一种机制 - 输入动作(Input Action)。一旦定义了一种输入动作,意味着对应的输入方法被添加了。

再次打开“项目属性”对话框,切换到“Input Map”选项卡。添加4个动作:left_move_up, left_move_down, right_move_up, right_move_down,并为它们指定按键。为左手边玩家设置A/Z键,右手边玩家设置向上/向下光标键,这样的设置在多数场景下都能正常工作。

img_4f919158e1be784d02ad1fc461521aa7.png

脚本

为场景面板中的根节点创建脚本,打开它。该脚本继承自Node2D:


    extends Node2D

    func _ready():
        pass

_ready()函数是最先被调用的函数(其实更早被执行的是_enter_tree(),只是这里还未涉及到这个概念)。构造函数中,完成了两件事情:首先是启用处理流程,然后是保存一些有用的值:屏幕尺寸、pad:



    extends Node2D

    # 成员变量
    var screen_size
    var pad_size
    var direction = Vector2(1.0, 0.0)

    func _ready():
        screen_size = get_viewport_rect().size
        pad_size = get_node("left").get_texture().get_size()
        set_process(true)

接着,添加一些在游戏处理过程中需要用到的变量:


# 成员变量
var screen_size
var pad_size
var direction = Vector2(1.0, 0.0)

# 常量,球初始移动速度(单位:像素/秒)
const INITIAL_BALL_SPEED = 80
# 球的实时速度(单位:像素/秒)
var ball_speed = INITIAL_BALL_SPEED
# pad的移动速度
const PAD_SPEED = 150

func _ready():
    screen_size = get_viewport_rect().size
    pad_size = get_node("left").get_texture().get_size()
    set_process(true)

最后,编写处理函数:


    func _process(delta):

获取一些要用到的值进行计算。先是球的位置,再是每个pad的矩形区域(Rect2)。Sprite对象默认会对它们的纹理进行居中处理,所以必须要进行调整,pad_size / 2


        var ball_pos = get_node("ball").get_pos()
        var left_rect = Rect2( get_node("left").get_pos() - pad_size/2, pad_size )
        var right_rect = Rect2( get_node("right").get_pos() - pad_size/2, pad_size )

获取球的位置后,整合就比较简单:


        ball_pos += direction * ball_speed * delta

既然球有了新的位置,应该对之进行各种情况的测试。首先,针对底部和顶部边界:


        if ( (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > screen_size.y and direction.y > 0)):
            direction.y = -direction.y

如果其中一个pad被接触到,改变方向并少量加速。


        if ( (left_rect.has_point(ball_pos) and direction.x < 0) or (right_rect.has_point(ball_pos) and direction.x > 0)):
            direction.x = -direction.x
            ball_speed *= 1.1
            direction.y = randf() * 2.0 - 1
            direction = direction.normalized()

球如果跑出屏幕,游戏结束。游戏重新开始:


        if (ball_pos.x < 0 or ball_pos.x > screen_size.x):
            ball_pos = screen_size * 0.5  # ball goes to screen center
            ball_speed = 80
            direction = Vector2(-1, 0)

一旦球处理好了,节点根据新的位置更新:


        get_node("ball").set_pos(ball_pos)

要实现仅在玩家有相应输入时,更新对应pad。Input类在这里就非常有用了:


        #move left pad  
        var left_pos = get_node("left").get_pos()

        if (left_pos.y > 0 and Input.is_action_pressed("left_move_up")):
            left_pos.y += -PAD_SPEED * delta
        if (left_pos.y < screen_size.y and Input.is_action_pressed("left_move_down")):
            left_pos.y += PAD_SPEED * delta

        get_node("left").set_pos(left_pos)

        #move right pad 
        var right_pos = get_node("right").get_pos()

        if (right_pos.y > 0 and Input.is_action_pressed("right_move_up")):
            right_pos.y += -PAD_SPEED * delta
        if (right_pos.y < screen_size.y and Input.is_action_pressed("right_move_down")):
            right_pos.y += PAD_SPEED * delta

        get_node("right").set_pos(right_pos)

好了!这么几行代码就写出了一个简单的“Pong”游戏。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
x3d
[译]Godot系列教程六 - 简单的二维游戏
Pong Godot自带的Demo中有大量更复杂的示例,但这款叫“Pong”的游戏可以对2D游戏的基本特性做一个介绍。 静态资源 本文所用到的一些资源文件:http://files.cnblogs.com/files/x3d/pong_assets.zip 场景设置 考虑到兼容旧设备,该游戏的分辨率设置为 640x400像素,相关操作在项目设置中进行。
910 0
DotNetNuke模块制作Super-Simple(DAL+)教程-翻译
为入门者准备! (适用于 DotNetNuke Version 4.3.1 or higher) 使用 VB.NET 或 C# 这个教程向你演示如何创建一个使用DAL+“ExecuteSQL”方法的DotNetNuke模块,DAL+是DotNetNuke数据存取层(Data Access Layer, DAL)的一个扩展。
947 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
7251 0
x3d
[译]Godot系列教程一 - 场景与节点
场景(Scene)与节点(Node) 简介 先设想有那么一瞬间你自己不再是一名游戏开发者了,而是一名大厨! 你的装备换成了一套大厨的制服。不要考虑制作游戏的事情,你现在的职责是为你的顾客创建新的可口的食谱。
923 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
8947 0
使用 Docker 构建部署运行Spring Boot应用 《Spring Boot 2.0 极简教程》
使用 Docker 构建部署运行Spring Boot应用 《Spring Boot 2.0 极简教程》 image.png image.png image.png image.png 。
974 0
x3d
[译]Godot系列教程五 - 制作Godot编辑器插件
制作插件 下文仅针对2.1版本。 关于插件 插件是为编辑器扩展出更多有用工具的重要方式。它可以完全用GDScript和标准场景开发,甚至都不需重新加载编辑器就可生效。不像模块,你无需创建C++代码、也无需重新编译整个引擎。
1116 0
+关注
x3d
编程语言相关技术专家
527
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载