tutorial_2d - seraph526/godot-se GitHub Wiki

简单的2d游戏 (乒乓球!)

乒乓球

在这个简单的教程中,我们会创建一个简单的乒乓球游戏。引擎中有许多复杂的示例,但这个示例会简单介绍基本的2D游戏编程。

资源

这个教程要包含一些资源文件pong pads, the ball and the divisor.

场景设置

因为是老年代的游戏,游戏设置为640*480分辨率。这可以在项目设置中设置(请参考前面的教程),默认场景颜色为黑色。

输入行为设置

电子游戏有许多输入方法...键盘,手柄,鼠标,触摸屏(多点触摸)。我们要做的是个乒乓球游戏,唯一的输入是控制拍子的上下。

处理所的可能的输入方式是件令人崩溃的事,而且会花费大量的代码。事实上,大部分游戏允许玩家自定义的使情况变得更糟。因此 ,Godot创建了“输入行为(Input Actions)”这一功能。一个行为被定义后,还要定义相应的触发的方法。

再次打开项目属性对话框,点击"Input Map"标签。在里,填加4种行为:"left_move_up","left_move_down","right_move_up","right_move_down".可以设置你希望使用的键位。大多情况下使用左边:A/Z,右边:Up/Down的设置方式。

脚本

为根节点创建一个脚本,打开它(前面已经讲过了)。脚本要继承自Node2D:

extends Node2D

func _ready():
	pass

在这个结构中,有两件事要做。第一,使proessing可用,第二,存储一些有用的值,这些值是场景和球拍的大小。


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)。精灵默认是以纹理中心为中心点的,所以需要使用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)
	

收工!一个简单的乒乓球游戏就制作完了.