Added level 1, base-level to abstract from, and level-controller
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
extends Node2D
|
||||
|
||||
onready var topBorder = $TopBorder
|
||||
onready var bottomBorder = $BottomBorder
|
||||
onready var leftBorder = $LeftBorder
|
||||
onready var rightBorder = $RightBorder
|
||||
|
||||
export var NUM_CLOUDS = 12
|
||||
|
||||
var clouds = []
|
||||
var speeds = []
|
||||
var rng = RandomNumberGenerator.new()
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
for num in range(NUM_CLOUDS):
|
||||
var cloud_image_path = "res://assets/cloud%s.png" % (num % 4 + 1)
|
||||
var new_cloud_sprite = Sprite.new()
|
||||
new_cloud_sprite.texture = load(cloud_image_path)
|
||||
add_child(new_cloud_sprite)
|
||||
clouds.append(new_cloud_sprite)
|
||||
var rand_speed = rng.randf_range(0.5,2)
|
||||
speeds.append(rand_speed)
|
||||
rng.randomize()
|
||||
_start_position()
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
var index := 0
|
||||
for cloud in clouds:
|
||||
if cloud.global_position.x + speeds[index] < rightBorder.global_position.x:
|
||||
cloud.global_position.x = cloud.global_position.x + speeds[index]
|
||||
else:
|
||||
cloud.global_position.x = leftBorder.global_position.x
|
||||
cloud.global_position.y = rng.randi_range(topBorder.global_position.y, bottomBorder.global_position.y)
|
||||
index += 1
|
||||
|
||||
func _start_position():
|
||||
rng.randomize()
|
||||
for cloud in clouds:
|
||||
var y = rng.randi_range(topBorder.global_position.y, bottomBorder.global_position.y)
|
||||
var x = rng.randi_range(leftBorder.global_position.x, rightBorder.global_position.x)
|
||||
cloud.global_position = Vector2(x, y)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
extends Sprite
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
+38
-4
@@ -1,18 +1,52 @@
|
||||
extends Node2D
|
||||
|
||||
class_name GUI
|
||||
|
||||
signal toggle_music(music_off)
|
||||
|
||||
onready var time_label := $MarginContainer/HBoxContainer/TimeLabel
|
||||
onready var neighbor_label := $MarginContainer/HBoxContainer/NeighborLabel
|
||||
onready var game_timer := $GameTimer
|
||||
onready var music_button := $MarginContainer/HBoxContainer/VBoxContainer/MusicButton
|
||||
onready var pause_button := $MarginContainer/HBoxContainer/GridContainer/PauseButton
|
||||
|
||||
var arrow = preload("res://assets/ui/pointer.png")
|
||||
var hand = preload("res://assets/ui/pointer_hand.png")
|
||||
#var music_enabled_texture = preload("res://assets/ui/music-enabled.png")
|
||||
#var music_disabled_texture = preload("res://assets/ui/music-disabled.png")
|
||||
#var pause_texture = preload("res://assets/ui/pause.png")
|
||||
#var play_texture = preload("res://assets/ui/play.png")
|
||||
|
||||
func start_timer(seconds: int) -> void:
|
||||
game_timer.start(seconds)
|
||||
|
||||
func set_neighbor_count(neighbors_left: int) -> void:
|
||||
neighbor_label.text = "Neighbors left: %s" % neighbors_left
|
||||
|
||||
func set_game_label(content: String) -> void:
|
||||
neighbor_label.text = content
|
||||
|
||||
func _ready() -> void:
|
||||
start_timer(60)
|
||||
Input.set_custom_mouse_cursor(arrow)
|
||||
# Input.set_custom_mouse_cursor(beam, Input.CURSOR_IBEAM)
|
||||
# start_timer(60)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
var time = int(game_timer.get_time_left())
|
||||
time_label.text = "Time %s" % time
|
||||
time_label.text = "Time: %s" % time
|
||||
|
||||
func _on_PauseButton_toggled(button_pressed: bool) -> void:
|
||||
print('TODO nothing happens...')
|
||||
|
||||
func _on_MusicButton_toggled(button_pressed: bool) -> void:
|
||||
emit_signal("toggle_music", !button_pressed)
|
||||
|
||||
func _on_mouse_entered() -> void:
|
||||
Input.set_custom_mouse_cursor(hand)
|
||||
|
||||
func _on_mouse_exited() -> void:
|
||||
Input.set_custom_mouse_cursor(arrow)
|
||||
|
||||
|
||||
func _on_ToolButton_toggled(button_pressed: bool) -> void:
|
||||
print(button_pressed)
|
||||
func _on_GameTimer_timeout() -> void:
|
||||
pass # Replace with function body.
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
extends Node2D
|
||||
|
||||
class_name BaseLevel
|
||||
|
||||
var helped_neighbors := []
|
||||
var total_neighbors := 0
|
||||
var playback_position: float
|
||||
var level_num := 1
|
||||
var last_level := false
|
||||
|
||||
export var SECONDS_TO_COMPLETE := 10
|
||||
|
||||
signal game_complete(is_win)
|
||||
|
||||
onready var trolley = $YSort/Trolley as Trolley
|
||||
onready var player = $YSort/Player as Player
|
||||
onready var bounds = $CameraBounds
|
||||
onready var audio_player = $AudioStreamPlayer
|
||||
onready var gui = $YSort/Player/GUI as GUI
|
||||
onready var trolley_locations = $TrolleyLocations
|
||||
onready var end_game_panel = $Panel
|
||||
onready var end_game_label_title = $Panel/VBoxContainer/EndGameTitle
|
||||
onready var end_game_label_body = $Panel/VBoxContainer/EndGameBody
|
||||
onready var display_timer = $DisplayTimer
|
||||
|
||||
func display_start(this_level_num: int, is_last_level: bool = false) -> void:
|
||||
last_level = is_last_level
|
||||
level_num = this_level_num
|
||||
end_game_label_title.text = 'Land of make believe'
|
||||
end_game_label_body.text = '1 %s' % level_num
|
||||
end_game_panel.visible = true
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if end_game_panel.visible:
|
||||
end_game_panel.rect_global_position = player.camera.get_camera_screen_center() - Vector2(get_viewport().get_visible_rect().size.x / 2, get_viewport().get_visible_rect().size.y / 2)
|
||||
|
||||
func _on_neighbor_found_home(id: int) -> void:
|
||||
helped_neighbors.append(id)
|
||||
gui.set_neighbor_count(total_neighbors - len(helped_neighbors))
|
||||
if len(helped_neighbors) == total_neighbors:
|
||||
trolley.set_trolley_open(true)
|
||||
gui.set_game_label("Get to the Trolley!")
|
||||
player.follower = trolley
|
||||
|
||||
func _on_toggle_music(music_off: bool) -> void:
|
||||
if music_off:
|
||||
playback_position = audio_player.get_playback_position()
|
||||
audio_player.stop()
|
||||
else:
|
||||
audio_player.play(playback_position)
|
||||
|
||||
|
||||
func _on_Trolley_rogers_entered_trolley() -> void:
|
||||
player.follower = null
|
||||
trolley.move_to_leave()
|
||||
|
||||
func _on_Trolley_rogers_left_trolley() -> void:
|
||||
gui.start_timer(SECONDS_TO_COMPLETE)
|
||||
trolley.move_to_end(trolley_locations.get_node("TrolleyEnd").global_position, SECONDS_TO_COMPLETE)
|
||||
|
||||
func _on_GameTimer_timeout() -> void:
|
||||
trolley.move_to_leave()
|
||||
|
||||
|
||||
func _on_Trolley_left_wih_rogers(has_rogers) -> void:
|
||||
if has_rogers:
|
||||
if last_level:
|
||||
end_game_label_title.text = 'You are very neighborly'
|
||||
end_game_label_body.text = 'You saved all the neighbors in the land of make believe'
|
||||
emit_signal("game_complete", true)
|
||||
else:
|
||||
end_game_label_title.text = 'You win'
|
||||
end_game_label_body.text = 'Proceeding to level %s' % (level_num + 1)
|
||||
emit_signal("game_complete", true)
|
||||
else:
|
||||
end_game_label_title.text = 'Oh no'
|
||||
end_game_label_body.text = 'You were left in the land of make-believe'
|
||||
emit_signal("game_complete", false)
|
||||
end_game_panel.visible = true
|
||||
|
||||
# Sets up the level start
|
||||
func _on_DisplayTimer_timeout() -> void:
|
||||
end_game_panel.visible = false
|
||||
if trolley != null:
|
||||
trolley.global_position = Vector2(bounds.get_node("Left").global_position.x - 20, trolley_locations.get_node("TrolleyStart").global_position.y)
|
||||
if player != null:
|
||||
player.global_position = trolley.get_node("TrolleySeatArea/SeatAreaShape").global_position
|
||||
for node in get_node("YSort").get_children():
|
||||
if 'Neighbor' in node.name:
|
||||
var err = node.connect("found_home", self, "_on_neighbor_found_home")
|
||||
total_neighbors += 1
|
||||
print('Level loaded with %s neighbors' % total_neighbors)
|
||||
gui.set_neighbor_count(total_neighbors)
|
||||
player.set_camera_bounds(bounds.get_node("Top").global_position.y, bounds.get_node("Bottom").global_position.y, bounds.get_node("Left").global_position.x, bounds.get_node("Right").global_position.x)
|
||||
var err = gui.connect("toggle_music", self, "_on_toggle_music")
|
||||
err = gui.get_node("GameTimer").connect("timeout", self, "_on_GameTimer_timeout")
|
||||
trolley.move_to_start(get_node("TrolleyLocations/TrolleyStart").global_position)
|
||||
@@ -0,0 +1,36 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
var level_path := "res://scenes/level{num}.tscn"
|
||||
var level1 = preload("res://scenes/level1.tscn")
|
||||
var current_level_num = 1
|
||||
var current_level : Node
|
||||
var max_levels = 3
|
||||
var level_win := false
|
||||
|
||||
onready var end_timer := $EndTimer
|
||||
|
||||
func _ready() -> void:
|
||||
current_level = level1.instance()
|
||||
add_child(current_level)
|
||||
var err = current_level.get_child(0).connect("game_complete", self, "_on_level_complete")
|
||||
|
||||
func _on_level_complete(is_win: bool) -> void:
|
||||
print('Level complete')
|
||||
level_win = is_win
|
||||
end_timer.start(2)
|
||||
|
||||
|
||||
func _on_EndTimer_timeout() -> void:
|
||||
if level_win and current_level_num < max_levels:
|
||||
current_level_num += 1
|
||||
var new_level_path = level_path.format({"num": current_level_num})
|
||||
var next_level = load(new_level_path).instance()
|
||||
add_child(next_level)
|
||||
current_level.queue_free()
|
||||
current_level = next_level
|
||||
var current_base_level = current_level.get_node("BaseLevel") as BaseLevel
|
||||
current_base_level.display_start(current_level_num)
|
||||
var err = current_base_level.connect("game_complete", self, "_on_level_complete")
|
||||
|
||||
|
||||
@@ -95,7 +95,6 @@ func _idle_state(delta: float) -> void:
|
||||
|
||||
func _go_home_state(delta: float) -> void:
|
||||
_move_neighbor(house_direction, true)
|
||||
# print((house_position - global_position).length())
|
||||
if ((house_position - global_position).length() < 30):
|
||||
emit_signal("found_home", id)
|
||||
queue_free()
|
||||
|
||||
+12
-8
@@ -13,13 +13,23 @@ var leader := self
|
||||
|
||||
onready var sprite := $AnimatedSprite
|
||||
onready var chevron_sprite := $ChevronSprite
|
||||
onready var camera := $Camera2D
|
||||
onready var gui := $GUI
|
||||
|
||||
enum State {
|
||||
MOVE,
|
||||
IDLE
|
||||
}
|
||||
|
||||
func set_camera_bounds(up: int, down: int, left: int, right: int):
|
||||
camera.set_limit(MARGIN_TOP, up)
|
||||
camera.set_limit(MARGIN_BOTTOM, down)
|
||||
camera.set_limit(MARGIN_LEFT, left)
|
||||
camera.set_limit(MARGIN_RIGHT, right)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
gui.global_position = camera.get_camera_screen_center() - Vector2(get_viewport().get_visible_rect().size.x / 2, get_viewport().get_visible_rect().size.y / 2) # Get Height)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
match state:
|
||||
State.MOVE:
|
||||
@@ -28,6 +38,8 @@ func _physics_process(delta: float) -> void:
|
||||
_idle_state(delta)
|
||||
chevron_sprite.visible = follower != null
|
||||
if follower != null:
|
||||
if follower.name == "Trolley":
|
||||
chevron_sprite.set_modulate(Color(0,0.9,0))
|
||||
chevron_sprite.rotation_degrees = rad2deg((follower.house_position - global_position).angle()) - 90
|
||||
|
||||
func _move_state(delta: float) -> void:
|
||||
@@ -58,11 +70,3 @@ func _idle_state(delta: float) -> void:
|
||||
state = State.MOVE
|
||||
else:
|
||||
sprite.set_animation("idle")
|
||||
# if Input.is_action_pressed("ui_up"):
|
||||
# speed.y -= ACCELERATION
|
||||
# elif Input.is_action_pressed("ui_right"):
|
||||
# print("right")
|
||||
# elif Input.is_action_pressed("ui_left"):
|
||||
# print("left")
|
||||
# elif Input.is_action_pressed("ui_down"):
|
||||
# print("down")
|
||||
|
||||
@@ -17,7 +17,6 @@ func _on_rogers_left_trolley() -> void:
|
||||
pass
|
||||
|
||||
func _on_neighbor_found_home(id: int) -> void:
|
||||
print('You helped a neighbor')
|
||||
helped_neighbors.append(id)
|
||||
if len(helped_neighbors) == total_neighbors:
|
||||
trolley.set_trolley_open(true)
|
||||
|
||||
+88
-12
@@ -3,38 +3,114 @@ extends KinematicBody2D
|
||||
class_name Trolley
|
||||
|
||||
signal rogers_left_trolley()
|
||||
signal rogers_entered_trolley()
|
||||
signal left_wih_rogers(has_rogers)
|
||||
|
||||
export var TIME = 60
|
||||
onready var trolley_closed_shape = $TrolleyClosedShape
|
||||
export var MAX_VELOCITY = .3
|
||||
export var MAX_VELOCITY = 8
|
||||
|
||||
var velocity := Vector2.ZERO
|
||||
var state = State.STOPPED
|
||||
var has_roger := false
|
||||
var destination := Vector2.ZERO
|
||||
var house_position : Vector2
|
||||
var arrival_time: int
|
||||
var en_route_length: float
|
||||
|
||||
func _ready() -> void:
|
||||
set_trolley_open(true)
|
||||
enum State {
|
||||
MOVE_TO_START,
|
||||
STOPPED,
|
||||
EN_ROUTE,
|
||||
LEAVING
|
||||
}
|
||||
|
||||
func set_trolley_open(trolley_open: bool) -> void:
|
||||
trolley_closed_shape.set_deferred("disabled", trolley_open)
|
||||
|
||||
func move_to_start(start_pos: Vector2) -> void:
|
||||
state = State.MOVE_TO_START
|
||||
destination = start_pos
|
||||
velocity = Vector2(MAX_VELOCITY, 0)
|
||||
set_trolley_open(false)
|
||||
|
||||
func move_to_end(end_pos: Vector2, seconds_to_exit) -> void:
|
||||
state = State.EN_ROUTE
|
||||
destination = end_pos
|
||||
velocity = Vector2.ZERO
|
||||
arrival_time = seconds_to_exit
|
||||
set_trolley_open(false)
|
||||
en_route_length = destination.x - global_position.x
|
||||
|
||||
func move_to_leave() -> void:
|
||||
if state != State.LEAVING:
|
||||
set_trolley_open(false)
|
||||
emit_signal("left_wih_rogers", has_roger)
|
||||
state = State.LEAVING
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
velocity.x = move_toward(velocity.x, MAX_VELOCITY, delta if not has_roger else delta * 10)
|
||||
match state:
|
||||
State.MOVE_TO_START:
|
||||
_decelerate_to_start(delta)
|
||||
State.STOPPED:
|
||||
_stop(delta)
|
||||
State.EN_ROUTE:
|
||||
_en_route(delta)
|
||||
State.LEAVING:
|
||||
_leaving(delta)
|
||||
# For the player indicator to show where the trolley is, update 'house_position' to current position
|
||||
house_position = global_position
|
||||
|
||||
func _decelerate_to_start(delta: float) -> void:
|
||||
var length_to_start := destination.x - global_position.x - 100
|
||||
velocity.x = min(move_toward(velocity.x, length_to_start, delta * 10), MAX_VELOCITY)
|
||||
var collision := move_and_collide(velocity)
|
||||
if collision:
|
||||
var collider = collision.get_collider()
|
||||
if collider.get_class() == "KinematicBody2D":
|
||||
collider.move_and_collide(velocity * 2)
|
||||
if global_position.x >= destination.x:
|
||||
set_trolley_open(true)
|
||||
state = State.STOPPED
|
||||
|
||||
|
||||
func _stop(delta: float) -> void:
|
||||
pass
|
||||
|
||||
func _en_route(delta: float) -> void:
|
||||
velocity.x = en_route_length / arrival_time * delta
|
||||
var collision := move_and_collide(velocity)
|
||||
if collision:
|
||||
var collider = collision.get_collider()
|
||||
if collider.get_class() == "KinematicBody2D":
|
||||
if has_roger:
|
||||
MAX_VELOCITY = 10
|
||||
return
|
||||
collider.move_and_collide(velocity * 3)
|
||||
if global_position.x >= destination.x:
|
||||
set_trolley_open(false)
|
||||
state = State.LEAVING
|
||||
|
||||
|
||||
func _leaving(delta: float) -> void:
|
||||
velocity.x = min(move_toward(velocity.x, (destination.x + 200), delta * 10), MAX_VELOCITY)
|
||||
var collision := move_and_collide(velocity)
|
||||
if collision:
|
||||
var collider = collision.get_collider()
|
||||
if collider.get_class() == "KinematicBody2D":
|
||||
collider.move_and_collide(velocity * 3)
|
||||
# if global_position.x >= destination.x:
|
||||
# set_trolley_open(true)
|
||||
# state = State.STOPPED
|
||||
|
||||
func set_trolley_open(trolley_open: bool) -> void:
|
||||
trolley_closed_shape.set_deferred("disabled", trolley_open)
|
||||
|
||||
func _on_TrolleySeatArea_body_entered(body: Node) -> void:
|
||||
if body is Player:
|
||||
if body is Player and state != State.STOPPED and state != State.MOVE_TO_START:
|
||||
has_roger = true
|
||||
print('closing trolley')
|
||||
trolley_closed_shape.set_deferred("disabled", false)
|
||||
emit_signal("rogers_entered_trolley")
|
||||
|
||||
|
||||
|
||||
func _on_TrolleySeatArea_body_exited(body: Node) -> void:
|
||||
func _on_TrolleySurroundingArea_body_exited(body_rid: RID, body: Node, body_shape_index: int, local_shape_index: int) -> void:
|
||||
if body is Player:
|
||||
has_roger = false
|
||||
emit_signal("rogers_left_trolley")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user