Selaa lähdekoodia

:sparkles: added first bots

Felix Bytow 10 kuukautta sitten
vanhempi
sitoutus
98313ae3d4

+ 28 - 0
assets/scenes/bot.gd

@@ -0,0 +1,28 @@
+extends Area2D
+class_name Bot
+
+const SKINS: Array[CompressedTexture2D] = [
+	preload("res://assets/textures/bots/robits_1.png"),
+	preload("res://assets/textures/bots/robits_2.png"),
+	preload("res://assets/textures/bots/robits_3.png"),
+	preload("res://assets/textures/bots/robits_4.png"),
+]
+
+@onready var sprite: Sprite2D = $Sprite2D
+@onready var base: Area2D = null
+
+@export var speed: float = 42.0
+
+func _ready() -> void:
+	base = get_tree().get_first_node_in_group("base")
+	if base != null:
+		var base_center = get_base_center()
+		global_rotation = global_position.angle_to_point(base_center)
+	sprite.texture = SKINS.pick_random()
+	
+func get_base_center() -> Vector2:
+	return base.get_child(0).global_position
+
+func _physics_process(delta) -> void:
+	if base != null:
+		global_position = global_position.move_toward(get_base_center(), speed * delta)

+ 21 - 0
assets/scenes/bot.tscn

@@ -0,0 +1,21 @@
+[gd_scene load_steps=4 format=3 uid="uid://chsjfsydj2ey6"]
+
+[ext_resource type="Texture2D" uid="uid://b0yyuvpv4b0wc" path="res://assets/textures/bots/robits_1.png" id="1_dd3nd"]
+[ext_resource type="Script" path="res://assets/scenes/bot.gd" id="1_juoa1"]
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_7wci8"]
+size = Vector2(46, 38)
+
+[node name="Bot" type="Area2D" groups=["foe"]]
+collision_layer = 4
+collision_mask = 19
+script = ExtResource("1_juoa1")
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+rotation = 1.5708
+scale = Vector2(0.03, 0.03)
+texture = ExtResource("1_dd3nd")
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+position = Vector2(7, 0)
+shape = SubResource("RectangleShape2D_7wci8")

+ 6 - 6
assets/scenes/transition.tscn

@@ -4,8 +4,8 @@
 [ext_resource type="Script" path="res://assets/scenes/transition.gd" id="1_jl8cy"]
 [ext_resource type="FontFile" uid="uid://cqtognhaksl7j" path="res://assets/fonts/Potra.ttf" id="3_liow6"]
 
-[sub_resource type="Animation" id="Animation_7tdps"]
-resource_name = "slide-out"
+[sub_resource type="Animation" id="Animation_sqshj"]
+resource_name = "slide-in"
 step = 0.0333333
 tracks/0/type = "value"
 tracks/0/imported = false
@@ -17,11 +17,11 @@ tracks/0/keys = {
 "times": PackedFloat32Array(0, 1),
 "transitions": PackedFloat32Array(1, 1),
 "update": 0,
-"values": [Vector2(0, 0), Vector2(-1280, 0)]
+"values": [Vector2(-1280, 0), Vector2(0, 0)]
 }
 
-[sub_resource type="Animation" id="Animation_sqshj"]
-resource_name = "slide-in"
+[sub_resource type="Animation" id="Animation_7tdps"]
+resource_name = "slide-out"
 step = 0.0333333
 tracks/0/type = "value"
 tracks/0/imported = false
@@ -33,7 +33,7 @@ tracks/0/keys = {
 "times": PackedFloat32Array(0, 1),
 "transitions": PackedFloat32Array(1, 1),
 "update": 0,
-"values": [Vector2(-1280, 0), Vector2(0, 0)]
+"values": [Vector2(0, 0), Vector2(-1280, 0)]
 }
 
 [sub_resource type="AnimationLibrary" id="AnimationLibrary_3vpft"]

BIN
assets/textures/bots/robits_1.png


+ 34 - 0
assets/textures/bots/robits_1.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b0yyuvpv4b0wc"
+path="res://.godot/imported/robits_1.png-d64f5f8eaf3591d403cd77e9fcdc12a4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/textures/bots/robits_1.png"
+dest_files=["res://.godot/imported/robits_1.png-d64f5f8eaf3591d403cd77e9fcdc12a4.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

BIN
assets/textures/bots/robits_2.png


+ 34 - 0
assets/textures/bots/robits_2.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bwny551hp3rrs"
+path="res://.godot/imported/robits_2.png-1d76da2b6a788a85d5a24b63d0b569d9.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/textures/bots/robits_2.png"
+dest_files=["res://.godot/imported/robits_2.png-1d76da2b6a788a85d5a24b63d0b569d9.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

BIN
assets/textures/bots/robits_3.png


+ 34 - 0
assets/textures/bots/robits_3.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c08e1qa0cgmk"
+path="res://.godot/imported/robits_3.png-61b9f28e1cef7d32573290e6b05a79ab.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/textures/bots/robits_3.png"
+dest_files=["res://.godot/imported/robits_3.png-61b9f28e1cef7d32573290e6b05a79ab.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

BIN
assets/textures/bots/robits_4.png


+ 34 - 0
assets/textures/bots/robits_4.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cypc67f1ec0vp"
+path="res://.godot/imported/robits_4.png-47defe460508c5b2a4e1917f3f30da15.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/textures/bots/robits_4.png"
+dest_files=["res://.godot/imported/robits_4.png-47defe460508c5b2a4e1917f3f30da15.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

+ 8 - 0
project.godot

@@ -33,6 +33,14 @@ toggle_fullscreen={
 ]
 }
 
+[layer_names]
+
+2d_physics/layer_1="base"
+2d_physics/layer_2="world"
+2d_physics/layer_3="foes"
+2d_physics/layer_4="foe-weapons"
+2d_physics/layer_5="player-weapons"
+
 [rendering]
 
 renderer/rendering_method="gl_compatibility"

+ 30 - 8
screens/game.gd

@@ -2,11 +2,21 @@ extends Node2D
 
 @onready var health_bar = $HealthBar
 @onready var transition = $Overlay/Transition
+@onready var spawn_timer = $Timer
 
-var direction = -1
+@onready var main_menu: PackedScene = load("res://screens/main_menu.tscn")
+@onready var bot_scene: PackedScene = load("res://assets/scenes/bot.tscn")
+
+@onready var spawn_points: Array[Marker2D] = [
+	$EnemySpawn_1,
+	$EnemySpawn_2,
+	$EnemySpawn_3,
+]
 
 func _ready() -> void:
 	transition.slide_out()
+	await transition.game_fully_visible
+	spawn_bot()
 
 func _process(_delta: float) -> void:
 	if Input.is_action_pressed("ui_cancel"):
@@ -14,11 +24,23 @@ func _process(_delta: float) -> void:
 		transition.text = ""
 		transition.slide_in()
 		await transition.game_fully_hidden
-		tree.paused = true
-		tree.change_scene_to_file("res://screens/main_menu.tscn")
-		tree.paused = false
+		tree.change_scene_to_packed(main_menu)
+		
+func spawn_bot() -> void:
+	var spawn = spawn_points.pick_random()
+	var bot = bot_scene.instantiate()
+	bot.global_position = spawn.global_position
+	add_child(bot)
+
+func _on_timer_timeout() -> void:
+	spawn_bot()
 
-func _on_timer_timeout():
-	health_bar.health += direction
-	if health_bar.health == 0 || health_bar.health == health_bar.MAX_HEALTH:
-		direction *= -1
+func _on_base_area_entered(area: Area2D) -> void:
+	if area.is_in_group("foe") || area.is_in_group("foe_weapons"):
+		area.queue_free()
+		health_bar.health -= 1
+		if health_bar.health == 0:
+			spawn_timer.stop()
+			var foes = get_tree().get_nodes_in_group("foe")
+			for foe in foes:
+				foe.queue_free()

+ 22 - 1
screens/game.tscn

@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=3 uid="uid://c483fkssc36s"]
+[gd_scene load_steps=8 format=3 uid="uid://c483fkssc36s"]
 
 [ext_resource type="Script" path="res://screens/game.gd" id="1_4dd0q"]
 [ext_resource type="Texture2D" uid="uid://djifkreeh0nb4" path="res://assets/textures/game_background.jpg" id="2_qk61j"]
@@ -10,6 +10,9 @@
 blend_mode = 1
 light_mode = 1
 
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_p2163"]
+size = Vector2(472, 288)
+
 [node name="Game" type="Node2D"]
 script = ExtResource("1_4dd0q")
 
@@ -29,6 +32,7 @@ texture = ExtResource("3_86s7d")
 position = Vector2(640, 58)
 
 [node name="Timer" type="Timer" parent="."]
+wait_time = 3.5
 autostart = true
 
 [node name="Overlay" type="CanvasLayer" parent="."]
@@ -36,4 +40,21 @@ layer = 10
 
 [node name="Transition" parent="Overlay" instance=ExtResource("4_yc6k4")]
 
+[node name="Base" type="Area2D" parent="." groups=["base"]]
+collision_mask = 12
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="Base"]
+position = Vector2(639, 509)
+shape = SubResource("RectangleShape2D_p2163")
+
+[node name="EnemySpawn_1" type="Marker2D" parent="." groups=["spawner"]]
+position = Vector2(63, 424)
+
+[node name="EnemySpawn_2" type="Marker2D" parent="." groups=["spawner"]]
+position = Vector2(1222, 424)
+
+[node name="EnemySpawn_3" type="Marker2D" parent="." groups=["spawner"]]
+position = Vector2(641, 144)
+
 [connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
+[connection signal="area_entered" from="Base" to="." method="_on_base_area_entered"]

+ 12 - 7
screens/main_menu.gd

@@ -3,16 +3,21 @@ extends Control
 @onready var leaderboard_button = $Buttons/Leaderboard
 @onready var quit_button = $Buttons/Quit
 
-func _ready():
+@onready var settings_menu: PackedScene = load("res://screens/settings_menu.tscn")
+@onready var game: PackedScene = load("res://screens/game.tscn")
+
+const DESKTOP_PLATFORMS = ["Windows", "macOS", "Linux"]
+
+func _ready() -> void:
 	leaderboard_button.disabled = not Leaderboard.exists()
-	if OS.get_name() not in ["Windows", "macOS", "Linux"]:
+	if OS.get_name() not in DESKTOP_PLATFORMS:
 		quit_button.visible = false
 
-func _on_new_game_pressed():
-	get_tree().change_scene_to_file("res://screens/game.tscn")
+func _on_new_game_pressed() -> void:
+	get_tree().change_scene_to_packed(game)
 
-func _on_quit_pressed():
+func _on_quit_pressed() -> void:
 	get_tree().quit()
 
-func _on_settings_pressed():
-	get_tree().change_scene_to_file("res://screens/settings_menu.tscn")
+func _on_settings_pressed() -> void:
+	get_tree().change_scene_to_packed(settings_menu)

+ 4 - 2
screens/settings_menu.gd

@@ -6,6 +6,8 @@ const SHOW_TUTORIAL = "SHOW_TUTORIAL"
 @onready var show_tutorial = $MarginContainer/VBoxContainer/Tabs/General/GridContainer/TutorialCheckBox
 @onready var discard_button = $MarginContainer/VBoxContainer/Buttons/Discard
 
+@onready var main_menu: PackedScene = load("res://screens/main_menu.tscn")
+
 func _ready():
 	discard_button.text = "BACK"
 	show_tutorial.button_pressed = Config.show_tutorial
@@ -15,12 +17,12 @@ func _process(_delta):
 		self._on_discard_pressed()
 
 func _on_discard_pressed():
-	get_tree().change_scene_to_file("res://screens/main_menu.tscn")
+	get_tree().change_scene_to_packed(main_menu)
 	
 func _on_save_pressed():
 	Config.show_tutorial = show_tutorial.button_pressed
 	Config.save()
-	get_tree().change_scene_to_file("res://screens/main_menu.tscn")
+	get_tree().change_scene_to_packed(main_menu)
 	
 func update_discard_button():
 	var dirty = \