codeberg copy

This commit is contained in:
CatAClock 2025-04-15 12:00:09 -07:00
commit d177f1f71a
50 changed files with 325906 additions and 0 deletions

10
.gitignore vendored Normal file
View file

@ -0,0 +1,10 @@
# Godot 4+ specific ignores
demo/.godot/
demo/android/
demo/**/*.import
# Other bullshit
.sconsign.dblite
*.o
*.a
*.os

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "godot-cpp"]
path = godot-cpp
url = https://github.com/godotengine/godot-cpp.git
branch = 4.3

121
LICENSE.md Normal file
View file

@ -0,0 +1,121 @@
# PolyForm Small Business License 1.0.0
<https://polyformproject.org/licenses/small-business/1.0.0>
## Acceptance
In order to get any license under these terms, you must agree
to them as both strict obligations and conditions to all
your licenses.
## Copyright License
The licensor grants you a copyright license for the
software to do everything you might do with the software
that would otherwise infringe the licensor's copyright
in it for any permitted purpose. However, you may
only distribute the software according to [Distribution
License](#distribution-license) and make changes or new works
based on the software according to [Changes and New Works
License](#changes-and-new-works-license).
## Distribution License
The licensor grants you an additional copyright license
to distribute copies of the software. Your license
to distribute covers distributing the software with
changes and new works permitted by [Changes and New Works
License](#changes-and-new-works-license).
## Notices
You must ensure that anyone who gets a copy of any part of
the software from you also gets a copy of these terms or the
URL for them above, as well as copies of any plain-text lines
beginning with `Required Notice:` that the licensor provided
with the software. For example:
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
## Changes and New Works License
The licensor grants you an additional copyright license to
make changes and new works based on the software for any
permitted purpose.
## Patent License
The licensor grants you a patent license for the software that
covers patent claims the licensor can license, or becomes able
to license, that you would infringe by using the software.
## Fair Use
You may have "fair use" rights for the software under the
law. These terms do not limit them.
## Small Business
Use of the software for the benefit of your company is use for
a permitted purpose if your company has fewer than 100 total
individuals working as employees and independent contractors,
and less than 1,000,000 USD (2019) total revenue in the prior
tax year. Adjust this revenue threshold for inflation according
to the United States Bureau of Labor Statistics' consumer price
index for all urban consumers, U.S. city average, for all items,
not seasonally adjusted, with 1982–1984=100 reference base.
## No Other Rights
These terms do not allow you to sublicense or transfer any of
your licenses to anyone else, or prevent the licensor from
granting licenses to anyone else. These terms do not imply
any other licenses.
## Patent Defense
If you make any written claim that the software infringes or
contributes to infringement of any patent, your patent license
for the software granted under these terms ends immediately. If
your company makes such a claim, your patent license ends
immediately for work on behalf of your company.
## Violations
The first time you are notified in writing that you have
violated any of these terms, or done anything with the software
not covered by your licenses, your licenses can nonetheless
continue if you come into full compliance with these terms,
and take practical steps to correct past violations, within
32 days of receiving notice. Otherwise, all your licenses
end immediately.
## No Liability
***As far as the law allows, the software comes as is, without
any warranty or condition, and the licensor will not be liable
to you for any damages arising out of these terms or the use
or nature of the software, under any kind of legal claim.***
## Definitions
The **licensor** is the individual or entity offering these
terms, and the **software** is the software the licensor makes
available under these terms.
**You** refers to the individual or entity agreeing to these
terms.
**Your company** is any legal entity, sole proprietorship,
or other kind of organization that you work for, plus all
organizations that have control over, are under the control of,
or are under common control with that organization. **Control**
means ownership of substantially all the assets of an entity,
or the power to direct its management and policies by vote,
contract, or otherwise. Control can be direct or indirect.
**Your licenses** are all the licenses granted to you for the
software under these terms.
**Use** means anything you do with the software requiring one
of your licenses.

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# template
yeah

25
SConstruct Normal file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env python
import os
import sys
env = SConscript("godot-cpp/SConstruct")
# For reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
# - CXXFLAGS are for C++-specific compilation flags
# - CPPFLAGS are for pre-processor flags
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags
# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=["src/"])
sources = Glob("src/*.cpp")
try:
Documentation = env.GodotCPPDocData("src/gen/doc_data.gen.cpp", source=Glob("docs/*.xml"))
sources.append(Documentation)
except AttributeError:
print("Dear friends! Make sure to have Godot Engine be 4.4 or higher for integrated documentation!")
Default(env.SharedLibrary("demo/bin/TwinStick2DShootEmUp{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),source=sources,))

View file

@ -0,0 +1,6 @@
extends Area2D
func _on_body_entered(body):
if body.is_in_group("Player"):
body.get_parent().Coin += 1
self.queue_free()

View file

@ -0,0 +1 @@
uid://cgvfc7ffnfyir

View file

@ -0,0 +1,27 @@
[gd_scene load_steps=6 format=3 uid="uid://c16xjmwoohnsq"]
[ext_resource type="Script" uid="uid://cgvfc7ffnfyir" path="res://Godot/collectible.gd" id="1_dyylg"]
[sub_resource type="SphereMesh" id="SphereMesh_5ikb6"]
[sub_resource type="Gradient" id="Gradient_bioww"]
colors = PackedColorArray(1, 1, 0, 1, 1, 0.870588, 0, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_35tu8"]
gradient = SubResource("Gradient_bioww")
[sub_resource type="CircleShape2D" id="CircleShape2D_5u2yj"]
[node name="Collectible" type="Area2D"]
script = ExtResource("1_dyylg")
[node name="MeshInstance2D" type="MeshInstance2D" parent="."]
position = Vector2(-8.9407e-07, 2.02656e-06)
scale = Vector2(20.0227, 20)
mesh = SubResource("SphereMesh_5ikb6")
texture = SubResource("GradientTexture2D_35tu8")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_5u2yj")
[connection signal="body_entered" from="." to="." method="_on_body_entered"]

10
demo/Godot/main_scene.gd Normal file
View file

@ -0,0 +1,10 @@
extends Node2D
var Score = 0
var Coin = 0
func _process(_delta):
get_node("Score").text = "Score: " + str(Score) + "\nCoins: " + str(Coin)
func ScoreAdd(score):
Score += score

View file

@ -0,0 +1 @@
uid://cr4csxl0khabs

143
demo/Godot/main_scene.tscn Normal file
View file

@ -0,0 +1,143 @@
[gd_scene load_steps=16 format=3 uid="uid://dyqku4b80noy4"]
[ext_resource type="Script" uid="uid://cr4csxl0khabs" path="res://Godot/main_scene.gd" id="1_6ltk3"]
[ext_resource type="Texture2D" uid="uid://cgrc7fd8xohcm" path="res://Non-Godot/Temp.png" id="2_g3lig"]
[ext_resource type="AudioStream" uid="uid://byodmf0g5kw64" path="res://Non-Godot/Poof.wav" id="2_mthls"]
[ext_resource type="Texture2D" uid="uid://dxyo0qx6sfvhr" path="res://Non-Godot/Player.png" id="2_t4ro5"]
[ext_resource type="AudioStream" uid="uid://crkpiw57ipdgi" path="res://Non-Godot/Player_Kill.wav" id="3_lee88"]
[ext_resource type="AudioStream" uid="uid://7rnng3yryqfd" path="res://Non-Godot/Hurt.wav" id="3_mthls"]
[ext_resource type="Texture2D" uid="uid://bw7liao61jovj" path="res://Non-Godot/Bullet.png" id="4_ju4ic"]
[ext_resource type="Script" uid="uid://dwu85q6q3wft7" path="res://Godot/spawner.gd" id="5_lee88"]
[ext_resource type="Script" uid="uid://dxqphakp0wvj7" path="res://Godot/player.gd" id="5_lttqn"]
[ext_resource type="Script" uid="uid://cvg673gajpuhs" path="res://Godot/spawner_item.gd" id="6_1d8q1"]
[ext_resource type="PackedScene" uid="uid://c16xjmwoohnsq" path="res://Godot/collectible.tscn" id="7_k2rys"]
[ext_resource type="PackedScene" uid="uid://bsu8nbvtd4bvq" path="res://Godot/powerable.tscn" id="8_i64o6"]
[sub_resource type="Gradient" id="Gradient_t4ro5"]
colors = PackedColorArray(1, 1, 0, 1, 0, 0, 0, 0)
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_7qtk0"]
[sub_resource type="BoxMesh" id="BoxMesh_eii8h"]
size = Vector3(1000, 20, 1)
[node name="Main Scene" type="Node2D"]
script = ExtResource("1_6ltk3")
[node name="Score" type="Label" parent="."]
top_level = true
offset_left = 340.0
offset_top = 349.0
offset_right = 428.0
offset_bottom = 436.0
theme_override_font_sizes/font_size = 30
text = "Score:
Coins:"
horizontal_alignment = 1
[node name="Player" type="Player" parent="." groups=["Player"]]
ShootPoofSound = ExtResource("2_mthls")
ShootHitSound = ExtResource("3_mthls")
ShootBulletTexture = ExtResource("4_ju4ic")
DragsTexture = ExtResource("2_t4ro5")
DragsDeathAudio = ExtResource("3_lee88")
DragsDeathParticles = SubResource("Gradient_t4ro5")
InputLeft = &"Left"
InputUp = &"Up"
InputRight = &"Right"
InputDown = &"Down"
InputShoot = &"Shoot"
InputRespawn = &"Respawn"
position = Vector2(375, 396)
scale = Vector2(1.5, 1.5)
script = ExtResource("5_lttqn")
[node name="Spawner" type="Spawner" parent="."]
SizeX = 2.0
SizeY = 2.0
position = Vector2(23, -23)
script = ExtResource("5_lee88")
tex = ExtResource("2_g3lig")
[node name="Spawner2" type="Spawner" parent="."]
TimerRandomization = true
SizeX = 2.0
SizeY = 2.0
position = Vector2(793, -27)
script = ExtResource("5_lee88")
tex = ExtResource("2_g3lig")
[node name="Spawner3" type="Spawner" parent="."]
TimerRandomization = true
SizeX = 8.0
SizeY = 8.0
position = Vector2(35, 762)
script = ExtResource("5_lee88")
Size = 1.5
Health = 3
Value = 3
tex = ExtResource("2_g3lig")
[node name="Spawner4" type="Spawner" parent="."]
SpawnInterval = 1.0
position = Vector2(803, 820)
script = ExtResource("5_lee88")
tex = ExtResource("2_g3lig")
[node name="CollectSpawner" type="Spawner" parent="."]
SizeX = 400.0
SizeY = 400.0
position = Vector2(384, 397)
script = ExtResource("6_1d8q1")
Coin = ExtResource("7_k2rys")
PowerUp = ExtResource("8_i64o6")
[node name="Object" type="StaticBody2D" parent="."]
position = Vector2(417, 905)
[node name="CollisionShape2D" type="CollisionShape2D" parent="Object"]
position = Vector2(0, -9)
shape = SubResource("WorldBoundaryShape2D_7qtk0")
[node name="MeshInstance2D" type="MeshInstance2D" parent="Object"]
mesh = SubResource("BoxMesh_eii8h")
[node name="Object2" type="StaticBody2D" parent="."]
position = Vector2(-73, 395)
rotation = 1.5708
[node name="CollisionShape2D" type="CollisionShape2D" parent="Object2"]
position = Vector2(0, -9)
shape = SubResource("WorldBoundaryShape2D_7qtk0")
[node name="MeshInstance2D" type="MeshInstance2D" parent="Object2"]
mesh = SubResource("BoxMesh_eii8h")
[node name="Object3" type="StaticBody2D" parent="."]
position = Vector2(417, -115)
rotation = 3.14159
[node name="CollisionShape2D" type="CollisionShape2D" parent="Object3"]
position = Vector2(0, -9)
shape = SubResource("WorldBoundaryShape2D_7qtk0")
[node name="MeshInstance2D" type="MeshInstance2D" parent="Object3"]
mesh = SubResource("BoxMesh_eii8h")
[node name="Object4" type="StaticBody2D" parent="."]
position = Vector2(907, 395)
rotation = -1.5708
[node name="CollisionShape2D" type="CollisionShape2D" parent="Object4"]
position = Vector2(0, -9)
shape = SubResource("WorldBoundaryShape2D_7qtk0")
[node name="MeshInstance2D" type="MeshInstance2D" parent="Object4"]
mesh = SubResource("BoxMesh_eii8h")
[connection signal="Respawn" from="Player" to="Player" method="_on_respawn"]
[connection signal="Spawn" from="Spawner" to="Spawner" method="_on_spawn"]
[connection signal="Spawn" from="Spawner2" to="Spawner2" method="_on_spawn"]
[connection signal="Spawn" from="Spawner3" to="Spawner3" method="_on_spawn"]
[connection signal="Spawn" from="Spawner4" to="Spawner4" method="_on_spawn"]
[connection signal="Spawn" from="CollectSpawner" to="CollectSpawner" method="_on_spawn"]

4
demo/Godot/player.gd Normal file
View file

@ -0,0 +1,4 @@
extends Player
func _on_respawn() -> void:
get_tree().reload_current_scene()

1
demo/Godot/player.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://dxqphakp0wvj7

6
demo/Godot/powerable.gd Normal file
View file

@ -0,0 +1,6 @@
extends Area2D
func _on_body_entered(body):
if body.is_in_group("Player"):
body.SetPowerUp(0);
self.queue_free()

View file

@ -0,0 +1 @@
uid://bffgf4c382pwy

27
demo/Godot/powerable.tscn Normal file
View file

@ -0,0 +1,27 @@
[gd_scene load_steps=6 format=3 uid="uid://bsu8nbvtd4bvq"]
[ext_resource type="Script" uid="uid://bffgf4c382pwy" path="res://Godot/powerable.gd" id="1_w7icu"]
[sub_resource type="SphereMesh" id="SphereMesh_5ikb6"]
[sub_resource type="Gradient" id="Gradient_c6ss2"]
colors = PackedColorArray(0.111197, 0.111197, 0.111197, 1, 0.180392, 1, 0.152941, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_frole"]
gradient = SubResource("Gradient_c6ss2")
[sub_resource type="CircleShape2D" id="CircleShape2D_5u2yj"]
[node name="Powerable" type="Area2D"]
script = ExtResource("1_w7icu")
[node name="MeshInstance2D" type="MeshInstance2D" parent="."]
position = Vector2(-8.9407e-07, 2.02656e-06)
scale = Vector2(20.0227, 20)
mesh = SubResource("SphereMesh_5ikb6")
texture = SubResource("GradientTexture2D_frole")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_5u2yj")
[connection signal="body_entered" from="." to="." method="_on_body_entered"]

19
demo/Godot/spawner.gd Normal file
View file

@ -0,0 +1,19 @@
extends Spawner
@export var Size: float = 1
@export var Health: int = 1
@export var Value: int = 1
@export var tex: Texture2D
func _on_spawn():
var temp = Enemy.new()
temp.global_position = self.global_position + Vector2(randf_range(-GetSizeX(), GetSizeX()), randf_range(-GetSizeY(), GetSizeY()))
temp.VariableHealth = Health
temp.DragsAudio = ResourceLoader.load("res://Non-Godot/Kill.wav")
temp.VariableScoreValue = Value
temp.scale = Vector2(Size, Size);
temp.connect("AddScore", Callable(get_parent(), "ScoreAdd"))
temp.add_to_group("Enemy")
# The randomization at the end is so that way the collisions don't go fucky wucky
temp.DragsTexture = tex
add_sibling(temp)

View file

@ -0,0 +1 @@
uid://dwu85q6q3wft7

View file

@ -0,0 +1,20 @@
extends Spawner
@export var Coin: PackedScene
@export var PowerUp: PackedScene
@export var power_spawn_rate: float = 20
var power_timer: float = 0
func _process(delta: float) -> void:
power_timer += delta
func _on_spawn() -> void:
var temp = Coin.instantiate()
temp.position = self.position + Vector2(randf_range(-GetSizeX(), GetSizeX()), randf_range(-GetSizeY(), GetSizeY()))
add_sibling.call_deferred(temp)
if power_timer >= power_spawn_rate:
power_timer = 0
temp = PowerUp.instantiate()
temp.position = self.position + Vector2(randf_range(-GetSizeX(), GetSizeX()), randf_range(-GetSizeY(), GetSizeY()))
add_sibling.call_deferred(temp)

View file

@ -0,0 +1 @@
uid://cvg673gajpuhs

BIN
demo/Non-Godot/Bullet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

BIN
demo/Non-Godot/Hurt.wav Normal file

Binary file not shown.

BIN
demo/Non-Godot/Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
demo/Non-Godot/Kill.wav Normal file

Binary file not shown.

BIN
demo/Non-Godot/Player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

BIN
demo/Non-Godot/Poof.wav Normal file

Binary file not shown.

BIN
demo/Non-Godot/Temp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

View file

@ -0,0 +1,18 @@
[configuration]
entry_symbol = "LibraryInit"
compatibility_minimum = "4.1"
reloadable = true
[libraries]
windows.debug.x86_32 = "res://bin/libTwinStick2DShootEmUp.windows.template_debug.x86_32.dll"
windows.release.x86_32 = "res://bin/libTwinStick2DShootEmUp.windows.template_release.x86_32.dll"
windows.debug.x86_64 = "res://bin/libTwinStick2DShootEmUp.windows.template_debug.x86_64.dll"
windows.release.x86_64 = "res://bin/libTwinStick2DShootEmUp.windows.template_release.x86_64.dll"
linux.debug.x86_64 = "res://bin/libTwinStick2DShootEmUp.linux.template_debug.x86_64.so"
linux.release.x86_64 = "res://bin/libTwinStick2DShootEmUp.linux.template_release.x86_64.so"
linux.debug.arm64 = "res://bin/libTwinStick2DShootEmUp.linux.template_debug.arm64.so"
linux.release.arm64 = "res://bin/libTwinStick2DShootEmUp.linux.template_release.arm64.so"
linux.debug.rv64 = "res://bin/libTwinStick2DShootEmUp.linux.template_debug.rv64.so"
linux.release.rv64 = "res://bin/libTwinStick2DShootEmUp.linux.template_release.rv64.so"

View file

@ -0,0 +1 @@
uid://cbf87lkammw1x

View file

@ -0,0 +1,4 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://d15xa45h2iaci"]
[resource]
bus/0/volume_db = -9.63278

108
demo/export_presets.cfg Normal file
View file

@ -0,0 +1,108 @@
[preset.0]
name="Linux/X11"
platform="Linux/X11"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../../../Linux Final/2d-shoot-em-up.x86_64"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_encryption_key=""
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_script=1
binary_format/embed_pck=true
texture_format/bptc=false
texture_format/s3tc=true
texture_format/etc=false
texture_format/etc2=false
texture_format/no_bptc_fallbacks=true
binary_format/architecture="x86_64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
export DISPLAY=:0
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
\"{temp_dir}/{exe_name}\" {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""
[preset.1]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../../../Windows Final/2d-shoot-em-up.exe"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_encryption_key=""
[preset.1.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_script=1
binary_format/embed_pck=false
texture_format/bptc=false
texture_format/s3tc=true
texture_format/etc=false
texture_format/etc2=false
texture_format/no_bptc_fallbacks=true
binary_format/architecture="x86_64"
codesign/enable=false
codesign/identity_type=0
codesign/identity=""
codesign/password=""
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"

77
demo/project.godot Normal file
View file

@ -0,0 +1,77 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Demo: Twin Stick 2D Shoot Em Up"
run/main_scene="res://Godot/main_scene.tscn"
config/features=PackedStringArray("4.4", "Forward Plus")
boot_splash/image="res://Non-Godot/Icon.png"
config/icon="uid://ygdyfxjgeibr"
[display]
window/size/viewport_width=800
window/size/viewport_height=800
[dotnet]
project/assembly_name="2d-shoot-em-up"
[editor]
version_control/plugin_name="Git"
[filesystem]
import/blender/enabled=false
[global_group]
Player=""
Enemy=""
[input]
Shoot={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
Respawn={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
Up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
]
}
Left={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
Right={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
]
}
Down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
]
}
[physics]
common/physics_ticks_per_second=90
common/max_physics_steps_per_frame=10

17
docs/Bullet.xml Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Bullet" inherits="Area2D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/godotengine/godot/master/doc/class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
</members>
<signals>
</signals>
<constants>
</constants>
</class>

17
docs/Enemy.xml Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Enemy" inherits="CharacterBody2D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/godotengine/godot/master/doc/class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
</members>
<signals>
</signals>
<constants>
</constants>
</class>

22
docs/Player.xml Normal file
View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Player" inherits="CharacterBody2D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/godotengine/godot/master/doc/class.xsd">
<brief_description>
The main player character for the Twin Stick Shooter
</brief_description>
<description>
The complete player character for all player functions.
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="VariableSpeed" type="Float" setter="SetSpeed" getter="GetSpeed">
The speed of the character.
</member>
</members>
<signals>
</signals>
<constants>
</constants>
</class>

17
docs/Spawner.xml Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Spawner" inherits="Marker2D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/godotengine/godot/master/doc/class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
</members>
<signals>
</signals>
<constants>
</constants>
</class>

323821
extension_api.json Normal file

File diff suppressed because it is too large Load diff

117
src/Bullet.cpp Normal file
View file

@ -0,0 +1,117 @@
#include "Bullet.hpp"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/property_info.hpp>
#include <godot_cpp/core/memory.hpp>
#include <godot_cpp/classes/collision_shape2d.hpp>
#include <godot_cpp/classes/circle_shape2d.hpp>
#include <godot_cpp/classes/gradient.hpp>
namespace godot {
Bullet::Bullet() {
set_scale(Vector2(0.5, 0.5));
CollisionShape2D* Collision = memnew(CollisionShape2D);
CircleShape2D* CollisionShape = memnew(CircleShape2D);
Sprite = memnew(Sprite2D);
PoofParticles = memnew(CPUParticles2D);
PoofAudio = memnew(AudioStreamPlayer);
Gradient* PoofGradient = memnew(Gradient);
HitParticles = memnew(CPUParticles2D);
HitAudio = memnew(AudioStreamPlayer);
Gradient* HitGradient = memnew(Gradient);
Collision->set_shape(CollisionShape);
Color color1 = {1, 1, 1, 1};
Color color2 = {0.25, 0.25, 0.25, 0};
PoofParticles->set_emitting(false);
PoofParticles->set_amount(4);
PoofParticles->set_lifetime(0.25);
PoofParticles->set_one_shot(true);
PoofParticles->set_explosiveness_ratio(1.0);
PoofParticles->set_spread(180);
PoofParticles->set_gravity(Vector2(0, 0));
PoofParticles->set_param_min(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 30);
PoofParticles->set_param_max(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 30);
PoofParticles->set_param_max(CPUParticles2D::PARAM_ANGULAR_VELOCITY, 360);
PoofParticles->set_param_min(CPUParticles2D::PARAM_SCALE, 5);
PoofParticles->set_param_max(CPUParticles2D::PARAM_SCALE, 5);
PoofGradient->set_colors({color1, color2});
PoofParticles->set_color_ramp(PoofGradient);
HitParticles->set_emitting(false);
HitParticles->set_amount(4);
HitParticles->set_lifetime(0.25);
HitParticles->set_one_shot(true);
HitParticles->set_explosiveness_ratio(1.0);
HitParticles->set_spread(180);
HitParticles->set_gravity(Vector2(0, 0));
HitParticles->set_param_min(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 30);
HitParticles->set_param_max(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 30);
HitParticles->set_param_max(CPUParticles2D::PARAM_ANGULAR_VELOCITY, 360);
HitParticles->set_param_min(CPUParticles2D::PARAM_SCALE, 5);
HitParticles->set_param_max(CPUParticles2D::PARAM_SCALE, 5);
HitGradient->set_colors({color1, color2});
HitParticles->set_color_ramp(HitGradient);
// add teh children
add_child(Collision);
connect("body_entered", Callable(this, "BodyEntered"));
add_child(Sprite);
add_child(PoofParticles);
add_child(PoofAudio);
add_child(HitParticles);
add_child(HitAudio);
}
Bullet::~Bullet() {
queue_free();
}
void Bullet::_bind_methods() {
ClassDB::bind_method(D_METHOD("GetPoofAudio"), &Bullet::GetPoofAudio);
ClassDB::bind_method(D_METHOD("SetPoofAudio", "PoofAudio"), &Bullet::SetPoofAudio);
ClassDB::add_property("Bullet", PropertyInfo(Variant::OBJECT, "PoofAudio"), "SetPoofAudio", "GetPoofAudio");
ClassDB::bind_method(D_METHOD("GetHitAudio"), &Bullet::GetHitAudio);
ClassDB::bind_method(D_METHOD("SetHitAudio", "HitAudio"), &Bullet::SetHitAudio);
ClassDB::add_property("Bullet", PropertyInfo(Variant::OBJECT, "HitAudio"), "SetHitAudio", "GetHitAudio");
ClassDB::bind_method(D_METHOD("GetTexture"), &Bullet::GetTexture);
ClassDB::bind_method(D_METHOD("SetTexture", "Texture"), &Bullet::SetTexture);
ClassDB::add_property("Bullet", PropertyInfo(Variant::OBJECT, "Texture"), "SetTexture", "GetTexture");
// Standalone Method
ClassDB::bind_method(D_METHOD("BodyEntered"), &Bullet::BodyEntered);
}
void Bullet::_physics_process(double delta) {
translate(AreaDirection * Speed * delta);
}
void Bullet::BodyEntered(Node2D* body) {
if (Debounce == true) {
return;
}
// Don't destroy walls or players, only enemies
if (body->is_in_group("Player")) {
return;
}
else if (body->is_in_group("Enemy")) {
body->call("SetHealth", int(body->call("GetHealth")) - 1);
HitParticles->set_emitting(true);
HitParticles->reparent(get_parent());
HitAudio->play();
HitAudio->reparent(get_parent());
queue_free();
}
else {
PoofParticles->set_emitting(true);
PoofParticles->reparent(get_parent());
PoofAudio->play();
PoofAudio->reparent(get_parent());
queue_free();
}
}
}

67
src/Bullet.hpp Normal file
View file

@ -0,0 +1,67 @@
#ifndef BULLET_HPP
#define BULLET_HPP
#include <godot_cpp/classes/area2d.hpp>
#include <godot_cpp/classes/cpu_particles2d.hpp>
#include <godot_cpp/classes/audio_stream_player.hpp>
#include <godot_cpp/classes/audio_stream.hpp>
#include <godot_cpp/classes/sprite2d.hpp>
#include <godot_cpp/classes/texture2d.hpp>
namespace godot {
class Bullet : public Area2D {
GDCLASS(Bullet, Area2D);
public:
float Speed = 800;
// This variable Tracks which way the bullet should go. for example: (-1, 0) will make the bullet go left
Vector2 AreaDirection = Vector2(0, 0);
// This variable stops a crash
bool Debounce = false;
Ref<AudioStream> PoofAudioClip;
Ref<AudioStream> HitAudioClip;
Ref<Texture2D> Texture;
Sprite2D* Sprite;
CPUParticles2D* PoofParticles;
AudioStreamPlayer* PoofAudio;
CPUParticles2D* HitParticles;
AudioStreamPlayer* HitAudio;
Bullet();
~Bullet();
static void _bind_methods();
void _physics_process(double delta) override;
// Standalone methods
void BodyEntered(Node2D* body);
// Gets and Sets
Ref<AudioStream> GetPoofAudio() const {
return PoofAudioClip;
}
Ref<AudioStream> GetHitAudio() const {
return PoofAudioClip;
}
Ref<Texture2D> GetTexture() const {
return Texture;
}
void SetPoofAudio(const Ref<AudioStream>& audio ) {
PoofAudioClip = audio;
PoofAudio->set_stream(PoofAudioClip);
}
void SetHitAudio(const Ref<AudioStream>& audio ) {
HitAudioClip = audio;
HitAudio->set_stream(HitAudioClip);
}
void SetTexture(const Ref<Texture2D>& texture ) {
Texture = texture;
Sprite->set_texture(Texture);
}
};
}
#endif

134
src/Enemy.cpp Normal file
View file

@ -0,0 +1,134 @@
#include "Enemy.hpp"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/property_info.hpp>
#include <godot_cpp/core/memory.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/collision_shape2d.hpp>
#include <godot_cpp/classes/circle_shape2d.hpp>
#include <godot_cpp/classes/area2d.hpp>
#include <godot_cpp/classes/scene_tree.hpp>
#include <godot_cpp/classes/gradient.hpp>
#include <godot_cpp/variant/signal.hpp>
namespace godot {
Enemy::Enemy() {
// Other nodes to be attached.
CollisionShape2D* Collision = memnew(CollisionShape2D);
CircleShape2D* CollisionShape = memnew(CircleShape2D);
Area2D* Area = memnew(Area2D);
CollisionShape2D* Collision2 = memnew(CollisionShape2D);
CircleShape2D* CollisionShape2 = memnew(CircleShape2D);
Sprite = memnew(Sprite2D);
Particles = memnew(CPUParticles2D);
Gradient* ParticleGradient = memnew(Gradient);
Audio = memnew(AudioStreamPlayer);
// Assigning things.
Collision->set_shape(CollisionShape);
CollisionShape2->set_radius(12.0);
Collision2->set_shape(CollisionShape2);
Particles->set_emitting(false);
Particles->set_amount(20);
Particles->set_lifetime(0.5);
Particles->set_one_shot(true);
Particles->set_explosiveness_ratio(1.0);
Particles->set_spread(180);
Particles->set_gravity(Vector2(0, 0));
Particles->set_param_min(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 40);
Particles->set_param_max(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 110);
Particles->set_param_min(CPUParticles2D::PARAM_ANGULAR_VELOCITY, 360);
Particles->set_param_min(CPUParticles2D::PARAM_LINEAR_ACCEL, -200);
Particles->set_param_max(CPUParticles2D::PARAM_LINEAR_ACCEL, -200);
Particles->set_param_min(CPUParticles2D::PARAM_SCALE, 5);
Particles->set_param_max(CPUParticles2D::PARAM_SCALE, 8);
Color color1 = {0.75, 0, 0.13, 1};
Color color2 = {1, 0.4, 0.4, 1};
Color color3 = {1, 0.45, 0.4, 0};
PackedFloat32Array offset = {0, 0.5, 1};
ParticleGradient->set_offsets(offset);
ParticleGradient->set_colors({color1, color2, color3});
Particles->set_color_ramp(ParticleGradient);
// Add children
add_child(Collision);
add_child(Area);
Area->add_child(Collision2);
Area->connect("body_entered", Callable(this, "DetectorBodyEnter"));
add_child(Sprite);
add_child(Particles);
add_child(Audio);
}
Enemy::~Enemy() {
queue_free();
}
void Enemy::_physics_process(double delta) {
// Stop running in certain circumstances
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
// Follow the player
auto tree = get_tree();
Array player = tree->get_nodes_in_group("Player");
if (player.size() > 0) {
look_at(player[0].get("position"));
set_velocity(Vector2(0, 0));
set_position(get_position().move_toward(player[0].get("position"), Speed * delta));
}
// Death
if (Health <= 0) {
Die();
}
move_and_slide();
}
void Enemy::_bind_methods() {
ClassDB::add_property_group("Enemy", "Variables", "Variable");
ClassDB::bind_method(D_METHOD("GetSpeed"), &Enemy::GetSpeed);
ClassDB::bind_method(D_METHOD("SetSpeed", "Speed"), &Enemy::SetSpeed);
ClassDB::add_property("Enemy", PropertyInfo(Variant::FLOAT, "VariableSpeed"), "SetSpeed", "GetSpeed");
ClassDB::bind_method(D_METHOD("GetHealth"), &Enemy::GetHealth);
ClassDB::bind_method(D_METHOD("SetHealth", "Health"), &Enemy::SetHealth);
ClassDB::add_property("Enemy", PropertyInfo(Variant::INT, "VariableHealth"), "SetHealth", "GetHealth");
ClassDB::bind_method(D_METHOD("GetScoreValue"), &Enemy::GetScoreValue);
ClassDB::bind_method(D_METHOD("SetScoreValue", "ScoreValue"), &Enemy::SetScoreValue);
ClassDB::add_property("Enemy", PropertyInfo(Variant::INT, "VariableScoreValue"), "SetScoreValue", "GetScoreValue");
ClassDB::add_property_group("Enemy", "Drag&Drops", "Drags");
ClassDB::bind_method(D_METHOD("GetTexture"), &Enemy::GetTexture);
ClassDB::bind_method(D_METHOD("SetTexture", "Texture"), &Enemy::SetTexture);
ClassDB::add_property("Enemy", PropertyInfo(Variant::OBJECT, "DragsTexture"), "SetTexture", "GetTexture");
ClassDB::bind_method(D_METHOD("GetDeathAudio"), &Enemy::GetDeathAudio);
ClassDB::bind_method(D_METHOD("SetDeathAudio", "Audio"), &Enemy::SetDeathAudio);
ClassDB::add_property("Enemy", PropertyInfo(Variant::OBJECT, "DragsAudio"), "SetDeathAudio", "GetDeathAudio");
// Standalone functions
ClassDB::bind_method(D_METHOD("DetectorBodyEnter"), &Enemy::DetectorBodyEnter);
// Signals
ClassDB::add_signal("Enemy", MethodInfo("AddScore", PropertyInfo(Variant::INT, "Score")));
}
void Enemy::DetectorBodyEnter(Node2D* body) {
if (body->is_in_group("Player")) {
body->call("Die");
}
}
void Enemy::Die() {
Particles->set_emitting(true);
Particles->reparent(get_parent());
Audio->play();
Audio->reparent(get_parent());
emit_signal("AddScore", ScoreValue);
queue_free();
}
}

74
src/Enemy.hpp Normal file
View file

@ -0,0 +1,74 @@
#ifndef ENEMY_HPP
#define ENEMY_HPP
#include <godot_cpp/classes/character_body2d.hpp>
#include <godot_cpp/classes/sprite2d.hpp>
#include <godot_cpp/classes/texture2d.hpp>
#include <godot_cpp/classes/cpu_particles2d.hpp>
#include <godot_cpp/classes/audio_stream.hpp>
#include <godot_cpp/classes/audio_stream_player.hpp>
#include <godot_cpp/classes/node2d.hpp>
namespace godot {
class Enemy : public CharacterBody2D {
GDCLASS(Enemy, CharacterBody2D);
public:
float Speed = 100;
int Health = 1;
int ScoreValue = 1;
Ref<Texture2D> Texture;
Ref<AudioStream> DeathAudio;
Enemy();
~Enemy();
// Nodes
Sprite2D* Sprite;
CPUParticles2D* Particles;
AudioStreamPlayer* Audio;
void _physics_process(double delta) override;
static void _bind_methods();
void DetectorBodyEnter(Node2D* body);
void Die();
// Getters and Setters
float GetSpeed() const {
return Speed;
}
int GetHealth() const {
return Health;
}
int GetScoreValue() const {
return ScoreValue;
}
Ref<Texture2D> GetTexture() const {
return Texture;
}
Ref<AudioStream> GetDeathAudio() const {
return DeathAudio;
}
void SetSpeed(const float speed) {
Speed = speed;
}
void SetHealth(const int health) {
Health = health;
}
void SetScoreValue(const int score) {
ScoreValue = score;
}
void SetTexture(const Ref<Texture2D>& texture) {
Texture = texture;
Sprite->set_texture(Texture);
}
void SetDeathAudio(const Ref<AudioStream>& audio) {
DeathAudio = audio;
Audio->set_stream(DeathAudio);
}
};
}
#endif

191
src/Player.cpp Normal file
View file

@ -0,0 +1,191 @@
#include "Player.hpp"
#include "Bullet.hpp"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/memory.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/classes/collision_shape2d.hpp>
#include <godot_cpp/classes/circle_shape2d.hpp>
#include <godot_cpp/classes/cpu_particles2d.hpp>
#include <godot_cpp/classes/gradient.hpp>
namespace godot {
Player::Player() {
// Other nodes to be attached.
CollisionShape2D* Collision = memnew(CollisionShape2D);
CircleShape2D* CollisionShape = memnew(CircleShape2D);
Sprite = memnew(Sprite2D);
Marker = memnew(Marker2D);
Camera = memnew(Camera2D);
Particles = memnew(CPUParticles2D);
Gradient* ParticleGradient = memnew(Gradient);
Audio = memnew(AudioStreamPlayer);
// Assigning stuff.
Collision->set_shape(CollisionShape);
Marker->set_position(Vector2(15, 0));
Particles->set_emitting(false);
Particles->set_amount(450);
Particles->set_lifetime(2);
Particles->set_one_shot(true);
Particles->set_spread(180);
Particles->set_gravity(Vector2(0, 0));
Particles->set_param_min(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 70);
Particles->set_param_max(CPUParticles2D::PARAM_INITIAL_LINEAR_VELOCITY, 210);
Particles->set_param_max(CPUParticles2D::PARAM_ANGULAR_VELOCITY, 360);
Particles->set_param_min(CPUParticles2D::PARAM_SCALE, 10);
Particles->set_param_max(CPUParticles2D::PARAM_SCALE, 15);
Camera->set_position(Vector2(100, 0));
Camera->set_position_smoothing_enabled(true);
// Complete the player.
add_child(Collision);
add_child(Sprite);
add_child(Marker);
add_child(Camera);
add_child(Particles);
add_child(Audio);
}
Player::~Player() {
queue_free();
}
void Player::_bind_methods() {
// Global
ClassDB::add_property_group("Player", "Variables", "Variable");
ClassDB::bind_method(D_METHOD("GetSpeed"), &Player::GetSpeed);
ClassDB::bind_method(D_METHOD("SetSpeed", "Speed"), &Player::SetSpeed);
ClassDB::add_property("Player", PropertyInfo(Variant::FLOAT, "VariableSpeed"), "SetSpeed", "GetSpeed");
ClassDB::bind_method(D_METHOD("GetDead"), &Player::GetDead);
ClassDB::bind_method(D_METHOD("SetDead", "IsDead"), &Player::SetDead);
ClassDB::add_property("Player", PropertyInfo(Variant::BOOL, "VariableIsDead"), "SetDead", "GetDead");
// Shooting
ClassDB::add_property_group("Player", "Shooting", "Shoot");
ClassDB::bind_method(D_METHOD("GetFireRate"), &Player::GetFireRate);
ClassDB::bind_method(D_METHOD("SetFireRate", "FireRate"), &Player::SetFireRate);
ClassDB::add_property("Player", PropertyInfo(Variant::FLOAT, "ShootFireRate"), "SetFireRate", "GetFireRate");
ClassDB::bind_method(D_METHOD("GetPoof"), &Player::GetPoof);
ClassDB::bind_method(D_METHOD("SetPoof"), &Player::SetPoof);
ClassDB::add_property("Player", PropertyInfo(Variant::OBJECT, "ShootPoofSound"), "SetPoof", "GetPoof");
ClassDB::bind_method(D_METHOD("GetHit"), &Player::GetHit);
ClassDB::bind_method(D_METHOD("SetHit"), &Player::SetHit);
ClassDB::add_property("Player", PropertyInfo(Variant::OBJECT, "ShootHitSound"), "SetHit", "GetHit");
ClassDB::bind_method(D_METHOD("GetBulletTexture"), &Player::GetBulletTexture);
ClassDB::bind_method(D_METHOD("SetBulletTexture"), &Player::SetBulletTexture);
ClassDB::add_property("Player", PropertyInfo(Variant::OBJECT, "ShootBulletTexture"), "SetBulletTexture", "GetBulletTexture");
// Drag & Drops
ClassDB::add_property_group("Player", "Drag&Drops", "Drags");
ClassDB::bind_method(D_METHOD("GetTexture"), &Player::GetTexture);
ClassDB::bind_method(D_METHOD("SetTexture", "Texture"), &Player::SetTexture);
ClassDB::add_property("Player", PropertyInfo(Variant::OBJECT, "DragsTexture"), "SetTexture", "GetTexture");
ClassDB::bind_method(D_METHOD("GetDeathAudio"), &Player::GetDeathAudio);
ClassDB::bind_method(D_METHOD("SetDeathAudio", "DeathAudio"), &Player::SetDeathAudio);
ClassDB::add_property("Player", PropertyInfo(Variant::OBJECT, "DragsDeathAudio"), "SetDeathAudio", "GetDeathAudio");
ClassDB::bind_method(D_METHOD("GetDeathParticles"), &Player::GetDeathParticles);
ClassDB::bind_method(D_METHOD("SetDeathParticles", "DeathParticles"), &Player::SetDeathParticles);
ClassDB::add_property("Player", PropertyInfo(Variant::OBJECT, "DragsDeathParticles", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "SetDeathParticles", "GetDeathParticles");
// Inputs
ClassDB::add_property_group("Player", "Input Map Names", "Input");
ClassDB::bind_method(D_METHOD("GetLeft"), &Player::GetLeft);
ClassDB::bind_method(D_METHOD("SetLeft", "Left"), &Player::SetLeft);
ClassDB::add_property("Player", PropertyInfo(Variant::STRING_NAME, "InputLeft"), "SetLeft", "GetLeft");
ClassDB::bind_method(D_METHOD("GetUp"), &Player::GetUp);
ClassDB::bind_method(D_METHOD("SetUp", "Up"), &Player::SetUp);
ClassDB::add_property("Player", PropertyInfo(Variant::STRING_NAME, "InputUp"), "SetUp", "GetUp");
ClassDB::bind_method(D_METHOD("GetRight"), &Player::GetRight);
ClassDB::bind_method(D_METHOD("SetRight", "Right"), &Player::SetRight);
ClassDB::add_property("Player", PropertyInfo(Variant::STRING_NAME, "InputRight"), "SetRight", "GetRight");
ClassDB::bind_method(D_METHOD("GetDown"), &Player::GetDown);
ClassDB::bind_method(D_METHOD("SetDown", "Down"), &Player::SetDown);
ClassDB::add_property("Player", PropertyInfo(Variant::STRING_NAME, "InputDown"), "SetDown", "GetDown");
ClassDB::bind_method(D_METHOD("GetShoot"), &Player::GetShoot);
ClassDB::bind_method(D_METHOD("SetShoot", "Shoot"), &Player::SetShoot);
ClassDB::add_property("Player", PropertyInfo(Variant::STRING_NAME, "InputShoot"), "SetShoot", "GetShoot");
ClassDB::bind_method(D_METHOD("GetRespawn"), &Player::GetRespawn);
ClassDB::bind_method(D_METHOD("SetRespawn", "Respawn"), &Player::SetRespawn);
ClassDB::add_property("Player", PropertyInfo(Variant::STRING_NAME, "InputRespawn"), "SetRespawn", "GetRespawn");
ClassDB::bind_method(D_METHOD("GetPowerUp"), &Player::GetPowerUp);
ClassDB::bind_method(D_METHOD("SetPowerUp", "PowerUp"), &Player::SetPowerUp);
ClassDB::add_property("Player", PropertyInfo(Variant::STRING, "PowerUp"), "SetPowerUp", "GetPowerUp");
// Signals
ClassDB::add_signal("Player", MethodInfo("Respawn"));
// Standalone Functions
ClassDB::bind_method(D_METHOD("Die"), &Player::Die);
}
void Player::_physics_process(double delta) {
// Stop running in certain circumstances
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
if (IsDead == true) {
set_velocity(Vector2(0, 0));
// Respawn stuff
if (Input::get_singleton()->is_action_just_pressed(Respawn)) {
emit_signal("Respawn");
}
return;
}
timer += delta;
// Power Up things
float RealFireRate = FireRate;
if (PowerUpEnable == true) {
PowerUpTimer += delta;
RealFireRate /= 2;
// Disable powerups
if (PowerUpTimer >= 10) {
PowerUpEnable = false;
PowerUpTimer = 0;
}
}
// Movement
float AxisX = Input::get_singleton()->get_axis(Left, Right);
float AxisY = Input::get_singleton()->get_axis(Up, Down);
set_velocity(Vector2(AxisX * Speed, AxisY * Speed));
// Shooting
if (Input::get_singleton()->get_action_strength(Shoot) >= 1 && timer >= RealFireRate) {
Bullet* bullet = memnew(Bullet);
bullet->AreaDirection = (get_global_mouse_position() - get_global_position()).normalized();
bullet->set_global_position(Marker->get_global_position());
bullet->SetPoofAudio(PoofSound);
bullet->SetHitAudio(HitSound);
bullet->SetTexture(BulletTexture);
add_sibling(bullet);
Player::Camera->set_offset(Vector2(UtilityFunctions::randf_range(-4, 4), UtilityFunctions::randf_range(-4, 4)));
timer = 0;
}
else {
// Stop wiggling the camera if there is no shooting
Player::Camera->set_offset(Vector2(0, 0));
}
move_and_slide();
look_at(get_global_mouse_position());
}
void Player::Die() {
if (IsDead == false) {
Particles->reparent(get_parent());
Particles->set_emitting(true);
Audio->play();
Camera->set_position(Vector2(0, 0));
set_visible(false);
IsDead = true;
}
}
}

179
src/Player.hpp Normal file
View file

@ -0,0 +1,179 @@
#ifndef PLAYER_HPP
#define PLAYER_HPP
#include <godot_cpp/classes/input.hpp>
#include <godot_cpp/classes/ref.hpp>
#include <godot_cpp/classes/character_body2d.hpp>
#include <godot_cpp/classes/sprite2d.hpp>
#include <godot_cpp/classes/texture2d.hpp>
#include <godot_cpp/classes/marker2d.hpp>
#include <godot_cpp/classes/camera2d.hpp>
#include <godot_cpp/classes/cpu_particles2d.hpp>
#include <godot_cpp/classes/audio_stream.hpp>
#include <godot_cpp/classes/audio_stream_player.hpp>
#include <godot_cpp/classes/gradient.hpp>
namespace godot {
class Player : public CharacterBody2D {
GDCLASS(Player, CharacterBody2D)
public:
// General
float Speed = 300;
bool IsDead = false;
Ref<Texture2D> Texture;
Ref<AudioStream> DeathAudio;
Ref<Gradient> DeathParticles;
// Shooting
Ref<AudioStream> PoofSound;
Ref<AudioStream> HitSound;
Ref<Texture2D> BulletTexture;
double FireRate = 0.2;
// Other
double timer = 0.0;
double PowerUpTimer = 0.0;
// PowerUps
bool PowerUpEnable = false;
enum PowerUps {
DOUBLE_FIRERATE = 0,
DOUBLE_POINTS = 1,
DOUBLE_CASH = 2,
};
int CurrentPowerUp = DOUBLE_FIRERATE;
// Input names
StringName Left;
StringName Up;
StringName Right;
StringName Down;
StringName Shoot;
StringName Respawn;
// Nodes
Sprite2D* Sprite;
Marker2D* Marker;
Camera2D* Camera;
CPUParticles2D* Particles;
AudioStreamPlayer* Audio;
Player();
~Player();
// Godot Engine functions
void _physics_process(double delta) override;
static void _bind_methods();
// Custom functions
void Die();
// Getters and Setters
float GetSpeed() const {
return Speed;
}
double GetFireRate() const {
return FireRate;
}
Ref<Texture2D> GetTexture() const {
return Texture;
}
bool GetDead() const {
return IsDead;
}
Ref<AudioStream> GetDeathAudio() const {
return DeathAudio;
}
Ref<Gradient> GetDeathParticles() const {
return DeathParticles;
}
int GetPowerUp() const {
return CurrentPowerUp;
}
StringName GetLeft() const {
return Left;
}
StringName GetUp() const {
return Up;
}
StringName GetRight() const {
return Right;
}
StringName GetDown() const {
return Down;
}
StringName GetShoot() const {
return Shoot;
}
StringName GetRespawn() const {
return Respawn;
}
Ref<AudioStream> GetHit() const {
return HitSound;
}
Ref<AudioStream> GetPoof() const {
return PoofSound;
}
Ref<Texture2D> GetBulletTexture() const {
return BulletTexture;
}
void SetSpeed(const float speed) {
Speed = speed;
}
void SetFireRate(const double firerate) {
FireRate = firerate;
}
void SetTexture(const Ref<Texture2D>& texture) {
Texture = texture;
Sprite->set_texture(Texture);
}
void SetDead(const bool dead) {
IsDead = dead;
}
void SetDeathAudio(const Ref<AudioStream>& audio) {
DeathAudio = audio;
Audio->set_stream(DeathAudio);
}
void SetDeathParticles(const Ref<Gradient> particles) {
DeathParticles = particles;
Particles->set_color_ramp(DeathParticles);
}
void SetPowerUp(const int PowerUp) {
PowerUpEnable = true;
CurrentPowerUp = PowerUp;
}
void SetLeft(const StringName left) {
Left = left;
}
void SetUp(const StringName up) {
Up = up;
}
void SetRight(const StringName right) {
Right = right;
}
void SetDown(const StringName down) {
Down = down;
}
void SetShoot(const StringName shoot) {
Shoot = shoot;
}
void SetRespawn(const StringName respawn) {
Respawn = respawn;
}
void SetHit(const Ref<AudioStream> audio) {
HitSound = audio;
}
void SetPoof(const Ref<AudioStream> audio) {
PoofSound = audio;
}
void SetBulletTexture(const Ref<Texture2D> audio) {
BulletTexture = audio;
}
};
}
#endif

42
src/RegisterTypes.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "RegisterTypes.hpp"
#include "Player.hpp"
#include "Bullet.hpp"
#include "Enemy.hpp"
#include "Spawner.hpp"
#include <gdextension_interface.h>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>
using namespace godot;
void InitializeModule(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
GDREGISTER_CLASS(Player);
GDREGISTER_CLASS(Bullet);
GDREGISTER_CLASS(Enemy);
GDREGISTER_CLASS(Spawner);
}
void UninitializeModule(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
}
extern "C" {
// Initialization.
GDExtensionBool GDE_EXPORT LibraryInit(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
init_obj.register_initializer(InitializeModule);
init_obj.register_terminator(UninitializeModule);
init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
return init_obj.init();
}
}

11
src/RegisterTypes.hpp Normal file
View file

@ -0,0 +1,11 @@
#ifndef REGISTER_TYPES_HPP
#define REGISTER_TYPES_HPP
#include <godot_cpp/core/class_db.hpp>
using namespace godot;
void InitializeModule(ModuleInitializationLevel p_level);
void UninitializeModule(ModuleInitializationLevel p_level);
#endif

51
src/Spawner.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "Spawner.hpp"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/memory.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
namespace godot {
Spawner::Spawner() {
}
Spawner::~Spawner() {
queue_free();
}
void Spawner::_bind_methods() {
// Numbers
ClassDB::bind_method(D_METHOD("GetTimerRandomization"), &Spawner::GetTimerRandomization);
ClassDB::bind_method(D_METHOD("SetTimerRandomization", "TimerRandomization"), &Spawner::SetTimerRandomization);
ClassDB::add_property("Spawner", PropertyInfo(Variant::BOOL, "TimerRandomization"), "SetTimerRandomization", "GetTimerRandomization");
ClassDB::bind_method(D_METHOD("GetSpawnInterval"), &Spawner::GetSpawnInterval);
ClassDB::bind_method(D_METHOD("SetSpawnInterval", "SpawnInterval"), &Spawner::SetSpawnInterval);
ClassDB::add_property("Spawner", PropertyInfo(Variant::FLOAT, "SpawnInterval"), "SetSpawnInterval", "GetSpawnInterval");
ClassDB::bind_method(D_METHOD("GetSizeX"), &Spawner::GetSizeX);
ClassDB::bind_method(D_METHOD("SetSizeX", "SizeX"), &Spawner::SetSizeX);
ClassDB::add_property("Spawner", PropertyInfo(Variant::FLOAT, "SizeX"), "SetSizeX", "GetSizeX");
ClassDB::bind_method(D_METHOD("GetSizeY"), &Spawner::GetSizeY);
ClassDB::bind_method(D_METHOD("SetSizeY", "SizeY"), &Spawner::SetSizeY);
ClassDB::add_property("Spawner", PropertyInfo(Variant::FLOAT, "SizeY"), "SetSizeY", "GetSizeY");
// Signals
ClassDB::add_signal("Spawner", MethodInfo("Spawn"));
}
void Spawner::_physics_process(double delta) {
// Stop running in certain circumstances
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
timer += delta;
if (timer >= RealSpawnInterval) {
emit_signal("Spawn");
timer = 0;
if (TimerRandomization == true) {
RealSpawnInterval = SpawnInterval + UtilityFunctions::randf_range(-0.75, 0.75);
}
}
}
}

58
src/Spawner.hpp Normal file
View file

@ -0,0 +1,58 @@
#ifndef SPAWNER_HPP
#define SPAWNER_HPP
#include <godot_cpp/core/property_info.hpp>
#include <godot_cpp/classes/ref.hpp>
#include <godot_cpp/classes/marker2d.hpp>
namespace godot {
class Spawner : public Marker2D {
GDCLASS(Spawner, Marker2D);
public:
bool TimerRandomization = false;
double SpawnInterval = 2.5;
double RealSpawnInterval = SpawnInterval;
double timer = 0.0;
float SizeX = 0.0;
float SizeY = 0.0;
Spawner();
~Spawner();
void _physics_process(double delta) override;
static void _bind_methods();
// Gets and Sets
bool GetTimerRandomization() const {
return TimerRandomization;
}
double GetSpawnInterval() const {
return SpawnInterval;
}
float GetSizeX() const {
return SizeX;
}
float GetSizeY() const {
return SizeY;
}
void SetTimerRandomization(const bool timerRandomization) {
TimerRandomization = timerRandomization;
}
void SetSpawnInterval(const double spawnInterval) {
SpawnInterval = spawnInterval;
RealSpawnInterval = SpawnInterval;
}
void SetSizeX(const float sizeX) {
SizeX = sizeX;
}
void SetSizeY(const float sizeY) {
SizeY = sizeY;
}
};
}
#endif

449
src/gen/doc_data.gen.cpp Normal file
View file

@ -0,0 +1,449 @@
/* THIS FILE IS GENERATED DO NOT EDIT */
#include <godot_cpp/godot.hpp>
static const char *_doc_data_hash = "4115647380405609627";
static const int _doc_data_uncompressed_size = 2037;
static const int _doc_data_compressed_size = 437;
static const unsigned char _doc_data_compressed[] = {
120,
218,
237,
84,
77,
79,
28,
49,
12,
61,
195,
175,
136,
114,
103,
178,
208,
75,
181,
218,
1,
149,
182,
244,
2,
8,
105,
182,
85,
111,
149,
55,
227,
157,
137,
200,
199,
40,
246,
116,
118,
255,
125,
51,
95,
104,
65,
28,
42,
84,
81,
181,
226,
102,
251,
197,
47,
182,
159,
229,
213,
197,
206,
89,
241,
19,
35,
153,
224,
115,
121,
154,
45,
164,
64,
175,
67,
105,
124,
149,
203,
175,
235,
171,
147,
247,
82,
92,
156,
31,
175,
180,
5,
34,
225,
193,
97,
46,
47,
91,
107,
145,
165,
48,
190,
198,
104,
152,
114,
249,
33,
34,
156,
125,
146,
34,
145,
121,
90,
238,
200,
228,
178,
102,
110,
150,
74,
117,
93,
151,
117,
239,
178,
16,
43,
117,
182,
88,
156,
170,
239,
55,
215,
133,
174,
209,
193,
137,
241,
196,
224,
53,
166,
44,
50,
75,
31,
110,
19,
55,
53,
160,
113,
196,
175,
131,
6,
30,
138,
234,
153,
40,
81,
69,
232,
178,
202,
112,
221,
110,
90,
194,
168,
131,
103,
244,
156,
233,
224,
84,
21,
202,
144,
156,
202,
120,
28,
109,
229,
128,
24,
163,
42,
131,
86,
67,
229,
217,
142,
74,
121,
126,
124,
180,
218,
68,
131,
219,
31,
37,
146,
142,
166,
233,
249,
251,
160,
122,
54,
250,
244,
209,
19,
159,
91,
14,
209,
128,
165,
1,
124,
228,
57,
228,
58,
148,
35,
112,
96,
59,
116,
155,
52,
233,
41,
252,
96,
147,
169,
252,
76,
115,
96,
167,
6,
251,
1,
241,
8,
28,
120,
171,
177,
165,
100,
188,
68,
188,
207,
30,
221,
254,
80,
187,
143,
53,
68,
208,
105,
90,
151,
161,
220,
191,
137,
248,
79,
136,
120,
103,
97,
143,
241,
63,
84,
241,
104,
93,
163,
112,
96,
188,
104,
134,
22,
133,
158,
251,
18,
219,
16,
5,
39,
116,
221,
37,
180,
96,
163,
239,
69,
81,
135,
244,
89,
252,
77,
241,
7,
238,
84,
99,
147,
142,
23,
62,
207,
15,
214,
206,
192,
182,
245,
186,
79,
164,
236,
15,
175,
205,
108,
79,
82,
126,
131,
148,
186,
177,
88,
52,
136,
165,
20,
188,
111,
82,
240,
202,
6,
72,
7,
150,
144,
83,
101,
185,
44,
144,
39,
184,
154,
34,
95,
230,
72,
79,
56,
52,
70,
189,
43,
194,
118,
152,
209,
67,
87,
89,
255,
223,
180,
167,
127,
119,
101,
139,
6,
58,
255,
120,
103,
111,
32,
222,
99,
124,
59,
57,
175,
125,
114,
126,
1,
170,
7,
183,
154,
};
static godot::internal::DocDataRegistration _doc_data_registration(_doc_data_hash, _doc_data_uncompressed_size, _doc_data_compressed_size, _doc_data_compressed);