博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[译]Godot系列教程六 - 简单的二维游戏
阅读量:6192 次
发布时间:2019-06-21

本文共 3349 字,大约阅读时间需要 11 分钟。

Pong

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

静态资源

本文所用到的一些资源文件:

场景设置

考虑到兼容旧设备,该游戏的分辨率设置为 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_sizevar pad_sizevar direction = Vector2(1.0, 0.0)# 常量,球初始移动速度(单位:像素/秒)const INITIAL_BALL_SPEED = 80# 球的实时速度(单位:像素/秒)var ball_speed = INITIAL_BALL_SPEED# pad的移动速度const PAD_SPEED = 150func _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”游戏。

转载地址:http://zjgda.baihongyu.com/

你可能感兴趣的文章
list<T>泛型类和dictionary()泛型类的基本使用和介绍
查看>>
php数组内容分页的例子(转)
查看>>
面试题:寻找热门查询
查看>>
fcntl函数
查看>>
docker的常用命令
查看>>
初始windows程序
查看>>
bzoj2730(割点+分类讨论)
查看>>
操作符重载为成员函数、非成员函数与友元函数的区别
查看>>
Python Tips阅读摘要
查看>>
WPF 气泡提示框的简单实现
查看>>
单行及多行上下翻滚
查看>>
数据可视化建设是企业战略决策之刚需
查看>>
JSON AND BSON
查看>>
What does enumerable mean?
查看>>
Eclipse快捷键【转载】
查看>>
Winform 快速开发框架,上位机开发,工控机程序开发,CS程序开发
查看>>
秒杀系统架构优化思路
查看>>
单源最短路-dijkstra
查看>>
BitcoinCore JSONRPC Java使用,创建账号,获取余额,转账等等...
查看>>
SpringBoot整合微信小程序登录
查看>>