diff --git a/entities/sheep.gd b/entities/sheep.gd new file mode 100644 index 0000000..4f5ede1 --- /dev/null +++ b/entities/sheep.gd @@ -0,0 +1,113 @@ +extends RigidBody2D + +var initial_self_position: Vector2 = Vector2.ZERO +var initial_mouse_position: Vector2 = Vector2.ZERO + +@onready var rand_walk_timer: Timer = Timer.new() +var rng = RandomNumberGenerator.new() +enum State {STATE_IDLE, STATE_WALK, STATE_PICKED, STATE_RUN, STATE_THROWN} +var state: State = State.STATE_IDLE +var walk_dir: Vector2 = Vector2.ZERO +var last_dir: int = 1 + + +@export var min_run_dist = 200 +@export var max_run_dist = 250 + +@export var walk_speed = 150 +@export var run_speed = 500 + +@export var drag_damp = 40 +@export var normal_damp = 4 +@export var thrown_damp = 2 + + +# Called when the node enters the scene tree for the first time. +func _ready(): + add_child(rand_walk_timer) + rand_walk_timer.one_shot = true; + rand_walk_timer.connect("timeout", _on_timer_timeout) + init_timer() + +func init_timer(): + if state == State.STATE_IDLE: + var rand_time = max(0, rng.randfn(4, 1.5)) + rand_walk_timer.start(rand_time) + elif state == State.STATE_WALK: + rand_walk_timer.start(5) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + gravity_scale = 0 + var curr_mpos = get_viewport().get_mouse_position() + + if state == State.STATE_PICKED and not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): + pick_down() + if state == State.STATE_THROWN and linear_velocity.length() < 1: + state = State.STATE_WALK + init_timer() + + var mouse_dis = position.distance_to(curr_mpos) + if (state == State.STATE_IDLE or state == State.STATE_WALK) and mouse_dis < min_run_dist: + # Run away from mouse + state = State.STATE_RUN + rand_walk_timer.stop() + elif state == State.STATE_RUN and mouse_dis > max_run_dist: + state = State.STATE_IDLE + init_timer() + + var force = Vector2.ZERO + + if state == State.STATE_WALK: + force = walk_speed * walk_dir + elif state == State.STATE_RUN: + var run_dir = -position.direction_to(curr_mpos) + force = run_speed * run_dir + elif state == State.STATE_PICKED: + var dest_position = initial_self_position + (curr_mpos - initial_mouse_position) + apply_central_force(50 * (dest_position - position) * dest_position.distance_to(position) * delta) + else: + pass + + if force.length_squared() > 0.001: + apply_central_force(force) + last_dir = sign(force.dot(Vector2.LEFT)) + + scale.x = last_dir + + if state == State.STATE_PICKED: + linear_damp = drag_damp + elif state == State.STATE_THROWN: + linear_damp = thrown_damp + else: + linear_damp = normal_damp + + +func _on_input_event(viewport, event, shape_idx): + if event is InputEventMouseButton: + var was_picked_up = state == State.STATE_PICKED + var is_picked_up = event.pressed + initial_mouse_position = event.position + initial_self_position = position + + if not was_picked_up and is_picked_up: + state = State.STATE_PICKED + rand_walk_timer.stop() + elif was_picked_up and not is_picked_up: + pick_down() + +func pick_down(): + state = State.STATE_THROWN + init_timer() + + +func _on_timer_timeout(): + if state == State.STATE_IDLE: + state = State.STATE_WALK + walk_dir = Vector2.from_angle(rng.randf_range(0, 2*PI)) + elif state == State.STATE_WALK: + state = State.STATE_IDLE + init_timer() + + diff --git a/entities/sheep.tscn b/entities/sheep.tscn new file mode 100644 index 0000000..37bb596 --- /dev/null +++ b/entities/sheep.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=4 format=3 uid="uid://bc2bm8lbol18w"] + +[ext_resource type="Script" path="res://entities/sheep.gd" id="1_c2hn8"] +[ext_resource type="Texture2D" uid="uid://cbljqvt053eka" path="res://media/sheep.png" id="1_rhwit"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ycfcx"] +size = Vector2(120, 92) + +[node name="Sheep" type="RigidBody2D"] +input_pickable = true +linear_damp = 20.0 +script = ExtResource("1_c2hn8") + +[node name="Sheep" type="Sprite2D" parent="."] +position = Vector2(3, -3) +texture = ExtResource("1_rhwit") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(3, -3) +shape = SubResource("RectangleShape2D_ycfcx") + +[connection signal="input_event" from="." to="." method="_on_input_event"] diff --git a/main.gd b/main.gd index 36ab5b5..eec3aa8 100644 --- a/main.gd +++ b/main.gd @@ -34,6 +34,8 @@ var current_stage: Stage: match current_stage: Stage.MENU: build_menu() + Stage.GAME: + build_game() ## The [Stage] that [field current_stage] should be set to upon starting the game. @export var starting_stage: Stage @@ -41,9 +43,11 @@ var current_stage: Stage: ## The main menu scene. const SCENE_MENU: PackedScene = preload("res://scenes/interface/main_menu.tscn") +const SCENE_GAME: PackedScene = preload("res://scenes/game/game.tscn") ## The main menu node. var scene_menu: MainMenu = null +var scene_game: MainGame = null ## Destroy the main menu. func destroy_menu() -> void: @@ -58,6 +62,11 @@ func build_menu() -> void: container.add_child(scene_menu) +## Build the main menu. +func build_game() -> void: + scene_game = SCENE_GAME.instantiate() + scene_game.selected_exit.connect(_on_game_selected_exit) + container.add_child(scene_game) func _ready() -> void: current_stage = starting_stage @@ -67,3 +76,6 @@ func _on_menu_selected_play() -> void: func _on_menu_selected_options() -> void: current_stage = Stage.OPTIONS + +func _on_game_selected_exit() -> void: + current_stage = Stage.MENU diff --git a/media/sheep.png b/media/sheep.png new file mode 100644 index 0000000..aae5b12 --- /dev/null +++ b/media/sheep.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:259e76e43c2215c35da08bd7e458a6e6df988f6c91d6c82aa7b8aa96682ffc24 +size 872 diff --git a/media/sheep.png.import b/media/sheep.png.import new file mode 100644 index 0000000..4603e2b --- /dev/null +++ b/media/sheep.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbljqvt053eka" +path="res://.godot/imported/sheep.png-2baca8f2fcbb83024e65011814b3432a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://media/sheep.png" +dest_files=["res://.godot/imported/sheep.png-2baca8f2fcbb83024e65011814b3432a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/project.godot b/project.godot index 490080d..f1c5481 100644 --- a/project.godot +++ b/project.godot @@ -23,6 +23,7 @@ window/size/initial_position_type=3 [rendering] +textures/canvas_textures/default_texture_filter=0 renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" environment/defaults/default_clear_color=Color(0.0235294, 0.0235294, 0.0235294, 1) diff --git a/scenes/game/game.gd b/scenes/game/game.gd new file mode 100644 index 0000000..79dbeda --- /dev/null +++ b/scenes/game/game.gd @@ -0,0 +1,18 @@ +extends Node2D +class_name MainGame + +## Emitted when the player has clicked on the Options button. +signal selected_exit + + +func _on_exit_pressed() -> void: + selected_exit.emit() + +# 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 diff --git a/scenes/game/game.tscn b/scenes/game/game.tscn new file mode 100644 index 0000000..1f61459 --- /dev/null +++ b/scenes/game/game.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=3 uid="uid://cxj5aud02f40j"] + +[ext_resource type="Script" path="res://scenes/game/game.gd" id="1_tau5t"] +[ext_resource type="PackedScene" uid="uid://bc2bm8lbol18w" path="res://entities/sheep.tscn" id="2_8268g"] + +[sub_resource type="TileSet" id="TileSet_g2dkm"] + +[node name="World" type="Node2D"] +script = ExtResource("1_tau5t") + +[node name="TileMap" type="TileMap" parent="."] +tile_set = SubResource("TileSet_g2dkm") +format = 2 + +[node name="Sheep" parent="." instance=ExtResource("2_8268g")] +position = Vector2(637, 318) +run_speed = 600 diff --git a/scenes/game/gameplay.tscn b/scenes/game/gameplay.tscn new file mode 100644 index 0000000..a9b8229 --- /dev/null +++ b/scenes/game/gameplay.tscn @@ -0,0 +1,74 @@ +[gd_scene load_steps=2 format=3 uid="uid://b1na52ogrisd1"] + +[ext_resource type="Script" path="res://scenes/interface/main_menu.gd" id="1_yshb5"] + +[node name="MainMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_yshb5") + +[node name="Panel" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Layout" type="VBoxContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +alignment = 1 + +[node name="Title" type="MarginContainer" parent="Panel/Layout"] +layout_mode = 2 +theme_override_constants/margin_left = 16 +theme_override_constants/margin_top = 16 +theme_override_constants/margin_right = 16 +theme_override_constants/margin_bottom = 16 + +[node name="Label" type="RichTextLabel" parent="Panel/Layout/Title"] +layout_mode = 2 +size_flags_vertical = 6 +bbcode_enabled = true +text = "[center][font_size=144px]Playasauto[/font_size] +[font_size=64px]Il casello del destino[/font_size] + +[font_size=32px]Un gioco del Garasautomobileclub Italia[/font_size][/center]" +fit_content = true + +[node name="Buttons" type="MarginContainer" parent="Panel/Layout"] +layout_mode = 2 +theme_override_constants/margin_left = 16 +theme_override_constants/margin_top = 16 +theme_override_constants/margin_right = 16 +theme_override_constants/margin_bottom = 16 + +[node name="Layout" type="HBoxContainer" parent="Panel/Layout/Buttons"] +layout_mode = 2 +alignment = 1 + +[node name="Play" type="Button" parent="Panel/Layout/Buttons/Layout"] +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 +theme_override_font_sizes/font_size = 36 +text = "Play" + +[node name="Options" type="Button" parent="Panel/Layout/Buttons/Layout"] +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 +theme_override_font_sizes/font_size = 36 +text = "Options" + +[node name="Node2D" type="Node2D" parent="."] + +[connection signal="pressed" from="Panel/Layout/Buttons/Layout/Play" to="." method="_on_play_pressed"] +[connection signal="pressed" from="Panel/Layout/Buttons/Layout/Options" to="." method="_on_options_pressed"]