Compare commits

..

9 Commits

Author SHA1 Message Date
Aaron Franke
ab9be2e79d [3.0] Simplify list of branches in the README (#1255) 2025-10-02 16:39:50 -07:00
Rémi Verschelde
3e4f49cef7 Update README for new branches, matches Godot upstream
(cherry picked from commit c0180d20d1)
2023-02-28 18:37:18 +01:00
Aaron Franke
a3c35ce2be [3.0] Update README for the new 3.3 branch 2021-11-05 10:15:40 -05:00
Aaron Franke
74a5c91794 Merge pull request #609 from aaronfranke/3.0-readme-license-3.2
[3.0] Update README for the new 3.2 branch
2021-04-21 03:51:11 -05:00
Aaron Franke
9ac0b6f58b [3.0] Update README for the new 3.2 branch 2021-04-04 01:16:02 -04:00
Aaron Franke
6501f329b7 Merge pull request #403 from aaronfranke/3.0-readme-license
[3.0] Update README and LICENSE
2020-02-03 17:06:45 -05:00
Aaron Franke
8cbfd92486 [3.0] Update README and LICENSE 2020-02-03 17:02:37 -05:00
Rémi Verschelde
e113915c80 Merge pull request #333 from aaronfranke/3.0-no-bl
Remove "background load" demo from the 3.0 branch
2019-06-11 12:27:29 +02:00
Aaron Franke
ef5cec6aaf Remove "background load" demo from the 3.0 branch
This was created by reduz in 3.1 dev before alpha. The simplest solution is to require using Godot 3.1 to use this demo (and therefore removing it from the 3.0 branch).
2019-06-05 23:27:21 -04:00
2137 changed files with 33088 additions and 45533 deletions

16
.editorconfig Normal file
View File

@@ -0,0 +1,16 @@
# Top-most EditorConfig file.
root = true
# Unix-style newlines with a newline ending every file.
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
[*.cs]
csharp_space_after_cast = false
indent_size = 4
[*.csproj]
insert_final_newline = false
indent_size = 2

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

6
.github/CODEOWNERS vendored
View File

@@ -1,6 +0,0 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.
# Owners can be @users, @org/teams or emails
/misc/2.5d @aaronfranke
/mono/2.5d @aaronfranke

2
.github/FUNDING.yml vendored
View File

@@ -1,2 +0,0 @@
patreon: godotengine
custom: https://godotengine.org/donate

View File

@@ -1,34 +0,0 @@
---
name: Bug Report
about: Report a bug with one of the demo projects.
title: ''
labels: bug
assignees: ''
---
<!--
Please search existing issues for potential duplicates before filing yours:
https://github.com/godotengine/godot-demo-projects/issues?q=is%3Aissue
Only submit an issue if it is reproducible with the latest stable Godot version.
-->
**Which demo project is affected:**
<!-- Specify the project name or path. -->
**OS/device including version:**
<!-- Specify GPU model and drivers if graphics-related. -->
**Issue description:**
<!-- What happened, what was expected, and what went wrong. -->
**Screenshots of issue:**
<!--
This section is optional.
Drag in an image, or post an image with a link in the form of:
![Alt Text Here](https://pbs.twimg.com/media/DW5AJnZVAAM1805?format=jpg)
-->

View File

@@ -1,19 +0,0 @@
---
name: Feature / Enhancement Request
about: Adding new features or improving existing ones.
title: ''
labels: enhancement
assignees: ''
---
<!--
Please search existing issues for potential duplicates before filing yours:
https://github.com/godotengine/godot-demo-projects/issues?q=is%3Aissue
-->
**Which demo project is affected:**
<!-- Specify the project name or path. -->
**Description:**

View File

@@ -1,24 +0,0 @@
<!--
Only submit a pull request if all of the following conditions are met:
* It must work with the latest stable Godot version. Do not submit a
pull request if it only works with alpha/beta builds.
* It must follow all of the Godot style guides, including the GDScript
style guide and the C# style guide.
* The demo should not be overcomplicated. Simplicity is usually preferred.
* If you are submitting a new demo, please ensure that it includes a
README file similar to the other demos.
* If you are submitting a copy of a demo translated to C# etc:
* Please ensure that there is a good reason to have this demo translated.
We don't want to have multiple copies of every single project.
* Please ensure that the code mirrors the original closely.
* In the project.godot file and in the README, include "with C#" etc in
the title, and also include a link to the original in the README.
-->

View File

@@ -1,15 +0,0 @@
name: Continuous integration
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Lint demo projects
run: |
sudo apt-get update -qq
sudo apt-get install -qq dos2unix recode
bash ./format.sh

19
.github/workflows/static_checks.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Static Checks
on: [push, pull_request]
jobs:
format:
name: File formatting (file_format.sh)
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -qq dos2unix recode
- name: File formatting checks (file_format.sh)
run: |
bash ./file_format.sh

5
.gitignore vendored
View File

@@ -1,8 +1,12 @@
# Godot 4+ specific ignores
.godot/
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Dummy HTML5 export presets file for continuous integration
!.github/dist/export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
@@ -14,4 +18,5 @@ mono_crash.*.json
# System/tool-specific ignores
.directory
.DS_Store
*~

View File

@@ -1,8 +0,0 @@
# 2D Demos
These demos are all 2D, but otherwise do not have a common theme.
Languages: Most have GDScript, some have
[GDSL](https://docs.godotengine.org/en/latest/tutorials/shading/shading_reference/shading_language.html)
Renderers: 6 of them are GLES 3, but most are GLES 2

View File

@@ -7,24 +7,19 @@ func show_message(text):
$MessageLabel.show()
$MessageTimer.start()
func show_game_over():
show_message("Game Over")
yield($MessageTimer, "timeout")
$MessageLabel.text = "Dodge the\nCreeps"
$MessageLabel.show()
yield(get_tree().create_timer(1), "timeout")
$StartButton.show()
$MessageLabel.text = "Dodge the\nCreeps!"
$MessageLabel.show()
func update_score(score):
$ScoreLabel.text = str(score)
func _on_StartButton_pressed():
$StartButton.hide()
emit_signal("start_game")
func _on_MessageTimer_timeout():
$MessageLabel.hide()

View File

@@ -1,57 +1,126 @@
[gd_scene load_steps=7 format=2]
[gd_scene load_steps=6 format=2]
[ext_resource path="res://HUD.gd" type="Script" id=1]
[ext_resource path="res://fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=2]
[sub_resource type="DynamicFont" id=1]
size = 64
use_mipmaps = false
use_filter = false
font_data = ExtResource( 2 )
_sections_unfolded = [ "Font", "Settings" ]
[sub_resource type="DynamicFont" id=2]
size = 64
size = 72
use_mipmaps = false
use_filter = false
font_data = ExtResource( 2 )
_sections_unfolded = [ "Font", "Settings" ]
[sub_resource type="InputEventAction" id=3]
action = "ui_select"
[sub_resource type="DynamicFont" id=3]
[sub_resource type="ShortCut" id=4]
shortcut = SubResource( 3 )
size = 48
use_mipmaps = false
use_filter = false
font_data = ExtResource( 2 )
_sections_unfolded = [ "Font", "Settings" ]
[node name="HUD" type="CanvasLayer"]
layer = 1
offset = Vector2( 0, 0 )
rotation = 0.0
scale = Vector2( 1, 1 )
transform = Transform2D( 1, 0, 0, 1, 0, 0 )
script = ExtResource( 1 )
[node name="ScoreLabel" type="Label" parent="."]
anchor_right = 1.0
margin_bottom = 78.0
[node name="ScoreLabel" type="Label" parent="." index="0"]
anchor_left = 0.5
anchor_top = 0.0
anchor_right = 0.5
anchor_bottom = 0.0
margin_left = -25.0
margin_right = 25.0
margin_bottom = 100.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 1 )
text = "0"
align = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Anchor", "Margin", "custom_fonts" ]
[node name="MessageLabel" type="Label" parent="."]
[node name="MessageLabel" type="Label" parent="." index="1"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 1.0
anchor_right = 0.5
anchor_bottom = 0.5
margin_top = -79.5
margin_bottom = 79.5
custom_fonts/font = SubResource( 1 )
margin_left = -200.0
margin_top = -150.0
margin_right = 200.0
margin_bottom = 50.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 2 )
text = "Dodge the
Creeps"
Creeps!"
align = 1
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Anchor", "Margin", "custom_fonts" ]
[node name="MessageTimer" type="Timer" parent="." index="2"]
process_mode = 1
wait_time = 2.0
one_shot = true
autostart = false
[node name="StartButton" type="Button" parent="." index="3"]
[node name="StartButton" type="Button" parent="."]
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
margin_left = -90.0
margin_left = -100.0
margin_top = -200.0
margin_right = 90.0
margin_right = 100.0
margin_bottom = -100.0
custom_fonts/font = SubResource( 2 )
shortcut = SubResource( 4 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
custom_fonts/font = SubResource( 3 )
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Start"
flat = false
align = 1
_sections_unfolded = [ "Anchor", "Margin", "Visibility", "custom_fonts" ]
[node name="MessageTimer" type="Timer" parent="."]
one_shot = true
[connection signal="pressed" from="StartButton" to="." method="_on_StartButton_pressed"]
[connection signal="timeout" from="MessageTimer" to="." method="_on_MessageTimer_timeout"]
[connection signal="pressed" from="StartButton" to="." method="_on_StartButton_pressed"]

View File

@@ -1,47 +1,42 @@
extends Node
export(PackedScene) var Mob
export (PackedScene) var Mob
var score
func _ready():
randomize()
func game_over():
$ScoreTimer.stop()
$MobTimer.stop()
$HUD.show_game_over()
$Music.stop()
$DeathSound.play()
func new_game():
score = 0
$HUD.update_score(score)
$Player.start($StartPosition.position)
$StartTimer.start()
$HUD.update_score(score)
$HUD.show_message("Get Ready")
$Music.play()
func game_over():
$DeathSound.play()
$Music.stop()
$ScoreTimer.stop()
$MobTimer.stop()
$HUD.show_game_over()
func _on_MobTimer_timeout():
$MobPath/MobSpawnLocation.offset = randi()
# choose a random location on the Path2D
$MobPath/MobSpawnLocation.set_offset(randi())
var mob = Mob.instance()
add_child(mob)
var direction = $MobPath/MobSpawnLocation.rotation + TAU / 4
var direction = $MobPath/MobSpawnLocation.rotation + PI/2
mob.position = $MobPath/MobSpawnLocation.position
direction += rand_range(-TAU / 8, TAU / 8)
# add some randomness to the direction
direction += rand_range(-PI/4, PI/4)
mob.rotation = direction
mob.linear_velocity = Vector2(rand_range(mob.min_speed, mob.max_speed), 0).rotated(direction)
# warning-ignore:return_value_discarded
$HUD.connect("start_game", mob, "_on_start_game")
func _on_ScoreTimer_timeout():
score += 1
$HUD.update_score(score)
mob.set_linear_velocity(Vector2(rand_range(mob.MIN_SPEED, mob.MAX_SPEED), 0).rotated(direction))
func _on_StartTimer_timeout():
$MobTimer.start()
$ScoreTimer.start()
func _on_ScoreTimer_timeout():
score += 1
$HUD.update_score(score)

View File

@@ -8,47 +8,105 @@
[ext_resource path="res://art/gameover.wav" type="AudioStream" id=6]
[sub_resource type="Curve2D" id=1]
bake_interval = 5.0
_data = {
"points": PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, 480, 720, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0 )
"points": PoolVector2Array( 0, 0, 0, 0, 1.70602, 3.56798, 0, 0, 0, 0, 482.263, 3.26522, 0, 0, 0, 0, 480.489, 729.458, 0, 0, 0, 0, 0.794434, 732.118, 0, 0, 0, 0, 1.97066, 3.83263 )
}
[node name="Main" type="Node"]
[node name="Main" type="Node" index="0"]
script = ExtResource( 1 )
Mob = ExtResource( 2 )
[node name="ColorRect" type="ColorRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
color = Color( 0.219608, 0.372549, 0.380392, 1 )
[node name="ColorRect" type="ColorRect" parent="." index="0"]
[node name="Player" parent="." instance=ExtResource( 3 )]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 486.0
margin_bottom = 734.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
color = Color( 0.253451, 0.425288, 0.429412, 1 )
[node name="MobTimer" type="Timer" parent="."]
[node name="Player" parent="." index="1" instance=ExtResource( 3 )]
[node name="MobTimer" type="Timer" parent="." index="2"]
process_mode = 1
wait_time = 0.5
one_shot = false
autostart = false
[node name="ScoreTimer" type="Timer" parent="."]
[node name="ScoreTimer" type="Timer" parent="." index="3"]
[node name="StartTimer" type="Timer" parent="."]
process_mode = 1
wait_time = 1.0
one_shot = false
autostart = false
[node name="StartTimer" type="Timer" parent="." index="4"]
process_mode = 1
wait_time = 2.0
one_shot = true
autostart = false
[node name="StartPosition" type="Position2D" parent="." index="5"]
[node name="StartPosition" type="Position2D" parent="."]
position = Vector2( 240, 450 )
_sections_unfolded = [ "Transform" ]
[node name="HUD" parent="." index="6" instance=ExtResource( 4 )]
transform = Transform2D( 1, 0, 0, 1, 0, 0 )
[node name="Music" type="AudioStreamPlayer" parent="." index="7"]
stream = ExtResource( 5 )
volume_db = -8.0
autoplay = false
mix_target = 0
bus = "Master"
[node name="DeathSound" type="AudioStreamPlayer" parent="." index="8"]
stream = ExtResource( 6 )
volume_db = -5.0
autoplay = false
mix_target = 0
bus = "Master"
[node name="MobPath" type="Path2D" parent="." index="9"]
[node name="MobPath" type="Path2D" parent="."]
curve = SubResource( 1 )
[node name="MobSpawnLocation" type="PathFollow2D" parent="MobPath"]
[node name="MobSpawnLocation" type="PathFollow2D" parent="MobPath" index="0"]
[node name="HUD" parent="." instance=ExtResource( 4 )]
position = Vector2( 1.70602, 3.56798 )
rotation = -0.000630111
offset = 0.0
h_offset = 0.0
v_offset = 0.0
rotate = true
cubic_interp = true
loop = true
lookahead = 4.0
[node name="Music" type="AudioStreamPlayer" parent="."]
stream = ExtResource( 5 )
[node name="DeathSound" type="AudioStreamPlayer" parent="."]
stream = ExtResource( 6 )
[connection signal="hit" from="Player" to="." method="game_over"]
[connection signal="timeout" from="MobTimer" to="." method="_on_MobTimer_timeout"]
[connection signal="timeout" from="ScoreTimer" to="." method="_on_ScoreTimer_timeout"]
[connection signal="timeout" from="StartTimer" to="." method="_on_StartTimer_timeout"]
[connection signal="start_game" from="HUD" to="." method="new_game"]

View File

@@ -1,17 +1,11 @@
extends RigidBody2D
#warning-ignore-all:unused_class_variable
export var min_speed = 150
export var max_speed = 250
export (int) var MIN_SPEED
export (int) var MAX_SPEED
var mob_types = ["walk", "swim", "fly"]
func _ready():
$AnimatedSprite.animation = mob_types[randi() % mob_types.size()]
func _on_VisibilityNotifier2D_screen_exited():
queue_free()
func _on_start_game():
func _on_Visibility_screen_exited():
queue_free()

View File

@@ -1,24 +1,25 @@
[gd_scene load_steps=10 format=2]
[ext_resource path="res://Mob.gd" type="Script" id=1]
[ext_resource path="res://art/enemyFlyingAlt_1.png" type="Texture" id=2]
[ext_resource path="res://art/enemyFlyingAlt_2.png" type="Texture" id=3]
[ext_resource path="res://art/enemyWalking_1.png" type="Texture" id=4]
[ext_resource path="res://art/enemyWalking_2.png" type="Texture" id=5]
[ext_resource path="res://art/enemyWalking_1.png" type="Texture" id=2]
[ext_resource path="res://art/enemyWalking_2.png" type="Texture" id=3]
[ext_resource path="res://art/enemyFlyingAlt_1.png" type="Texture" id=4]
[ext_resource path="res://art/enemyFlyingAlt_2.png" type="Texture" id=5]
[ext_resource path="res://art/enemySwimming_1.png" type="Texture" id=6]
[ext_resource path="res://art/enemySwimming_2.png" type="Texture" id=7]
[sub_resource type="SpriteFrames" id=1]
animations = [ {
"frames": [ ExtResource( 2 ), ExtResource( 3 ) ],
"loop": true,
"name": "fly",
"speed": 3.0
"name": "walk",
"speed": 4.0
}, {
"frames": [ ExtResource( 4 ), ExtResource( 5 ) ],
"loop": true,
"name": "walk",
"speed": 4.0
"name": "fly",
"speed": 3.0
}, {
"frames": [ ExtResource( 6 ), ExtResource( 7 ) ],
"loop": true,
@@ -27,27 +28,55 @@ animations = [ {
} ]
[sub_resource type="CapsuleShape2D" id=2]
radius = 35.2706
height = 23.3281
custom_solver_bias = 0.0
radius = 34.8222
height = 28.8308
[node name="Mob" type="RigidBody2D"]
input_pickable = true
collision_layer = 1
collision_mask = 0
mode = 0
mass = 1.0
friction = 1.0
bounce = 0.0
gravity_scale = 0.0
custom_integrator = false
continuous_cd = 0
contacts_reported = 0
contact_monitor = false
sleeping = false
can_sleep = true
linear_velocity = Vector2( 0, 0 )
linear_damp = 0.1
angular_velocity = 0.0
angular_damp = 1.0
script = ExtResource( 1 )
_sections_unfolded = [ "Angular", "Collision", "Transform" ]
__meta__ = {
"_edit_group_": true
}
MIN_SPEED = 150
MAX_SPEED = 250
[node name="AnimatedSprite" type="AnimatedSprite" parent="." index="0"]
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
scale = Vector2( 0.75, 0.75 )
frames = SubResource( 1 )
animation = "walk"
frame = 1
animation = "swim"
playing = true
_sections_unfolded = [ "Transform" ]
[node name="Collision" type="CollisionShape2D" parent="." index="1"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
rotation = 1.5708
shape = SubResource( 2 )
_sections_unfolded = [ "Transform", "Visibility" ]
[node name="Visibility" type="VisibilityNotifier2D" parent="." index="2"]
rect = Rect2( -10, -10, 20, 20 )
[node name="VisibilityNotifier2D" type="VisibilityNotifier2D" parent="."]
[connection signal="screen_exited" from="VisibilityNotifier2D" to="." method="_on_VisibilityNotifier2D_screen_exited"]

View File

@@ -2,27 +2,40 @@ extends Area2D
signal hit
export var speed = 400
var screen_size
export (int) var SPEED
var velocity = Vector2()
var screensize
func _ready():
screen_size = get_viewport_rect().size
hide()
screensize = get_viewport_rect().size
func start(pos):
position = pos
show()
$Collision.disabled = false
func _process(delta):
var velocity = Vector2()
velocity.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
velocity.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
velocity = Vector2()
if Input.is_action_pressed("ui_right"):
velocity.x += 1
if Input.is_action_pressed("ui_left"):
velocity.x -= 1
if Input.is_action_pressed("ui_down"):
velocity.y += 1
if Input.is_action_pressed("ui_up"):
velocity.y -= 1
if velocity.length() > 0:
velocity = velocity.normalized() * speed
velocity = velocity.normalized() * SPEED
$AnimatedSprite.play()
$Trail.emitting = true
else:
$AnimatedSprite.stop()
$Trail.emitting = false
position += velocity * delta
position.x = clamp(position.x, 0, screen_size.x)
position.y = clamp(position.y, 0, screen_size.y)
position.x = clamp(position.x, 0, screensize.x)
position.y = clamp(position.y, 0, screensize.y)
if velocity.x != 0:
$AnimatedSprite.animation = "right"
@@ -32,14 +45,10 @@ func _process(delta):
$AnimatedSprite.animation = "up"
$AnimatedSprite.flip_v = velocity.y > 0
func start(pos):
position = pos
show()
$CollisionShape2D.disabled = false
func _on_Player_body_entered(_body):
func _on_Player_body_entered( body ):
$Collision.disabled = true
hide()
emit_signal("hit")
$CollisionShape2D.set_deferred("disabled", true)

View File

@@ -7,6 +7,7 @@
[ext_resource path="res://art/playerGrey_up2.png" type="Texture" id=5]
[sub_resource type="SpriteFrames" id=1]
animations = [ {
"frames": [ ExtResource( 2 ), ExtResource( 3 ) ],
"loop": true,
@@ -20,51 +21,125 @@ animations = [ {
} ]
[sub_resource type="CapsuleShape2D" id=2]
radius = 26.1701
height = 14.822
custom_solver_bias = 0.0
radius = 26.5155
height = 13.8847
[sub_resource type="Gradient" id=3]
colors = PoolColorArray( 1, 1, 1, 0.501961, 1, 1, 1, 0 )
offsets = PoolRealArray( 0, 1 )
colors = PoolColorArray( 1, 1, 1, 0.523804, 1, 1, 1, 0 )
[sub_resource type="GradientTexture" id=4]
flags = 4
gradient = SubResource( 3 )
width = 2048
[sub_resource type="Curve" id=5]
_data = [ Vector2( 0.00501098, 0.5 ), 0.0, 0.0, 0, 0, Vector2( 0.994989, 0.324 ), 0.0, 0.0, 0, 0 ]
min_value = 0.0
max_value = 1.0
bake_resolution = 100
_data = [ Vector2( 0, 0.446289 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.306641 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CurveTexture" id=6]
flags = 4
width = 2048
curve = SubResource( 5 )
[sub_resource type="ParticlesMaterial" id=7]
render_priority = 0
trail_divisor = 1
emission_shape = 0
flag_align_y = false
flag_rotate_y = false
flag_disable_z = true
spread = 45.0
flatness = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 1.0
initial_velocity_random = 0.0
angular_velocity = 1.56945e-43
angular_velocity_random = 0.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
scale = 0.75
linear_accel = 0.0
linear_accel_random = 0.0
radial_accel = 0.0
radial_accel_random = 0.0
tangential_accel = 0.0
tangential_accel_random = 0.0
damping = 0.0
damping_random = 0.0
angle = 0.0
angle_random = 0.0
scale = 1.0
scale_random = 0.0
scale_curve = SubResource( 6 )
color_ramp = SubResource( 4 )
hue_variation = 0.0
hue_variation_random = 0.0
anim_speed = 0.0
anim_speed_random = 0.0
anim_offset = 0.0
anim_offset_random = 0.0
anim_loop = false
_sections_unfolded = [ "Color", "Gravity", "Scale" ]
[node name="Player" type="Area2D"]
z_index = 10
input_pickable = true
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Transform" ]
__meta__ = {
"_edit_group_": true
}
SPEED = 400
[node name="AnimatedSprite" type="AnimatedSprite" parent="." index="0"]
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
scale = Vector2( 0.5, 0.5 )
frames = SubResource( 1 )
animation = "right"
_sections_unfolded = [ "Region", "Transform", "Z" ]
[node name="Collision" type="CollisionShape2D" parent="." index="1"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 2 )
[node name="Trail" type="Particles2D" parent="."]
z_index = -1
[node name="Trail" type="Particles2D" parent="." index="2"]
show_behind_parent = true
emitting = true
amount = 10
lifetime = 1.0
one_shot = false
preprocess = 0.0
speed_scale = 2.0
explosiveness = 0.0
randomness = 0.0
fixed_fps = 0
fract_delta = true
visibility_rect = Rect2( -100, -100, 200, 200 )
local_coords = false
draw_order = 0
process_material = SubResource( 7 )
texture = ExtResource( 2 )
texture = ExtResource( 4 )
normal_map = null
h_frames = 1
v_frames = 1
_sections_unfolded = [ "Drawing", "Process Material", "Textures", "Time", "Transform", "Visibility" ]
[connection signal="body_entered" from="." to="." method="_on_Player_body_entered"]

View File

@@ -1,27 +0,0 @@
# Dodge the Creeps
This is a simple game where your character must move
and avoid the enemies for as long as possible.
This is a finished version of the game featured in the
["Your first game"](https://docs.godotengine.org/en/latest/getting_started/step_by_step/your_first_game.html)
tutorial in the documentation. For more details,
consider following the tutorial in the documentation.
Language: GDScript
Renderer: GLES 3 (particles are not available in GLES 2)
Note: There is a C# version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/mono/dodge_the_creeps).
## Screenshots
![GIF from the documentation](https://docs.godotengine.org/en/latest/_images/dodge_preview.gif)
## Copying
`art/House In a Forest Loop.ogg` Copyright &copy; 2012 [HorrorPen](https://opengameart.org/users/horrorpen), [CC-BY 3.0: Attribution](http://creativecommons.org/licenses/by/3.0/). Source: https://opengameart.org/content/loop-house-in-a-forest
Images are from "Abstract Platformer". Created in 2016 by kenney.nl, [CC0 1.0 Universal](http://creativecommons.org/publicdomain/zero/1.0/). Source: https://www.kenney.nl/assets/abstract-platformer
Font is "Xolonium". Copyright &copy; 2011-2016 Severin Meyer <sev.ch@web.de>, with Reserved Font Name Xolonium, SIL open font license version 1.1. Details are in `fonts/LICENSE.txt`.

View File

@@ -6,8 +6,7 @@ path="res://.import/House In a Forest Loop.ogg-1a6a72ae843ad792b7039931227e8d50.
[deps]
source_file="res://art/House In a Forest Loop.ogg"
dest_files=[ "res://.import/House In a Forest Loop.ogg-1a6a72ae843ad792b7039931227e8d50.oggstr" ]
source_md5="c395b0cc351a71713417cf862282849f"
[params]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/enemyFlyingAlt_1.png-559f599b16c69b112c1b53f6332e9489.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/enemyFlyingAlt_1.png"
dest_files=[ "res://.import/enemyFlyingAlt_1.png-559f599b16c69b112c1b53f6332e9489.stex" ]
source_md5="64d9fdc23f76112a64a283673e3fd8dd"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/enemyFlyingAlt_2.png-31dc7310eda6e1b721224f3cd932c076.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/enemyFlyingAlt_2.png"
dest_files=[ "res://.import/enemyFlyingAlt_2.png-31dc7310eda6e1b721224f3cd932c076.stex" ]
source_md5="5281b0d2b947deb09cbf95ecf9628ae7"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/enemySwimming_1.png-dd0e11759dc3d624c8a704f6e98a3d80.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/enemySwimming_1.png"
dest_files=[ "res://.import/enemySwimming_1.png-dd0e11759dc3d624c8a704f6e98a3d80.stex" ]
source_md5="5e557d1bd564dd553650de1c38746ed9"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/enemySwimming_2.png-4c0cbc0732264c4ea3290340bd4a0a62.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/enemySwimming_2.png"
dest_files=[ "res://.import/enemySwimming_2.png-4c0cbc0732264c4ea3290340bd4a0a62.stex" ]
source_md5="d04b001ba2f4ac6884fdbe44b55fa656"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/enemyWalking_1.png-5af6eedbe61b701677d490ffdc1e6471.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/enemyWalking_1.png"
dest_files=[ "res://.import/enemyWalking_1.png-5af6eedbe61b701677d490ffdc1e6471.stex" ]
source_md5="0e417b74e72f5d8f4aca0e557a735643"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/enemyWalking_2.png-67c480ed60c35e95f5acb0436246b935.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/enemyWalking_2.png"
dest_files=[ "res://.import/enemyWalking_2.png-67c480ed60c35e95f5acb0436246b935.stex" ]
source_md5="838f40a8b77a0cb387dc5e5aff6bd8d5"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

View File

@@ -6,8 +6,7 @@ path="res://.import/gameover.wav-98c95c744b35280048c2bd093cf8a356.sample"
[deps]
source_file="res://art/gameover.wav"
dest_files=[ "res://.import/gameover.wav-98c95c744b35280048c2bd093cf8a356.sample" ]
source_md5="fe94a3a7558cff917a5500a1298fdcac"
[params]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/playerGrey_up1.png-6bd114d0a6beac91f48e3a7314d44564.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/playerGrey_up1.png"
dest_files=[ "res://.import/playerGrey_up1.png-6bd114d0a6beac91f48e3a7314d44564.stex" ]
source_md5="f84241d41055080a3393c9a8619f172b"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/playerGrey_up2.png-d6aba85f5f2675ebc7045efa7552ee79.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/playerGrey_up2.png"
dest_files=[ "res://.import/playerGrey_up2.png-d6aba85f5f2675ebc7045efa7552ee79.stex" ]
source_md5="57618c302a312d248705c7f045978765"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/playerGrey_walk1.png-c4773fe7a7bf85d7ab732eb4458c2742.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/playerGrey_walk1.png"
dest_files=[ "res://.import/playerGrey_walk1.png-c4773fe7a7bf85d7ab732eb4458c2742.stex" ]
source_md5="7892ed98ba910fbda0d37266127e96bb"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/playerGrey_walk2.png-34d2d916366100182d08037c51884043.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/playerGrey_walk2.png"
dest_files=[ "res://.import/playerGrey_walk2.png-34d2d916366100182d08037c51884043.stex" ]
source_md5="9fc73e1224a6b16d8fb5d0f667e3aed2"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,8 +22,7 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
detect_3d=false
svg/scale=1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/set3_tiles.png-7dd06b1fc0bcfaa06e9dd732f61382a2.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://art/set3_tiles.png"
dest_files=[ "res://.import/set3_tiles.png-7dd06b1fc0bcfaa06e9dd732f61382a2.stex" ]
source_md5="eef34d896b231438a2d97707c0ab06a2"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

View File

@@ -0,0 +1,2 @@
"Abstract Platformer" by kenney.nl is licensed under http://creativecommons.org/publicdomain/zero/1.0/
"House in a Forest Loop" by https://opengameart.org/users/horrorpen is licensed under http://creativecommons.org/licenses/by/3.0/

View File

@@ -0,0 +1,102 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
radiance_size = 4
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
sky_curve = 0.25
sky_energy = 1.0
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
ground_energy = 1.0
sun_color = Color( 1, 1, 1, 1 )
sun_latitude = 35.0
sun_longitude = 0.0
sun_angle_min = 1.0
sun_angle_max = 100.0
sun_curve = 0.05
sun_energy = 16.0
texture_size = 2
[resource]
background_mode = 2
background_sky = SubResource( 1 )
background_sky_custom_fov = 0.0
background_color = Color( 0, 0, 0, 1 )
background_energy = 1.0
background_canvas_max_layer = 0
ambient_light_color = Color( 0, 0, 0, 1 )
ambient_light_energy = 1.0
ambient_light_sky_contribution = 0.0
fog_enabled = false
fog_color = Color( 0.5, 0.6, 0.7, 1 )
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
fog_sun_amount = 0.0
fog_depth_enabled = true
fog_depth_begin = 10.0
fog_depth_curve = 1.0
fog_transmit_enabled = false
fog_transmit_curve = 1.0
fog_height_enabled = false
fog_height_min = 0.0
fog_height_max = 100.0
fog_height_curve = 1.0
tonemap_mode = 0
tonemap_exposure = 1.0
tonemap_white = 1.0
auto_exposure_enabled = false
auto_exposure_scale = 0.4
auto_exposure_min_luma = 0.05
auto_exposure_max_luma = 8.0
auto_exposure_speed = 0.5
ss_reflections_enabled = false
ss_reflections_max_steps = 64
ss_reflections_fade_in = 0.15
ss_reflections_fade_out = 2.0
ss_reflections_depth_tolerance = 0.2
ss_reflections_roughness = true
ssao_enabled = false
ssao_radius = 1.0
ssao_intensity = 1.0
ssao_radius2 = 0.0
ssao_intensity2 = 1.0
ssao_bias = 0.01
ssao_light_affect = 0.0
ssao_color = Color( 0, 0, 0, 1 )
ssao_quality = 0
ssao_blur = 1
ssao_edge_sharpness = 4.0
dof_blur_far_enabled = false
dof_blur_far_distance = 10.0
dof_blur_far_transition = 5.0
dof_blur_far_amount = 0.1
dof_blur_far_quality = 1
dof_blur_near_enabled = false
dof_blur_near_distance = 2.0
dof_blur_near_transition = 1.0
dof_blur_near_amount = 0.1
dof_blur_near_quality = 1
glow_enabled = false
glow_levels/1 = false
glow_levels/2 = false
glow_levels/3 = true
glow_levels/4 = false
glow_levels/5 = true
glow_levels/6 = false
glow_levels/7 = false
glow_intensity = 0.8
glow_strength = 1.0
glow_bloom = 0.0
glow_blend_mode = 2
glow_hdr_threshold = 1.0
glow_hdr_scale = 2.0
glow_bicubic_upscale = false
adjustment_enabled = false
adjustment_brightness = 1.0
adjustment_contrast = 1.0
adjustment_saturation = 1.0
_sections_unfolded = [ "Background" ]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -3,21 +3,16 @@
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
source_md5="7b0d811088c13a3b6d79f9895b9f2935"
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
@@ -27,7 +22,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

View File

@@ -6,22 +6,11 @@
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ ]
_global_script_class_icons={
}
config_version=3
[application]
config/name="Dodge the Creeps"
config/description="This is a simple game where your character must move
and avoid the enemies for as long as possible.
This is a finished version of the game featured in the 'Your first game'
tutorial in the documentation, but ported to C#. For more details,
consider following the tutorial in the documentation."
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
@@ -29,38 +18,12 @@ config/icon="res://icon.png"
window/size/width=480
window/size/height=720
window/size/resizable=false
[input]
[gdnative]
move_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
]
}
move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
]
}
move_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
]
}
move_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
]
}
singletons=[ ]
[rendering]
environment/default_environment="res://default_env.tres"

View File

@@ -1,25 +1,21 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://player/Player.tscn" type="PackedScene" id=1]
[ext_resource path="res://debug/Explanations.tscn" type="PackedScene" id=2]
[ext_resource path="res://debug/StatesStackDiplayer.tscn" type="PackedScene" id=3]
[ext_resource path="res://debug/ControlsPanel.tscn" type="PackedScene" id=4]
[ext_resource path="res://debug/StatesStackDiplayer.tscn" type="PackedScene" id=2]
[ext_resource path="res://debug/ControlsPanel.tscn" type="PackedScene" id=3]
[ext_resource path="res://debug/Explanations.tscn" type="PackedScene" id=4]
[node name="Demo" type="Node"]
[node name="Player" parent="." instance=ExtResource( 1 )]
[node name="Player" parent="." index="0" instance=ExtResource( 1 )]
[node name="Explanations" parent="." instance=ExtResource( 2 )]
editor/display_folded = true
[node name="Control" type="Control" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="StatesStackDiplayer" parent="." index="1" instance=ExtResource( 2 )]
[node name="StatesStackDiplayer" parent="Control" instance=ExtResource( 3 )]
[node name="ControlsPanel" parent="." index="2" instance=ExtResource( 3 )]
[node name="Explanations" parent="." index="3" instance=ExtResource( 4 )]
[node name="ControlsPanel" parent="Control" instance=ExtResource( 4 )]
[editable path="Player"]

View File

@@ -1,30 +0,0 @@
# Hierarchical Finite State Machine
This example shows how to apply the State machine programming
pattern in GDscript, including Hierarchical States, and a
pushdown automaton.
Language: GDScript
Renderer: GLES 2
## Why use a state machine
States are common in games. You can use the pattern to:
1. Separate each behavior and transitions between behaviors,
thus make scripts shorter and easier to manage.
2. Respect the Single Responsibility Principle.
Each State object represents one action.
3. Improve your code's structure. Look at the scene tree and
FileSystem tab: without looking at the code, you'll know
what the Player can or cannot do.
You can read more about States in the excellent
[Game Programming Patterns ebook](https://gameprogrammingpatterns.com/state.html).
## Screenshots
![Screenshot](screenshots/fsm-attack.png)

View File

@@ -1,41 +1,77 @@
[gd_scene load_steps=2 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://fonts/source_code_pro_explanations.tres" type="DynamicFont" id=1]
[ext_resource path="res://debug/top_level_ui.gd" type="Script" id=1]
[ext_resource path="res://fonts/source_code_pro_explanations.tres" type="DynamicFont" id=2]
[node name="ControlsPanel" type="Panel" index="0"]
[node name="ControlsPanel" type="Panel"]
anchor_left = 1.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 0.0
margin_left = -220.0
margin_bottom = 170.0
__meta__ = {
"_edit_use_anchors_": false
}
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
script = ExtResource( 1 )
[node name="Keys" type="Label" parent="."]
[node name="Keys" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = 10.0
margin_right = -10.0
margin_bottom = -10.0
custom_fonts/font = ExtResource( 1 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = ExtResource( 2 )
text = "Shoot:
Attack:
Stagger:
Jump:
Sprint:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "BBCode", "custom_fonts" ]
[node name="Keys2" type="Label" parent="."]
[node name="Keys2" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = 10.0
margin_right = -10.0
margin_bottom = -10.0
custom_fonts/font = ExtResource( 1 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = ExtResource( 2 )
text = "R
F
X
Space
Shift"
align = 2
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "BBCode", "custom_fonts" ]

View File

@@ -1,17 +1,25 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://fonts/source_code_pro_explanations_bold.tres" type="DynamicFont" id=1]
[ext_resource path="res://fonts/source_code_pro_explanations.tres" type="DynamicFont" id=2]
[ext_resource path="res://debug/top_level_ui.gd" type="Script" id=3]
[node name="Explanations" type="RichTextLabel"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = -370.0
margin_right = -10.0
margin_bottom = -730.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/bold_font = ExtResource( 1 )
custom_fonts/normal_font = ExtResource( 2 )
@@ -25,6 +33,10 @@ States are common in games. You can use the pattern to:
3. Improve your code's structure. Look at the scene tree and FileSystem tab: without looking at the code, you'll know what the Player can or cannot do.
You can read more about States in the excellent [url=http://gameprogrammingpatterns.com/state.html]Game Programming Patterns ebook[/url]."
visible_characters = -1
percent_visible = 1.0
meta_underlined = true
tab_size = 4
text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
States are common in games. You can use the pattern to:
@@ -34,6 +46,14 @@ States are common in games. You can use the pattern to:
3. Improve your code's structure. Look at the scene tree and FileSystem tab: without looking at the code, you'll know what the Player can or cannot do.
You can read more about States in the excellent Game Programming Patterns ebook."
scroll_active = true
scroll_following = false
selection_enabled = false
override_selected_font_color = false
script = ExtResource( 3 )
_sections_unfolded = [ "BBCode", "custom_fonts" ]
__meta__ = {
"_edit_lock_": true
}

View File

@@ -3,46 +3,106 @@
[ext_resource path="res://debug/states_stack_displayer.gd" type="Script" id=1]
[ext_resource path="res://fonts/SourceCodePro-Bold.ttf" type="DynamicFontData" id=2]
[sub_resource type="DynamicFont" id=1]
size = 20
use_mipmaps = false
use_filter = true
font_data = ExtResource( 2 )
_sections_unfolded = [ "Font", "Settings" ]
[node name="StatesStackDiplayer" type="Panel"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 210.0
margin_bottom = 170.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
script = ExtResource( 1 )
__meta__ = {
"_edit_group_": true
}
[node name="Title" type="Label" parent="."]
[node name="Title" type="Label" parent="." index="0"]
anchor_left = 0.5
anchor_top = 0.0
anchor_right = 0.5
anchor_bottom = 0.0
margin_left = -105.0
margin_right = 105.0
margin_bottom = 40.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 1 )
text = "Pushown"
align = 1
valign = 1
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
[node name="States" type="Label" parent="."]
[node name="States" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 20.0
margin_top = 50.0
margin_right = 190.0
margin_bottom = 170.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 1 )
text = "Jump
Test"
align = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]
[node name="Numbers" type="Label" parent="."]
[node name="Numbers" type="Label" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 20.0
margin_top = 50.0
margin_right = 190.0
margin_bottom = 170.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 1 )
text = "1.
2."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "custom_fonts" ]

View File

@@ -1,14 +1,18 @@
extends Panel
onready var fsm_node = get_node("../../Player/StateMachine")
onready var fsm_node = get_node("../Player/StateMachine")
func _process(_delta):
var states_names = ""
var numbers = ""
func _ready():
set_as_toplevel(true)
func _process(delta):
var states_names = ''
var numbers = ''
var index = 0
for state in fsm_node.states_stack:
states_names += state.get_name() + "\n"
numbers += str(index) + "\n"
states_names += state.get_name() + '\n'
numbers += str(index) + '\n'
index += 1
$States.text = states_names
$Numbers.text = numbers

View File

@@ -0,0 +1,5 @@
tool
extends Control
func _ready():
set_as_toplevel(true)

View File

@@ -0,0 +1,101 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
radiance_size = 4
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
sky_curve = 0.25
sky_energy = 1.0
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
ground_energy = 1.0
sun_color = Color( 1, 1, 1, 1 )
sun_latitude = 35.0
sun_longitude = 0.0
sun_angle_min = 1.0
sun_angle_max = 100.0
sun_curve = 0.05
sun_energy = 16.0
texture_size = 2
[resource]
background_mode = 2
background_sky = SubResource( 1 )
background_sky_custom_fov = 0.0
background_color = Color( 0, 0, 0, 1 )
background_energy = 1.0
background_canvas_max_layer = 0
ambient_light_color = Color( 0, 0, 0, 1 )
ambient_light_energy = 1.0
ambient_light_sky_contribution = 1.0
fog_enabled = false
fog_color = Color( 0.5, 0.6, 0.7, 1 )
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
fog_sun_amount = 0.0
fog_depth_enabled = true
fog_depth_begin = 10.0
fog_depth_curve = 1.0
fog_transmit_enabled = false
fog_transmit_curve = 1.0
fog_height_enabled = false
fog_height_min = 0.0
fog_height_max = 100.0
fog_height_curve = 1.0
tonemap_mode = 0
tonemap_exposure = 1.0
tonemap_white = 1.0
auto_exposure_enabled = false
auto_exposure_scale = 0.4
auto_exposure_min_luma = 0.05
auto_exposure_max_luma = 8.0
auto_exposure_speed = 0.5
ss_reflections_enabled = false
ss_reflections_max_steps = 64
ss_reflections_fade_in = 0.15
ss_reflections_fade_out = 2.0
ss_reflections_depth_tolerance = 0.2
ss_reflections_roughness = true
ssao_enabled = false
ssao_radius = 1.0
ssao_intensity = 1.0
ssao_radius2 = 0.0
ssao_intensity2 = 1.0
ssao_bias = 0.01
ssao_light_affect = 0.0
ssao_color = Color( 0, 0, 0, 1 )
ssao_quality = 0
ssao_blur = 3
ssao_edge_sharpness = 4.0
dof_blur_far_enabled = false
dof_blur_far_distance = 10.0
dof_blur_far_transition = 5.0
dof_blur_far_amount = 0.1
dof_blur_far_quality = 1
dof_blur_near_enabled = false
dof_blur_near_distance = 2.0
dof_blur_near_transition = 1.0
dof_blur_near_amount = 0.1
dof_blur_near_quality = 1
glow_enabled = false
glow_levels/1 = false
glow_levels/2 = false
glow_levels/3 = true
glow_levels/4 = false
glow_levels/5 = true
glow_levels/6 = false
glow_levels/7 = false
glow_intensity = 0.8
glow_strength = 1.0
glow_bloom = 0.0
glow_blend_mode = 2
glow_hdr_threshold = 1.0
glow_hdr_scale = 2.0
glow_bicubic_upscale = false
adjustment_enabled = false
adjustment_brightness = 1.0
adjustment_contrast = 1.0
adjustment_saturation = 1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -3,9 +3,6 @@
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
@@ -17,7 +14,6 @@ dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
@@ -27,7 +23,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

View File

@@ -18,8 +18,15 @@
[sub_resource type="Animation" id=1]
length = 1.0
loop = false
step = 0.1
[sub_resource type="Animation" id=2]
length = 0.6
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath("BodyPivot/Body:modulate")
tracks/0/interp = 1
@@ -35,87 +42,159 @@ tracks/0/keys = {
[sub_resource type="Animation" id=3]
length = 1.0
loop = false
step = 0.1
[sub_resource type="DynamicFont" id=4]
size = 20
use_mipmaps = false
use_filter = true
font_data = ExtResource( 14 )
_sections_unfolded = [ "Font", "Settings" ]
[node name="Player" type="KinematicBody2D" index="0"]
[node name="Player" type="KinematicBody2D"]
position = Vector2( 628.826, 391.266 )
input_pickable = false
collision_layer = 1
collision_mask = 1
collision/safe_margin = 0.08
script = ExtResource( 1 )
_sections_unfolded = [ "Visibility" ]
__meta__ = {
"_edit_horizontal_guides_": [ ]
}
[node name="StateMachine" type="Node" parent="."]
script = ExtResource( 2 )
[node name="StateMachine" type="Node" parent="." index="0"]
script = ExtResource( 2 )
START_STATE = NodePath("Idle")
[node name="Idle" type="Node" parent="StateMachine" index="0"]
[node name="Idle" type="Node" parent="StateMachine"]
script = ExtResource( 3 )
[node name="Move" type="Node" parent="StateMachine"]
[node name="Move" type="Node" parent="StateMachine" index="1"]
script = ExtResource( 4 )
MAX_WALK_SPEED = 450
MAX_RUN_SPEED = 700
[node name="Jump" type="Node" parent="StateMachine" index="2"]
[node name="Jump" type="Node" parent="StateMachine"]
script = ExtResource( 5 )
BASE_MAX_HORIZONTAL_SPEED = 400.0
AIR_ACCELERATION = 1000.0
AIR_DECCELERATION = 2000.0
AIR_STEERING_POWER = 50.0
JUMP_HEIGHT = 120.0
JUMP_DURATION = 0.8
GRAVITY = 1600.0
[node name="Stagger" type="Node" parent="StateMachine" index="3"]
[node name="Stagger" type="Node" parent="StateMachine"]
script = ExtResource( 6 )
[node name="Attack" type="Node" parent="StateMachine"]
[node name="Attack" type="Node" parent="StateMachine" index="4"]
script = ExtResource( 7 )
[node name="Die" type="Node" parent="StateMachine"]
[node name="Die" type="Node" parent="StateMachine" index="5"]
script = ExtResource( 8 )
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="1"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/idle = SubResource( 1 )
anims/stagger = SubResource( 2 )
anims/walk = SubResource( 3 )
blend_times = [ ]
[node name="Shadow" type="Sprite" parent="." index="2"]
[node name="Shadow" type="Sprite" parent="."]
self_modulate = Color( 1, 1, 1, 0.361098 )
position = Vector2( 0, -4 )
texture = ExtResource( 9 )
_sections_unfolded = [ "Visibility" ]
[node name="BodyPivot" type="Position2D" parent="."]
[node name="BodyPivot" type="Position2D" parent="." index="3"]
[node name="Body" type="Sprite" parent="BodyPivot" index="0"]
[node name="Body" type="Sprite" parent="BodyPivot"]
position = Vector2( 0, -58.8242 )
texture = ExtResource( 10 )
[node name="BulletSpawn" type="Node2D" parent="BodyPivot"]
[node name="BulletSpawn" type="Node2D" parent="BodyPivot" index="1"]
editor/display_folded = true
position = Vector2( 1.17401, -61.266 )
script = ExtResource( 11 )
_sections_unfolded = [ "Transform" ]
[node name="CooldownTimer" type="Timer" parent="BodyPivot/BulletSpawn"]
[node name="CooldownTimer" type="Timer" parent="BodyPivot/BulletSpawn" index="0"]
process_mode = 1
wait_time = 0.2
one_shot = true
autostart = false
[node name="WeaponPivot" type="Position2D" parent="BodyPivot" index="2"]
[node name="WeaponPivot" type="Position2D" parent="BodyPivot"]
position = Vector2( 1.17401, -61.266 )
script = ExtResource( 12 )
[node name="Offset" type="Position2D" parent="BodyPivot/WeaponPivot"]
[node name="Offset" type="Position2D" parent="BodyPivot/WeaponPivot" index="0"]
position = Vector2( 110, 0 )
[node name="Sword" parent="BodyPivot/WeaponPivot/Offset" instance=ExtResource( 13 )]
[node name="Sword" parent="BodyPivot/WeaponPivot/Offset" index="0" instance=ExtResource( 13 )]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="4"]
build_mode = 0
polygon = PoolVector2Array( -20, 0, -20, -20, 20, -20, 20, 0 )
[node name="StateNameDisplayer" type="Label" parent="."]
[node name="StateNameDisplayer" type="Label" parent="." index="5"]
editor/display_folded = true
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = -109.0
margin_top = -172.0
margin_right = 110.0
margin_bottom = -138.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 4 )
text = "Test"
align = 1
valign = 1
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
script = ExtResource( 15 )
[connection signal="state_changed" from="StateMachine" to="StateNameDisplayer" method="_on_StateMachine_state_changed"]
_sections_unfolded = [ "Rect", "custom_fonts" ]
[connection signal="state_changed" from="StateMachine" to="BodyPivot/WeaponPivot/Offset/Sword" method="_on_StateMachine_state_changed"]
[connection signal="state_changed" from="StateMachine" to="StateNameDisplayer" method="_on_StateMachine_state_changed"]
[connection signal="animation_finished" from="AnimationPlayer" to="StateMachine" method="_on_animation_finished"]
[connection signal="attack_finished" from="BodyPivot/WeaponPivot/Offset/Sword" to="StateMachine/Attack" method="_on_Sword_attack_finished"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -3,9 +3,6 @@
importer="texture"
type="StreamTexture"
path="res://.import/body.png-313f6363670a5852a7b7126ab476d8b1.stex"
metadata={
"vram_texture": false
}
[deps]
@@ -17,7 +14,6 @@ dest_files=[ "res://.import/body.png-313f6363670a5852a7b7126ab476d8b1.stex" ]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
@@ -27,7 +23,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

View File

@@ -2,13 +2,24 @@
[ext_resource path="res://player/bullet/bullet.gd" type="Script" id=1]
[sub_resource type="CircleShape2D" id=1]
custom_solver_bias = 0.0
radius = 12.0
[node name="Bullet" type="KinematicBody2D"]
input_pickable = false
collision_layer = 2
collision_mask = 2
collision/safe_margin = 0.08
script = ExtResource( 1 )
_sections_unfolded = [ "Collision", "collision" ]
SPEED = 1000.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="0"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )

View File

@@ -1,23 +1,28 @@
extends KinematicBody2D
var direction = Vector2()
export(float) var speed = 1000.0
onready var root = get_tree().root
var direction = Vector2()
export(float) var SPEED = 1000.0
func _ready():
set_as_toplevel(true)
func _physics_process(delta):
if not root.get_visible_rect().has_point(position):
if is_outside_view_bounds():
queue_free()
var motion = direction * speed * delta
var motion = direction * SPEED * delta
var collision_info = move_and_collide(motion)
if collision_info:
queue_free()
func is_outside_view_bounds():
return position.x > OS.get_screen_size().x or position.x < 0.0 \
or position.y > OS.get_screen_size().y or position.y < 0.0
func _draw():
draw_circle(Vector2(), $CollisionShape2D.shape.radius, Color.white)
draw_circle(Vector2(), $CollisionShape2D.shape.radius, Color('#ffffff'))

View File

@@ -2,11 +2,10 @@ extends Node2D
var bullet = preload("Bullet.tscn")
func _unhandled_input(event):
func _input(event):
if event.is_action_pressed("fire"):
fire(owner.look_direction)
func fire(direction):
if not $CooldownTimer.is_stopped():
return

View File

@@ -1,25 +1,25 @@
"""
The Player is a KinematicBody2D, in other words a physics-driven object.
It can move, collide with the world...
It HAS a state machine, but the body and the state machine are separate.
"""
extends KinematicBody2D
# The Player is a KinematicBody2D, in other words a physics-driven object.
# It can move, collide with the world, etc...
# The player has a state machine, but the body and the state machine are separate.
signal direction_changed(new_direction)
var look_direction = Vector2.RIGHT setget set_look_direction
var look_direction = Vector2(1, 0) setget set_look_direction
func take_damage(attacker, amount, effect = null):
if is_a_parent_of(attacker):
func take_damage(attacker, amount, effect=null):
if self.is_a_parent_of(attacker):
return
$States/Stagger.knockback_direction = (attacker.global_position - global_position).normalized()
$Health.take_damage(amount, effect)
func set_dead(value):
set_process_input(not value)
set_physics_process(not value)
$CollisionPolygon2D.disabled = value
func set_look_direction(value):
look_direction = value
emit_signal("direction_changed", value)

View File

@@ -1,37 +1,33 @@
extends "res://state_machine/state_machine.gd"
onready var idle = $Idle
onready var move = $Move
onready var jump = $Jump
onready var stagger = $Stagger
onready var attack = $Attack
func _ready():
states_map = {
"idle": idle,
"move": move,
"jump": jump,
"stagger": stagger,
"attack": attack,
"idle": $Idle,
"move": $Move,
"jump": $Jump,
"stagger": $Stagger,
"attack": $Attack,
}
func _change_state(state_name):
# The base state_machine interface this node extends does most of the work.
"""
The base state_machine interface this node extends does most of the work
"""
if not _active:
return
if state_name in ["stagger", "jump", "attack"]:
states_stack.push_front(states_map[state_name])
if state_name == "jump" and current_state == move:
jump.initialize(move.speed, move.velocity)
if state_name == "jump" and current_state == $Move:
$Jump.initialize($Move.speed, $Move.velocity)
._change_state(state_name)
func _unhandled_input(event):
# Here we only handle input that can interrupt states, attacking in this case,
# otherwise we let the state node handle it.
func _input(event):
"""
Here we only handle input that can interrupt states, attacking in this case
otherwise we let the state node handle it
"""
if event.is_action_pressed("attack"):
if current_state in [attack, stagger]:
if current_state in [$Attack, $Stagger]:
return
_change_state("attack")
return

Binary file not shown.

Before

Width:  |  Height:  |  Size: 765 B

After

Width:  |  Height:  |  Size: 967 B

View File

@@ -3,9 +3,6 @@
importer="texture"
type="StreamTexture"
path="res://.import/shadow.png-493c4635eca1ce8bdece629560617dc7.stex"
metadata={
"vram_texture": false
}
[deps]
@@ -17,7 +14,6 @@ dest_files=[ "res://.import/shadow.png-493c4635eca1ce8bdece629560617dc7.stex" ]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
@@ -27,7 +23,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

View File

@@ -3,6 +3,5 @@ extends "res://state_machine/state.gd"
func enter():
owner.get_node("AnimationPlayer").play("idle")
func _on_Sword_attack_finished():
emit_signal("finished", "previous")

View File

@@ -1,12 +1,15 @@
"""
The stagger state end with the stagger animation from the AnimationPlayer
The animation only affects the Body Sprite"s modulate property so
it could stack with other animations if we had two AnimationPlayer nodes
"""
extends "res://state_machine/state.gd"
# The stagger state end with the stagger animation from the AnimationPlayer.
# The animation only affects the Body Sprite's modulate property so it
# could stack with other animations if we had two AnimationPlayer nodes.
var knockback_direction = Vector2()
func enter():
owner.get_node("AnimationPlayer").play("stagger")
func _on_animation_finished(anim_name):
assert(anim_name == "stagger")
assert anim_name == "stagger"
emit_signal("finished", "previous")

View File

@@ -5,10 +5,8 @@ var start_position = Vector2()
func _ready():
start_position = rect_position
func _physics_process(_delta):
func _physics_process(delta):
rect_position = $"../BodyPivot".position + start_position
func _on_StateMachine_state_changed(current_state):
text = current_state.get_name()

View File

@@ -1,10 +1,10 @@
extends "res://state_machine/state.gd"
# Initialize the state. E.g. change the animation.
# Initialize the state. E.g. change the animation
func enter():
owner.set_dead(true)
owner.get_node("AnimationPlayer").play("die")
func _on_animation_finished(_anim_name):
func _on_animation_finished(anim_name):
emit_signal("finished", "dead")

View File

@@ -1,12 +1,15 @@
extends "../motion.gd"
export(float) var base_max_horizontal_speed = 400.0
export(float) var BASE_MAX_HORIZONTAL_SPEED = 400.0
export(float) var air_acceleration = 1000.0
export(float) var air_deceleration = 2000.0
export(float) var air_steering_power = 50.0
export(float) var AIR_ACCELERATION = 1000.0
export(float) var AIR_DECCELERATION = 2000.0
export(float) var AIR_STEERING_POWER = 50.0
export(float) var gravity = 1600.0
export(float) var JUMP_HEIGHT = 120.0
export(float) var JUMP_DURATION = 0.8
export(float) var GRAVITY = 1600.0
var enter_velocity = Vector2()
@@ -19,10 +22,9 @@ var height = 0.0
func initialize(speed, velocity):
horizontal_speed = speed
max_horizontal_speed = speed if speed > 0.0 else base_max_horizontal_speed
max_horizontal_speed = speed if speed > 0.0 else BASE_MAX_HORIZONTAL_SPEED
enter_velocity = velocity
func enter():
var input_direction = get_input_direction()
update_look_direction(input_direction)
@@ -32,7 +34,6 @@ func enter():
owner.get_node("AnimationPlayer").play("idle")
func update(delta):
var input_direction = get_input_direction()
update_look_direction(input_direction)
@@ -42,23 +43,21 @@ func update(delta):
if height <= 0.0:
emit_signal("finished", "previous")
func move_horizontally(delta, direction):
if direction:
horizontal_speed += air_acceleration * delta
horizontal_speed += AIR_ACCELERATION * delta
else:
horizontal_speed -= air_deceleration * delta
horizontal_speed -= AIR_DECCELERATION * delta
horizontal_speed = clamp(horizontal_speed, 0, max_horizontal_speed)
var target_velocity = horizontal_speed * direction.normalized()
var steering_velocity = (target_velocity - horizontal_velocity).normalized() * air_steering_power
var steering_velocity = (target_velocity - horizontal_velocity).normalized() * AIR_STEERING_POWER
horizontal_velocity += steering_velocity
owner.move_and_slide(horizontal_velocity)
func animate_jump_height(delta):
vertical_speed -= gravity * delta
vertical_speed -= GRAVITY * delta
height += vertical_speed * delta
height = max(0.0, height)

View File

@@ -1,19 +1,16 @@
# Collection of important methods to handle direction and animation
extends "res://state_machine/state.gd"
# Collection of important methods to handle direction and animation.
func handle_input(event):
if event.is_action_pressed("simulate_damage"):
emit_signal("finished", "stagger")
func get_input_direction():
var input_direction = Vector2(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
)
var input_direction = Vector2()
input_direction.x = int(Input.is_action_pressed("move_right")) - int(Input.is_action_pressed("move_left"))
input_direction.y = int(Input.is_action_pressed("move_down")) - int(Input.is_action_pressed("move_up"))
return input_direction
func update_look_direction(direction):
if direction and owner.look_direction != direction:
owner.look_direction = direction

View File

@@ -3,12 +3,10 @@ extends "on_ground.gd"
func enter():
owner.get_node("AnimationPlayer").play("idle")
func handle_input(event):
return .handle_input(event)
func update(_delta):
func update(delta):
var input_direction = get_input_direction()
if input_direction:
emit_signal("finished", "move")

View File

@@ -1,7 +1,7 @@
extends "on_ground.gd"
export(float) var max_walk_speed = 450
export(float) var max_run_speed = 700
export(float) var MAX_WALK_SPEED = 450
export(float) var MAX_RUN_SPEED = 700
func enter():
speed = 0.0
@@ -11,25 +11,22 @@ func enter():
update_look_direction(input_direction)
owner.get_node("AnimationPlayer").play("walk")
func handle_input(event):
return .handle_input(event)
func update(_delta):
func update(delta):
var input_direction = get_input_direction()
if not input_direction:
emit_signal("finished", "idle")
update_look_direction(input_direction)
speed = max_run_speed if Input.is_action_pressed("run") else max_walk_speed
speed = MAX_RUN_SPEED if Input.is_action_pressed("run") else MAX_WALK_SPEED
var collision_info = move(speed, input_direction)
if not collision_info:
return
if speed == max_run_speed and collision_info.collider.is_in_group("environment"):
if speed == MAX_RUN_SPEED and collision_info.collider.is_in_group("environment"):
return null
func move(speed, direction):
velocity = direction.normalized() * speed
owner.move_and_slide(velocity, Vector2(), 5, 2)

View File

@@ -1,6 +1,5 @@
extends "../motion.gd"
# warning-ignore-all:unused_class_variable
var speed = 0.0
var velocity = Vector2()

View File

@@ -4,7 +4,11 @@
[ext_resource path="res://player/weapon/sword.png" type="Texture" id=2]
[sub_resource type="Animation" id=1]
resource_name = "SETUP"
length = 1.0
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
tracks/0/interp = 1
@@ -67,8 +71,10 @@ tracks/4/keys = {
}
[sub_resource type="Animation" id=2]
resource_name = "attack_circular"
length = 0.3
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
@@ -108,7 +114,9 @@ tracks/2/keys = {
}
[sub_resource type="Animation" id=3]
length = 0.45
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
@@ -165,8 +173,10 @@ tracks/3/keys = {
}
[sub_resource type="Animation" id=4]
resource_name = "attack_medium"
length = 0.5
loop = false
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath(".:rotation_degrees")
@@ -206,7 +216,10 @@ tracks/2/keys = {
}
[sub_resource type="Animation" id=5]
length = 0.01
loop = false
step = 0.1
tracks/0/type = "value"
tracks/0/path = NodePath(".:visible")
tracks/0/interp = 1
@@ -221,23 +234,45 @@ tracks/0/keys = {
}
[node name="Sword" type="Area2D"]
input_pickable = false
gravity_vec = Vector2( 0, 1 )
gravity = 98.0
linear_damp = 0.1
angular_damp = 1.0
monitorable = false
collision_layer = 16
collision_mask = 3
audio_bus_override = false
audio_bus_name = "Master"
script = ExtResource( 1 )
_sections_unfolded = [ "Transform" ]
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="0"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/SETUP = SubResource( 1 )
anims/attack_circular = SubResource( 2 )
anims/attack_fast = SubResource( 3 )
anims/attack_medium = SubResource( 4 )
anims/idle = SubResource( 5 )
blend_times = [ ]
_sections_unfolded = [ "Playback Options" ]
[node name="sword" type="Sprite" parent="." index="1"]
[node name="Sword" type="Sprite" parent="."]
position = Vector2( 4, 0 )
texture = ExtResource( 2 )
offset = Vector2( 67, 0 )
_sections_unfolded = [ "Offset", "Transform" ]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." index="2"]
build_mode = 0
polygon = PoolVector2Array( 28.0001, -15.9999, 136, -15.9995, 160, 0, 136, 16.0005, 27.9999, 16.0001 )

View File

@@ -2,112 +2,101 @@ extends Area2D
signal attack_finished
enum States { IDLE, ATTACK }
enum STATES { IDLE, ATTACK }
var state = null
enum AttackInputStates { IDLE, LISTENING, REGISTERED }
var attack_input_state = AttackInputStates.IDLE
enum ATTACK_INPUT_STATES { IDLE, LISTENING, REGISTERED }
var attack_input_state = ATTACK_INPUT_STATES.IDLE
var ready_for_next_attack = false
const MAX_COMBO_COUNT = 3
var combo_count = 0
var attack_current = {}
var combo = [{
"damage": 1,
"animation": "attack_fast",
"effect": null
'damage': 1,
'animation': 'attack_fast',
'effect': null
},
{
"damage": 1,
"animation": "attack_fast",
"effect": null
'damage': 1,
'animation': 'attack_fast',
'effect': null
},
{
"damage": 3,
"animation": "attack_medium",
"effect": null
'damage': 3,
'animation': 'attack_medium',
'effect': null
}]
var hit_objects = []
func _ready():
# warning-ignore:return_value_discarded
$AnimationPlayer.connect("animation_finished", self, "_on_animation_finished")
# warning-ignore:return_value_discarded
$AnimationPlayer.connect('animation_finished', self, "_on_animation_finished")
self.connect("body_entered", self, "_on_body_entered")
_change_state(States.IDLE)
_change_state(STATES.IDLE)
func _change_state(new_state):
match state:
States.ATTACK:
STATES.ATTACK:
hit_objects = []
attack_input_state = AttackInputStates.LISTENING
attack_input_state = ATTACK_INPUT_STATES.LISTENING
ready_for_next_attack = false
match new_state:
States.IDLE:
STATES.IDLE:
combo_count = 0
$AnimationPlayer.stop()
visible = false
monitoring = false
States.ATTACK:
STATES.ATTACK:
attack_current = combo[combo_count -1]
$AnimationPlayer.play(attack_current["animation"])
$AnimationPlayer.play(attack_current['animation'])
visible = true
monitoring = true
state = new_state
func _unhandled_input(event):
if not state == States.ATTACK:
func _input(event):
if not state == STATES.ATTACK:
return
if attack_input_state != AttackInputStates.LISTENING:
if attack_input_state != ATTACK_INPUT_STATES.LISTENING:
return
if event.is_action_pressed("attack"):
attack_input_state = AttackInputStates.REGISTERED
if event.is_action_pressed('attack'):
attack_input_state = ATTACK_INPUT_STATES.REGISTERED
func _physics_process(_delta):
if attack_input_state == AttackInputStates.REGISTERED and ready_for_next_attack:
func _physics_process(delta):
if attack_input_state == ATTACK_INPUT_STATES.REGISTERED and ready_for_next_attack:
attack()
func attack():
combo_count += 1
_change_state(States.ATTACK)
_change_state(STATES.ATTACK)
# Use with AnimationPlayer func track.
# use with AnimationPlayer func track
func set_attack_input_listening():
attack_input_state = AttackInputStates.LISTENING
attack_input_state = ATTACK_INPUT_STATES.LISTENING
# Use with AnimationPlayer func track.
# use with AnimationPlayer func track
func set_ready_for_next_attack():
ready_for_next_attack = true
func _on_body_entered(body):
if not body.has_node("Health"):
if not body.has_node('Health'):
return
if body.get_rid().get_id() in hit_objects:
return
hit_objects.append(body.get_rid().get_id())
body.take_damage(self, attack_current["damage"], attack_current["effect"])
body.take_damage(self, attack_current['damage'], attack_current['effect'])
func _on_animation_finished(_name):
func _on_animation_finished(name):
if not attack_current:
return
if attack_input_state == AttackInputStates.REGISTERED and combo_count < MAX_COMBO_COUNT:
if attack_input_state == ATTACK_INPUT_STATES.REGISTERED and combo_count < MAX_COMBO_COUNT:
attack()
else:
_change_state(States.IDLE)
_change_state(STATES.IDLE)
emit_signal("attack_finished")
func _on_StateMachine_state_changed(current_state):
if current_state.name == "Attack":
attack()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -3,9 +3,6 @@
importer="texture"
type="StreamTexture"
path="res://.import/sword.png-fc7f0084cdf333c826eda2b33f2ec3cc.stex"
metadata={
"vram_texture": false
}
[deps]
@@ -17,7 +14,6 @@ dest_files=[ "res://.import/sword.png-fc7f0084cdf333c826eda2b33f2ec3cc.stex" ]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
@@ -27,7 +23,6 @@ flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true

View File

@@ -3,15 +3,13 @@ extends Position2D
var z_index_start = 0
func _ready():
#warning-ignore:return_value_discarded
owner.connect("direction_changed", self, "_on_Parent_direction_changed")
owner.connect("direction_changed", self, '_on_Parent_direction_changed')
z_index_start = z_index
func _on_Parent_direction_changed(direction):
rotation = direction.angle()
match direction:
Vector2.UP:
Vector2(0, -1):
z_index = z_index_start - 1
_:
z_index = z_index_start

View File

@@ -6,19 +6,11 @@
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ ]
_global_script_class_icons={
}
config_version=3
[application]
config/name="Hierarchical Finite State Machine"
config/description="This example shows how to apply the State machine programming
pattern in GDscript, including Hierarchical States, and a
pushdown automaton."
config/name="Hierarchical Finite State Machine example"
run/main_scene="res://Demo.tscn"
config/icon="res://icon.png"
@@ -26,8 +18,10 @@ config/icon="res://icon.png"
window/size/width=1280
window/size/height=720
window/size/test_width=1280
window/size/test_height=720
window/stretch/mode="2d"
window/stretch/aspect="expand"
window/stretch/aspect="keep"
[gdnative]
@@ -35,69 +29,36 @@ singletons=[ ]
[input]
move_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
move_left=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
]
}
move_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
move_up=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
]
}
move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
move_right=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
]
}
move_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
move_down=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
]
}
fire={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null)
fire=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
]
run=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
]
}
run={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
]
}
jump={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
jump=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
simulate_damage={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":88,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
simulate_damage=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":88,"unicode":0,"echo":false,"script":null)
]
}
attack={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":6,"pressure":0.0,"pressed":false,"script":null)
attack=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"unicode":0,"echo":false,"script":null)
]
}
[rendering]
quality/driver/driver_name="GLES2"
environment/default_environment="res://default_env.tres"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -1,28 +1,25 @@
"""
Base interface for all states: it doesn't do anything in itself
but forces us to pass the right arguments to the methods below
and makes sure every State object had all of these methods.
"""
extends Node
# Base interface for all states: it doesn't do anything by itself,
# but forces us to pass the right arguments to the methods below
# and makes sure every State object had all of these methods.
# warning-ignore:unused_signal
signal finished(next_state_name)
# Initialize the state. E.g. change the animation.
# Initialize the state. E.g. change the animation
func enter():
pass
return
# Clean up the state. Reinitialize values like a timer.
# Clean up the state. Reinitialize values like a timer
func exit():
pass
return
func handle_input(event):
return
func handle_input(_event):
pass
func update(delta):
return
func update(_delta):
pass
func _on_animation_finished(_anim_name):
pass
func _on_animation_finished(anim_name):
return

View File

@@ -1,16 +1,21 @@
"""
Base interface for a generic state machine
It handles initializing, setting the machine active or not
delegating _physics_process, _input calls to the State nodes,
and changing the current/active state.
See the PlayerV2 scene for an example on how to use it
"""
extends Node
# Base interface for a generic state machine.
# It handles initializing, setting the machine active or not
# delegating _physics_process, _input calls to the State nodes,
# and changing the current/active state.
# See the PlayerV2 scene for an example on how to use it.
signal state_changed(current_state)
# You should set a starting node from the inspector or on the node that inherits
# from this state machine interface. If you don't, the game will default to
# the first state in the state machine's children.
export(NodePath) var start_state
"""
You must set a starting node from the inspector or on
the node that inherits from this state machine interface
If you don't the game will crash (on purpose, so you won't
forget to initialize the state machine)
"""
export(NodePath) var START_STATE
var states_map = {}
var states_stack = []
@@ -18,22 +23,18 @@ var current_state = null
var _active = false setget set_active
func _ready():
if not start_state:
start_state = get_child(0).get_path()
if not START_STATE:
START_STATE = get_child(0).get_path()
for child in get_children():
var err = child.connect("finished", self, "_change_state")
if err:
printerr(err)
initialize(start_state)
child.connect("finished", self, "_change_state")
initialize(START_STATE)
func initialize(initial_state):
func initialize(start_state):
set_active(true)
states_stack.push_front(get_node(initial_state))
states_stack.push_front(get_node(start_state))
current_state = states_stack[0]
current_state.enter()
func set_active(value):
_active = value
set_physics_process(value)
@@ -42,21 +43,17 @@ func set_active(value):
states_stack = []
current_state = null
func _unhandled_input(event):
func _input(event):
current_state.handle_input(event)
func _physics_process(delta):
current_state.update(delta)
func _on_animation_finished(anim_name):
if not _active:
return
current_state._on_animation_finished(anim_name)
func _change_state(state_name):
if not _active:
return

View File

@@ -1,13 +0,0 @@
# GD Paint
GD Paint is a simple image editor made using Godot and GDScript.
It supports different types of "brushes": a basic pen/pencil
and eraser, as well as a rectangle and a circle brush.
Language: GDScript
Renderer: GLES 2
## Screenshots
![Screenshot](screenshots/gdpaint.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

View File

@@ -1,247 +0,0 @@
extends Control
# A constant for whether or not we're needing to undo a shape.
const UNDO_MODE_SHAPE = -2
# A constant for whether or not we can undo.
const UNDO_NONE = -1
# How large is the image (it's actually the size of DrawingAreaBG, because that's our background canvas).
const IMAGE_SIZE = Vector2(930, 720)
# Enums for the various modes and brush shapes that can be applied.
enum BrushModes {
PENCIL, ERASER, CIRCLE_SHAPE, RECTANGLE_SHAPE
}
enum BrushShapes {
RECTANGLE, CIRCLE
}
# The top-left position of the canvas.
var TL_node
# A list to hold all of the dictionaries that make up each brush.
var brush_data_list = []
# A boolean to hold whether or not the mouse is inside the drawing area, the mouse position last _process call
# and the position of the mouse when the left mouse button was pressed.
var is_mouse_in_drawing_area = false
var last_mouse_pos = Vector2()
var mouse_click_start_pos = null
# A boolean to tell whether we've set undo_elements_list_num, which holds the size of draw_elements_list
# before a new stroke is added (unless the current brush mode is 'rectangle shape' or 'circle shape', in
# which case we do things a litte differently. See the undo_stroke function for more details).
var undo_set = false
var undo_element_list_num = -1
# The current brush settings: The mode, size, color, and shape we have currently selected.
var brush_mode = BrushModes.PENCIL
var brush_size = 32
var brush_color = Color.black
var brush_shape = BrushShapes.CIRCLE;
# The color of the background. We need this for the eraser (see the how we handle the eraser
# in the _draw function for more details).
var bg_color = Color.white
func _ready():
# Get the top left position node. We need this to find out whether or not the mouse is inside the canvas.
TL_node = get_node("TLPos")
set_process(true)
func _process(_delta):
var mouse_pos = get_viewport().get_mouse_position()
# Check if the mouse is currently inside the canvas/drawing-area.
is_mouse_in_drawing_area = false
if mouse_pos.x > TL_node.global_position.x:
if mouse_pos.y > TL_node.global_position.y:
is_mouse_in_drawing_area = true
if Input.is_mouse_button_pressed(BUTTON_LEFT):
# If we do not have a position for when the mouse was first clicked, then this must
# be the first time is_mouse_button_pressed has been called since the mouse button was
# released, so we need to store the position.
if mouse_click_start_pos == null:
mouse_click_start_pos = mouse_pos
# If the mouse is inside the canvas and the mouse is 1px away from the position of the mouse last _process call.
if check_if_mouse_is_inside_canvas():
if mouse_pos.distance_to(last_mouse_pos) >= 1:
# If we are in pencil or eraser mode, then we need to draw.
if brush_mode == BrushModes.PENCIL or brush_mode == BrushModes.ERASER:
# If undo has not been set, meaning we've started a new stroke, then store the size of the
# draw_elements_list so we can undo from this point in time.
if undo_set == false:
undo_set = true
undo_element_list_num = brush_data_list.size()
# Add the brush object to draw_elements_array.
add_brush(mouse_pos, brush_mode)
else:
# We've finished our stroke, so we can set a new undo (if a new storke is made).
undo_set = false
# If the mouse is inside the canvas.
if check_if_mouse_is_inside_canvas():
# If we're using either the circle shape mode, or the rectangle shape mode, then
# add the brush object to draw_elements_array.
if brush_mode == BrushModes.CIRCLE_SHAPE or brush_mode == BrushModes.RECTANGLE_SHAPE:
add_brush(mouse_pos, brush_mode)
# We handle undo's differently than either pencil or eraser mode, so we need to set undo
# element_list_num to -2 so we can tell if we need to undo a shape. See undo_stroke for details.
undo_element_list_num = UNDO_MODE_SHAPE
# Since we've released the left mouse, we need to get a new mouse_click_start_pos next time
#is_mouse_button_pressed is true.
mouse_click_start_pos = null
# Store mouse_pos as last_mouse_pos now that we're done with _process.
last_mouse_pos = mouse_pos
func check_if_mouse_is_inside_canvas():
# Make sure we have a mouse click starting position.
if mouse_click_start_pos != null:
# Make sure the mouse click starting position is inside the canvas.
# This is so if we start out click outside the canvas (say chosing a color from the color picker)
# and then move our mouse back into the canvas, it won't start painting.
if mouse_click_start_pos.x > TL_node.global_position.x:
if mouse_click_start_pos.y > TL_node.global_position.y:
# Make sure the current mouse position is inside the canvas.
if is_mouse_in_drawing_area == true:
return true
return false
func undo_stroke():
# Only undo a stroke if we have one.
if undo_element_list_num == UNDO_NONE:
return
# If we are undoing a shape, then we can just remove the latest brush.
if undo_element_list_num == UNDO_MODE_SHAPE:
if brush_data_list.size() > 0:
brush_data_list.remove(brush_data_list.size() - 1)
# Now that we've undone a shape, we cannot undo again until another stoke is added.
undo_element_list_num = UNDO_NONE
# NOTE: if we only had shape brushes, then we could remove the above line and could let the user
# undo until we have a empty element list.
# Otherwise we're removing a either a pencil stroke or a eraser stroke.
else:
# Figure out how many elements/brushes we've added in the last stroke.
var elements_to_remove = brush_data_list.size() - undo_element_list_num
# Remove all of the elements we've added this in the last stroke.
#warning-ignore:unused_variable
for elment_num in range(0, elements_to_remove):
brush_data_list.pop_back()
# Now that we've undone a stoke, we cannot undo again until another stoke is added.
undo_element_list_num = UNDO_NONE
# Redraw the brushes
update()
func add_brush(mouse_pos, type):
# Make new brush dictionary that will hold all of the data we need for the brush.
var new_brush = {}
# Populate the dictionary with values based on the global brush variables.
# We will override these as needed if the brush is a rectange or circle.
new_brush.brush_type = type
new_brush.brush_pos = mouse_pos
new_brush.brush_shape = brush_shape
new_brush.brush_size = brush_size
new_brush.brush_color = brush_color
# If the new bursh is a rectangle shape, we need to calculate the top left corner of the rectangle and the
# bottom right corner of the rectangle.
if type == BrushModes.RECTANGLE_SHAPE:
var TL_pos = Vector2()
var BR_pos = Vector2()
# Figure out the left and right positions of the corners and assign them to the proper variable.
if mouse_pos.x < mouse_click_start_pos.x:
TL_pos.x = mouse_pos.x
BR_pos.x = mouse_click_start_pos.x
else:
TL_pos.x = mouse_click_start_pos.x
BR_pos.x = mouse_pos.x
# Figure out the top and bottom positions of the corners and assign them to the proper variable.
if mouse_pos.y < mouse_click_start_pos.y:
TL_pos.y = mouse_pos.y
BR_pos.y = mouse_click_start_pos.y
else:
TL_pos.y = mouse_click_start_pos.y
BR_pos.y = mouse_pos.y
# Assign the positions to the brush.
new_brush.brush_pos = TL_pos
new_brush.brush_shape_rect_pos_BR = BR_pos
# If the brush isa circle shape, then we need to calculate the radius of the circle.
if type == BrushModes.CIRCLE_SHAPE:
# Get the center point inbetween the mouse position and the position of the mouse when we clicked.
var center_pos = Vector2((mouse_pos.x + mouse_click_start_pos.x) / 2, (mouse_pos.y + mouse_click_start_pos.y) / 2)
# Assign the brush position to the center point, and calculate the radius of the circle using the distance from
# the center to the top/bottom positon of the mouse.
new_brush.brush_pos = center_pos
new_brush.brush_shape_circle_radius = center_pos.distance_to(Vector2(center_pos.x, mouse_pos.y))
# Add the brush and update/draw all of the brushes.
brush_data_list.append(new_brush)
update()
func _draw():
# Go through all of the brushes in brush_data_list.
for brush in brush_data_list:
match brush.brush_type:
BrushModes.PENCIL:
# If the brush shape is a rectangle, then we need to make a Rect2 so we can use draw_rect.
# Draw_rect draws a rectagle at the top left corner, using the scale for the size.
# So we offset the position by half of the brush size so the rectangle's center is at mouse position.
if brush.brush_shape == BrushShapes.RECTANGLE:
var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size))
draw_rect(rect, brush.brush_color)
# If the brush shape is a circle, then we draw a circle at the mouse position,
# making the radius half of brush size (so the circle is brush size pixels in diameter).
elif brush.brush_shape == BrushShapes.CIRCLE:
draw_circle(brush.brush_pos, brush.brush_size / 2, brush.brush_color)
BrushModes.ERASER:
# NOTE: this is a really cheap way of erasing that isn't really erasing!
# However, this gives similar results in a fairy simple way!
# Erasing works exactly the same was as pencil does for both the rectangle shape and the circle shape,
# but instead of using brush.brush_color, we instead use bg_color instead.
if brush.brush_shape == BrushShapes.RECTANGLE:
var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size))
draw_rect(rect, bg_color)
elif brush.brush_shape == BrushShapes.CIRCLE:
draw_circle(brush.brush_pos, brush.brush_size / 2, bg_color)
BrushModes.RECTANGLE_SHAPE:
# We make a Rect2 with the postion at the top left. To get the size we take the bottom right position
# and subtract the top left corner's position.
var rect = Rect2(brush.brush_pos, brush.brush_shape_rect_pos_BR - brush.brush_pos)
draw_rect(rect, brush.brush_color)
BrushModes.CIRCLE_SHAPE:
# We simply draw a circle using stored in brush.
draw_circle(brush.brush_pos, brush.brush_shape_circle_radius, brush.brush_color)
func save_picture(path):
# Wait until the frame has finished before getting the texture.
yield(VisualServer, "frame_post_draw")
# Get the viewport image.
var img = get_viewport().get_texture().get_data()
# Crop the image so we only have canvas area.
var cropped_image = img.get_rect(Rect2(TL_node.global_position, IMAGE_SIZE))
# Flip the image on the Y-axis (it's flipped upside down by default).
cropped_image.flip_y()
# Save the image with the passed in path we got from the save dialog.
cropped_image.save_png(path)

View File

@@ -1,222 +0,0 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://paint_control.gd" type="Script" id=1]
[ext_resource path="res://tools_panel.gd" type="Script" id=2]
[ext_resource path="res://paint_tools.png" type="Texture" id=3]
[sub_resource type="StyleBoxFlat" id=1]
bg_color = Color( 1, 1, 1, 1 )
[node name="PaintRoot" type="Control"]
margin_right = 40.0
margin_bottom = 40.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="DrawingAreaBG" type="Panel" parent="."]
margin_left = 350.0
margin_right = 1280.0
margin_bottom = 720.0
custom_styles/panel = SubResource( 1 )
[node name="PaintControl" type="Control" parent="."]
margin_right = 40.0
margin_bottom = 40.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TLPos" type="Position2D" parent="PaintControl"]
position = Vector2( 350, 0 )
[node name="ToolsPanel" type="Panel" parent="."]
margin_right = 350.0
margin_bottom = 720.0
script = ExtResource( 2 )
[node name="LabelTools" type="Label" parent="ToolsPanel"]
margin_left = 20.0
margin_top = 10.0
margin_right = 330.0
margin_bottom = 24.0
text = "Selected tool: Pencil"
align = 1
[node name="ButtonToolPencil" type="Button" parent="ToolsPanel"]
margin_left = 40.0
margin_top = 40.0
margin_right = 100.0
margin_bottom = 100.0
[node name="Sprite" type="Sprite" parent="ToolsPanel/ButtonToolPencil"]
position = Vector2( 30, 30 )
scale = Vector2( 2.5, 2.5 )
texture = ExtResource( 3 )
region_enabled = true
region_rect = Rect2( 0, 0, 16, 16 )
[node name="ButtonToolEraser" type="Button" parent="ToolsPanel"]
margin_left = 110.0
margin_top = 40.0
margin_right = 170.0
margin_bottom = 100.0
[node name="Sprite" type="Sprite" parent="ToolsPanel/ButtonToolEraser"]
position = Vector2( 30, 30 )
scale = Vector2( 2.5, 2.5 )
texture = ExtResource( 3 )
region_enabled = true
region_rect = Rect2( 16, 0, 16, 16 )
[node name="ButtonToolRectangle" type="Button" parent="ToolsPanel"]
margin_left = 180.0
margin_top = 40.0
margin_right = 240.0
margin_bottom = 100.0
[node name="Sprite" type="Sprite" parent="ToolsPanel/ButtonToolRectangle"]
position = Vector2( 30, 30 )
scale = Vector2( 2.5, 2.5 )
texture = ExtResource( 3 )
region_enabled = true
region_rect = Rect2( 0, 16, 16, 16 )
[node name="ButtonToolCircle" type="Button" parent="ToolsPanel"]
margin_left = 250.0
margin_top = 40.0
margin_right = 310.0
margin_bottom = 100.0
[node name="Sprite" type="Sprite" parent="ToolsPanel/ButtonToolCircle"]
position = Vector2( 30, 30 )
scale = Vector2( 2.5, 2.5 )
texture = ExtResource( 3 )
region_enabled = true
region_rect = Rect2( 16, 16, 16, 16 )
[node name="LabelBrushColor" type="Label" parent="ToolsPanel"]
margin_left = 20.0
margin_top = 120.0
margin_right = 330.0
margin_bottom = 134.0
text = "Current color"
align = 1
[node name="ColorPickerBrush" type="ColorPickerButton" parent="ToolsPanel"]
margin_left = 20.0
margin_top = 140.0
margin_right = 330.0
margin_bottom = 190.0
[node name="BrushSettings" type="Control" parent="ToolsPanel"]
margin_top = 200.0
margin_right = 350.0
margin_bottom = 375.0
[node name="LabelBrushSize" type="Label" parent="ToolsPanel/BrushSettings"]
margin_left = 20.0
margin_top = 10.0
margin_right = 330.0
margin_bottom = 24.0
text = "Brush size: 32px"
align = 1
[node name="HScrollBarBrushSize" type="HScrollBar" parent="ToolsPanel/BrushSettings"]
margin_left = 20.0
margin_top = 30.0
margin_right = 330.0
margin_bottom = 60.0
min_value = 2.0
step = 1.0
value = 32.0
[node name="LabelBrushShape" type="Label" parent="ToolsPanel/BrushSettings"]
margin_left = 20.0
margin_top = 80.0
margin_right = 330.0
margin_bottom = 94.0
text = "Brush shape: Circle"
align = 1
[node name="ButtonShapeBox" type="Button" parent="ToolsPanel/BrushSettings"]
margin_left = 100.0
margin_top = 100.0
margin_right = 160.0
margin_bottom = 160.0
[node name="Sprite" type="Sprite" parent="ToolsPanel/BrushSettings/ButtonShapeBox"]
position = Vector2( 30, 30 )
scale = Vector2( 2.5, 2.5 )
texture = ExtResource( 3 )
region_enabled = true
region_rect = Rect2( 0, 16, 16, 16 )
[node name="ButtonShapeCircle" type="Button" parent="ToolsPanel/BrushSettings"]
margin_left = 190.0
margin_top = 100.0
margin_right = 250.0
margin_bottom = 160.0
[node name="Sprite" type="Sprite" parent="ToolsPanel/BrushSettings/ButtonShapeCircle"]
position = Vector2( 30, 30 )
scale = Vector2( 2.5, 2.5 )
texture = ExtResource( 3 )
region_enabled = true
region_rect = Rect2( 16, 16, 16, 16 )
[node name="LabelBackgroundColor" type="Label" parent="ToolsPanel"]
margin_left = 20.0
margin_top = 400.0
margin_right = 330.0
margin_bottom = 414.0
text = "Background color"
align = 1
[node name="ColorPickerBackground" type="ColorPickerButton" parent="ToolsPanel"]
margin_left = 20.0
margin_top = 420.0
margin_right = 330.0
margin_bottom = 470.0
color = Color( 1, 1, 1, 1 )
edit_alpha = false
[node name="LabelStats" type="Label" parent="ToolsPanel"]
modulate = Color( 0.414062, 0.414062, 0.414062, 1 )
margin_left = 20.0
margin_top = 590.0
margin_right = 330.0
margin_bottom = 604.0
text = "Brush objects: 00000"
align = 1
[node name="ButtonUndo" type="Button" parent="ToolsPanel"]
margin_left = 10.0
margin_top = 520.0
margin_right = 340.0
margin_bottom = 560.0
text = "Undo last stroke"
[node name="ButtonSave" type="Button" parent="ToolsPanel"]
margin_left = 10.0
margin_top = 620.0
margin_right = 340.0
margin_bottom = 660.0
text = "Save picture"
[node name="ButtonClear" type="Button" parent="ToolsPanel"]
margin_left = 10.0
margin_top = 670.0
margin_right = 340.0
margin_bottom = 710.0
text = "Clear picture"
[node name="SaveFileDialog" type="FileDialog" parent="."]
margin_right = 600.0
margin_bottom = 400.0
resizable = true
access = 2
filters = PoolStringArray( "*.png" )
current_dir = "/home/aaronfranke/workspace/godot-demo-projects/2d/gd_paint"
current_path = "/home/aaronfranke/workspace/godot-demo-projects/2d/gd_paint/"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

View File

@@ -1,38 +0,0 @@
; 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=4
_global_script_classes=[ ]
_global_script_class_icons={
}
[application]
config/name="GD Paint"
config/description="GD Paint is a simple image editor made using Godot and GDScript.
It supports different types of 'brushes': a basic pen/pencil
and eraser, as well as a rectangle and a circle brush."
run/main_scene="res://paint_root.tscn"
config/icon="res://icon.png"
[display]
window/size/width=1280
window/size/height=720
window/stretch/mode="2d"
window/stretch/aspect="keep"
[gdnative]
singletons=[ ]
[rendering]
quality/driver/driver_name="GLES2"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -1,112 +0,0 @@
extends Panel
onready var brush_settings = $BrushSettings
onready var label_brush_size = brush_settings.get_node(@"LabelBrushSize")
onready var label_brush_shape = brush_settings.get_node(@"LabelBrushShape")
onready var label_stats = $LabelStats
onready var label_tools = $LabelTools
onready var _parent = get_parent()
onready var save_dialog = _parent.get_node(@"SaveFileDialog")
onready var paint_control = _parent.get_node(@"PaintControl")
func _ready():
# warning-ignore-all:return_value_discarded
# Assign all of the needed signals for the oppersation buttons.
$ButtonUndo.connect("pressed", self, "button_pressed", ["undo_stroke"])
$ButtonSave.connect("pressed", self, "button_pressed", ["save_picture"])
$ButtonClear.connect("pressed", self, "button_pressed", ["clear_picture"])
# Assign all of the needed signals for the brush buttons.
$ButtonToolPencil.connect("pressed", self, "button_pressed", ["mode_pencil"])
$ButtonToolEraser.connect("pressed", self, "button_pressed", ["mode_eraser"])
$ButtonToolRectangle.connect("pressed", self, "button_pressed", ["mode_rectangle"])
$ButtonToolCircle.connect("pressed", self, "button_pressed", ["mode_circle"])
$BrushSettings/ButtonShapeBox.connect("pressed", self, "button_pressed", ["shape_rectangle"])
$BrushSettings/ButtonShapeCircle.connect("pressed", self, "button_pressed", ["shape_circle"])
# Assign all of the needed signals for the other brush settings (and ColorPickerBackground).
$ColorPickerBrush.connect("color_changed", self, "brush_color_changed")
$ColorPickerBackground.connect("color_changed", self, "background_color_changed")
$BrushSettings/HScrollBarBrushSize.connect("value_changed", self, "brush_size_changed")
# Assign the "file_selected" signal in SaveFileDialog.
save_dialog.connect("file_selected", self, "save_file_selected")
# Set physics process so we can update the status label.
set_physics_process(true)
func _physics_process(_delta):
# Update the status label with the newest brush element count.
label_stats.text = "Brush objects: " + String(paint_control.brush_data_list.size())
func button_pressed(button_name):
# If a brush mode button is pressed.
var tool_name = null
var shape_name = null
if button_name == "mode_pencil":
paint_control.brush_mode = paint_control.BrushModes.PENCIL
brush_settings.modulate = Color(1, 1, 1, 1)
tool_name = "Pencil"
elif button_name == "mode_eraser":
paint_control.brush_mode = paint_control.BrushModes.ERASER
brush_settings.modulate = Color(1, 1, 1, 1)
tool_name = "Eraser"
elif button_name == "mode_rectangle":
paint_control.brush_mode = paint_control.BrushModes.RECTANGLE_SHAPE
brush_settings.modulate = Color(1, 1, 1, 0.5)
tool_name = "Rectangle shape"
elif button_name == "mode_circle":
paint_control.brush_mode = paint_control.BrushModes.CIRCLE_SHAPE
brush_settings.modulate = Color(1, 1, 1, 0.5)
tool_name = "Circle shape"
# If a brush shape button is pressed
elif button_name == "shape_rectangle":
paint_control.brush_shape = paint_control.BrushShapes.RECTANGLE
shape_name = "Rectangle"
elif button_name == "shape_circle":
paint_control.brush_shape = paint_control.BrushShapes.CIRCLE
shape_name = "Circle";
# If a opperation button is pressed
elif button_name == "clear_picture":
paint_control.brush_data_list = []
paint_control.update()
elif button_name == "save_picture":
save_dialog.popup_centered()
elif button_name == "undo_stroke":
paint_control.undo_stroke()
# Update the labels (in case the brush mode or brush shape has changed).
if tool_name != null:
label_tools.text = "Selected tool: " + tool_name
if shape_name != null:
label_brush_shape.text = "Brush shape: " + shape_name
func brush_color_changed(color):
# Change the brush color to whatever color the color picker is.
paint_control.brush_color = color
func background_color_changed(color):
# Change the background color to whatever colorthe background color picker is.
get_parent().get_node("DrawingAreaBG").modulate = color
paint_control.bg_color = color
# Because of how the eraser works we also need to redraw the paint control.
paint_control.update()
func brush_size_changed(value):
# Change the size of the brush, and update the label to reflect the new value.
paint_control.brush_size = ceil(value)
label_brush_size.text = "Brush size: " + String(ceil(value)) + "px"
func save_file_selected(path):
# Call save_picture in paint_control, passing in the path we recieved from SaveFileDialog.
paint_control.save_picture(path)

View File

@@ -0,0 +1,99 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://tilesets/grid_lines/grid_lines_tileset.tres" type="TileSet" id=1]
[ext_resource path="res://tilesets/grid/grid_tileset.tres" type="TileSet" id=2]
[ext_resource path="res://grid/grid.gd" type="Script" id=3]
[ext_resource path="res://pawns/Actor.tscn" type="PackedScene" id=4]
[ext_resource path="res://pawns/pawn.gd" type="Script" id=5]
[ext_resource path="res://pawns/sprites/character_grey.png" type="Texture" id=6]
[ext_resource path="res://pawns/sprites/star.png" type="Texture" id=7]
[node name="Game" type="Node"]
[node name="GridLines" type="TileMap" parent="." index="0"]
modulate = Color( 1, 1, 1, 0.271059 )
z_index = -1
z_as_relative = false
mode = 0
tile_set = ExtResource( 1 )
cell_size = Vector2( 64, 64 )
cell_quadrant_size = 16
cell_custom_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
cell_half_offset = 2
cell_tile_origin = 0
cell_y_sort = false
cell_clip_uv = false
collision_use_kinematic = false
collision_friction = 1.0
collision_bounce = 0.0
collision_layer = 1
collision_mask = 1
occluder_light_mask = 1
format = 1
tile_data = PoolIntArray( 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 10, 0, 0, 11, 0, 0, 12, 0, 0, 13, 0, 0, 14, 0, 0, 15, 0, 0, 16, 0, 0, 65536, 0, 0, 65537, 0, 0, 65538, 0, 0, 65539, 0, 0, 65540, 0, 0, 65541, 0, 0, 65542, 0, 0, 65543, 0, 0, 65544, 0, 0, 65545, 0, 0, 65546, 0, 0, 65547, 0, 0, 65548, 0, 0, 65549, 0, 0, 65550, 0, 0, 65551, 0, 0, 65552, 0, 0, 131072, 0, 0, 131073, 0, 0, 131074, 0, 0, 131075, 0, 0, 131076, 0, 0, 131077, 0, 0, 131078, 0, 0, 131079, 0, 0, 131080, 0, 0, 131081, 0, 0, 131082, 0, 0, 131083, 0, 0, 131084, 0, 0, 131085, 0, 0, 131086, 0, 0, 131087, 0, 0, 131088, 0, 0, 196608, 0, 0, 196609, 0, 0, 196610, 0, 0, 196611, 0, 0, 196612, 0, 0, 196613, 0, 0, 196614, 0, 0, 196615, 0, 0, 196616, 0, 0, 196617, 0, 0, 196618, 0, 0, 196619, 0, 0, 196620, 0, 0, 196621, 0, 0, 196622, 0, 0, 196623, 0, 0, 196624, 0, 0, 262144, 0, 0, 262145, 0, 0, 262146, 0, 0, 262147, 0, 0, 262148, 0, 0, 262149, 0, 0, 262150, 0, 0, 262151, 0, 0, 262152, 0, 0, 262153, 0, 0, 262154, 0, 0, 262155, 0, 0, 262156, 0, 0, 262157, 0, 0, 262158, 0, 0, 262159, 0, 0, 262160, 0, 0, 327680, 0, 0, 327681, 0, 0, 327682, 0, 0, 327683, 0, 0, 327684, 0, 0, 327685, 0, 0, 327686, 0, 0, 327687, 0, 0, 327688, 0, 0, 327689, 0, 0, 327690, 0, 0, 327691, 0, 0, 327692, 0, 0, 327693, 0, 0, 327694, 0, 0, 327695, 0, 0, 327696, 0, 0, 393216, 0, 0, 393217, 0, 0, 393218, 0, 0, 393219, 0, 0, 393220, 0, 0, 393221, 0, 0, 393222, 0, 0, 393223, 0, 0, 393224, 0, 0, 393225, 0, 0, 393226, 0, 0, 393227, 0, 0, 393228, 0, 0, 393229, 0, 0, 393230, 0, 0, 393231, 0, 0, 393232, 0, 0, 458752, 0, 0, 458753, 0, 0, 458754, 0, 0, 458755, 0, 0, 458756, 0, 0, 458757, 0, 0, 458758, 0, 0, 458759, 0, 0, 458760, 0, 0, 458761, 0, 0, 458762, 0, 0, 458763, 0, 0, 458764, 0, 0, 458765, 0, 0, 458766, 0, 0, 458767, 0, 0, 458768, 0, 0, 524288, 0, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 524298, 0, 0, 524299, 0, 0, 524300, 0, 0, 524301, 0, 0, 524302, 0, 0, 524303, 0, 0, 524304, 0, 0, 589824, 0, 0, 589825, 0, 0, 589826, 0, 0, 589827, 0, 0, 589828, 0, 0, 589829, 0, 0, 589830, 0, 0, 589831, 0, 0, 589832, 0, 0, 589833, 0, 0, 589834, 0, 0, 589835, 0, 0, 589836, 0, 0, 589837, 0, 0, 589838, 0, 0, 589839, 0, 0, 589840, 0, 0 )
_sections_unfolded = [ "Visibility", "Z Index" ]
__meta__ = {
"_edit_lock_": true
}
[node name="Grid" type="TileMap" parent="." index="1"]
mode = 0
tile_set = ExtResource( 2 )
cell_size = Vector2( 64, 64 )
cell_quadrant_size = 16
cell_custom_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
cell_half_offset = 2
cell_tile_origin = 0
cell_y_sort = false
cell_clip_uv = false
collision_use_kinematic = false
collision_friction = 1.0
collision_bounce = 0.0
collision_layer = 1
collision_mask = 1
occluder_light_mask = 1
format = 1
tile_data = PoolIntArray( 18, 1, 0, 19, 1, 0, 65554, 1, 0, 65555, 1, 0, 131090, 1, 0, 131091, 1, 0, 196615, 1, 0, 196616, 1, 0, 196617, 1, 0, 196626, 1, 0, 196627, 1, 0, 262151, 1, 0, 262162, 1, 0, 262163, 1, 0, 327687, 1, 0, 327688, 1, 0, 327689, 1, 0, 327698, 1, 0, 327699, 1, 0, 393234, 1, 0, 393235, 1, 0, 458753, 1, 0, 458754, 1, 0, 458770, 1, 0, 458771, 1, 0, 524289, 1, 0, 524290, 1, 0, 524306, 1, 0, 524307, 1, 0, 589825, 1, 0, 589826, 1, 0, 589827, 1, 0, 589828, 1, 0, 589829, 1, 0, 589830, 1, 0, 589831, 1, 0, 589842, 1, 0, 589843, 1, 0, 655360, 1, 0, 655361, 1, 0, 655362, 1, 0, 655363, 1, 0, 655364, 1, 0, 655365, 1, 0, 655366, 1, 0, 655367, 1, 0, 655368, 1, 0, 655369, 1, 0, 655370, 1, 0, 655371, 1, 0, 655372, 1, 0, 655373, 1, 0, 655374, 1, 0, 655375, 1, 0, 655376, 1, 0, 655377, 1, 0, 655378, 1, 0, 655379, 1, 0, 720896, 1, 0, 720897, 1, 0, 720898, 1, 0, 720899, 1, 0, 720900, 1, 0, 720901, 1, 0, 720902, 1, 0, 720903, 1, 0, 720904, 1, 0, 720905, 1, 0, 720906, 1, 0, 720907, 1, 0, 720908, 1, 0, 720909, 1, 0, 720910, 1, 0, 720911, 1, 0, 720912, 1, 0, 720913, 1, 0, 720914, 1, 0, 720915, 1, 0 )
script = ExtResource( 3 )
_sections_unfolded = [ "Visibility" ]
__meta__ = {
"_edit_lock_": true
}
[node name="Actor" parent="Grid" index="0" instance=ExtResource( 4 )]
editor/display_folded = true
position = Vector2( 416, 288 )
[node name="Sprite" parent="Grid/Actor/Pivot" index="0"]
position = Vector2( 1.43051e-06, -1.90735e-06 )
[node name="Actor2" type="Node2D" parent="Grid" index="1"]
editor/display_folded = true
position = Vector2( 480, 480 )
z_index = 1
script = ExtResource( 5 )
_sections_unfolded = [ "Offset" ]
type = 0
[node name="Sprite" type="Sprite" parent="Grid/Actor2" index="0"]
texture = ExtResource( 6 )
[node name="Object" type="Node2D" parent="Grid" index="2"]
editor/display_folded = true
position = Vector2( 544, 288 )
script = ExtResource( 5 )
type = 2
[node name="Sprite" type="Sprite" parent="Grid/Object" index="0"]
texture = ExtResource( 7 )
[editable path="Grid/Actor"]

View File

@@ -0,0 +1,101 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
radiance_size = 4
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
sky_curve = 0.25
sky_energy = 1.0
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
ground_energy = 1.0
sun_color = Color( 1, 1, 1, 1 )
sun_latitude = 35.0
sun_longitude = 0.0
sun_angle_min = 1.0
sun_angle_max = 100.0
sun_curve = 0.05
sun_energy = 16.0
texture_size = 2
[resource]
background_mode = 2
background_sky = SubResource( 1 )
background_sky_custom_fov = 0.0
background_color = Color( 0, 0, 0, 1 )
background_energy = 1.0
background_canvas_max_layer = 0
ambient_light_color = Color( 0, 0, 0, 1 )
ambient_light_energy = 1.0
ambient_light_sky_contribution = 1.0
fog_enabled = false
fog_color = Color( 0.5, 0.6, 0.7, 1 )
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
fog_sun_amount = 0.0
fog_depth_enabled = true
fog_depth_begin = 10.0
fog_depth_curve = 1.0
fog_transmit_enabled = false
fog_transmit_curve = 1.0
fog_height_enabled = false
fog_height_min = 0.0
fog_height_max = 100.0
fog_height_curve = 1.0
tonemap_mode = 0
tonemap_exposure = 1.0
tonemap_white = 1.0
auto_exposure_enabled = false
auto_exposure_scale = 0.4
auto_exposure_min_luma = 0.05
auto_exposure_max_luma = 8.0
auto_exposure_speed = 0.5
ss_reflections_enabled = false
ss_reflections_max_steps = 64
ss_reflections_fade_in = 0.15
ss_reflections_fade_out = 2.0
ss_reflections_depth_tolerance = 0.2
ss_reflections_roughness = true
ssao_enabled = false
ssao_radius = 1.0
ssao_intensity = 1.0
ssao_radius2 = 0.0
ssao_intensity2 = 1.0
ssao_bias = 0.01
ssao_light_affect = 0.0
ssao_color = Color( 0, 0, 0, 1 )
ssao_quality = 0
ssao_blur = 3
ssao_edge_sharpness = 4.0
dof_blur_far_enabled = false
dof_blur_far_distance = 10.0
dof_blur_far_transition = 5.0
dof_blur_far_amount = 0.1
dof_blur_far_quality = 1
dof_blur_near_enabled = false
dof_blur_near_distance = 2.0
dof_blur_near_transition = 1.0
dof_blur_near_amount = 0.1
dof_blur_near_quality = 1
glow_enabled = false
glow_levels/1 = false
glow_levels/2 = false
glow_levels/3 = true
glow_levels/4 = false
glow_levels/5 = true
glow_levels/6 = false
glow_levels/7 = false
glow_intensity = 0.8
glow_strength = 1.0
glow_bloom = 0.0
glow_blend_mode = 2
glow_hdr_threshold = 1.0
glow_hdr_scale = 2.0
glow_bicubic_upscale = false
adjustment_enabled = false
adjustment_brightness = 1.0
adjustment_contrast = 1.0
adjustment_saturation = 1.0

View File

@@ -0,0 +1,36 @@
extends TileMap
enum CELL_TYPES { EMPTY = -1, ACTOR, OBSTACLE, OBJECT}
func _ready():
for child in get_children():
set_cellv(world_to_map(child.position), child.type)
func get_cell_pawn(coordinates):
for node in get_children():
if world_to_map(node.position) == coordinates:
return(node)
func request_move(pawn, direction):
var cell_start = world_to_map(pawn.position)
var cell_target = cell_start + direction
var cell_target_type = get_cellv(cell_target)
match cell_target_type:
EMPTY:
return update_pawn_position(pawn, cell_start, cell_target)
OBJECT:
var object_pawn = get_cell_pawn(cell_target)
object_pawn.queue_free()
return update_pawn_position(pawn, cell_start, cell_target)
ACTOR:
var pawn_name = get_cell_pawn(cell_target).name
print("Cell %s contains %s" % [cell_target, pawn_name])
func update_pawn_position(pawn, cell_start, cell_target):
set_cellv(cell_target, pawn.type)
set_cellv(cell_start, EMPTY)
return map_to_world(cell_target) + cell_size / 2

Some files were not shown because too many files have changed in this diff Show More