feat: initial commit

This commit is contained in:
installer
2025-01-22 17:54:21 +01:00
commit 288f889130
69 changed files with 1525 additions and 0 deletions

11
scenes/game_over.gd Normal file
View File

@@ -0,0 +1,11 @@
extends Node2D
@export var scene: PackedScene
func _ready():
$CanvasLayer/VBoxContainer/Score.text += str(Global.score);
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
if Input.is_action_just_pressed("continue"):
get_tree().change_scene_to_packed(scene)

81
scenes/game_over.tscn Normal file
View File

@@ -0,0 +1,81 @@
[gd_scene load_steps=5 format=3 uid="uid://dsujhlrcl3hr3"]
[ext_resource type="Script" path="res://scenes/game_over.gd" id="1_h2fw8"]
[ext_resource type="PackedScene" uid="uid://byrjn2ta5gsld" path="res://scenes/level.tscn" id="2_latqh"]
[ext_resource type="Texture2D" uid="uid://p8npigebbm88" path="res://assets/gfx/ship.png" id="3_rgq6y"]
[ext_resource type="AudioStream" uid="uid://cr5eb0te0go26" path="res://assets/sfx/ship_explosion2.wav" id="4_0i6ac"]
[node name="GameOver" type="Node2D"]
script = ExtResource("1_h2fw8")
scene = ExtResource("2_latqh")
[node name="CanvasLayer" type="CanvasLayer" parent="."]
[node name="BG" type="ColorRect" parent="CanvasLayer"]
offset_right = 1280.0
offset_bottom = 1280.0
scale = Vector2(2, 2)
color = Color(0.0652247, 0.101439, 0.35129, 1)
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer"]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -114.5
offset_top = -47.5
offset_right = 114.5
offset_bottom = 47.5
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/separation = 50
[node name="GameOver" type="Label" parent="CanvasLayer/VBoxContainer"]
layout_mode = 2
theme_override_font_sizes/font_size = 40
text = "GAME OVER"
horizontal_alignment = 1
[node name="Score" type="Label" parent="CanvasLayer/VBoxContainer"]
layout_mode = 2
theme_override_font_sizes/font_size = 26
text = "Score: "
horizontal_alignment = 1
[node name="Control" type="Control" parent="CanvasLayer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
[node name="TouchScreenButton" type="TouchScreenButton" parent="CanvasLayer/VBoxContainer/Control"]
position = Vector2(-16, -16)
scale = Vector2(2, 2)
texture_normal = ExtResource("3_rgq6y")
action = "continue"
[node name="VBoxContainer2" type="VBoxContainer" parent="CanvasLayer"]
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -91.5
offset_top = -40.0
offset_right = 91.5
grow_horizontal = 2
grow_vertical = 0
size_flags_horizontal = 4
size_flags_vertical = 4
theme_override_constants/separation = 20
[node name="Label" type="Label" parent="CanvasLayer/VBoxContainer2"]
layout_mode = 2
size_flags_horizontal = 4
text = "Press space to continue"
[node name="ShipDestroyed" type="AudioStreamPlayer" parent="."]
stream = ExtResource("4_0i6ac")
autoplay = true
[connection signal="resized" from="CanvasLayer/BG" to="." method="_on_bg_resized"]

19
scenes/laser.gd Normal file
View File

@@ -0,0 +1,19 @@
extends Area2D
@export var speed = 500;
func _ready() -> void:
var tween = create_tween();
tween.tween_property(
$Sprite2D,
'scale',
Vector2(1.,1.),
0.2
).from(Vector2(0., 0.));
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
position.y -= speed * delta;
if position.y < 0:
queue_free();

19
scenes/laser.tscn Normal file
View File

@@ -0,0 +1,19 @@
[gd_scene load_steps=4 format=3 uid="uid://ck8ed6dd12vqs"]
[ext_resource type="Script" path="res://scenes/laser.gd" id="1_62hup"]
[ext_resource type="Texture2D" uid="uid://cwsth67tjjxxt" path="res://assets/gfx/laser.png" id="1_fb6k8"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_c5bm6"]
size = Vector2(6, 29)
[node name="laser" type="Area2D"]
collision_layer = 8
collision_mask = 2
script = ExtResource("1_62hup")
[node name="Sprite2D" type="Sprite2D" parent="."]
texture = ExtResource("1_fb6k8")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, 1.5)
shape = SubResource("RectangleShape2D_c5bm6")

58
scenes/level.gd Normal file
View File

@@ -0,0 +1,58 @@
extends Node2D
var meteor_scene: PackedScene = load("res://scenes/meteor.tscn");
var laser_scene: PackedScene = load("res://scenes/laser.tscn");
@export var health: int = 3
func _ready() -> void:
var rng := RandomNumberGenerator.new()
var window_size = get_viewport().get_visible_rect().size;
$Borders/Left/Coll.shape.size.y = window_size[1];
$Borders/Right/Coll.shape.size.y = window_size[1];
$Borders/Top/Coll.shape.size.x = window_size[0];
$Borders/Bot/Coll.shape.size.x = window_size[0];
$Borders/Right.position.x = window_size[0] + 30;
$Borders/Bot.position.y = window_size[1];
Global.enemy_level = 0;
Global.ship_level = 0;
Global.score = 0;
Global.meteor_base_speed = 400;
Global.meteor_base_timer = 0.25;
Global.player_base_speed = 500;
Global.player_shoot_cooldown = 0.5;
for _n in range(4, 15):
var star = $Stars/base.duplicate();
$Stars.add_child(star);
star.autoplay = "true";
star.global_position = Vector2(
rng.randi_range(0, window_size[0]),
rng.randi_range(0, window_size[1]),
);
star.speed_scale = rng.randf_range(0.5, 1.5);
var s = rng.randf_range(0.5, 1.5);
star.scale = Vector2(s, s);
get_tree().call_group("ui", "set_health", health);
func _on_meteor_timer_timeout() -> void:
$MeteorTimer.wait_time = Global.meteor_base_timer;
var meteor = meteor_scene.instantiate();
$Meteors.add_child(meteor);
meteor.connect("collision", _on_meteor_collision);
func _on_meteor_collision() -> void:
health -= 1;
get_tree().call_group("ui", "set_health", health);
if health <= 0:
get_tree().change_scene_to_file("res://scenes/game_over.tscn");
else:
$ShipHit.play();
func _on_player_laser(pos: Vector2) -> void:
var laser = laser_scene.instantiate();
$Lasers.add_child(laser);
laser.position = pos;

124
scenes/level.tscn Normal file
View File

@@ -0,0 +1,124 @@
[gd_scene load_steps=15 format=3 uid="uid://byrjn2ta5gsld"]
[ext_resource type="PackedScene" uid="uid://2kccnun8mkjv" path="res://scenes/player.tscn" id="1_35q1n"]
[ext_resource type="Script" path="res://scenes/level.gd" id="1_bh63m"]
[ext_resource type="Texture2D" uid="uid://bqssrdxkdgjiv" path="res://assets/gfx/bg.png" id="2_ek6d0"]
[ext_resource type="Texture2D" uid="uid://dski3gvj6msun" path="res://assets/gfx/star1.png" id="3_4miyn"]
[ext_resource type="Texture2D" uid="uid://duavnpv4rkkgx" path="res://assets/gfx/star2.png" id="4_blnv3"]
[ext_resource type="Texture2D" uid="uid://cn2kdlnfxrhah" path="res://assets/gfx/star3.png" id="5_fkc8v"]
[ext_resource type="Texture2D" uid="uid://51s6an87yc1f" path="res://assets/gfx/star4.png" id="6_7ucuq"]
[ext_resource type="Texture2D" uid="uid://62bvbadc4yhc" path="res://assets/gfx/star5.png" id="7_vyiqk"]
[ext_resource type="Texture2D" uid="uid://c53y4qb5nh44q" path="res://assets/gfx/star6.png" id="8_dy6n5"]
[ext_resource type="PackedScene" uid="uid://drg5covf2vhj8" path="res://scenes/ui.tscn" id="10_ac25c"]
[ext_resource type="AudioStream" uid="uid://cwsqbuoipmtad" path="res://assets/sfx/hurt2.wav" id="11_vh4gx"]
[sub_resource type="SpriteFrames" id="SpriteFrames_v16wl"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("3_4miyn")
}, {
"duration": 1.0,
"texture": ExtResource("4_blnv3")
}, {
"duration": 1.0,
"texture": ExtResource("5_fkc8v")
}, {
"duration": 1.0,
"texture": ExtResource("6_7ucuq")
}, {
"duration": 1.0,
"texture": ExtResource("7_vyiqk")
}, {
"duration": 1.0,
"texture": ExtResource("8_dy6n5")
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_dc5e8"]
size = Vector2(60, 720)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_u7dyo"]
size = Vector2(1280, 10)
[node name="Level" type="Node2D"]
script = ExtResource("1_bh63m")
[node name="BG" type="Sprite2D" parent="."]
scale = Vector2(5, 10)
texture = ExtResource("2_ek6d0")
offset = Vector2(300, 200)
metadata/_edit_lock_ = true
[node name="Stars" type="Node2D" parent="."]
metadata/_edit_lock_ = true
[node name="base" type="AnimatedSprite2D" parent="Stars"]
position = Vector2(146, 96)
sprite_frames = SubResource("SpriteFrames_v16wl")
autoplay = "default"
frame_progress = 0.705026
[node name="Player" parent="." groups=["ui"] instance=ExtResource("1_35q1n")]
z_index = 999
position = Vector2(642, 602)
[node name="Borders" type="Node2D" parent="."]
metadata/_edit_lock_ = true
[node name="Right" type="StaticBody2D" parent="Borders"]
position = Vector2(1300, 360)
collision_layer = 4
metadata/_edit_lock_ = true
[node name="Coll" type="CollisionShape2D" parent="Borders/Right"]
shape = SubResource("RectangleShape2D_dc5e8")
metadata/_edit_lock_ = true
[node name="Top" type="StaticBody2D" parent="Borders"]
position = Vector2(640, 0)
collision_layer = 4
metadata/_edit_lock_ = true
[node name="Coll" type="CollisionShape2D" parent="Borders/Top"]
shape = SubResource("RectangleShape2D_u7dyo")
metadata/_edit_lock_ = true
[node name="Bot" type="StaticBody2D" parent="Borders"]
position = Vector2(640, 720)
collision_layer = 4
metadata/_edit_lock_ = true
[node name="Coll" type="CollisionShape2D" parent="Borders/Bot"]
shape = SubResource("RectangleShape2D_u7dyo")
metadata/_edit_lock_ = true
[node name="Left" type="StaticBody2D" parent="Borders"]
position = Vector2(-30, 360)
collision_layer = 4
metadata/_edit_lock_ = true
[node name="Coll" type="CollisionShape2D" parent="Borders/Left"]
shape = SubResource("RectangleShape2D_dc5e8")
metadata/_edit_lock_ = true
[node name="MeteorTimer" type="Timer" parent="."]
wait_time = 0.25
autostart = true
[node name="Meteors" type="Node2D" parent="."]
metadata/_edit_lock_ = true
[node name="Lasers" type="Node2D" parent="."]
metadata/_edit_lock_ = true
[node name="UI" parent="." groups=["ui"] instance=ExtResource("10_ac25c")]
[node name="ShipHit" type="AudioStreamPlayer" parent="."]
stream = ExtResource("11_vh4gx")
[connection signal="laser" from="Player" to="." method="_on_player_laser"]
[connection signal="timeout" from="MeteorTimer" to="." method="_on_meteor_timer_timeout"]

40
scenes/meteor.gd Normal file
View File

@@ -0,0 +1,40 @@
extends Area2D
@export var direction := 0.;
@export var speed := 400;
@export var rot_speed := 0.;
var can_collide := true;
signal collision
func _ready() -> void:
var rng := RandomNumberGenerator.new();
var width = get_viewport().get_visible_rect().size[0]
var rand_x = rng.randi_range(10, width - 10);
var rand_y = rng.randi_range(-150, -50);
position = Vector2(rand_x, rand_y);
speed = rng.randi_range(Global.meteor_base_speed - 200, Global.meteor_base_speed + 200);
rot_speed = rng.randi_range(0, 100);
direction = rng.randf_range(-1., 1.);
func _process(delta) -> void:
position += Vector2(direction, 1.0) * speed * delta;
rotation += rot_speed * delta;
var height = get_viewport().get_visible_rect().size[1]
if position.y > height:
queue_free();
func _on_body_entered(_body: Node2D) -> void:
if can_collide:
collision.emit();
func _on_area_entered(area: Area2D) -> void:
area.queue_free();
$DestroyMeteor.play();
Global.score += 10;
$MeteorImage.hide();
can_collide = false;
await get_tree().create_timer(0.5).timeout;
queue_free();

22
scenes/meteor.tscn Normal file
View File

@@ -0,0 +1,22 @@
[gd_scene load_steps=4 format=3 uid="uid://ec5t4ff57drg"]
[ext_resource type="Texture2D" uid="uid://cy0lqjas2aw15" path="res://assets/gfx/meteroid.png" id="1_8ih5k"]
[ext_resource type="Script" path="res://scenes/meteor.gd" id="1_i72w4"]
[ext_resource type="AudioStream" uid="uid://4g4kmiy5ussi" path="res://assets/sfx/explosion2.wav" id="3_rgtxm"]
[node name="Meteor" type="Area2D"]
collision_layer = 2
collision_mask = 9
script = ExtResource("1_i72w4")
[node name="MeteorImage" type="Sprite2D" parent="."]
texture = ExtResource("1_8ih5k")
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PackedVector2Array(-11, 10, -11, 1, -9, -5, -2, -10, 6, -11, 11, -7, 11, 4, 5, 12)
[node name="DestroyMeteor" type="AudioStreamPlayer" parent="."]
stream = ExtResource("3_rgtxm")
[connection signal="area_entered" from="." to="." method="_on_area_entered"]
[connection signal="body_entered" from="." to="." method="_on_body_entered"]

38
scenes/player.gd Normal file
View File

@@ -0,0 +1,38 @@
extends CharacterBody2D
#@export var SPEED: int = 500;
#@export var SHOOT_COOLDOWN: float = 0.5;
var cooldown := 0.0;
var last_direction := Vector2(0., 0.);
@export var last_direction_coef := 1.2;
@export var max_last_direction := -1.5;
signal laser(pos: Vector2);
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var window_size = get_viewport().get_visible_rect().size;
position = Vector2(window_size[0] / 2, window_size[1] / 4 * 3);
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
var speed = Global.player_base_speed;
var direction = Input.get_vector("left", "right", "up", "down");
velocity = (last_direction + direction) * speed;
last_direction = (last_direction + direction) / last_direction_coef;
if last_direction.x < -max_last_direction:
last_direction.x = -max_last_direction;
if last_direction.y < -max_last_direction:
last_direction.y = -max_last_direction;
if last_direction.x > max_last_direction:
last_direction.x = max_last_direction;
if last_direction.y > max_last_direction:
last_direction.y = max_last_direction;
if cooldown > 0:
cooldown -= delta;
move_and_slide();
if Input.is_action_just_pressed("fire") and cooldown <= 0:
laser.emit($LaserStart.global_position)
cooldown = Global.player_shoot_cooldown;
$LaserSound.play()

35
scenes/player.tscn Normal file
View File

@@ -0,0 +1,35 @@
[gd_scene load_steps=5 format=3 uid="uid://2kccnun8mkjv"]
[ext_resource type="Texture2D" uid="uid://p8npigebbm88" path="res://assets/gfx/ship.png" id="1_6r50y"]
[ext_resource type="Script" path="res://scenes/player.gd" id="1_spn58"]
[ext_resource type="AudioStream" uid="uid://bio5bv0mi006i" path="res://assets/sfx/shoot2.wav" id="3_650e3"]
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gc25u"]
lifetime_randomness = 0.29
particle_flag_disable_z = true
emission_shape = 1
emission_sphere_radius = 8.5
angular_velocity_min = 112.09
angular_velocity_max = 198.32
gravity = Vector3(0, 98, 0)
color = Color(1, 0.556863, 0.145098, 1)
[node name="Player" type="CharacterBody2D"]
collision_mask = 6
script = ExtResource("1_spn58")
[node name="PlayerImage" type="Sprite2D" parent="."]
texture = ExtResource("1_6r50y")
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
position = Vector2(-0.445736, -0.727245)
polygon = PackedVector2Array(-13.5543, 8.72725, 0.445736, -11.2728, 14.4457, 8.72725)
[node name="LaserStart" type="Marker2D" parent="."]
position = Vector2(0, -21)
[node name="LaserSound" type="AudioStreamPlayer" parent="."]
stream = ExtResource("3_650e3")
[node name="GPUParticles2D" type="GPUParticles2D" parent="."]
process_material = SubResource("ParticleProcessMaterial_gc25u")

48
scenes/ui.gd Normal file
View File

@@ -0,0 +1,48 @@
extends CanvasLayer
static var health_sprite = load("res://assets/gfx/ship.png");
var elapsed := 0;
func set_health(amount):
for child in $Health/HealthContainer.get_children():
child.queue_free();
for i in amount:
var text_rect = TextureRect.new();
text_rect.texture = health_sprite;
text_rect.stretch_mode = TextureRect.STRETCH_KEEP;
$Health/HealthContainer.add_child(text_rect);
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
Global.score = 0;
var size = get_viewport().get_visible_rect().size;
$Score.position = Vector2(size[0] / 2, 50);
$Health.position = Vector2(50, size[1] - 100);
$TouchButtons/Shoot.position = Vector2(size[0] - 200, size[1] - 200);
$"TouchButtons/Virtual Joystick".position = Vector2(200, size[1] - 400);
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
pass
func _on_score_timer_timeout() -> void:
elapsed += 1;
if elapsed >= 10:
Global.enemy_level += 1;
if Global.enemy_level % 2 == 0 or Global.meteor_base_timer <= 0.1:
Global.meteor_base_speed += 25;
else:
Global.meteor_base_timer -= 0.05;
Global.score += 1;
if Global.score / 50 > Global.ship_level:
Global.ship_level += 1;
if Global.ship_level % 2 == 0:
Global.player_base_speed += 50;
else:
Global.player_shoot_cooldown -= 0.05;
$Score.text = str(Global.score);
$Details/MeteorSpeed.text = "Meteor Speed: " + str(Global.meteor_base_speed);
$Details/MeteorDelay.text = "Meteor Delay: " + str(Global.meteor_base_timer);
$Details/ShipSpeed.text = "Ship Speed: " + str(Global.player_base_speed);
$Details/ShootCooldown.text = "Shoot Cooldown: " + str(Global.player_shoot_cooldown);

76
scenes/ui.tscn Normal file
View File

@@ -0,0 +1,76 @@
[gd_scene load_steps=4 format=3 uid="uid://drg5covf2vhj8"]
[ext_resource type="Script" path="res://scenes/ui.gd" id="1_a1wuu"]
[ext_resource type="PackedScene" uid="uid://dmr0fcamx7t56" path="res://addons/virtual_joystick/virtual_joystick_scene.tscn" id="4_pooqj"]
[ext_resource type="Texture2D" uid="uid://040ccmi5cn3x" path="res://assets/gfx/shoot.png" id="7_76vfp"]
[node name="UI" type="CanvasLayer"]
script = ExtResource("1_a1wuu")
[node name="Score" type="Label" parent="."]
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -39.0
offset_right = 39.0
offset_bottom = 23.0
grow_horizontal = 2
theme_override_font_sizes/font_size = 50
text = "0"
horizontal_alignment = 1
[node name="Health" type="MarginContainer" parent="."]
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_top = -40.0
offset_right = 152.0
grow_vertical = 0
theme_override_constants/margin_left = 10
theme_override_constants/margin_bottom = 10
[node name="HealthContainer" type="HBoxContainer" parent="Health"]
layout_mode = 2
theme_override_constants/separation = 5
[node name="ScoreTimer" type="Timer" parent="."]
autostart = true
[node name="TouchButtons" type="CanvasLayer" parent="."]
[node name="Shoot" type="TouchScreenButton" parent="TouchButtons"]
position = Vector2(1240, 680)
scale = Vector2(3, 3)
texture_normal = ExtResource("7_76vfp")
action = "fire"
[node name="Virtual Joystick" parent="TouchButtons" instance=ExtResource("4_pooqj")]
offset_top = -300.0
offset_bottom = 0.0
joystick_mode = 2
action_left = "left"
action_right = "right"
action_up = "up"
action_down = "down"
[node name="Details" type="VBoxContainer" parent="."]
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -40.0
offset_bottom = 40.0
grow_horizontal = 0
[node name="MeteorSpeed" type="Label" parent="Details"]
layout_mode = 2
[node name="MeteorDelay" type="Label" parent="Details"]
layout_mode = 2
[node name="ShipSpeed" type="Label" parent="Details"]
layout_mode = 2
[node name="ShootCooldown" type="Label" parent="Details"]
layout_mode = 2
[connection signal="timeout" from="ScoreTimer" to="." method="_on_score_timer_timeout"]