Compare commits
10 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 439f906817 | |||
| e287853798 | |||
| 64c055b23f | |||
| 9a0348f212 | |||
| 991fceb5b6 | |||
| bb963db15f | |||
| e46d1066c0 | |||
| e490c92ffb | |||
| bb18edb1be | |||
| baa57c4d33 |
21 changed files with 1694 additions and 135 deletions
|
|
@ -2,8 +2,9 @@ extends Area2D
|
||||||
|
|
||||||
var velocity = Vector2(0, 0)
|
var velocity = Vector2(0, 0)
|
||||||
var rot_velocity = 0
|
var rot_velocity = 0
|
||||||
|
|
||||||
var explosion = preload('res://Scenes/explosion.tscn')
|
var explosion = preload('res://Scenes/explosion.tscn')
|
||||||
var pop = preload("res://Sounds/Explosion5.wav")
|
var pop = preload("res://Sounds/Explosion.wav")
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
connect("body_entered", _on_body_entered)
|
connect("body_entered", _on_body_entered)
|
||||||
|
|
@ -15,14 +16,16 @@ func _physics_process(delta):
|
||||||
Utils.wrap_position(self)
|
Utils.wrap_position(self)
|
||||||
|
|
||||||
func _on_body_entered(body):
|
func _on_body_entered(body):
|
||||||
if body.name == "Ship":
|
if body.name == "Ship" and body.hit():
|
||||||
Game.set_lives(Game.lives - 1)
|
|
||||||
|
|
||||||
Utils.play_sound(pop, get_parent())
|
|
||||||
|
|
||||||
var boom = explosion.instantiate()
|
|
||||||
boom.position = body.global_position
|
|
||||||
boom.scale = Vector2(6, 6)
|
|
||||||
get_parent().add_child(boom)
|
|
||||||
body.reset()
|
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
func hit():
|
||||||
|
Utils.play_sound(pop, get_parent())
|
||||||
|
|
||||||
|
var boom = explosion.instantiate()
|
||||||
|
boom.position = global_position
|
||||||
|
boom.scale = scale
|
||||||
|
get_parent().add_child(boom)
|
||||||
|
|
||||||
|
Game.set_score(Game.score + 100)
|
||||||
|
queue_free()
|
||||||
|
|
|
||||||
47
Scenes/credits.gd
Normal file
47
Scenes/credits.gd
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
@onready var grid: GridContainer = $Columns
|
||||||
|
|
||||||
|
signal main_menu
|
||||||
|
|
||||||
|
const CREDIT_LABELS_LINKS := {
|
||||||
|
"Godot Engine" : ["Godot Team : godotengine.org", "https://godotengine.org"],
|
||||||
|
"Ship and Enemies" : ["bart : opengameart.org", "https://opengameart.org/content/i-are-spaceship-16x16-space-sprites"],
|
||||||
|
"Starry Background" : ["Kutejnikov : opengameart.org", "https://opengameart.org/content/space-9"],
|
||||||
|
"Laser Sound" : ["dklon : opengameart.org", "https://opengameart.org/content/laser-fire"],
|
||||||
|
"Explosion Sounds" : ["TeamAlpha : opengameart.org", "https://opengameart.org/content/8-bitnes-explosion-sound-effecs"],
|
||||||
|
"Extra Life Jingle" : ["Mrthenoronha : freesound.org", "https://freesound.org/people/Mrthenoronha/sounds/518306/"]
|
||||||
|
}
|
||||||
|
|
||||||
|
const LEFT_COL_WIDTH := 350
|
||||||
|
const RIGHT_COL_WIDTH := 350
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
$Back.pressed.connect(_emit_back)
|
||||||
|
|
||||||
|
# center the grid
|
||||||
|
grid.anchor_left = 0.5
|
||||||
|
grid.anchor_right = 0.5
|
||||||
|
grid.offset_left = int(-(LEFT_COL_WIDTH + RIGHT_COL_WIDTH) / 2.0)
|
||||||
|
grid.offset_right = int((LEFT_COL_WIDTH + RIGHT_COL_WIDTH) / 2.0)
|
||||||
|
|
||||||
|
for btn_name in CREDIT_LABELS_LINKS.keys():
|
||||||
|
var display_text = CREDIT_LABELS_LINKS[btn_name][0]
|
||||||
|
var link: String = CREDIT_LABELS_LINKS[btn_name][1]
|
||||||
|
|
||||||
|
var label = Label.new()
|
||||||
|
label.text = btn_name
|
||||||
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||||
|
label.custom_minimum_size.x = LEFT_COL_WIDTH
|
||||||
|
grid.add_child(label)
|
||||||
|
|
||||||
|
var button = Button.new()
|
||||||
|
button.text = display_text
|
||||||
|
button.focus_mode = Control.FOCUS_NONE
|
||||||
|
button.custom_minimum_size.x = RIGHT_COL_WIDTH
|
||||||
|
var link_local := link
|
||||||
|
button.pressed.connect(func(): OS.shell_open(link_local))
|
||||||
|
grid.add_child(button)
|
||||||
|
|
||||||
|
func _emit_back():
|
||||||
|
emit_signal("main_menu")
|
||||||
1
Scenes/credits.gd.uid
Normal file
1
Scenes/credits.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dinqb3ubrx76h
|
||||||
58
Scenes/credits.tscn
Normal file
58
Scenes/credits.tscn
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
[gd_scene load_steps=3 format=3 uid="uid://dylsy7qq16t6e"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dinqb3ubrx76h" path="res://Scenes/credits.gd" id="1_r18jl"]
|
||||||
|
|
||||||
|
[sub_resource type="LabelSettings" id="LabelSettings_gryuy"]
|
||||||
|
font_size = 36
|
||||||
|
|
||||||
|
[node name="Control" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 13
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_r18jl")
|
||||||
|
|
||||||
|
[node name="Title" type="Label" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 5
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
offset_left = -61.5
|
||||||
|
offset_top = 35.0
|
||||||
|
offset_right = 61.5
|
||||||
|
offset_bottom = 85.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
text = "Credits"
|
||||||
|
label_settings = SubResource("LabelSettings_gryuy")
|
||||||
|
|
||||||
|
[node name="Columns" type="GridContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 5
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = 100.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 140.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
theme_override_constants/h_separation = 30
|
||||||
|
theme_override_constants/v_separation = 5
|
||||||
|
columns = 2
|
||||||
|
|
||||||
|
[node name="Back" type="Button" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 7
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -50.0
|
||||||
|
offset_top = -73.0
|
||||||
|
offset_right = 50.0
|
||||||
|
offset_bottom = -38.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 0
|
||||||
|
text = "Back"
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
[ext_resource type="Script" uid="uid://cf1vwutwpi4rf" path="res://Scripts/game_over.gd" id="1_ojehl"]
|
[ext_resource type="Script" uid="uid://cf1vwutwpi4rf" path="res://Scripts/game_over.gd" id="1_ojehl"]
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_i2yjh"]
|
[sub_resource type="LabelSettings" id="LabelSettings_i2yjh"]
|
||||||
font_size = 72
|
font_size = 120
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_ojehl"]
|
[sub_resource type="LabelSettings" id="LabelSettings_ojehl"]
|
||||||
font_size = 32
|
font_size = 48
|
||||||
|
|
||||||
[node name="Control" type="Control"]
|
[node name="Control" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
|
@ -34,9 +34,10 @@ layout_mode = 1
|
||||||
anchors_preset = 5
|
anchors_preset = 5
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
offset_left = -195.0
|
offset_left = -326.0
|
||||||
offset_right = 195.0
|
offset_top = -55.0
|
||||||
offset_bottom = 99.0
|
offset_right = 326.0
|
||||||
|
offset_bottom = 110.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
text = "Game Over"
|
text = "Game Over"
|
||||||
label_settings = SubResource("LabelSettings_i2yjh")
|
label_settings = SubResource("LabelSettings_i2yjh")
|
||||||
|
|
@ -46,10 +47,10 @@ layout_mode = 1
|
||||||
anchors_preset = 5
|
anchors_preset = 5
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
offset_left = -60.5
|
offset_left = -90.5
|
||||||
offset_top = 85.0
|
offset_top = 80.0
|
||||||
offset_right = 60.5
|
offset_right = 90.5
|
||||||
offset_bottom = 130.0
|
offset_bottom = 147.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
text = "Score: 0"
|
text = "Score: 0"
|
||||||
label_settings = SubResource("LabelSettings_ojehl")
|
label_settings = SubResource("LabelSettings_ojehl")
|
||||||
|
|
@ -59,9 +60,10 @@ layout_mode = 1
|
||||||
anchors_preset = 5
|
anchors_preset = 5
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
offset_left = -46.5
|
offset_left = -125.0
|
||||||
offset_top = 150.0
|
offset_top = 170.0
|
||||||
offset_right = 46.5
|
offset_right = 125.0
|
||||||
offset_bottom = 181.0
|
offset_bottom = 223.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
|
theme_override_font_sizes/font_size = 32
|
||||||
text = "New Game"
|
text = "New Game"
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,19 @@
|
||||||
[ext_resource type="Texture2D" uid="uid://cv84w0y2jg3i3" path="res://Sprites/i_are_spaceship.png" id="1_fn5yt"]
|
[ext_resource type="Texture2D" uid="uid://cv84w0y2jg3i3" path="res://Sprites/i_are_spaceship.png" id="1_fn5yt"]
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_6vqwg"]
|
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_6vqwg"]
|
||||||
radius = 3.0
|
radius = 2.0
|
||||||
height = 10.0
|
height = 8.0
|
||||||
|
|
||||||
[node name="Laser" type="Area2D"]
|
[node name="Laser" type="Area2D"]
|
||||||
script = ExtResource("1_6vqwg")
|
script = ExtResource("1_6vqwg")
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
position = Vector2(-1, 1)
|
position = Vector2(-1, 1)
|
||||||
scale = Vector2(2, 2)
|
scale = Vector2(1.5, 1.5)
|
||||||
texture = ExtResource("1_fn5yt")
|
texture = ExtResource("1_fn5yt")
|
||||||
region_enabled = true
|
region_enabled = true
|
||||||
region_rect = Rect2(34, 17, 3, 7)
|
region_rect = Rect2(34, 17, 3, 7)
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
position = Vector2(0, 1)
|
||||||
shape = SubResource("CapsuleShape2D_6vqwg")
|
shape = SubResource("CapsuleShape2D_6vqwg")
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
[gd_scene load_steps=2 format=3 uid="uid://j2mr8pluyo37"]
|
[gd_scene load_steps=2 format=3 uid="uid://dkqojwn3escv3"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cvfsmhdbgh8vh" path="res://Sprites/idle_spaceship.png" id="1_bkce2"]
|
[ext_resource type="Texture2D" uid="uid://cvfsmhdbgh8vh" path="res://Sprites/idle_spaceship.png" id="1_bkce2"]
|
||||||
|
|
||||||
[node name="Life" type="TextureRect"]
|
[node name="TextureRect" type="TextureRect"]
|
||||||
offset_right = 15.0
|
custom_minimum_size = Vector2(30, 48)
|
||||||
offset_bottom = 24.0
|
offset_right = 30.0
|
||||||
texture = ExtResource("1_bkce2")
|
texture = ExtResource("1_bkce2")
|
||||||
|
expand_mode = 5
|
||||||
stretch_mode = 4
|
stretch_mode = 4
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" uid="uid://dxbdiq4y3mqtd" path="res://Scripts/main_menu.gd" id="1_28flt"]
|
[ext_resource type="Script" uid="uid://dxbdiq4y3mqtd" path="res://Scripts/main_menu.gd" id="1_28flt"]
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_i2yjh"]
|
[sub_resource type="LabelSettings" id="LabelSettings_i2yjh"]
|
||||||
font_size = 72
|
font_size = 120
|
||||||
|
|
||||||
[node name="Control" type="Control"]
|
[node name="Control" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
|
@ -21,8 +21,8 @@ anchors_preset = 13
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
offset_top = -100.0
|
offset_top = -120.0
|
||||||
offset_bottom = -100.0
|
offset_bottom = -120.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
|
||||||
|
|
@ -31,34 +31,38 @@ layout_mode = 1
|
||||||
anchors_preset = 5
|
anchors_preset = 5
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
offset_left = -195.0
|
offset_left = -273.0
|
||||||
offset_right = 195.0
|
offset_top = -52.0
|
||||||
offset_bottom = 99.0
|
offset_right = 273.0
|
||||||
|
offset_bottom = 113.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
text = "Asteroids"
|
text = "Asteroids"
|
||||||
label_settings = SubResource("LabelSettings_i2yjh")
|
label_settings = SubResource("LabelSettings_i2yjh")
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
[node name="New Game" type="Button" parent="Container"]
|
[node name="ButtonContainer" type="VBoxContainer" parent="Container"]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 5
|
anchors_preset = 5
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
offset_left = -46.5
|
offset_left = -125.0
|
||||||
offset_top = 111.0
|
offset_top = 120.0
|
||||||
offset_right = 46.5
|
offset_right = 125.0
|
||||||
offset_bottom = 142.0
|
offset_bottom = 420.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
|
theme_override_constants/separation = 15
|
||||||
|
|
||||||
|
[node name="New Game" type="Button" parent="Container/ButtonContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_font_sizes/font_size = 32
|
||||||
text = "New Game"
|
text = "New Game"
|
||||||
|
|
||||||
[node name="Quit" type="Button" parent="Container"]
|
[node name="Credits" type="Button" parent="Container/ButtonContainer"]
|
||||||
layout_mode = 1
|
layout_mode = 2
|
||||||
anchors_preset = 5
|
theme_override_font_sizes/font_size = 32
|
||||||
anchor_left = 0.5
|
text = "Credits"
|
||||||
anchor_right = 0.5
|
|
||||||
offset_left = -46.5
|
[node name="Quit" type="Button" parent="Container/ButtonContainer"]
|
||||||
offset_top = 150.0
|
layout_mode = 2
|
||||||
offset_right = 46.5
|
theme_override_font_sizes/font_size = 32
|
||||||
offset_bottom = 181.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
text = "Quit"
|
text = "Quit"
|
||||||
|
|
|
||||||
|
|
@ -77,14 +77,16 @@ animations = [{
|
||||||
}]
|
}]
|
||||||
|
|
||||||
[sub_resource type="ConvexPolygonShape2D" id="ConvexPolygonShape2D_kek77"]
|
[sub_resource type="ConvexPolygonShape2D" id="ConvexPolygonShape2D_kek77"]
|
||||||
points = PackedVector2Array(-6, 0, -7, 7, 8, 7, 7, 0, 0, -8)
|
points = PackedVector2Array(-7, 0, -8, 7, 7, 7, 6, 0, 0, -8)
|
||||||
|
|
||||||
[node name="Ship" type="CharacterBody2D"]
|
[node name="Ship" type="CharacterBody2D"]
|
||||||
|
scale = Vector2(2, 2)
|
||||||
script = ExtResource("1_6ejuo")
|
script = ExtResource("1_6ejuo")
|
||||||
Laser = ExtResource("2_8aq7e")
|
Laser = ExtResource("2_8aq7e")
|
||||||
pew = ExtResource("3_fwcnm")
|
pew = ExtResource("3_fwcnm")
|
||||||
|
|
||||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
|
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
|
||||||
|
position = Vector2(-1, 0)
|
||||||
sprite_frames = SubResource("SpriteFrames_1bvp3")
|
sprite_frames = SubResource("SpriteFrames_1bvp3")
|
||||||
animation = &"right"
|
animation = &"right"
|
||||||
autoplay = "idle"
|
autoplay = "idle"
|
||||||
|
|
@ -94,4 +96,4 @@ position = Vector2(0, -4)
|
||||||
shape = SubResource("ConvexPolygonShape2D_kek77")
|
shape = SubResource("ConvexPolygonShape2D_kek77")
|
||||||
|
|
||||||
[node name="Muzzle" type="Marker2D" parent="."]
|
[node name="Muzzle" type="Marker2D" parent="."]
|
||||||
position = Vector2(0, -15)
|
position = Vector2(0, -14)
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,17 @@ var player: CharacterBody2D
|
||||||
var ui: CanvasLayer
|
var ui: CanvasLayer
|
||||||
var game_over_ui: Control
|
var game_over_ui: Control
|
||||||
var menu_ui: Control
|
var menu_ui: Control
|
||||||
|
var credits_ui: Control
|
||||||
var life_icon = preload("res://Scenes/life.tscn")
|
var life_icon = preload("res://Scenes/life.tscn")
|
||||||
var menu_scn = preload("res://Scenes/main_menu.tscn")
|
var menu_scn = preload("res://Scenes/main_menu.tscn")
|
||||||
|
var credits_scn = preload("res://Scenes/credits.tscn")
|
||||||
var game_over_scn = preload("res://Scenes/game_over.tscn")
|
var game_over_scn = preload("res://Scenes/game_over.tscn")
|
||||||
var ship = preload("res://Scenes/ship.tscn")
|
var ship = preload("res://Scenes/ship.tscn")
|
||||||
var life = preload("res://Sounds/extra_life.wav")
|
var life = preload("res://Sounds/extra_life.wav")
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
menu_ui = menu_scn.instantiate()
|
|
||||||
menu_ui.new_game.connect(_new_game)
|
|
||||||
menu_ui.quit_game.connect(_quit_game)
|
|
||||||
|
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
ui.add_child(menu_ui)
|
_main_menu()
|
||||||
|
|
||||||
func set_score(amount: int):
|
func set_score(amount: int):
|
||||||
score = amount
|
score = amount
|
||||||
|
|
@ -84,5 +82,23 @@ func _new_game():
|
||||||
|
|
||||||
get_tree().current_scene.add_child(player)
|
get_tree().current_scene.add_child(player)
|
||||||
|
|
||||||
|
func _credits():
|
||||||
|
if menu_ui:
|
||||||
|
menu_ui.queue_free()
|
||||||
|
|
||||||
|
credits_ui = credits_scn.instantiate()
|
||||||
|
credits_ui.connect("main_menu", _main_menu)
|
||||||
|
ui.add_child(credits_ui)
|
||||||
|
|
||||||
|
func _main_menu():
|
||||||
|
if credits_ui:
|
||||||
|
credits_ui.queue_free()
|
||||||
|
|
||||||
|
menu_ui = menu_scn.instantiate()
|
||||||
|
menu_ui.new_game.connect(_new_game)
|
||||||
|
menu_ui.credits.connect(_credits)
|
||||||
|
menu_ui.quit_game.connect(_quit_game)
|
||||||
|
ui.add_child(menu_ui)
|
||||||
|
|
||||||
func _quit_game():
|
func _quit_game():
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
extends Area2D
|
extends Area2D
|
||||||
|
|
||||||
var explosion = preload('res://Scenes/explosion.tscn')
|
|
||||||
var pop = preload("res://Sounds/Explosion.wav")
|
|
||||||
var speed = 750
|
var speed = 750
|
||||||
|
|
||||||
var half_size: Vector2 # half of sprite dimensions (used for wrapping)
|
var half_size: Vector2 # half of sprite dimensions (used for wrapping)
|
||||||
|
|
@ -17,21 +15,10 @@ func _physics_process(delta):
|
||||||
var rect = get_viewport_rect()
|
var rect = get_viewport_rect()
|
||||||
|
|
||||||
if position.x < -half_size.x or position.x > rect.size.x + half_size.x or position.y < -half_size.y or position.y > rect.size.y + half_size.y:
|
if position.x < -half_size.x or position.x > rect.size.x + half_size.x or position.y < -half_size.y or position.y > rect.size.y + half_size.y:
|
||||||
#print_debug("FREED")
|
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
func _on_body_entered(body):
|
func _on_body_entered(body):
|
||||||
if body.is_in_group("enemies"):
|
if body.is_in_group("enemies"):
|
||||||
body.queue_free()
|
body.hit()
|
||||||
|
|
||||||
Utils.play_sound(pop, get_parent())
|
|
||||||
|
|
||||||
var boom = explosion.instantiate()
|
|
||||||
boom.position = body.global_position
|
|
||||||
boom.scale = body.scale
|
|
||||||
get_parent().add_child(boom)
|
|
||||||
|
|
||||||
Game.set_score(Game.score + 100)
|
|
||||||
|
|
||||||
queue_free()
|
queue_free()
|
||||||
#print_debug("KILLED")
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
signal new_game
|
signal new_game
|
||||||
|
signal credits
|
||||||
signal quit_game
|
signal quit_game
|
||||||
|
|
||||||
func _ready():
|
func _ready() -> void:
|
||||||
$"Container/New Game".pressed.connect(_emit_new)
|
var buttons = {
|
||||||
$Container/Quit.pressed.connect(_emit_quit)
|
"New Game": "new_game",
|
||||||
|
"Credits": "credits",
|
||||||
func _emit_new():
|
"Quit": "quit_game",
|
||||||
emit_signal("new_game")
|
}
|
||||||
|
|
||||||
func _emit_quit():
|
for btn_name in buttons.keys():
|
||||||
emit_signal("quit_game")
|
var btn = $Container/ButtonContainer.get_node(btn_name)
|
||||||
|
btn.pressed.connect(func(): emit_signal(buttons[btn_name]))
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,21 @@
|
||||||
extends CharacterBody2D
|
extends CharacterBody2D
|
||||||
|
|
||||||
const ROT_SPEED = 3.0
|
const ROT_SPEED = 4.0
|
||||||
const MOVE_ACC = 100
|
const MOVE_ACC = 120
|
||||||
const FRICTION = 0.995
|
const FRICTION = 0.995
|
||||||
const FIRE_RATE = 0.2
|
const FIRE_RATE = 0.2
|
||||||
|
const INV_FLASH_INT = 0.1
|
||||||
|
|
||||||
@export var Laser: PackedScene
|
@export var Laser: PackedScene
|
||||||
@export var pew: Resource
|
@export var pew: Resource
|
||||||
|
|
||||||
var speed = Vector2(0, 0)
|
var speed = Vector2(0, 0)
|
||||||
var last_shot = 0.0
|
var last_shot = 0.0
|
||||||
|
var last_flash = 0.0
|
||||||
|
var inv_time = 0.0
|
||||||
|
|
||||||
|
var explosion = preload('res://Scenes/explosion.tscn')
|
||||||
|
var pop = preload("res://Sounds/Explosion5.wav")
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
Game.player = self
|
Game.player = self
|
||||||
|
|
@ -47,6 +53,15 @@ func _physics_process(delta: float) -> void:
|
||||||
|
|
||||||
Utils.wrap_position(self)
|
Utils.wrap_position(self)
|
||||||
|
|
||||||
|
if is_invincible():
|
||||||
|
inv_time -= delta
|
||||||
|
last_flash += delta
|
||||||
|
if last_flash >= INV_FLASH_INT:
|
||||||
|
$AnimatedSprite2D.visible = !$AnimatedSprite2D.visible
|
||||||
|
last_flash = 0.0
|
||||||
|
else:
|
||||||
|
$AnimatedSprite2D.visible = true
|
||||||
|
|
||||||
# --- Fire projectile on space ---
|
# --- Fire projectile on space ---
|
||||||
last_shot += delta
|
last_shot += delta
|
||||||
if Input.is_action_pressed("ui_accept") and last_shot >= FIRE_RATE: # default = Space/Enter
|
if Input.is_action_pressed("ui_accept") and last_shot >= FIRE_RATE: # default = Space/Enter
|
||||||
|
|
@ -58,6 +73,25 @@ func _physics_process(delta: float) -> void:
|
||||||
bullet.transform = $Muzzle.global_transform
|
bullet.transform = $Muzzle.global_transform
|
||||||
last_shot = 0.0
|
last_shot = 0.0
|
||||||
|
|
||||||
func reset():
|
func die():
|
||||||
position = get_viewport_rect().size / 2
|
position = get_viewport_rect().size / 2
|
||||||
speed = Vector2(0, 0)
|
speed = Vector2(0, 0)
|
||||||
|
inv_time = 3.0
|
||||||
|
|
||||||
|
func is_invincible():
|
||||||
|
return inv_time > 0
|
||||||
|
|
||||||
|
func hit() -> bool:
|
||||||
|
if !is_invincible():
|
||||||
|
Game.set_lives(Game.lives - 1)
|
||||||
|
|
||||||
|
Utils.play_sound(pop, get_parent())
|
||||||
|
|
||||||
|
var boom = explosion.instantiate()
|
||||||
|
boom.position = global_position
|
||||||
|
boom.scale = Vector2(6, 6)
|
||||||
|
get_parent().add_child(boom)
|
||||||
|
die()
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ func _ready():
|
||||||
add_child(timer)
|
add_child(timer)
|
||||||
|
|
||||||
func spawn_time_from_score(score: int) -> float:
|
func spawn_time_from_score(score: int) -> float:
|
||||||
var min_time = 0.3
|
var min_time = 0.2
|
||||||
var max_time = 2.0
|
var max_time = 1.5
|
||||||
var max_score = 50000.0
|
var max_score = 100000.0
|
||||||
|
|
||||||
# Clamp score so it doesn’t overshoot
|
# Clamp score so it doesn’t overshoot
|
||||||
var clamped_score = clamp(score, 0, max_score)
|
var clamped_score = clamp(score, 0, max_score)
|
||||||
|
|
@ -38,44 +38,46 @@ func spawn_time_from_score(score: int) -> float:
|
||||||
return lerp(max_time, min_time, curved_t)
|
return lerp(max_time, min_time, curved_t)
|
||||||
|
|
||||||
func spawn_enemy():
|
func spawn_enemy():
|
||||||
var enemy = asteroids[randi_range(0, 3)].instantiate()
|
var idx = randi_range(0, 3)
|
||||||
var pos = get_random_edge_position()
|
var enemy = asteroids[idx].instantiate()
|
||||||
enemy.position = pos
|
|
||||||
|
|
||||||
# Direction vector toward center
|
# Direction vector toward center
|
||||||
var center = screen_size * 0.5
|
var center = screen_size * 0.5
|
||||||
|
|
||||||
|
enemy.rot_velocity = randf_range(-PI, PI)
|
||||||
|
enemy.rotation = randf_range(0, PI)
|
||||||
|
|
||||||
|
var scl = randi_range(2 + idx, 5 + 3*idx)
|
||||||
|
enemy.scale = Vector2(scl, scl)
|
||||||
|
|
||||||
|
var pos = get_random_edge_position(Utils.get_half_size(enemy))
|
||||||
var dir = (center - pos).normalized()
|
var dir = (center - pos).normalized()
|
||||||
|
|
||||||
# Add some randomness so it's not always perfect
|
# Add some randomness so it's not always perfect
|
||||||
var angle_variation = randf_range(-0.5, 0.5) # radians (~±14 degrees)
|
var angle_variation = randf_range(-0.5, 0.5) # radians (~±14 degrees)
|
||||||
dir = dir.rotated(angle_variation)
|
dir = dir.rotated(angle_variation)
|
||||||
|
|
||||||
# Apply starting velocity
|
enemy.velocity = dir * randf_range(75, 250)
|
||||||
enemy.rot_velocity = randf_range(0, PI)
|
enemy.position = pos
|
||||||
enemy.velocity = dir * randf_range(50, 200)
|
|
||||||
enemy.rotation = randf_range(0, PI)
|
|
||||||
|
|
||||||
var scl = randi_range(1, 5)
|
|
||||||
enemy.scale = Vector2(scl, scl)
|
|
||||||
|
|
||||||
enemy.add_to_group("enemies")
|
enemy.add_to_group("enemies")
|
||||||
add_child(enemy)
|
add_child(enemy)
|
||||||
|
|
||||||
timer.wait_time = spawn_time_from_score(Game.score)
|
timer.wait_time = spawn_time_from_score(Game.score)
|
||||||
|
|
||||||
func get_random_edge_position() -> Vector2:
|
func get_random_edge_position(half_size: Vector2) -> Vector2:
|
||||||
# Pick which edge (0=top,1=bottom,2=left,3=right)
|
# Pick which edge (0=top,1=bottom,2=left,3=right)
|
||||||
var edge = randi() % 4
|
var edge = randi() % 4
|
||||||
match edge:
|
match edge:
|
||||||
0: # top
|
0: # top
|
||||||
return Vector2(randf() * screen_size.x, 0)
|
return Vector2(randf() * screen_size.x, -half_size.y)
|
||||||
1: # bottom
|
1: # bottom
|
||||||
return Vector2(randf() * screen_size.x, screen_size.y)
|
return Vector2(randf() * screen_size.x, screen_size.y + half_size.y)
|
||||||
2: # left
|
2: # left
|
||||||
return Vector2(0, randf() * screen_size.y)
|
return Vector2(-half_size.x, randf() * screen_size.y)
|
||||||
3: # right
|
3: # right
|
||||||
return Vector2(screen_size.x, randf() * screen_size.y)
|
return Vector2(screen_size.x + half_size.x, randf() * screen_size.y)
|
||||||
return Vector2.ZERO
|
return Vector2.ZERO
|
||||||
|
|
||||||
|
|
||||||
func stop():
|
func stop():
|
||||||
timer.stop()
|
timer.stop()
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,34 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
func get_half_size(sprt: Node2D):
|
func get_half_size(node: Node2D) -> Vector2:
|
||||||
var half_size: Vector2
|
var tex_size := Vector2.ZERO
|
||||||
|
var sprite: Node2D = null
|
||||||
if sprt is Sprite2D:
|
|
||||||
half_size = (sprt.texture.get_size() * sprt.scale) / 2.0
|
# Try to find a Sprite2D or AnimatedSprite2D child
|
||||||
elif sprt is AnimatedSprite2D:
|
if node is Sprite2D or node is AnimatedSprite2D:
|
||||||
var tex: Texture2D = sprt.sprite_frames.get_frame_texture(sprt.animation, 0)
|
sprite = node
|
||||||
if tex:
|
|
||||||
half_size = (tex.get_size() * sprt.scale) / 2.0
|
|
||||||
else:
|
|
||||||
half_size = Vector2.ZERO
|
|
||||||
else:
|
else:
|
||||||
half_size = Vector2.ZERO
|
for child in node.get_children():
|
||||||
|
if child is Sprite2D or child is AnimatedSprite2D:
|
||||||
return half_size
|
sprite = child
|
||||||
|
break
|
||||||
|
|
||||||
|
if sprite == null:
|
||||||
|
return Vector2.ZERO
|
||||||
|
|
||||||
|
# Get texture size
|
||||||
|
if sprite is Sprite2D:
|
||||||
|
if sprite.texture:
|
||||||
|
tex_size = sprite.texture.get_size()
|
||||||
|
elif sprite is AnimatedSprite2D:
|
||||||
|
var tex: Texture2D = sprite.sprite_frames.get_frame_texture(sprite.animation, 0)
|
||||||
|
if tex:
|
||||||
|
tex_size = tex.get_size()
|
||||||
|
|
||||||
|
# Combine parent scaling (global scale includes both)
|
||||||
|
var global_scl = sprite.get_global_transform().get_scale()
|
||||||
|
|
||||||
|
return (tex_size * global_scl) * 0.5
|
||||||
|
|
||||||
func wrap_position(node: Node2D) -> void:
|
func wrap_position(node: Node2D) -> void:
|
||||||
var rect = node.get_viewport_rect()
|
var rect = node.get_viewport_rect()
|
||||||
|
|
|
||||||
BIN
Sprites/icon.png
Normal file
BIN
Sprites/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
40
Sprites/icon.png.import
Normal file
40
Sprites/icon.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dr3obrh68kktx"
|
||||||
|
path="res://.godot/imported/icon.png-f9ba9008f31679cd240e2c5f33a9a4fb.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Sprites/icon.png"
|
||||||
|
dest_files=["res://.godot/imported/icon.png-f9ba9008f31679cd240e2c5f33a9a4fb.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
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/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
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
|
||||||
|
|
@ -23,7 +23,7 @@ script_export_mode=2
|
||||||
custom_template/debug=""
|
custom_template/debug=""
|
||||||
custom_template/release=""
|
custom_template/release=""
|
||||||
debug/export_console_wrapper=1
|
debug/export_console_wrapper=1
|
||||||
binary_format/embed_pck=false
|
binary_format/embed_pck=true
|
||||||
texture_format/s3tc_bptc=true
|
texture_format/s3tc_bptc=true
|
||||||
texture_format/etc2_astc=false
|
texture_format/etc2_astc=false
|
||||||
shader_baker/enabled=false
|
shader_baker/enabled=false
|
||||||
|
|
@ -66,7 +66,7 @@ script_export_mode=2
|
||||||
custom_template/debug=""
|
custom_template/debug=""
|
||||||
custom_template/release=""
|
custom_template/release=""
|
||||||
debug/export_console_wrapper=1
|
debug/export_console_wrapper=1
|
||||||
binary_format/embed_pck=false
|
binary_format/embed_pck=true
|
||||||
texture_format/s3tc_bptc=true
|
texture_format/s3tc_bptc=true
|
||||||
texture_format/etc2_astc=false
|
texture_format/etc2_astc=false
|
||||||
shader_baker/enabled=false
|
shader_baker/enabled=false
|
||||||
|
|
@ -78,7 +78,7 @@ codesign/digest_algorithm=1
|
||||||
codesign/description=""
|
codesign/description=""
|
||||||
codesign/custom_options=PackedStringArray()
|
codesign/custom_options=PackedStringArray()
|
||||||
application/modify_resources=true
|
application/modify_resources=true
|
||||||
application/icon=""
|
application/icon="uid://dr3obrh68kktx"
|
||||||
application/console_wrapper_icon=""
|
application/console_wrapper_icon=""
|
||||||
application/icon_interpolation=4
|
application/icon_interpolation=4
|
||||||
application/file_version=""
|
application/file_version=""
|
||||||
|
|
|
||||||
23
main.tscn
23
main.tscn
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=7 format=3 uid="uid://cmlg48m6buclv"]
|
[gd_scene load_steps=6 format=3 uid="uid://cmlg48m6buclv"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cuqofgxmpn2fu" path="res://Sprites/space.png" id="1_7mycd"]
|
[ext_resource type="Texture2D" uid="uid://cuqofgxmpn2fu" path="res://Sprites/space.png" id="1_7mycd"]
|
||||||
[ext_resource type="Script" uid="uid://dpa4j6me328ak" path="res://Scripts/ui.gd" id="2_272bh"]
|
[ext_resource type="Script" uid="uid://dpa4j6me328ak" path="res://Scripts/ui.gd" id="2_272bh"]
|
||||||
|
|
@ -6,8 +6,6 @@
|
||||||
[ext_resource type="Script" uid="uid://mfgrqlsgsyrx" path="res://Scripts/spawner.gd" id="4_1bvp3"]
|
[ext_resource type="Script" uid="uid://mfgrqlsgsyrx" path="res://Scripts/spawner.gd" id="4_1bvp3"]
|
||||||
[ext_resource type="Script" uid="uid://miwfeu4n6uh7" path="res://Scripts/lives.gd" id="4_kek77"]
|
[ext_resource type="Script" uid="uid://miwfeu4n6uh7" path="res://Scripts/lives.gd" id="4_kek77"]
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_7mycd"]
|
|
||||||
|
|
||||||
[node name="Node2D" type="Node2D"]
|
[node name="Node2D" type="Node2D"]
|
||||||
|
|
||||||
[node name="Background" type="TextureRect" parent="."]
|
[node name="Background" type="TextureRect" parent="."]
|
||||||
|
|
@ -20,25 +18,24 @@ stretch_mode = 1
|
||||||
script = ExtResource("2_272bh")
|
script = ExtResource("2_272bh")
|
||||||
|
|
||||||
[node name="Score" type="Label" parent="UI"]
|
[node name="Score" type="Label" parent="UI"]
|
||||||
visible = false
|
|
||||||
anchors_preset = 1
|
anchors_preset = 1
|
||||||
anchor_left = 1.0
|
anchor_left = 1.0
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
offset_left = -66.0
|
offset_left = -102.0
|
||||||
offset_top = 2.0
|
offset_top = 10.0
|
||||||
offset_right = -5.0
|
offset_right = -11.0
|
||||||
offset_bottom = 25.0
|
offset_bottom = 44.0
|
||||||
grow_horizontal = 0
|
grow_horizontal = 0
|
||||||
text = "Score: 0"
|
text = "Score: 0"
|
||||||
label_settings = SubResource("LabelSettings_7mycd")
|
|
||||||
horizontal_alignment = 2
|
horizontal_alignment = 2
|
||||||
script = ExtResource("3_5vw27")
|
script = ExtResource("3_5vw27")
|
||||||
|
|
||||||
[node name="Lives" type="HBoxContainer" parent="UI"]
|
[node name="Lives" type="HBoxContainer" parent="UI"]
|
||||||
offset_left = 6.0
|
offset_left = 15.0
|
||||||
offset_top = 6.0
|
offset_top = 15.0
|
||||||
offset_right = 46.0
|
offset_right = 199.0
|
||||||
offset_bottom = 46.0
|
offset_bottom = 108.0
|
||||||
|
theme_override_constants/separation = 10
|
||||||
script = ExtResource("4_kek77")
|
script = ExtResource("4_kek77")
|
||||||
|
|
||||||
[node name="Spawner" type="Node2D" parent="."]
|
[node name="Spawner" type="Node2D" parent="."]
|
||||||
|
|
|
||||||
1345
main_theme.tres
Normal file
1345
main_theme.tres
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -22,7 +22,10 @@ Utils="*res://Scripts/utils.gd"
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
window/stretch/mode="viewport"
|
window/stretch/mode="viewport"
|
||||||
window/stretch/scale=1.5
|
|
||||||
|
[gui]
|
||||||
|
|
||||||
|
theme/custom="uid://bxhc76qakpr7r"
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue