Przeglądaj źródła

Smooth transition between levels

Create a dedicated Tween for level swapping.
DricomDragon 4 lat temu
rodzic
commit
0be15ebe54
3 zmienionych plików z 47 dodań i 8 usunięć
  1. 30 7
      Game.gd
  2. 5 1
      Game.tscn
  3. 12 0
      LevelSwap.gd

+ 30 - 7
Game.gd

@@ -13,8 +13,10 @@ var levelSceneToLoop
 
 export (Array, String) var levelNames = ["Square"]
 var levelScenes = []
+var levelOldNode
 var levelCurrentNode
 var levelIndex = -1
+onready var levelSwap = $LevelSwap
 
 var playerScene = preload("res://Player.tscn")
 var playerActionsLeft = ["p1_left", "p2_left", "p3_left"]
@@ -22,9 +24,12 @@ var playerActionsRight = ["p1_right", "p2_right", "p3_right"]
 export (Array, Color) var playerColors = [Color.red, Color.blue, Color.green, Color.yellow, Color.white, Color.cyan, Color.magenta, Color.orange]
 
 func _ready():
+	# Prepare levels
 	for _k in range(levelNames.size()):
 		levelScenes.append(null)
 
+	levelSwap.connect("tween_completed", self, "_on_swap_completed")
+
 	if levelToLoop:
 		levelSceneToLoop = load_level(levelToLoop)
 		if !levelSceneToLoop:
@@ -61,8 +66,9 @@ func _unhandled_input(event):
 func create_game():
 	# Clear if required
 	if levelCurrentNode:
-		remove_child(levelCurrentNode)
-		levelCurrentNode.queue_free()
+		levelOldNode = levelCurrentNode
+
+		levelSwap.swap_out(levelOldNode)
 		emit_signal("arena_removed")
 
 	# Create level node
@@ -81,9 +87,16 @@ func create_game():
 
 		levelCurrentNode = levelScenes[levelIndex].instance()
 
-	add_child(levelCurrentNode)
+	# Put the level far away, the tween will bring it back
+	levelCurrentNode.position.y = 2000
 
-	# Allocate spawn points to players
+	# Manually spawn players for the first game
+	if levelOldNode == null:
+		add_child(levelCurrentNode)
+		spawn_players()
+		levelSwap.swap_in(levelCurrentNode)
+
+func spawn_players():
 	var spawners = get_tree().get_nodes_in_group("spawn")
 	spawners.shuffle()
 
@@ -92,9 +105,6 @@ func create_game():
 	for k in p.size():
 		p[k].spawn(levelCurrentNode, spawners[k].position, spawners[k].rotation_degrees)
 
-	# Delay start
-	start_timer.start()
-
 func _on_player_crash():
 	if get_tree().get_nodes_in_group("running").size() <= 1 and !is_round_won:
 		emit_signal("round_won")
@@ -102,3 +112,16 @@ func _on_player_crash():
 
 func _on_start_game():
 	is_round_won = false
+
+func _on_swap_completed(object, _k):
+	if object == levelOldNode:
+		remove_child(levelOldNode)
+		levelOldNode.queue_free()
+		levelOldNode = null
+
+		add_child(levelCurrentNode)
+		spawn_players()
+		levelSwap.swap_in(levelCurrentNode)
+
+	elif object == levelCurrentNode:
+		start_timer.start()

+ 5 - 1
Game.tscn

@@ -1,6 +1,7 @@
-[gd_scene load_steps=3 format=2]
+[gd_scene load_steps=4 format=2]
 
 [ext_resource path="res://MainCamera.gd" type="Script" id=1]
+[ext_resource path="res://LevelSwap.gd" type="Script" id=2]
 [ext_resource path="res://Game.gd" type="Script" id=3]
 
 [node name="Game" type="Node2D"]
@@ -26,4 +27,7 @@ align = 1
 __meta__ = {
 "_edit_use_anchors_": false
 }
+
+[node name="LevelSwap" type="Tween" parent="."]
+script = ExtResource( 2 )
 [connection signal="timeout" from="StartTimer" to="." method="_on_start_game"]

+ 12 - 0
LevelSwap.gd

@@ -0,0 +1,12 @@
+extends Tween
+
+export var duration = 1
+const far_away = 4000
+
+func swap_out(node):
+	interpolate_property(node, "position:x", null, far_away, duration, Tween.TRANS_QUAD, Tween.EASE_IN)
+	start()
+
+func swap_in(node):
+	interpolate_property(node, "position:y", null, 0, duration, Tween.TRANS_QUAD, Tween.EASE_OUT)
+	start()