diff --git a/Assets/Icons/Logo.png.import b/Assets/Icons/Logo.png.import index 0dbc7cb..8dd0c09 100644 --- a/Assets/Icons/Logo.png.import +++ b/Assets/Icons/Logo.png.import @@ -1,34 +1,3 @@ [remap] -importer="texture" -type="CompressedTexture2D" -uid="uid://dvf2hc5jp81m7" -path="res://.godot/imported/Logo.png-6a3aaed283c68d645081dcefe9dc83c2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://Assets/Icons/Logo.png" -dest_files=["res://.godot/imported/Logo.png-6a3aaed283c68d645081dcefe9dc83c2.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 +importer="keep" diff --git a/Assets/TestGame/help.svg b/Assets/TestGame/help.svg new file mode 100644 index 0000000..acf7731 --- /dev/null +++ b/Assets/TestGame/help.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/TestGame/help.svg.import b/Assets/TestGame/help.svg.import new file mode 100644 index 0000000..22793b9 --- /dev/null +++ b/Assets/TestGame/help.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://7ywk3rxxgpwe" +path="res://.godot/imported/help.svg-f618e624a68cfa968b898c07197ac1bc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/TestGame/help.svg" +dest_files=["res://.godot/imported/help.svg-f618e624a68cfa968b898c07197ac1bc.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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/README.md b/README.md index db4090e..ac5866f 100644 --- a/README.md +++ b/README.md @@ -2,39 +2,45 @@ Created in [Godot Engine 4.0 Stable](https://godotengine.org/download) (Godot 3.x is not supported.) + [Download Windows/Linux Builds](https://github.com/stmSi/Ultimate-Myanmar-Typing-Wizard/releases/tag/pre-build) + + +If you want to download `latest` commit build (may not be stable and produce error), + +1. Go to [Github `Actions` Tab](https://github.com/stmSi/Ultimate-Myanmar-Typing-Wizard/actions) +2. Select the lastest `master` workflow +3. Scroll down to the bottom `Artifacts` area +4. Download zip file according to your platform. + ### **Requirements** * OpenGL 3.3 / OpenGL ES 3.0 compatible hardware * ***No Need To Install*** Myanmar Unicode Keyboard or Font (Auto Convert English-To-Myanmar ) - --- - - ### **Exercise Editor Screenshots** - ![](screenshots/ExerciseEditor.png) -- +----------------------------------- + ![](screenshots/ExerciseEditor_02.png) --- ### **Playground Screenshots** - ![](screenshots/Playground.png) -- +------------------------------- + ![](screenshots/Playground_02.png) --- #### **Exercise Editor Showcase Video** - https://user-images.githubusercontent.com/32661049/222511307-2d69d482-4424-4706-9908-92767fee9d7d.mp4 --- @@ -43,10 +49,8 @@ https://user-images.githubusercontent.com/32661049/222511307-2d69d482-4424-4706- https://user-images.githubusercontent.com/32661049/222511322-08bec3fa-689e-416e-8c0f-1baf2d4a756f.mp4 - --- - ### **Todo**: 1. Better UI Stuff (Proper Menus and stuffs) diff --git a/Texts/Lessons/Basic/00000011.cfg b/Texts/Lessons/Basic/00000011.cfg index 3eeaad1..028c4a8 100644 --- a/Texts/Lessons/Basic/00000011.cfg +++ b/Texts/Lessons/Basic/00000011.cfg @@ -1,6 +1,6 @@ [Exercise] -texts=PackedStringArray("န်", "မ်", "တ်", "ဆ်", "က်", "င်", "သ်", "စ်", "သင်", "တင်", "ဆင်", "နင်", "စင်", "ကင်", "သမ်", "တတ်", "ဆင်တတ်") +texts=PackedStringArray("န်", "မ်", "တ်", "ဆ်", "က်", "င်", "သ်", "စ်", "သင်", "တင်", "ဆင်", "နင်", "စင်", "ကင်", "သမ်", "တတ်", "ဆင်တတ်", "တတ်သင်") repeats=1.0 allow_mistakes=80.0 randomize=false diff --git a/project.godot b/project.godot index 01a19d9..598a311 100644 --- a/project.godot +++ b/project.godot @@ -43,6 +43,11 @@ version_control/autoload_on_startup=true enabled=PackedStringArray("res://addons/native_dialogs/plugin.cfg") +[layer_names] + +2d_physics/layer_2="Eater" +2d_physics/layer_3="To be Eaten" + [rendering] renderer/rendering_method="gl_compatibility" diff --git a/src/Autoload/EventBus.gd b/src/Autoload/EventBus.gd index eaf6764..133a667 100644 --- a/src/Autoload/EventBus.gd +++ b/src/Autoload/EventBus.gd @@ -21,3 +21,9 @@ signal message_popup(msg: String) signal message_popup_closed() signal lesson_id_loaded(lesson_id: int) + +# Game Specific Events +signal game_focus_enemy(enemy: Node2D) +signal game_enemy_pos_changed(pos: Vector2, enemy: Node2D) +signal game_enemy_dead(enemy: Node2D) +signal game_enemy_hit_npc(npc: Node2D) diff --git a/src/Autoload/SceneChanger.gd b/src/Autoload/SceneChanger.gd index bbea76c..5570c6c 100644 --- a/src/Autoload/SceneChanger.gd +++ b/src/Autoload/SceneChanger.gd @@ -3,6 +3,7 @@ extends Node var playground_scene = "res://src/Playground/Playground.tscn" var exercise_editor_scene = "res://src/ExerciseEditor/exercise_editor.tscn" var main_scene = "res://src/main.tscn" +var test_game_scene = "res://src/MiniGames/TestGame/test_game.tscn" var current_scene = null @@ -51,6 +52,9 @@ func change_to_exercise_editor_scene(): func change_to_main_scene(): goto_scene(main_scene) +func change_to_test_game_scene(): + goto_scene(test_game_scene) + func _animate_appear(): # Animate Panel first using "scene_change_bg" group # then Elements "scene_change_element" diff --git a/src/Keyboard/keyboard.gd b/src/Keyboard/keyboard.gd index 0e08024..24d54cc 100644 --- a/src/Keyboard/keyboard.gd +++ b/src/Keyboard/keyboard.gd @@ -1,6 +1,7 @@ @icon("res://Assets/Icons/keyboard-icon.png") extends Control class_name Keyboard + var key_node_mapping: Dictionary = {} var current_char: String = '' diff --git a/src/Keyboard/keyboard.tscn b/src/Keyboard/keyboard.tscn index eea3f08..44dc6dd 100644 --- a/src/Keyboard/keyboard.tscn +++ b/src/Keyboard/keyboard.tscn @@ -8,70 +8,100 @@ [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_scc4s"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dr5yv"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ng5ll"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xbnwi"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8djne"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jjy0n"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bbdjs"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_apsic"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_aoubn"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_axx0v"] resource_local_to_scene = true bg_color = Color(0.117647, 0.117647, 0.117647, 0.827451) -border_width_left = 3 +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 border_blend = true shadow_color = Color(1, 1, 1, 0.6) diff --git a/src/MiniGames/TestGame/Enemy.gd b/src/MiniGames/TestGame/Enemy.gd new file mode 100644 index 0000000..1f62468 --- /dev/null +++ b/src/MiniGames/TestGame/Enemy.gd @@ -0,0 +1,22 @@ +extends Area2D +class_name Enemy + +@export var speed = 200 + +var line = "" +@onready var sprite: Sprite2D = $Sprite + +signal moved(pos: Vector2) + +func _process(delta: float) -> void: + global_position.x -= (speed * delta) + self.moved.emit(global_position) + +func get_size(): + return sprite.texture.get_size() + + +func _on_area_entered(area: Area2D) -> void: + if area is NPC: + EventBus.game_enemy_hit_npc.emit(area) + diff --git a/src/MiniGames/TestGame/enemy.tscn b/src/MiniGames/TestGame/enemy.tscn new file mode 100644 index 0000000..6ca3b20 --- /dev/null +++ b/src/MiniGames/TestGame/enemy.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=4 format=3 uid="uid://6lfwla4eyxsm"] + +[ext_resource type="Texture2D" uid="uid://bwl4vqyiwh8la" path="res://src/icon.svg" id="1_poxmv"] +[ext_resource type="Script" path="res://src/MiniGames/TestGame/Enemy.gd" id="2_pj5ci"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_mgowg"] +size = Vector2(117.5, 125.5) + +[node name="Enemy" type="Area2D"] +modulate = Color(1, 0.509804, 0.443137, 1) +collision_layer = 2 +collision_mask = 4 +script = ExtResource("2_pj5ci") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(-2.75, -1.25) +shape = SubResource("RectangleShape2D_mgowg") + +[node name="Sprite" type="Sprite2D" parent="."] +texture = ExtResource("1_poxmv") + +[connection signal="area_entered" from="." to="." method="_on_area_entered"] diff --git a/src/MiniGames/TestGame/game_text_popup.gd b/src/MiniGames/TestGame/game_text_popup.gd new file mode 100644 index 0000000..818dab7 --- /dev/null +++ b/src/MiniGames/TestGame/game_text_popup.gd @@ -0,0 +1,48 @@ +extends FollowUpTextPopup + +@export var enemy: Node2D: + get: + return enemy + set(value): + visible = true + enemy = value + + +func _ready() -> void: + ori_richtext_minimum_size_x = follow_up_rich_text.custom_minimum_size.x + EventBus.exercise_loaded.connect(self._set_raw_text) + EventBus.written_string_changed.connect(self._on_written_string_changed) + + EventBus.game_focus_enemy.connect(self._on_game_focus_enemy) + +func _on_game_focus_enemy(enemy: Node2D): + + self.enemy = enemy + if enemy == null: + visible = false + +func _process(delta: float) -> void: + if self.enemy: + global_position = Vector2( + enemy.global_position.x, + enemy.global_position.y - enemy.get_size().y / 2 + ) + +# if visible: +# call_deferred("_animate_position") # Hack for first time position not working + + +func _animate_position(): + var pos := enemy.global_position + + # left boundry + if enemy.global_position.x - (panel.size.x / 2) < 5: # 5 is for some padding + pos.x = panel.size.x / 2 + + # right + if enemy.global_position.x + (panel.size.x / 2) > get_viewport_rect().size.x: # 5 is for some padding + pos.x = get_viewport_rect().size.x - (panel.size.x / 2) + + var tween = get_tree().create_tween() + tween.tween_property(self, "global_position", pos, .2).set_trans(Tween.TRANS_CUBIC) + diff --git a/src/MiniGames/TestGame/npc.gd b/src/MiniGames/TestGame/npc.gd new file mode 100644 index 0000000..2ba5359 --- /dev/null +++ b/src/MiniGames/TestGame/npc.gd @@ -0,0 +1,2 @@ +extends Area2D +class_name NPC diff --git a/src/MiniGames/TestGame/npc.tscn b/src/MiniGames/TestGame/npc.tscn new file mode 100644 index 0000000..dc6fff1 --- /dev/null +++ b/src/MiniGames/TestGame/npc.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=4 format=3 uid="uid://c1j3315qqetyc"] + +[ext_resource type="Script" path="res://src/MiniGames/TestGame/npc.gd" id="1_gd1hd"] +[ext_resource type="Texture2D" uid="uid://7ywk3rxxgpwe" path="res://Assets/TestGame/help.svg" id="1_lguy1"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_6g67m"] +size = Vector2(88, 96) + +[node name="NPC" type="Area2D"] +collision_layer = 4 +collision_mask = 0 +monitoring = false +script = ExtResource("1_gd1hd") +metadata/_edit_group_ = true + +[node name="Sprite" type="Sprite2D" parent="."] +texture = ExtResource("1_lguy1") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(-32, 58) +shape = SubResource("RectangleShape2D_6g67m") diff --git a/src/MiniGames/TestGame/test_game.gd b/src/MiniGames/TestGame/test_game.gd new file mode 100644 index 0000000..befcac2 --- /dev/null +++ b/src/MiniGames/TestGame/test_game.gd @@ -0,0 +1,47 @@ +extends Node2D + +var text +@onready var enemy_scene := preload("res://src/MiniGames/TestGame/enemy.tscn") + +@onready var game_follow_up_text_popup: Control = $GameFollowUpTextPopup +@onready var line_edit: LineEdit = $LineEdit + +@onready var spawn_point: Node2D = $SpawnPoint + +var sample_texts = PackedStringArray(["န်", "မ်", "တ်"]) + +var written_text = '' +var focused_enemy : Node2D = null + +func _ready() -> void: + randomize() + EventBus.exercise_line_finished.connect(self._on_line_finished) + EventBus.game_enemy_hit_npc.connect(self._on_game_enemy_hit_npc) + _spawn_enemy() + +func _on_line_finished(): + if self.focused_enemy: + self.focused_enemy.queue_free() + self.focused_enemy = null + EventBus.game_focus_enemy.emit(null) + + if sample_texts.size() > 0: + call_deferred("_spawn_enemy") + else: + EventBus.message_popup.emit("You Won!") + +func _spawn_enemy(): + self.focused_enemy = enemy_scene.instantiate() + add_child(self.focused_enemy) + self.focused_enemy.global_position = spawn_point.global_position + + var idx = randi() % sample_texts.size() + self.focused_enemy.line = sample_texts[idx] + + EventBus.game_focus_enemy.emit(self.focused_enemy) + EventBus.exercise_loaded.emit(sample_texts[idx]) + + sample_texts.remove_at(idx) + +func _on_game_enemy_hit_npc(npc: Node2D): + EventBus.message_popup.emit("He Dead.... gone forever... we lost.") diff --git a/src/MiniGames/TestGame/test_game.tscn b/src/MiniGames/TestGame/test_game.tscn new file mode 100644 index 0000000..303523d --- /dev/null +++ b/src/MiniGames/TestGame/test_game.tscn @@ -0,0 +1,78 @@ +[gd_scene load_steps=7 format=3 uid="uid://bllqf3ag5cr38"] + +[ext_resource type="Script" path="res://src/MiniGames/TestGame/test_game.gd" id="1_iypay"] +[ext_resource type="PackedScene" uid="uid://bulscf8jamb2b" path="res://src/FollowupRichText/follow_up_text_popup.tscn" id="3_raquw"] +[ext_resource type="PackedScene" uid="uid://c1j3315qqetyc" path="res://src/MiniGames/TestGame/npc.tscn" id="4_vf1i6"] +[ext_resource type="Script" path="res://src/MiniGames/TestGame/game_text_popup.gd" id="5_7iwhk"] +[ext_resource type="PackedScene" uid="uid://b7i3rua60ewr4" path="res://src/EscMenu/esc_menu.tscn" id="5_7ufpc"] + +[sub_resource type="GDScript" id="GDScript_3jnh1"] +script/source = "extends LineEdit + +var _eng_to_mm_converted = false +var current_exercise_text = \"\" + +# Called when the node enters the scene tree for the first time. +func _ready(): + grab_focus() + EventBus.lesson_id_loaded.connect(self._on_new_lesson_id_loaded) + EventBus.exercise_loaded.connect(self._exercise_loaded) + EventBus.exercise_line_finished.connect(self._exercise_line_finished) + +func _exercise_loaded(exercise_text: String) -> void: + self.current_exercise_text = exercise_text + clear() + grab_focus() + +func _exercise_line_finished() -> void: + clear() + +func _on_new_lesson_id_loaded(_lesson_id: int) -> void: + clear() + + +func _on_text_changed(new_text: String) -> void: + if not _eng_to_mm_converted: + _eng_to_mm_converted = true + self.text = EngToMmConverter.convert_str(new_text) + self.caret_column = len(self.text) + _eng_to_mm_converted = false + + EventBus.written_string_changed.emit(self.text) + if current_exercise_text != '' and current_exercise_text == self.text: + EventBus.exercise_line_finished.emit() +" + +[node name="TestGame" type="Node2D"] +script = ExtResource("1_iypay") + +[node name="SpawnPoint" type="Node2D" parent="."] +position = Vector2(1252, 606) + +[node name="GameFollowUpTextPopup" parent="." instance=ExtResource("3_raquw")] +offset_left = 708.0 +offset_top = 324.0 +offset_right = 708.0 +offset_bottom = 324.0 +script = ExtResource("5_7iwhk") + +[node name="npc_help" parent="." instance=ExtResource("4_vf1i6")] +position = Vector2(94, 582) + +[node name="LineEdit" type="LineEdit" parent="."] +offset_left = -99.0 +offset_top = -54.0 +offset_right = -31.9375 +offset_bottom = -23.0 +script = SubResource("GDScript_3jnh1") + +[node name="EscMenu" parent="." instance=ExtResource("5_7ufpc")] +offset_left = 690.0 +offset_top = 301.0 +offset_right = 690.0 +offset_bottom = 301.0 + +[connection signal="text_changed" from="LineEdit" to="LineEdit" method="_on_text_changed"] + +[editable path="GameFollowUpTextPopup"] +[editable path="GameFollowUpTextPopup/Panel/MarginContainer/FollowUpRichText"] diff --git a/src/main.gd b/src/main.gd index 22f638a..0e5f37f 100644 --- a/src/main.gd +++ b/src/main.gd @@ -1,4 +1,5 @@ extends Control -func _ready(): - pass + +func _on_test_game_btn_pressed() -> void: + SceneChanger diff --git a/src/main.tscn b/src/main.tscn index f80487f..d2316ea 100644 --- a/src/main.tscn +++ b/src/main.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=4 format=3 uid="uid://v5hum6qh2phh"] +[gd_scene load_steps=5 format=3 uid="uid://v5hum6qh2phh"] [ext_resource type="Script" path="res://src/main.gd" id="1_xgqc1"] @@ -20,6 +20,13 @@ func _on_pressed() -> void: pass # Replace with function body. " +[sub_resource type="GDScript" id="GDScript_08pft"] +script/source = "extends Button + +func _pressed() -> void: + SceneChanger.change_to_test_game_scene() +" + [node name="Main" type="Control"] layout_mode = 3 anchors_preset = 15 @@ -61,5 +68,19 @@ theme_override_font_sizes/font_size = 30 text = "Playground" script = SubResource("GDScript_6o4cl") +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +alignment = 2 + +[node name="TestGameBtn" type="Button" parent="VBoxContainer/HBoxContainer2"] +custom_minimum_size = Vector2(400, 120) +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 4 +theme_override_font_sizes/font_size = 30 +text = "Test Game" +script = SubResource("GDScript_08pft") + [connection signal="pressed" from="VBoxContainer/HBoxContainer/LessonEditorBtn" to="VBoxContainer/HBoxContainer/LessonEditorBtn" method="_on_pressed"] [connection signal="pressed" from="VBoxContainer/HBoxContainer/PlayGroundBtn" to="VBoxContainer/HBoxContainer/PlayGroundBtn" method="_on_pressed"] +[connection signal="pressed" from="VBoxContainer/HBoxContainer2/TestGameBtn" to="." method="_on_test_game_btn_pressed"]