乒乓球 Pong
在这个简单的教程中,我们会创建一个基本的乒乓球游戏。在引擎的演示中有很多复杂的例子,但是这里应该介绍一个具备基本功能的2D游戏。
资源 Assets
这个教程包含以下资源:乒乓垫,乒乓球,临界线
场景设置 Scene Setup
在以前,游戏是设定在640*400的分辨率的。分辨率的设置可以在工程配置project setting中进行设置。默认背景颜色应该设置为黑色:
在工程的根目录创建一个Node2D类型的节点,它是2D引擎中最基础的节点类型。然后,添加一些精灵(Sprite 类型节点)以及它们自身的纹理,最后的场景是很下面的相同的(注意:乒乓球是在中间的):
场景的树层级结构,看起来和下面的是相同的:
保存场景为“pong.scn”,并且设置它为工程属性的主场景(main_scene)
Input Actions Setup 输入动作配置
有很多输入的方法是专为游戏准备的,如Keyboard,Joypad,Mouse,TouchScreen(MutiTouch)。然而,这只是一个乒乓球游戏,它只需要控制乒乓球垫的上下移动。
处理所有的输入方法可能会令人诅丧并且需要写很多的代码。事实是,因为很多游戏允许控制者自定义从而导致了处理输入变得糟糕的。在这里,Godot创建了输入动作,一个动作被定义,那么对应激活它的方法就会被添加。
再次打开工程属性对话框,但是这次选择“Input Map”标签,并且在上面添加4个动作:
"left_move_up","left_move_down","right_move_up","right_move_down",绑定你需要使用的键值。左边的是A/Z,右边的是Up/Down
如下图:
Script
为当前的场景的根节点创建一个脚本并且打开它(前面的课程已经讲过),脚本会继承自Node2D:
extends Node2D func _ready(): pass
extends Node2D var screen_size var pad_size func _ready(): screen_size = get_viewport_rect().size pad_size = get_node("left").get_texture().get_size() set_process(true)然后在游戏中添加一些需要使用到的值:
#speed of the ball (in pixels/second0 var ball_speed = 80 #direction of the ball (normal vector) var direction = Vector2(-1,0) #constant for pad speed (also in pixels/second) const PAD_SPEED = 150最后,处理函数:
func _process(delta):获得一些计算需要使用的值,首先是球的位置,还有垫的矩形(Rect2)区域,精灵Sprites是以纹理的中心点为参考的,所以一个小的调整(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如果一个垫被触碰到了,那么改变球的方向并且增加一点速度:
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)根据玩家的输入更新垫的位置,在这里,输入类就变得很重要了:
#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)这就是一个简单的2D游戏!在这里,一个简单乒乓球游戏通过几行代码就完成了。