mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-05 10:09:47 +03:00
Compare commits
7 Commits
3.4-585455
...
3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea5b868fc7 | ||
|
|
a6ae6f64be | ||
|
|
507b8c6cf6 | ||
|
|
e59d96ef7a | ||
|
|
19584aae6a | ||
|
|
342f27e327 | ||
|
|
4d10544dd9 |
6
.editorconfig
Normal file
6
.editorconfig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Top-most EditorConfig file.
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Normalize EOL for all files that Git considers text files.
|
||||||
|
* text=auto eol=lf
|
||||||
19
.github/workflows/static_checks.yml
vendored
Normal file
19
.github/workflows/static_checks.yml
vendored
Normal 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
|
||||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,12 +1,22 @@
|
|||||||
|
# Godot 4+ specific ignores
|
||||||
|
.godot/
|
||||||
|
|
||||||
# Godot-specific ignores
|
# Godot-specific ignores
|
||||||
.import/
|
.import/
|
||||||
export.cfg
|
export.cfg
|
||||||
export_presets.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
|
||||||
|
|
||||||
# Mono-specific ignores
|
# Mono-specific ignores
|
||||||
.mono/
|
.mono/
|
||||||
|
data_*/
|
||||||
mono_crash.*.json
|
mono_crash.*.json
|
||||||
|
|
||||||
# System/tool-specific ignores
|
# System/tool-specific ignores
|
||||||
.directory
|
.directory
|
||||||
|
.DS_Store
|
||||||
*~
|
*~
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func _process(delta):
|
|||||||
var velocity = Vector2()
|
var velocity = Vector2()
|
||||||
velocity.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
|
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.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
|
||||||
|
|
||||||
if velocity.length() > 0:
|
if velocity.length() > 0:
|
||||||
velocity = velocity.normalized() * speed
|
velocity = velocity.normalized() * speed
|
||||||
$AnimatedSprite.play()
|
$AnimatedSprite.play()
|
||||||
|
|||||||
@@ -1,94 +1,94 @@
|
|||||||
Copyright 2011-2016 Severin Meyer <sev.ch@web.de>,
|
Copyright 2011-2016 Severin Meyer <sev.ch@web.de>,
|
||||||
with Reserved Font Name Xolonium.
|
with Reserved Font Name Xolonium.
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License,
|
This Font Software is licensed under the SIL Open Font License,
|
||||||
Version 1.1. This license is copied below, and is also available
|
Version 1.1. This license is copied below, and is also available
|
||||||
with a FAQ at <http://scripts.sil.org/OFL>
|
with a FAQ at <http://scripts.sil.org/OFL>
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
|
||||||
PREAMBLE
|
PREAMBLE
|
||||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
development of collaborative font projects, to support the font creation
|
development of collaborative font projects, to support the font creation
|
||||||
efforts of academic and linguistic communities, and to provide a free and
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
open framework in which fonts may be shared and improved in partnership
|
open framework in which fonts may be shared and improved in partnership
|
||||||
with others.
|
with others.
|
||||||
|
|
||||||
The OFL allows the licensed fonts to be used, studied, modified and
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
redistributed freely as long as they are not sold by themselves. The
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
fonts, including any derivative works, can be bundled, embedded,
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
redistributed and/or sold with any software provided that any reserved
|
redistributed and/or sold with any software provided that any reserved
|
||||||
names are not used by derivative works. The fonts and derivatives,
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
however, cannot be released under any other type of license. The
|
however, cannot be released under any other type of license. The
|
||||||
requirement for fonts to remain under this license does not apply
|
requirement for fonts to remain under this license does not apply
|
||||||
to any document created using the fonts or their derivatives.
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
"Font Software" refers to the set of files released by the Copyright
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
Holder(s) under this license and clearly marked as such. This may
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
include source files, build scripts and documentation.
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
"Reserved Font Name" refers to any names specified as such after the
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
copyright statement(s).
|
copyright statement(s).
|
||||||
|
|
||||||
"Original Version" refers to the collection of Font Software components as
|
"Original Version" refers to the collection of Font Software components as
|
||||||
distributed by the Copyright Holder(s).
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
or substituting -- in part or in whole -- any of the components of the
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
Original Version, by changing formats or by porting the Font Software to a
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
new environment.
|
new environment.
|
||||||
|
|
||||||
"Author" refers to any designer, engineer, programmer, technical
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
writer or other person who contributed to the Font Software.
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
PERMISSION & CONDITIONS
|
PERMISSION & CONDITIONS
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
redistribute, and sell modified and unmodified copies of the Font
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
Software, subject to the following conditions:
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
1) Neither the Font Software nor any of its individual components,
|
1) Neither the Font Software nor any of its individual components,
|
||||||
in Original or Modified Versions, may be sold by itself.
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
2) Original or Modified Versions of the Font Software may be bundled,
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
redistributed and/or sold with any software, provided that each copy
|
redistributed and/or sold with any software, provided that each copy
|
||||||
contains the above copyright notice and this license. These can be
|
contains the above copyright notice and this license. These can be
|
||||||
included either as stand-alone text files, human-readable headers or
|
included either as stand-alone text files, human-readable headers or
|
||||||
in the appropriate machine-readable metadata fields within text or
|
in the appropriate machine-readable metadata fields within text or
|
||||||
binary files as long as those fields can be easily viewed by the user.
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
3) No Modified Version of the Font Software may use the Reserved Font
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
Name(s) unless explicit written permission is granted by the corresponding
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
Copyright Holder. This restriction only applies to the primary font name as
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
presented to the users.
|
presented to the users.
|
||||||
|
|
||||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
Software shall not be used to promote, endorse or advertise any
|
Software shall not be used to promote, endorse or advertise any
|
||||||
Modified Version, except to acknowledge the contribution(s) of the
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
permission.
|
permission.
|
||||||
|
|
||||||
5) The Font Software, modified or unmodified, in part or in whole,
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
must be distributed entirely under this license, and must not be
|
must be distributed entirely under this license, and must not be
|
||||||
distributed under any other license. The requirement for fonts to
|
distributed under any other license. The requirement for fonts to
|
||||||
remain under this license does not apply to any document created
|
remain under this license does not apply to any document created
|
||||||
using the Font Software.
|
using the Font Software.
|
||||||
|
|
||||||
TERMINATION
|
TERMINATION
|
||||||
This license becomes null and void if any of the above conditions are
|
This license becomes null and void if any of the above conditions are
|
||||||
not met.
|
not met.
|
||||||
|
|
||||||
DISCLAIMER
|
DISCLAIMER
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ size_flags_vertical = 4
|
|||||||
custom_fonts/bold_font = ExtResource( 1 )
|
custom_fonts/bold_font = ExtResource( 1 )
|
||||||
custom_fonts/normal_font = ExtResource( 2 )
|
custom_fonts/normal_font = ExtResource( 2 )
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
bbcode_text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
|
bbcode_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:
|
States are common in games. You can use the pattern to:
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ 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.
|
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]."
|
You can read more about States in the excellent [url=http://gameprogrammingpatterns.com/state.html]Game Programming Patterns ebook[/url]."
|
||||||
text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
|
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:
|
States are common in games. You can use the pattern to:
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -60,14 +60,14 @@ func _change_state(state_name):
|
|||||||
if not _active:
|
if not _active:
|
||||||
return
|
return
|
||||||
current_state.exit()
|
current_state.exit()
|
||||||
|
|
||||||
if state_name == "previous":
|
if state_name == "previous":
|
||||||
states_stack.pop_front()
|
states_stack.pop_front()
|
||||||
else:
|
else:
|
||||||
states_stack[0] = states_map[state_name]
|
states_stack[0] = states_map[state_name]
|
||||||
|
|
||||||
current_state = states_stack[0]
|
current_state = states_stack[0]
|
||||||
emit_signal("state_changed", current_state)
|
emit_signal("state_changed", current_state)
|
||||||
|
|
||||||
if state_name != "previous":
|
if state_name != "previous":
|
||||||
current_state.enter()
|
current_state.enter()
|
||||||
|
|||||||
@@ -51,20 +51,20 @@ func _ready():
|
|||||||
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
var mouse_pos = get_viewport().get_mouse_position()
|
var mouse_pos = get_viewport().get_mouse_position()
|
||||||
|
|
||||||
# Check if the mouse is currently inside the canvas/drawing-area.
|
# Check if the mouse is currently inside the canvas/drawing-area.
|
||||||
is_mouse_in_drawing_area = false
|
is_mouse_in_drawing_area = false
|
||||||
if mouse_pos.x > TL_node.global_position.x:
|
if mouse_pos.x > TL_node.global_position.x:
|
||||||
if mouse_pos.y > TL_node.global_position.y:
|
if mouse_pos.y > TL_node.global_position.y:
|
||||||
is_mouse_in_drawing_area = true
|
is_mouse_in_drawing_area = true
|
||||||
|
|
||||||
if Input.is_mouse_button_pressed(BUTTON_LEFT):
|
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
|
# 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
|
# be the first time is_mouse_button_pressed has been called since the mouse button was
|
||||||
# released, so we need to store the position.
|
# released, so we need to store the position.
|
||||||
if mouse_click_start_pos == null:
|
if mouse_click_start_pos == null:
|
||||||
mouse_click_start_pos = mouse_pos
|
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 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 check_if_mouse_is_inside_canvas():
|
||||||
if mouse_pos.distance_to(last_mouse_pos) >= 1:
|
if mouse_pos.distance_to(last_mouse_pos) >= 1:
|
||||||
@@ -77,11 +77,11 @@ func _process(_delta):
|
|||||||
undo_element_list_num = brush_data_list.size()
|
undo_element_list_num = brush_data_list.size()
|
||||||
# Add the brush object to draw_elements_array.
|
# Add the brush object to draw_elements_array.
|
||||||
add_brush(mouse_pos, brush_mode)
|
add_brush(mouse_pos, brush_mode)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# We've finished our stroke, so we can set a new undo (if a new storke is made).
|
# We've finished our stroke, so we can set a new undo (if a new storke is made).
|
||||||
undo_set = false
|
undo_set = false
|
||||||
|
|
||||||
# If the mouse is inside the canvas.
|
# If the mouse is inside the canvas.
|
||||||
if check_if_mouse_is_inside_canvas():
|
if check_if_mouse_is_inside_canvas():
|
||||||
# If we're using either the circle shape mode, or the rectangle shape mode, then
|
# If we're using either the circle shape mode, or the rectangle shape mode, then
|
||||||
@@ -94,7 +94,7 @@ func _process(_delta):
|
|||||||
# Since we've released the left mouse, we need to get a new mouse_click_start_pos next time
|
# 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.
|
#is_mouse_button_pressed is true.
|
||||||
mouse_click_start_pos = null
|
mouse_click_start_pos = null
|
||||||
|
|
||||||
# Store mouse_pos as last_mouse_pos now that we're done with _process.
|
# Store mouse_pos as last_mouse_pos now that we're done with _process.
|
||||||
last_mouse_pos = mouse_pos
|
last_mouse_pos = mouse_pos
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ func check_if_mouse_is_inside_canvas():
|
|||||||
if mouse_click_start_pos.x > TL_node.global_position.x:
|
if mouse_click_start_pos.x > TL_node.global_position.x:
|
||||||
if mouse_click_start_pos.y > TL_node.global_position.y:
|
if mouse_click_start_pos.y > TL_node.global_position.y:
|
||||||
# Make sure the current mouse position is inside the canvas.
|
# Make sure the current mouse position is inside the canvas.
|
||||||
if is_mouse_in_drawing_area == true:
|
if is_mouse_in_drawing_area:
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
@@ -117,17 +117,17 @@ func undo_stroke():
|
|||||||
# Only undo a stroke if we have one.
|
# Only undo a stroke if we have one.
|
||||||
if undo_element_list_num == UNDO_NONE:
|
if undo_element_list_num == UNDO_NONE:
|
||||||
return
|
return
|
||||||
|
|
||||||
# If we are undoing a shape, then we can just remove the latest brush.
|
# If we are undoing a shape, then we can just remove the latest brush.
|
||||||
if undo_element_list_num == UNDO_MODE_SHAPE:
|
if undo_element_list_num == UNDO_MODE_SHAPE:
|
||||||
if brush_data_list.size() > 0:
|
if brush_data_list.size() > 0:
|
||||||
brush_data_list.remove(brush_data_list.size() - 1)
|
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.
|
# Now that we've undone a shape, we cannot undo again until another stoke is added.
|
||||||
undo_element_list_num = UNDO_NONE
|
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
|
# 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.
|
# undo until we have a empty element list.
|
||||||
|
|
||||||
# Otherwise we're removing a either a pencil stroke or a eraser stroke.
|
# Otherwise we're removing a either a pencil stroke or a eraser stroke.
|
||||||
else:
|
else:
|
||||||
# Figure out how many elements/brushes we've added in the last stroke.
|
# Figure out how many elements/brushes we've added in the last stroke.
|
||||||
@@ -136,7 +136,7 @@ func undo_stroke():
|
|||||||
#warning-ignore:unused_variable
|
#warning-ignore:unused_variable
|
||||||
for elment_num in range(0, elements_to_remove):
|
for elment_num in range(0, elements_to_remove):
|
||||||
brush_data_list.pop_back()
|
brush_data_list.pop_back()
|
||||||
|
|
||||||
# Now that we've undone a stoke, we cannot undo again until another stoke is added.
|
# Now that we've undone a stoke, we cannot undo again until another stoke is added.
|
||||||
undo_element_list_num = UNDO_NONE
|
undo_element_list_num = UNDO_NONE
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ func undo_stroke():
|
|||||||
func add_brush(mouse_pos, type):
|
func add_brush(mouse_pos, type):
|
||||||
# Make new brush dictionary that will hold all of the data we need for the brush.
|
# Make new brush dictionary that will hold all of the data we need for the brush.
|
||||||
var new_brush = {}
|
var new_brush = {}
|
||||||
|
|
||||||
# Populate the dictionary with values based on the global brush variables.
|
# 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.
|
# We will override these as needed if the brush is a rectange or circle.
|
||||||
new_brush.brush_type = type
|
new_brush.brush_type = type
|
||||||
@@ -155,13 +155,13 @@ func add_brush(mouse_pos, type):
|
|||||||
new_brush.brush_shape = brush_shape
|
new_brush.brush_shape = brush_shape
|
||||||
new_brush.brush_size = brush_size
|
new_brush.brush_size = brush_size
|
||||||
new_brush.brush_color = brush_color
|
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
|
# 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.
|
# bottom right corner of the rectangle.
|
||||||
if type == BrushModes.RECTANGLE_SHAPE:
|
if type == BrushModes.RECTANGLE_SHAPE:
|
||||||
var TL_pos = Vector2()
|
var TL_pos = Vector2()
|
||||||
var BR_pos = Vector2()
|
var BR_pos = Vector2()
|
||||||
|
|
||||||
# Figure out the left and right positions of the corners and assign them to the proper variable.
|
# 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:
|
if mouse_pos.x < mouse_click_start_pos.x:
|
||||||
TL_pos.x = mouse_pos.x
|
TL_pos.x = mouse_pos.x
|
||||||
@@ -169,7 +169,7 @@ func add_brush(mouse_pos, type):
|
|||||||
else:
|
else:
|
||||||
TL_pos.x = mouse_click_start_pos.x
|
TL_pos.x = mouse_click_start_pos.x
|
||||||
BR_pos.x = mouse_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.
|
# 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:
|
if mouse_pos.y < mouse_click_start_pos.y:
|
||||||
TL_pos.y = mouse_pos.y
|
TL_pos.y = mouse_pos.y
|
||||||
@@ -177,11 +177,11 @@ func add_brush(mouse_pos, type):
|
|||||||
else:
|
else:
|
||||||
TL_pos.y = mouse_click_start_pos.y
|
TL_pos.y = mouse_click_start_pos.y
|
||||||
BR_pos.y = mouse_pos.y
|
BR_pos.y = mouse_pos.y
|
||||||
|
|
||||||
# Assign the positions to the brush.
|
# Assign the positions to the brush.
|
||||||
new_brush.brush_pos = TL_pos
|
new_brush.brush_pos = TL_pos
|
||||||
new_brush.brush_shape_rect_pos_BR = BR_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 the brush isa circle shape, then we need to calculate the radius of the circle.
|
||||||
if type == BrushModes.CIRCLE_SHAPE:
|
if type == BrushModes.CIRCLE_SHAPE:
|
||||||
# Get the center point inbetween the mouse position and the position of the mouse when we clicked.
|
# Get the center point inbetween the mouse position and the position of the mouse when we clicked.
|
||||||
@@ -190,7 +190,7 @@ func add_brush(mouse_pos, type):
|
|||||||
# the center to the top/bottom positon of the mouse.
|
# the center to the top/bottom positon of the mouse.
|
||||||
new_brush.brush_pos = center_pos
|
new_brush.brush_pos = center_pos
|
||||||
new_brush.brush_shape_circle_radius = center_pos.distance_to(Vector2(center_pos.x, mouse_pos.y))
|
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.
|
# Add the brush and update/draw all of the brushes.
|
||||||
brush_data_list.append(new_brush)
|
brush_data_list.append(new_brush)
|
||||||
update()
|
update()
|
||||||
@@ -214,7 +214,7 @@ func _draw():
|
|||||||
BrushModes.ERASER:
|
BrushModes.ERASER:
|
||||||
# NOTE: this is a really cheap way of erasing that isn't really erasing!
|
# NOTE: this is a really cheap way of erasing that isn't really erasing!
|
||||||
# However, this gives similar results in a fairy simple way!
|
# 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,
|
# 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.
|
# but instead of using brush.brush_color, we instead use bg_color instead.
|
||||||
if brush.brush_shape == BrushShapes.RECTANGLE:
|
if brush.brush_shape == BrushShapes.RECTANGLE:
|
||||||
@@ -237,13 +237,13 @@ func save_picture(path):
|
|||||||
# Wait a couple frames so the save dialog isn't in the way.
|
# Wait a couple frames so the save dialog isn't in the way.
|
||||||
yield (get_tree(), "idle_frame")
|
yield (get_tree(), "idle_frame")
|
||||||
yield (get_tree(), "idle_frame")
|
yield (get_tree(), "idle_frame")
|
||||||
|
|
||||||
# Get the viewport image.
|
# Get the viewport image.
|
||||||
var img = get_viewport().get_texture().get_data()
|
var img = get_viewport().get_texture().get_data()
|
||||||
# Crop the image so we only have canvas area.
|
# Crop the image so we only have canvas area.
|
||||||
var cropped_image = img.get_rect(Rect2(TL_node.global_position, IMAGE_SIZE))
|
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).
|
# Flip the image on the Y-axis (it's flipped upside down by default).
|
||||||
cropped_image.flip_y()
|
cropped_image.flip_y()
|
||||||
|
|
||||||
# Save the image with the passed in path we got from the save dialog.
|
# Save the image with the passed in path we got from the save dialog.
|
||||||
cropped_image.save_png(path)
|
cropped_image.save_png(path)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func button_pressed(button_name):
|
|||||||
# If a brush mode button is pressed.
|
# If a brush mode button is pressed.
|
||||||
var tool_name = null
|
var tool_name = null
|
||||||
var shape_name = null
|
var shape_name = null
|
||||||
|
|
||||||
if button_name == "mode_pencil":
|
if button_name == "mode_pencil":
|
||||||
paint_control.brush_mode = paint_control.BrushModes.PENCIL
|
paint_control.brush_mode = paint_control.BrushModes.PENCIL
|
||||||
brush_settings.modulate = Color(1, 1, 1, 1)
|
brush_settings.modulate = Color(1, 1, 1, 1)
|
||||||
@@ -84,7 +84,7 @@ func button_pressed(button_name):
|
|||||||
save_dialog.popup_centered()
|
save_dialog.popup_centered()
|
||||||
elif button_name == "undo_stroke":
|
elif button_name == "undo_stroke":
|
||||||
paint_control.undo_stroke()
|
paint_control.undo_stroke()
|
||||||
|
|
||||||
# Update the labels (in case the brush mode or brush shape has changed).
|
# Update the labels (in case the brush mode or brush shape has changed).
|
||||||
if tool_name != null:
|
if tool_name != null:
|
||||||
label_tools.text = "Selected tool: " + tool_name
|
label_tools.text = "Selected tool: " + tool_name
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func get_cell_pawn(coordinates):
|
|||||||
func request_move(pawn, direction):
|
func request_move(pawn, direction):
|
||||||
var cell_start = world_to_map(pawn.position)
|
var cell_start = world_to_map(pawn.position)
|
||||||
var cell_target = cell_start + direction
|
var cell_target = cell_start + direction
|
||||||
|
|
||||||
var cell_target_type = get_cellv(cell_target)
|
var cell_target_type = get_cellv(cell_target)
|
||||||
match cell_target_type:
|
match cell_target_type:
|
||||||
CellType.EMPTY:
|
CellType.EMPTY:
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func move_to(target_position):
|
|||||||
|
|
||||||
# Stop the function execution until the animation finished
|
# Stop the function execution until the animation finished
|
||||||
yield($AnimationPlayer, "animation_finished")
|
yield($AnimationPlayer, "animation_finished")
|
||||||
|
|
||||||
set_process(true)
|
set_process(true)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func _physics_process(delta):
|
|||||||
|
|
||||||
if (velocity.x <= WALK_MIN_SPEED and velocity.x > -WALK_MAX_SPEED) or (velocity.x >= -WALK_MIN_SPEED and velocity.x < WALK_MAX_SPEED):
|
if (velocity.x <= WALK_MIN_SPEED and velocity.x > -WALK_MAX_SPEED) or (velocity.x >= -WALK_MIN_SPEED and velocity.x < WALK_MAX_SPEED):
|
||||||
force.x += WALK_FORCE * walk
|
force.x += WALK_FORCE * walk
|
||||||
|
|
||||||
if abs(walk) < 0.5:
|
if abs(walk) < 0.5:
|
||||||
var vsign = sign(velocity.x)
|
var vsign = sign(velocity.x)
|
||||||
var vlen = abs(velocity.x)
|
var vlen = abs(velocity.x)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -26,24 +26,24 @@ func _integrate_forces(s):
|
|||||||
new_anim = "explode"
|
new_anim = "explode"
|
||||||
elif state == State.WALKING:
|
elif state == State.WALKING:
|
||||||
new_anim = "walk"
|
new_anim = "walk"
|
||||||
|
|
||||||
var wall_side = 0.0
|
var wall_side = 0.0
|
||||||
|
|
||||||
for i in range(s.get_contact_count()):
|
for i in range(s.get_contact_count()):
|
||||||
var cc = s.get_contact_collider_object(i)
|
var cc = s.get_contact_collider_object(i)
|
||||||
var dp = s.get_contact_local_normal(i)
|
var dp = s.get_contact_local_normal(i)
|
||||||
|
|
||||||
if cc:
|
if cc:
|
||||||
if cc is Bullet and not cc.disabled:
|
if cc is Bullet and not cc.disabled:
|
||||||
# enqueue call
|
# enqueue call
|
||||||
call_deferred("_bullet_collider", cc, s, dp)
|
call_deferred("_bullet_collider", cc, s, dp)
|
||||||
break
|
break
|
||||||
|
|
||||||
if dp.x > 0.9:
|
if dp.x > 0.9:
|
||||||
wall_side = 1.0
|
wall_side = 1.0
|
||||||
elif dp.x < -0.9:
|
elif dp.x < -0.9:
|
||||||
wall_side = -1.0
|
wall_side = -1.0
|
||||||
|
|
||||||
if wall_side != 0 and wall_side != direction:
|
if wall_side != 0 and wall_side != direction:
|
||||||
direction = -direction
|
direction = -direction
|
||||||
($Sprite as Sprite).scale.x = -direction
|
($Sprite as Sprite).scale.x = -direction
|
||||||
@@ -53,13 +53,13 @@ func _integrate_forces(s):
|
|||||||
elif direction > 0 and not rc_right.is_colliding() and rc_left.is_colliding():
|
elif direction > 0 and not rc_right.is_colliding() and rc_left.is_colliding():
|
||||||
direction = -direction
|
direction = -direction
|
||||||
($Sprite as Sprite).scale.x = -direction
|
($Sprite as Sprite).scale.x = -direction
|
||||||
|
|
||||||
lv.x = direction * WALK_SPEED
|
lv.x = direction * WALK_SPEED
|
||||||
|
|
||||||
if anim != new_anim:
|
if anim != new_anim:
|
||||||
anim = new_anim
|
anim = new_anim
|
||||||
($AnimationPlayer as AnimationPlayer).play(anim)
|
($AnimationPlayer as AnimationPlayer).play(anim)
|
||||||
|
|
||||||
s.set_linear_velocity(lv)
|
s.set_linear_velocity(lv)
|
||||||
|
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ func _pre_explode():
|
|||||||
$Shape1.queue_free()
|
$Shape1.queue_free()
|
||||||
$Shape2.queue_free()
|
$Shape2.queue_free()
|
||||||
$Shape3.queue_free()
|
$Shape3.queue_free()
|
||||||
|
|
||||||
# Stay there
|
# Stay there
|
||||||
mode = MODE_STATIC
|
mode = MODE_STATIC
|
||||||
($SoundExplode as AudioStreamPlayer2D).play()
|
($SoundExplode as AudioStreamPlayer2D).play()
|
||||||
@@ -81,7 +81,7 @@ func _pre_explode():
|
|||||||
func _bullet_collider(cc, s, dp):
|
func _bullet_collider(cc, s, dp):
|
||||||
mode = MODE_RIGID
|
mode = MODE_RIGID
|
||||||
state = State.DYING
|
state = State.DYING
|
||||||
|
|
||||||
s.set_angular_velocity(sign(dp.x) * 33.0)
|
s.set_angular_velocity(sign(dp.x) * 33.0)
|
||||||
set_friction(1)
|
set_friction(1)
|
||||||
cc.disable()
|
cc.disable()
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ var accum = 0.0
|
|||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
accum += delta * (1.0 / cycle) * TAU
|
accum += delta * (1.0 / cycle) * TAU
|
||||||
accum = fmod(accum, TAU)
|
accum = fmod(accum, TAU)
|
||||||
|
|
||||||
var d = sin(accum)
|
var d = sin(accum)
|
||||||
var xf = Transform2D()
|
var xf = Transform2D()
|
||||||
|
|
||||||
xf[2]= motion * d
|
xf[2]= motion * d
|
||||||
($Platform as RigidBody2D).transform = xf
|
($Platform as RigidBody2D).transform = xf
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ func _ready():
|
|||||||
func disable():
|
func disable():
|
||||||
if disabled:
|
if disabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
($AnimationPlayer as AnimationPlayer).play("shutdown")
|
($AnimationPlayer as AnimationPlayer).play("shutdown")
|
||||||
disabled = true
|
disabled = true
|
||||||
|
|||||||
@@ -50,47 +50,47 @@ var Enemy = preload("res://enemy/Enemy.tscn")
|
|||||||
func _integrate_forces(s):
|
func _integrate_forces(s):
|
||||||
var lv = s.get_linear_velocity()
|
var lv = s.get_linear_velocity()
|
||||||
var step = s.get_step()
|
var step = s.get_step()
|
||||||
|
|
||||||
var new_anim = anim
|
var new_anim = anim
|
||||||
var new_siding_left = siding_left
|
var new_siding_left = siding_left
|
||||||
|
|
||||||
# Get the controls.
|
# Get the controls.
|
||||||
var move_left = Input.is_action_pressed("move_left")
|
var move_left = Input.is_action_pressed("move_left")
|
||||||
var move_right = Input.is_action_pressed("move_right")
|
var move_right = Input.is_action_pressed("move_right")
|
||||||
var jump = Input.is_action_pressed("jump")
|
var jump = Input.is_action_pressed("jump")
|
||||||
var shoot = Input.is_action_pressed("shoot")
|
var shoot = Input.is_action_pressed("shoot")
|
||||||
var spawn = Input.is_action_pressed("spawn")
|
var spawn = Input.is_action_pressed("spawn")
|
||||||
|
|
||||||
if spawn:
|
if spawn:
|
||||||
call_deferred("_spawn_enemy_above")
|
call_deferred("_spawn_enemy_above")
|
||||||
|
|
||||||
# Deapply prev floor velocity.
|
# Deapply prev floor velocity.
|
||||||
lv.x -= floor_h_velocity
|
lv.x -= floor_h_velocity
|
||||||
floor_h_velocity = 0.0
|
floor_h_velocity = 0.0
|
||||||
|
|
||||||
# Find the floor (a contact with upwards facing collision normal).
|
# Find the floor (a contact with upwards facing collision normal).
|
||||||
var found_floor = false
|
var found_floor = false
|
||||||
var floor_index = -1
|
var floor_index = -1
|
||||||
|
|
||||||
for x in range(s.get_contact_count()):
|
for x in range(s.get_contact_count()):
|
||||||
var ci = s.get_contact_local_normal(x)
|
var ci = s.get_contact_local_normal(x)
|
||||||
|
|
||||||
if ci.dot(Vector2(0, -1)) > 0.6:
|
if ci.dot(Vector2(0, -1)) > 0.6:
|
||||||
found_floor = true
|
found_floor = true
|
||||||
floor_index = x
|
floor_index = x
|
||||||
|
|
||||||
# A good idea when implementing characters of all kinds,
|
# A good idea when implementing characters of all kinds,
|
||||||
# compensates for physics imprecision, as well as human reaction delay.
|
# compensates for physics imprecision, as well as human reaction delay.
|
||||||
if shoot and not shooting:
|
if shoot and not shooting:
|
||||||
call_deferred("_shot_bullet")
|
call_deferred("_shot_bullet")
|
||||||
else:
|
else:
|
||||||
shoot_time += step
|
shoot_time += step
|
||||||
|
|
||||||
if found_floor:
|
if found_floor:
|
||||||
airborne_time = 0.0
|
airborne_time = 0.0
|
||||||
else:
|
else:
|
||||||
airborne_time += step # Time it spent in the air.
|
airborne_time += step # Time it spent in the air.
|
||||||
|
|
||||||
var on_floor = airborne_time < MAX_FLOOR_AIRBORNE_TIME
|
var on_floor = airborne_time < MAX_FLOOR_AIRBORNE_TIME
|
||||||
|
|
||||||
# Process jump.
|
# Process jump.
|
||||||
@@ -100,10 +100,10 @@ func _integrate_forces(s):
|
|||||||
jumping = false
|
jumping = false
|
||||||
elif not jump:
|
elif not jump:
|
||||||
stopping_jump = true
|
stopping_jump = true
|
||||||
|
|
||||||
if stopping_jump:
|
if stopping_jump:
|
||||||
lv.y += STOP_JUMP_FORCE * step
|
lv.y += STOP_JUMP_FORCE * step
|
||||||
|
|
||||||
if on_floor:
|
if on_floor:
|
||||||
# Process logic when character is on floor.
|
# Process logic when character is on floor.
|
||||||
if move_left and not move_right:
|
if move_left and not move_right:
|
||||||
@@ -118,14 +118,14 @@ func _integrate_forces(s):
|
|||||||
if xv < 0:
|
if xv < 0:
|
||||||
xv = 0
|
xv = 0
|
||||||
lv.x = sign(lv.x) * xv
|
lv.x = sign(lv.x) * xv
|
||||||
|
|
||||||
# Check jump.
|
# Check jump.
|
||||||
if not jumping and jump:
|
if not jumping and jump:
|
||||||
lv.y = -JUMP_VELOCITY
|
lv.y = -JUMP_VELOCITY
|
||||||
jumping = true
|
jumping = true
|
||||||
stopping_jump = false
|
stopping_jump = false
|
||||||
($SoundJump as AudioStreamPlayer2D).play()
|
($SoundJump as AudioStreamPlayer2D).play()
|
||||||
|
|
||||||
# Check siding.
|
# Check siding.
|
||||||
if lv.x < 0 and move_left:
|
if lv.x < 0 and move_left:
|
||||||
new_siding_left = true
|
new_siding_left = true
|
||||||
@@ -154,11 +154,11 @@ func _integrate_forces(s):
|
|||||||
else:
|
else:
|
||||||
var xv = abs(lv.x)
|
var xv = abs(lv.x)
|
||||||
xv -= AIR_DEACCEL * step
|
xv -= AIR_DEACCEL * step
|
||||||
|
|
||||||
if xv < 0:
|
if xv < 0:
|
||||||
xv = 0
|
xv = 0
|
||||||
lv.x = sign(lv.x) * xv
|
lv.x = sign(lv.x) * xv
|
||||||
|
|
||||||
if lv.y < 0:
|
if lv.y < 0:
|
||||||
if shoot_time < MAX_SHOOT_POSE_TIME:
|
if shoot_time < MAX_SHOOT_POSE_TIME:
|
||||||
new_anim = "jumping_weapon"
|
new_anim = "jumping_weapon"
|
||||||
@@ -169,28 +169,28 @@ func _integrate_forces(s):
|
|||||||
new_anim = "falling_weapon"
|
new_anim = "falling_weapon"
|
||||||
else:
|
else:
|
||||||
new_anim = "falling"
|
new_anim = "falling"
|
||||||
|
|
||||||
# Update siding.
|
# Update siding.
|
||||||
if new_siding_left != siding_left:
|
if new_siding_left != siding_left:
|
||||||
if new_siding_left:
|
if new_siding_left:
|
||||||
($Sprite as Sprite).scale.x = -1
|
($Sprite as Sprite).scale.x = -1
|
||||||
else:
|
else:
|
||||||
($Sprite as Sprite).scale.x = 1
|
($Sprite as Sprite).scale.x = 1
|
||||||
|
|
||||||
siding_left = new_siding_left
|
siding_left = new_siding_left
|
||||||
|
|
||||||
# Change animation.
|
# Change animation.
|
||||||
if new_anim != anim:
|
if new_anim != anim:
|
||||||
anim = new_anim
|
anim = new_anim
|
||||||
($AnimationPlayer as AnimationPlayer).play(anim)
|
($AnimationPlayer as AnimationPlayer).play(anim)
|
||||||
|
|
||||||
shooting = shoot
|
shooting = shoot
|
||||||
|
|
||||||
# Apply floor velocity.
|
# Apply floor velocity.
|
||||||
if found_floor:
|
if found_floor:
|
||||||
floor_h_velocity = s.get_contact_collider_velocity_at_position(floor_index).x
|
floor_h_velocity = s.get_contact_collider_velocity_at_position(floor_index).x
|
||||||
lv.x += floor_h_velocity
|
lv.x += floor_h_velocity
|
||||||
|
|
||||||
# Finally, apply gravity and set back the linear velocity.
|
# Finally, apply gravity and set back the linear velocity.
|
||||||
lv += s.get_total_gravity() * step
|
lv += s.get_total_gravity() * step
|
||||||
s.set_linear_velocity(lv)
|
s.set_linear_velocity(lv)
|
||||||
@@ -205,15 +205,15 @@ func _shot_bullet():
|
|||||||
else:
|
else:
|
||||||
ss = 1.0
|
ss = 1.0
|
||||||
var pos = position + ($BulletShoot as Position2D).position * Vector2(ss, 1.0)
|
var pos = position + ($BulletShoot as Position2D).position * Vector2(ss, 1.0)
|
||||||
|
|
||||||
bi.position = pos
|
bi.position = pos
|
||||||
get_parent().add_child(bi)
|
get_parent().add_child(bi)
|
||||||
|
|
||||||
bi.linear_velocity = Vector2(800.0 * ss, -80)
|
bi.linear_velocity = Vector2(800.0 * ss, -80)
|
||||||
|
|
||||||
($Sprite/Smoke as Particles2D).restart()
|
($Sprite/Smoke as Particles2D).restart()
|
||||||
($SoundShoot as AudioStreamPlayer2D).play()
|
($SoundShoot as AudioStreamPlayer2D).play()
|
||||||
|
|
||||||
add_collision_exception_with(bi) # Make bullet and this not collide.
|
add_collision_exception_with(bi) # Make bullet and this not collide.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const FLOOR_NORMAL = Vector2(0, -1)
|
|||||||
|
|
||||||
const STATE_WALKING = 0
|
const STATE_WALKING = 0
|
||||||
const STATE_KILLED = 1
|
const STATE_KILLED = 1
|
||||||
const WALK_SPEED = 70
|
const WALK_SPEED = 70
|
||||||
|
|
||||||
var linear_velocity = Vector2()
|
var linear_velocity = Vector2()
|
||||||
var direction = -1
|
var direction = -1
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"dialog_1" : {"name": "Unknown", "text": "Hey, it's a good time to have a JRPG fight, right?"},
|
"dialog_1": { "name": "Unknown", "text": "Hey, it's a good time to have a JRPG fight, right?" },
|
||||||
"dialog_2" : {"name": "Unknown", "text": "Let me introduce myself, I'm the OPPONENT"},
|
"dialog_2": { "name": "Unknown", "text": "Let me introduce myself, I'm the OPPONENT" },
|
||||||
"dialog_3" : {"name": "Opponent", "text": "Enough talking. Let's fight!"},
|
"dialog_3": { "name": "Opponent", "text": "Enough talking. Let's fight!" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"dialog_1" : {"name":"Player", "text":"Just some object..." }
|
"dialog_1": { "name": "Player", "text": "Just some object..." }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"dialog_1" : {"name": "Opponent", "text": "Aha! I won, maybe you can try again next time"}
|
"dialog_1": { "name": "Opponent", "text": "Aha! I won, maybe you can try again next time" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"dialog_1" : {"name": "Opponent", "text": "Congratulations, you won!"}
|
"dialog_1": { "name": "Opponent", "text": "Congratulations, you won!" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func get_cell_pawn(cell, type = CellType.ACTOR):
|
|||||||
func request_move(pawn, direction):
|
func request_move(pawn, direction):
|
||||||
var cell_start = world_to_map(pawn.position)
|
var cell_start = world_to_map(pawn.position)
|
||||||
var cell_target = cell_start + direction
|
var cell_target = cell_start + direction
|
||||||
|
|
||||||
var cell_tile_id = get_cellv(cell_target)
|
var cell_tile_id = get_cellv(cell_target)
|
||||||
match cell_tile_id:
|
match cell_tile_id:
|
||||||
-1:
|
-1:
|
||||||
@@ -29,7 +29,7 @@ func request_move(pawn, direction):
|
|||||||
CellType.OBJECT, CellType.ACTOR:
|
CellType.OBJECT, CellType.ACTOR:
|
||||||
var target_pawn = get_cell_pawn(cell_target, cell_tile_id)
|
var target_pawn = get_cell_pawn(cell_target, cell_tile_id)
|
||||||
print("Cell %s contains %s" % [cell_target, target_pawn.name])
|
print("Cell %s contains %s" % [cell_target, target_pawn.name])
|
||||||
|
|
||||||
if not target_pawn.has_node("DialoguePlayer"):
|
if not target_pawn.has_node("DialoguePlayer"):
|
||||||
return
|
return
|
||||||
get_node(dialogue_ui).show_dialogue(pawn, target_pawn.get_node("DialoguePlayer"))
|
get_node(dialogue_ui).show_dialogue(pawn, target_pawn.get_node("DialoguePlayer"))
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ func get_input_direction():
|
|||||||
return Vector2()
|
return Vector2()
|
||||||
var random_x = DIRECTIONS[randi() % DIRECTIONS.size()]
|
var random_x = DIRECTIONS[randi() % DIRECTIONS.size()]
|
||||||
var random_y = DIRECTIONS[randi() % DIRECTIONS.size()]
|
var random_y = DIRECTIONS[randi() % DIRECTIONS.size()]
|
||||||
|
|
||||||
var random_axis = randi() % 2
|
var random_axis = randi() % 2
|
||||||
if random_axis > 0:
|
if random_axis > 0:
|
||||||
random_x = 0
|
random_x = 0
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ func move_to(target_position):
|
|||||||
$Tween.interpolate_property($Pivot, "position", move_direction * 32, Vector2(), $AnimationPlayer.current_animation_length, Tween.TRANS_LINEAR, Tween.EASE_IN)
|
$Tween.interpolate_property($Pivot, "position", move_direction * 32, Vector2(), $AnimationPlayer.current_animation_length, Tween.TRANS_LINEAR, Tween.EASE_IN)
|
||||||
$Pivot/Sprite.position = position - target_position
|
$Pivot/Sprite.position = position - target_position
|
||||||
position = target_position
|
position = target_position
|
||||||
|
|
||||||
yield($AnimationPlayer, "animation_finished")
|
yield($AnimationPlayer, "animation_finished")
|
||||||
|
|
||||||
set_process(true)
|
set_process(true)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func set_active(value):
|
|||||||
.set_active(value)
|
.set_active(value)
|
||||||
if not active:
|
if not active:
|
||||||
return
|
return
|
||||||
|
|
||||||
$Timer.start()
|
$Timer.start()
|
||||||
yield($Timer, \"timeout\")
|
yield($Timer, \"timeout\")
|
||||||
var target
|
var target
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func set_active(value):
|
|||||||
active = value
|
active = value
|
||||||
set_process(value)
|
set_process(value)
|
||||||
set_process_input(value)
|
set_process_input(value)
|
||||||
|
|
||||||
if not active:
|
if not active:
|
||||||
return
|
return
|
||||||
if $Health.armor >= $Health.base_armor + defense:
|
if $Health.armor >= $Health.base_armor + defense:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ func set_active(value):
|
|||||||
.set_active(value)
|
.set_active(value)
|
||||||
if not active:
|
if not active:
|
||||||
return
|
return
|
||||||
|
|
||||||
$Timer.start()
|
$Timer.start()
|
||||||
yield($Timer, "timeout")
|
yield($Timer, "timeout")
|
||||||
var target
|
var target
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ uniform float saturation = 1.8;
|
|||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
|
vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
|
||||||
|
|
||||||
c.rgb = mix(vec3(0.0), c.rgb, brightness);
|
c.rgb = mix(vec3(0.0), c.rgb, brightness);
|
||||||
c.rgb = mix(vec3(0.5), c.rgb, contrast);
|
c.rgb = mix(vec3(0.5), c.rgb, contrast);
|
||||||
c.rgb = mix(vec3(dot(vec3(1.0), c.rgb) * 0.33333), c.rgb, saturation);
|
c.rgb = mix(vec3(dot(vec3(1.0), c.rgb) * 0.33333), c.rgb, saturation);
|
||||||
|
|
||||||
COLOR.rgb = c;
|
COLOR.rgb = c;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ void fragment() {
|
|||||||
uv.x += sin(uv.y * frequency + TIME) * depth;
|
uv.x += sin(uv.y * frequency + TIME) * depth;
|
||||||
uv.x = clamp(uv.x, 0.0, 1.0);
|
uv.x = clamp(uv.x, 0.0, 1.0);
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb;
|
vec3 c = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb;
|
||||||
|
|
||||||
COLOR.rgb = c;
|
COLOR.rgb = c;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,17 +15,17 @@ float make_grain(float time, vec2 uv) {
|
|||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
|
vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
|
||||||
|
|
||||||
//float v = max(c.r, max(c.g, c.b));
|
//float v = max(c.r, max(c.g, c.b));
|
||||||
float v = dot(c, vec3(0.33333, 0.33333, 0.33333));
|
float v = dot(c, vec3(0.33333, 0.33333, 0.33333));
|
||||||
v = sqrt(v);
|
v = sqrt(v);
|
||||||
//v *= v;
|
//v *= v;
|
||||||
|
|
||||||
float f = 1.0 / fps;
|
float f = 1.0 / fps;
|
||||||
float g = make_grain(TIME - mod(TIME, f), UV);
|
float g = make_grain(TIME - mod(TIME, f), UV);
|
||||||
g = max(g, make_grain(TIME - mod(TIME, f) + f, UV) * 0.5);
|
g = max(g, make_grain(TIME - mod(TIME, f) + f, UV) * 0.5);
|
||||||
g = max(g, make_grain(TIME - mod(TIME, f) + f * 2.0, UV) * 0.25);
|
g = max(g, make_grain(TIME - mod(TIME, f) + f * 2.0, UV) * 0.25);
|
||||||
|
|
||||||
COLOR.rgb = base.rgb * v - vec3(g) * grain_strength;
|
COLOR.rgb = base.rgb * v - vec3(g) * grain_strength;
|
||||||
COLOR.rgb *= texture(vignette, UV).r;
|
COLOR.rgb *= texture(vignette, UV).r;
|
||||||
float ft = TIME * 0.002;
|
float ft = TIME * 0.002;
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ uniform float size_y = 0.008;
|
|||||||
void fragment() {
|
void fragment() {
|
||||||
vec2 uv = SCREEN_UV;
|
vec2 uv = SCREEN_UV;
|
||||||
uv -= mod(uv, vec2(size_x, size_y));
|
uv -= mod(uv, vec2(size_x, size_y));
|
||||||
|
|
||||||
COLOR.rgb = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb;
|
COLOR.rgb = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -52,61 +52,61 @@ func _ready():
|
|||||||
if has_node("target") == false:
|
if has_node("target") == false:
|
||||||
target = Spatial.new()
|
target = Spatial.new()
|
||||||
add_child(target)
|
add_child(target)
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
if get_tree() != null:
|
if get_tree() != null:
|
||||||
if get_tree().edited_scene_root != null:
|
if get_tree().edited_scene_root != null:
|
||||||
target.set_owner(get_tree().edited_scene_root)
|
target.set_owner(get_tree().edited_scene_root)
|
||||||
|
|
||||||
target.name = "target"
|
target.name = "target"
|
||||||
else:
|
else:
|
||||||
target = get_node("target")
|
target = get_node("target")
|
||||||
|
|
||||||
# If we are in the editor, we want to make a sphere at this node
|
# If we are in the editor, we want to make a sphere at this node
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_make_editor_sphere_at_node(target, Color(1, 0, 1, 1))
|
_make_editor_sphere_at_node(target, Color(1, 0, 1, 1))
|
||||||
|
|
||||||
if middle_joint_target == null:
|
if middle_joint_target == null:
|
||||||
if has_node("middle_joint_target") == false:
|
if has_node("middle_joint_target") == false:
|
||||||
middle_joint_target = Spatial.new()
|
middle_joint_target = Spatial.new()
|
||||||
add_child(middle_joint_target)
|
add_child(middle_joint_target)
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
if get_tree() != null:
|
if get_tree() != null:
|
||||||
if get_tree().edited_scene_root != null:
|
if get_tree().edited_scene_root != null:
|
||||||
middle_joint_target.set_owner(get_tree().edited_scene_root)
|
middle_joint_target.set_owner(get_tree().edited_scene_root)
|
||||||
|
|
||||||
middle_joint_target.name = "middle_joint_target"
|
middle_joint_target.name = "middle_joint_target"
|
||||||
else:
|
else:
|
||||||
middle_joint_target = get_node("middle_joint_target")
|
middle_joint_target = get_node("middle_joint_target")
|
||||||
|
|
||||||
# If we are in the editor, we want to make a sphere at this node
|
# If we are in the editor, we want to make a sphere at this node
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_make_editor_sphere_at_node(middle_joint_target, Color(1, 0.24, 1, 1))
|
_make_editor_sphere_at_node(middle_joint_target, Color(1, 0.24, 1, 1))
|
||||||
|
|
||||||
# Make all of the bone nodes for each bone in the IK chain
|
# Make all of the bone nodes for each bone in the IK chain
|
||||||
_make_bone_nodes()
|
_make_bone_nodes()
|
||||||
|
|
||||||
# Make sure we're using the right update mode
|
# Make sure we're using the right update mode
|
||||||
_set_update_mode(update_mode)
|
_set_update_mode(update_mode)
|
||||||
|
|
||||||
|
|
||||||
# Various upate methods
|
# Various upate methods
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if reset_iterations_on_update == true:
|
if reset_iterations_on_update:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
update_skeleton()
|
update_skeleton()
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(_delta):
|
func _physics_process(_delta):
|
||||||
if reset_iterations_on_update == true:
|
if reset_iterations_on_update:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
update_skeleton()
|
update_skeleton()
|
||||||
|
|
||||||
|
|
||||||
func _notification(what):
|
func _notification(what):
|
||||||
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
||||||
if reset_iterations_on_update == true:
|
if reset_iterations_on_update:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
update_skeleton()
|
update_skeleton()
|
||||||
|
|
||||||
@@ -115,51 +115,51 @@ func _notification(what):
|
|||||||
|
|
||||||
func update_skeleton():
|
func update_skeleton():
|
||||||
#### ERROR CHECKING conditions
|
#### ERROR CHECKING conditions
|
||||||
if first_call == true:
|
if first_call:
|
||||||
_set_skeleton_path(skeleton_path)
|
_set_skeleton_path(skeleton_path)
|
||||||
first_call = false
|
first_call = false
|
||||||
|
|
||||||
if skeleton == null:
|
if skeleton == null:
|
||||||
_set_skeleton_path(skeleton_path)
|
_set_skeleton_path(skeleton_path)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if bones_in_chain == null:
|
if bones_in_chain == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: No Bones in IK chain defined!")
|
printerr(name, " - IK_FABRIK: No Bones in IK chain defined!")
|
||||||
return
|
return
|
||||||
if bones_in_chain_lengths == null:
|
if bones_in_chain_lengths == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: No Bone lengths in IK chain defined!")
|
printerr(name, " - IK_FABRIK: No Bone lengths in IK chain defined!")
|
||||||
return
|
return
|
||||||
|
|
||||||
if bones_in_chain.size() != bones_in_chain_lengths.size():
|
if bones_in_chain.size() != bones_in_chain_lengths.size():
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: bones_in_chain and bones_in_chain_lengths!")
|
printerr(name, " - IK_FABRIK: bones_in_chain and bones_in_chain_lengths!")
|
||||||
return
|
return
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
||||||
# Set all of the bone IDs in bone_IDs, if they are not already made
|
# Set all of the bone IDs in bone_IDs, if they are not already made
|
||||||
var i = 0
|
var i = 0
|
||||||
if bone_IDs.size() <= 0:
|
if bone_IDs.size() <= 0:
|
||||||
for bone_name in bones_in_chain:
|
for bone_name in bones_in_chain:
|
||||||
bone_IDs[bone_name] = skeleton.find_bone(bone_name)
|
bone_IDs[bone_name] = skeleton.find_bone(bone_name)
|
||||||
|
|
||||||
# Set the bone node to the currect bone position
|
# Set the bone node to the currect bone position
|
||||||
bone_nodes[i].global_transform = get_bone_transform(i)
|
bone_nodes[i].global_transform = get_bone_transform(i)
|
||||||
# If this is not the last bone in the bone chain, make it look at the next bone in the bone chain
|
# If this is not the last bone in the bone chain, make it look at the next bone in the bone chain
|
||||||
if i < bone_IDs.size()-1:
|
if i < bone_IDs.size()-1:
|
||||||
bone_nodes[i].look_at(get_bone_transform(i+1).origin + skeleton.global_transform.origin, Vector3.UP)
|
bone_nodes[i].look_at(get_bone_transform(i+1).origin + skeleton.global_transform.origin, Vector3.UP)
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# Set the total length of the bone chain, if it is not already set
|
# Set the total length of the bone chain, if it is not already set
|
||||||
if total_length == INF:
|
if total_length == INF:
|
||||||
total_length = 0
|
total_length = 0
|
||||||
for bone_length in bones_in_chain_lengths:
|
for bone_length in bones_in_chain_lengths:
|
||||||
total_length += bone_length
|
total_length += bone_length
|
||||||
|
|
||||||
# Solve the bone chain
|
# Solve the bone chain
|
||||||
solve_chain()
|
solve_chain()
|
||||||
|
|
||||||
@@ -167,14 +167,14 @@ func update_skeleton():
|
|||||||
func solve_chain():
|
func solve_chain():
|
||||||
# If we have reached our max chain iteration, and we are limiting ourselves, then return.
|
# If we have reached our max chain iteration, and we are limiting ourselves, then return.
|
||||||
# Otherwise set chain_iterations to zero (so we constantly update)
|
# Otherwise set chain_iterations to zero (so we constantly update)
|
||||||
if chain_iterations >= CHAIN_MAX_ITER and limit_chain_iterations == true:
|
if chain_iterations >= CHAIN_MAX_ITER and limit_chain_iterations:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
|
|
||||||
# Update the origin with the current bone's origin
|
# Update the origin with the current bone's origin
|
||||||
chain_origin = get_bone_transform(0).origin
|
chain_origin = get_bone_transform(0).origin
|
||||||
|
|
||||||
# Get the direction of the final bone by using the next to last bone if there is more than 2 bones.
|
# Get the direction of the final bone by using the next to last bone if there is more than 2 bones.
|
||||||
# If there are only 2 bones, we use the target's forward Z vector instead (not ideal, but it works fairly well)
|
# If there are only 2 bones, we use the target's forward Z vector instead (not ideal, but it works fairly well)
|
||||||
var dir
|
var dir
|
||||||
@@ -182,19 +182,19 @@ func solve_chain():
|
|||||||
dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized()
|
dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized()
|
||||||
else:
|
else:
|
||||||
dir = -target.global_transform.basis.z.normalized()
|
dir = -target.global_transform.basis.z.normalized()
|
||||||
|
|
||||||
# Get the target position (accounting for the final bone and it's length)
|
# Get the target position (accounting for the final bone and it's length)
|
||||||
var target_pos = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
var target_pos = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
||||||
|
|
||||||
# If we are using middle joint target (and have more than 2 bones), move our middle joint towards it!
|
# If we are using middle joint target (and have more than 2 bones), move our middle joint towards it!
|
||||||
if use_middle_joint_target == true:
|
if use_middle_joint_target:
|
||||||
if bone_nodes.size() > 2:
|
if bone_nodes.size() > 2:
|
||||||
var middle_point_pos = middle_joint_target.global_transform
|
var middle_point_pos = middle_joint_target.global_transform
|
||||||
bone_nodes[bone_nodes.size()/2].global_transform.origin = middle_point_pos.origin
|
bone_nodes[bone_nodes.size()/2].global_transform.origin = middle_point_pos.origin
|
||||||
|
|
||||||
# Get the distance from the origin to the target
|
# Get the distance from the origin to the target
|
||||||
var distance = (chain_origin - target_pos).length()
|
var distance = (chain_origin - target_pos).length()
|
||||||
|
|
||||||
# If the distance is farther than our total reach, the target cannot be reached.
|
# If the distance is farther than our total reach, the target cannot be reached.
|
||||||
# Make the bone chain a straight line pointing towards the target
|
# Make the bone chain a straight line pointing towards the target
|
||||||
if distance > total_length:
|
if distance > total_length:
|
||||||
@@ -203,37 +203,37 @@ func solve_chain():
|
|||||||
var curr_origin = bone_nodes[i].global_transform.origin
|
var curr_origin = bone_nodes[i].global_transform.origin
|
||||||
var r =(target_pos - curr_origin).length()
|
var r =(target_pos - curr_origin).length()
|
||||||
var l = bones_in_chain_lengths[i] / r
|
var l = bones_in_chain_lengths[i] / r
|
||||||
|
|
||||||
# Find new join position
|
# Find new join position
|
||||||
var new_pos = curr_origin.linear_interpolate(target_pos, l)
|
var new_pos = curr_origin.linear_interpolate(target_pos, l)
|
||||||
|
|
||||||
# Apply it to the bone node
|
# Apply it to the bone node
|
||||||
bone_nodes[i].look_at(new_pos, Vector3.UP)
|
bone_nodes[i].look_at(new_pos, Vector3.UP)
|
||||||
bone_nodes[i].global_transform.origin = new_pos
|
bone_nodes[i].global_transform.origin = new_pos
|
||||||
|
|
||||||
# Apply the rotation to the first node in the bone chain, making it look at the next bone in the bone chain
|
# Apply the rotation to the first node in the bone chain, making it look at the next bone in the bone chain
|
||||||
bone_nodes[0].look_at(bone_nodes[1].global_transform.origin, Vector3.UP)
|
bone_nodes[0].look_at(bone_nodes[1].global_transform.origin, Vector3.UP)
|
||||||
|
|
||||||
# If the distance is NOT farther than our total reach, the target can be reached.
|
# If the distance is NOT farther than our total reach, the target can be reached.
|
||||||
else:
|
else:
|
||||||
# Get the difference between our end effector (the final bone in the chain) and the target
|
# Get the difference between our end effector (the final bone in the chain) and the target
|
||||||
var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
||||||
|
|
||||||
# Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE).
|
# Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE).
|
||||||
# If it not, move the chain towards the target (going forwards, backwards, and then applying rotation)
|
# If it not, move the chain towards the target (going forwards, backwards, and then applying rotation)
|
||||||
while dif > CHAIN_TOLERANCE:
|
while dif > CHAIN_TOLERANCE:
|
||||||
chain_backward()
|
chain_backward()
|
||||||
chain_forward()
|
chain_forward()
|
||||||
chain_apply_rotation()
|
chain_apply_rotation()
|
||||||
|
|
||||||
# Update the difference between our end effector (the final bone in the chain) and the target
|
# Update the difference between our end effector (the final bone in the chain) and the target
|
||||||
dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
||||||
|
|
||||||
# Add one to chain_iterations. If we have reached our max iterations, then break
|
# Add one to chain_iterations. If we have reached our max iterations, then break
|
||||||
chain_iterations = chain_iterations + 1
|
chain_iterations = chain_iterations + 1
|
||||||
if chain_iterations >= CHAIN_MAX_ITER:
|
if chain_iterations >= CHAIN_MAX_ITER:
|
||||||
break
|
break
|
||||||
|
|
||||||
# Reset the bone node transforms to the skeleton bone transforms
|
# Reset the bone node transforms to the skeleton bone transforms
|
||||||
#if constrained == false: # Resetting seems to break bone constraints...
|
#if constrained == false: # Resetting seems to break bone constraints...
|
||||||
for i in range(0, bone_nodes.size()):
|
for i in range(0, bone_nodes.size()):
|
||||||
@@ -250,17 +250,17 @@ func chain_backward():
|
|||||||
dir = bone_nodes[bone_nodes.size() - 2].global_transform.basis.z.normalized()
|
dir = bone_nodes[bone_nodes.size() - 2].global_transform.basis.z.normalized()
|
||||||
else:
|
else:
|
||||||
dir = -target.global_transform.basis.z.normalized()
|
dir = -target.global_transform.basis.z.normalized()
|
||||||
|
|
||||||
# Set the position of the end effector (the final bone in the chain) to the target position
|
# Set the position of the end effector (the final bone in the chain) to the target position
|
||||||
bone_nodes[bone_nodes.size()-1].global_transform.origin = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
bone_nodes[bone_nodes.size()-1].global_transform.origin = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
||||||
|
|
||||||
# For all of the other bones, move them towards the target
|
# For all of the other bones, move them towards the target
|
||||||
var i = bones_in_chain.size() - 1
|
var i = bones_in_chain.size() - 1
|
||||||
while i >= 1:
|
while i >= 1:
|
||||||
var prev_origin = bone_nodes[i].global_transform.origin
|
var prev_origin = bone_nodes[i].global_transform.origin
|
||||||
i -= 1
|
i -= 1
|
||||||
var curr_origin = bone_nodes[i].global_transform.origin
|
var curr_origin = bone_nodes[i].global_transform.origin
|
||||||
|
|
||||||
var r = prev_origin - curr_origin
|
var r = prev_origin - curr_origin
|
||||||
var l = bones_in_chain_lengths[i] / r.length()
|
var l = bones_in_chain_lengths[i] / r.length()
|
||||||
# Apply the new joint position
|
# Apply the new joint position
|
||||||
@@ -271,12 +271,12 @@ func chain_backward():
|
|||||||
func chain_forward():
|
func chain_forward():
|
||||||
# Set root at initial position
|
# Set root at initial position
|
||||||
bone_nodes[0].global_transform.origin = chain_origin
|
bone_nodes[0].global_transform.origin = chain_origin
|
||||||
|
|
||||||
# Go through every bone in the bone chain
|
# Go through every bone in the bone chain
|
||||||
for i in range(bones_in_chain.size() - 1):
|
for i in range(bones_in_chain.size() - 1):
|
||||||
var curr_origin = bone_nodes[i].global_transform.origin
|
var curr_origin = bone_nodes[i].global_transform.origin
|
||||||
var next_origin = bone_nodes[i + 1].global_transform.origin
|
var next_origin = bone_nodes[i + 1].global_transform.origin
|
||||||
|
|
||||||
var r = next_origin - curr_origin
|
var r = next_origin - curr_origin
|
||||||
var l = bones_in_chain_lengths[i] / r.length()
|
var l = bones_in_chain_lengths[i] / r.length()
|
||||||
# Apply the new joint position, (potentially with constraints), to the bone node
|
# Apply the new joint position, (potentially with constraints), to the bone node
|
||||||
@@ -297,38 +297,38 @@ func chain_apply_rotation():
|
|||||||
# Get the bone node for this bone, and the previous bone
|
# Get the bone node for this bone, and the previous bone
|
||||||
var b_target = bone_nodes[i].global_transform
|
var b_target = bone_nodes[i].global_transform
|
||||||
var b_target_two = bone_nodes[i-1].global_transform
|
var b_target_two = bone_nodes[i-1].global_transform
|
||||||
|
|
||||||
# Convert the bone nodes positions from world space to bone/skeleton space
|
# Convert the bone nodes positions from world space to bone/skeleton space
|
||||||
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
||||||
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
|
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
|
||||||
|
|
||||||
# Get the direction that the previous bone is pointing towards
|
# Get the direction that the previous bone is pointing towards
|
||||||
var dir = (target.global_transform.origin - b_target_two.origin).normalized()
|
var dir = (target.global_transform.origin - b_target_two.origin).normalized()
|
||||||
|
|
||||||
# Make this bone look in the same the direction as the last bone
|
# Make this bone look in the same the direction as the last bone
|
||||||
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
|
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
|
||||||
else:
|
else:
|
||||||
var b_target = target.global_transform
|
var b_target = target.global_transform
|
||||||
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
||||||
bone_trans = bone_trans.looking_at(b_target.origin, Vector3.UP)
|
bone_trans = bone_trans.looking_at(b_target.origin, Vector3.UP)
|
||||||
|
|
||||||
# If this is NOT the last bone in the bone chain, rotate the bone to look at the next
|
# If this is NOT the last bone in the bone chain, rotate the bone to look at the next
|
||||||
# bone in the bone chain.
|
# bone in the bone chain.
|
||||||
else:
|
else:
|
||||||
# Get the bone node for this bone, and the next bone
|
# Get the bone node for this bone, and the next bone
|
||||||
var b_target = bone_nodes[i].global_transform
|
var b_target = bone_nodes[i].global_transform
|
||||||
var b_target_two = bone_nodes[i+1].global_transform
|
var b_target_two = bone_nodes[i+1].global_transform
|
||||||
|
|
||||||
# Convert the bone nodes positions from world space to bone/skeleton space
|
# Convert the bone nodes positions from world space to bone/skeleton space
|
||||||
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
|
||||||
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
|
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
|
||||||
|
|
||||||
# Get the direction towards the next bone
|
# Get the direction towards the next bone
|
||||||
var dir = (b_target_two.origin - b_target.origin).normalized()
|
var dir = (b_target_two.origin - b_target.origin).normalized()
|
||||||
|
|
||||||
# Make this bone look towards the direction of the next bone
|
# Make this bone look towards the direction of the next bone
|
||||||
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
|
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
|
||||||
|
|
||||||
# The the bone's (updated) transform
|
# The the bone's (updated) transform
|
||||||
set_bone_transform(i, bone_trans)
|
set_bone_transform(i, bone_trans)
|
||||||
|
|
||||||
@@ -336,12 +336,12 @@ func chain_apply_rotation():
|
|||||||
func get_bone_transform(bone, convert_to_world_space = true):
|
func get_bone_transform(bone, convert_to_world_space = true):
|
||||||
# Get the global transform of the bone
|
# Get the global transform of the bone
|
||||||
var ret: Transform = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]])
|
var ret: Transform = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]])
|
||||||
|
|
||||||
# If we need to convert the bone position from bone/skeleton space to world space, we
|
# If we need to convert the bone position from bone/skeleton space to world space, we
|
||||||
# use the Xform of the skeleton (because bone/skeleton space is relative to the position of the skeleton node).
|
# use the Xform of the skeleton (because bone/skeleton space is relative to the position of the skeleton node).
|
||||||
if convert_to_world_space == true:
|
if convert_to_world_space:
|
||||||
ret.origin = skeleton.global_transform.xform(ret.origin)
|
ret.origin = skeleton.global_transform.xform(ret.origin)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@@ -381,11 +381,11 @@ func _make_editor_sphere_at_node(node, color):
|
|||||||
|
|
||||||
func _set_update_mode(new_value):
|
func _set_update_mode(new_value):
|
||||||
update_mode = new_value
|
update_mode = new_value
|
||||||
|
|
||||||
set_process(false)
|
set_process(false)
|
||||||
set_physics_process(false)
|
set_physics_process(false)
|
||||||
set_notify_transform(false)
|
set_notify_transform(false)
|
||||||
|
|
||||||
if update_mode == 0:
|
if update_mode == 0:
|
||||||
set_process(true)
|
set_process(true)
|
||||||
elif update_mode == 1:
|
elif update_mode == 1:
|
||||||
@@ -393,43 +393,43 @@ func _set_update_mode(new_value):
|
|||||||
elif update_mode == 2:
|
elif update_mode == 2:
|
||||||
set_notify_transform(true)
|
set_notify_transform(true)
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: Unknown update mode. NOT updating skeleton")
|
printerr(name, " - IK_FABRIK: Unknown update mode. NOT updating skeleton")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
func _set_skeleton_path(new_value):
|
func _set_skeleton_path(new_value):
|
||||||
# Because get_node doesn't work in the first call, we just want to assign instead
|
# Because get_node doesn't work in the first call, we just want to assign instead
|
||||||
if first_call == true:
|
if first_call:
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
return
|
return
|
||||||
|
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
|
|
||||||
if skeleton_path == null:
|
if skeleton_path == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
||||||
return
|
return
|
||||||
|
|
||||||
var temp = get_node(skeleton_path)
|
var temp = get_node(skeleton_path)
|
||||||
if temp != null:
|
if temp != null:
|
||||||
# If it has the method "get_bone_global_pose" it is likely a Skeleton
|
# If it has the method "get_bone_global_pose" it is likely a Skeleton
|
||||||
if temp.has_method("get_bone_global_pose") == true:
|
if temp.has_method("get_bone_global_pose"):
|
||||||
skeleton = temp
|
skeleton = temp
|
||||||
bone_IDs = {}
|
bone_IDs = {}
|
||||||
|
|
||||||
# (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain
|
# (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain
|
||||||
_make_bone_nodes()
|
_make_bone_nodes()
|
||||||
|
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: Attached to a new skeleton")
|
printerr(name, " - IK_FABRIK: Attached to a new skeleton")
|
||||||
# If not, then it's (likely) not a Skeleton node
|
# If not, then it's (likely) not a Skeleton node
|
||||||
else:
|
else:
|
||||||
skeleton = null
|
skeleton = null
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: skeleton_path does not point to a skeleton!")
|
printerr(name, " - IK_FABRIK: skeleton_path does not point to a skeleton!")
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
||||||
|
|
||||||
|
|
||||||
@@ -438,33 +438,33 @@ func _set_skeleton_path(new_value):
|
|||||||
func _make_bone_nodes():
|
func _make_bone_nodes():
|
||||||
# Remove all of the old bone nodes
|
# Remove all of the old bone nodes
|
||||||
# TODO: (not a huge concern, as these can be removed in the editor)
|
# TODO: (not a huge concern, as these can be removed in the editor)
|
||||||
|
|
||||||
for bone in range(0, bones_in_chain.size()):
|
for bone in range(0, bones_in_chain.size()):
|
||||||
|
|
||||||
var bone_name = bones_in_chain[bone]
|
var bone_name = bones_in_chain[bone]
|
||||||
if has_node(bone_name) == false:
|
if has_node(bone_name) == false:
|
||||||
var new_node = Spatial.new()
|
var new_node = Spatial.new()
|
||||||
bone_nodes[bone] = new_node
|
bone_nodes[bone] = new_node
|
||||||
add_child(bone_nodes[bone])
|
add_child(bone_nodes[bone])
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
if get_tree() != null:
|
if get_tree() != null:
|
||||||
if get_tree().edited_scene_root != null:
|
if get_tree().edited_scene_root != null:
|
||||||
bone_nodes[bone].set_owner(get_tree().edited_scene_root)
|
bone_nodes[bone].set_owner(get_tree().edited_scene_root)
|
||||||
|
|
||||||
bone_nodes[bone].name = bone_name
|
bone_nodes[bone].name = bone_name
|
||||||
|
|
||||||
else:
|
else:
|
||||||
bone_nodes[bone] = get_node(bone_name)
|
bone_nodes[bone] = get_node(bone_name)
|
||||||
|
|
||||||
# If we are in the editor, we want to make a sphere at this node
|
# If we are in the editor, we want to make a sphere at this node
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_make_editor_sphere_at_node(bone_nodes[bone], Color(0.65, 0, 1, 1))
|
_make_editor_sphere_at_node(bone_nodes[bone], Color(0.65, 0, 1, 1))
|
||||||
|
|
||||||
|
|
||||||
func _set_bone_chain_bones(new_value):
|
func _set_bone_chain_bones(new_value):
|
||||||
bones_in_chain = new_value
|
bones_in_chain = new_value
|
||||||
|
|
||||||
_make_bone_nodes()
|
_make_bone_nodes()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func _ready():
|
|||||||
set_process(false)
|
set_process(false)
|
||||||
set_physics_process(false)
|
set_physics_process(false)
|
||||||
set_notify_transform(false)
|
set_notify_transform(false)
|
||||||
|
|
||||||
if update_mode == 0:
|
if update_mode == 0:
|
||||||
set_process(true)
|
set_process(true)
|
||||||
elif update_mode == 1:
|
elif update_mode == 1:
|
||||||
@@ -28,10 +28,10 @@ func _ready():
|
|||||||
elif update_mode == 2:
|
elif update_mode == 2:
|
||||||
set_notify_transform(true)
|
set_notify_transform(true)
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: Unknown update mode. NOT updating skeleton")
|
print (name, " - IK_LookAt: Unknown update mode. NOT updating skeleton")
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_setup_for_editor()
|
_setup_for_editor()
|
||||||
|
|
||||||
|
|
||||||
@@ -51,33 +51,33 @@ func _notification(what):
|
|||||||
func update_skeleton():
|
func update_skeleton():
|
||||||
# NOTE: Because get_node doesn't work in _ready, we need to skip
|
# NOTE: Because get_node doesn't work in _ready, we need to skip
|
||||||
# a call before doing anything.
|
# a call before doing anything.
|
||||||
if first_call == true:
|
if first_call:
|
||||||
first_call = false
|
first_call = false
|
||||||
if skeleton_to_use == null:
|
if skeleton_to_use == null:
|
||||||
_set_skeleton_path(skeleton_path)
|
_set_skeleton_path(skeleton_path)
|
||||||
|
|
||||||
|
|
||||||
# If we do not have a skeleton and/or we're not supposed to update, then return.
|
# If we do not have a skeleton and/or we're not supposed to update, then return.
|
||||||
if skeleton_to_use == null:
|
if skeleton_to_use == null:
|
||||||
return
|
return
|
||||||
if update_mode >= 3:
|
if update_mode >= 3:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the bone
|
# Get the bone
|
||||||
var bone = skeleton_to_use.find_bone(bone_name)
|
var bone = skeleton_to_use.find_bone(bone_name)
|
||||||
|
|
||||||
# If no bone is found (-1), then return (and optionally print an error)
|
# If no bone is found (-1), then return (and optionally print an error)
|
||||||
if bone == -1:
|
if bone == -1:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: No bone in skeleton found with name [", bone_name, "]!")
|
print (name, " - IK_LookAt: No bone in skeleton found with name [", bone_name, "]!")
|
||||||
return
|
return
|
||||||
|
|
||||||
# get the bone's rest position
|
# get the bone's rest position
|
||||||
var rest = skeleton_to_use.get_bone_global_pose(bone)
|
var rest = skeleton_to_use.get_bone_global_pose(bone)
|
||||||
|
|
||||||
# Convert our position relative to the skeleton's transform
|
# Convert our position relative to the skeleton's transform
|
||||||
var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin)
|
var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin)
|
||||||
|
|
||||||
# Call helper's look_at function with the chosen up axis.
|
# Call helper's look_at function with the chosen up axis.
|
||||||
if look_at_axis == 0:
|
if look_at_axis == 0:
|
||||||
rest = rest.looking_at(target_pos, Vector3(1, 0, 0))
|
rest = rest.looking_at(target_pos, Vector3(1, 0, 0))
|
||||||
@@ -87,34 +87,34 @@ func update_skeleton():
|
|||||||
rest = rest.looking_at(target_pos, Vector3(0, 0, 1))
|
rest = rest.looking_at(target_pos, Vector3(0, 0, 1))
|
||||||
else:
|
else:
|
||||||
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
|
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: Unknown look_at_axis value!")
|
print (name, " - IK_LookAt: Unknown look_at_axis value!")
|
||||||
|
|
||||||
# Get our rotation euler, and the bone's rotation euler
|
# Get our rotation euler, and the bone's rotation euler
|
||||||
var rest_euler = rest.basis.get_euler()
|
var rest_euler = rest.basis.get_euler()
|
||||||
var self_euler = global_transform.basis.orthonormalized().get_euler()
|
var self_euler = global_transform.basis.orthonormalized().get_euler()
|
||||||
|
|
||||||
# If we using negative rotation, we flip our rotation euler
|
# If we using negative rotation, we flip our rotation euler
|
||||||
if use_negative_our_rot == true:
|
if use_negative_our_rot:
|
||||||
self_euler = -self_euler
|
self_euler = -self_euler
|
||||||
|
|
||||||
# Apply our rotation euler, if wanted/required
|
# Apply our rotation euler, if wanted/required
|
||||||
if use_our_rotation_x == true:
|
if use_our_rotation_x:
|
||||||
rest_euler.x = self_euler.x
|
rest_euler.x = self_euler.x
|
||||||
if use_our_rotation_y == true:
|
if use_our_rotation_y:
|
||||||
rest_euler.y = self_euler.y
|
rest_euler.y = self_euler.y
|
||||||
if use_our_rotation_z == true:
|
if use_our_rotation_z:
|
||||||
rest_euler.z = self_euler.z
|
rest_euler.z = self_euler.z
|
||||||
|
|
||||||
# Rotate the bone by the (potentially) changed euler angle(s)
|
# Rotate the bone by the (potentially) changed euler angle(s)
|
||||||
rest.basis = Basis(rest_euler)
|
rest.basis = Basis(rest_euler)
|
||||||
|
|
||||||
# If we have additional rotation, then rotate it by the local rotation vectors
|
# If we have additional rotation, then rotate it by the local rotation vectors
|
||||||
if additional_rotation != Vector3.ZERO:
|
if additional_rotation != Vector3.ZERO:
|
||||||
rest.basis = rest.basis.rotated(rest.basis.x, deg2rad(additional_rotation.x))
|
rest.basis = rest.basis.rotated(rest.basis.x, deg2rad(additional_rotation.x))
|
||||||
rest.basis = rest.basis.rotated(rest.basis.y, deg2rad(additional_rotation.y))
|
rest.basis = rest.basis.rotated(rest.basis.y, deg2rad(additional_rotation.y))
|
||||||
rest.basis = rest.basis.rotated(rest.basis.z, deg2rad(additional_rotation.z))
|
rest.basis = rest.basis.rotated(rest.basis.z, deg2rad(additional_rotation.z))
|
||||||
|
|
||||||
# Finally, apply the bone rotation to the skeleton
|
# Finally, apply the bone rotation to the skeleton
|
||||||
skeleton_to_use.set_bone_global_pose(bone, rest)
|
skeleton_to_use.set_bone_global_pose(bone, rest)
|
||||||
|
|
||||||
@@ -146,58 +146,58 @@ func _setup_for_editor():
|
|||||||
|
|
||||||
func _set_update(new_value):
|
func _set_update(new_value):
|
||||||
update_mode = new_value
|
update_mode = new_value
|
||||||
|
|
||||||
# Set all of our processes to false
|
# Set all of our processes to false
|
||||||
set_process(false)
|
set_process(false)
|
||||||
set_physics_process(false)
|
set_physics_process(false)
|
||||||
set_notify_transform(false)
|
set_notify_transform(false)
|
||||||
|
|
||||||
# Based on the value of upate, change how we handle updating the skeleton
|
# Based on the value of upate, change how we handle updating the skeleton
|
||||||
if update_mode == 0:
|
if update_mode == 0:
|
||||||
set_process(true)
|
set_process(true)
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: updating skeleton using _process...")
|
print (name, " - IK_LookAt: updating skeleton using _process...")
|
||||||
elif update_mode == 1:
|
elif update_mode == 1:
|
||||||
set_physics_process(true)
|
set_physics_process(true)
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: updating skeleton using _physics_process...")
|
print (name, " - IK_LookAt: updating skeleton using _physics_process...")
|
||||||
elif update_mode == 2:
|
elif update_mode == 2:
|
||||||
set_notify_transform(true)
|
set_notify_transform(true)
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: updating skeleton using _notification...")
|
print (name, " - IK_LookAt: updating skeleton using _notification...")
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: NOT updating skeleton due to unknown update method...")
|
print (name, " - IK_LookAt: NOT updating skeleton due to unknown update method...")
|
||||||
|
|
||||||
|
|
||||||
func _set_skeleton_path(new_value):
|
func _set_skeleton_path(new_value):
|
||||||
# Because get_node doesn't work in the first call, we just want to assign instead
|
# Because get_node doesn't work in the first call, we just want to assign instead
|
||||||
# This is to get around a issue with NodePaths exposed to the editor
|
# This is to get around a issue with NodePaths exposed to the editor
|
||||||
if first_call == true:
|
if first_call:
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
return
|
return
|
||||||
|
|
||||||
# Assign skeleton_path to whatever value is passed
|
# Assign skeleton_path to whatever value is passed
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
|
|
||||||
if skeleton_path == null:
|
if skeleton_path == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the node at that location, if there is one
|
# Get the node at that location, if there is one
|
||||||
var temp = get_node(skeleton_path)
|
var temp = get_node(skeleton_path)
|
||||||
if temp != null:
|
if temp != null:
|
||||||
# If the node has the method "find_bone" then we can assume it is (likely) a skeleton
|
# If the node has the method "find_bone" then we can assume it is (likely) a skeleton
|
||||||
if temp.has_method("find_bone") == true:
|
if temp.has_method("find_bone"):
|
||||||
skeleton_to_use = temp
|
skeleton_to_use = temp
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: attached to (new) skeleton")
|
print (name, " - IK_LookAt: attached to (new) skeleton")
|
||||||
# If not, then it's (likely) not a skeleton
|
# If not, then it's (likely) not a skeleton
|
||||||
else:
|
else:
|
||||||
skeleton_to_use = null
|
skeleton_to_use = null
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: skeleton_path does not point to a skeleton!")
|
print (name, " - IK_LookAt: skeleton_path does not point to a skeleton!")
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends EditorPlugin
|
|||||||
|
|
||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
# Plugin Initialization here!
|
# Plugin Initialization here!
|
||||||
|
|
||||||
# ------ IK STUFF ------
|
# ------ IK STUFF ------
|
||||||
add_custom_type("IK_LookAt", "Spatial", preload("ik_look_at.gd"), preload("ik_look_at.png"))
|
add_custom_type("IK_LookAt", "Spatial", preload("ik_look_at.gd"), preload("ik_look_at.png"))
|
||||||
add_custom_type("IK_FABRIK", "Spatial", preload("ik_fabrik.gd"), preload("ik_fabrik.png"))
|
add_custom_type("IK_FABRIK", "Spatial", preload("ik_fabrik.gd"), preload("ik_fabrik.png"))
|
||||||
@@ -12,7 +12,7 @@ func _enter_tree():
|
|||||||
|
|
||||||
func _exit_tree():
|
func _exit_tree():
|
||||||
# Plugin Clean-up here!
|
# Plugin Clean-up here!
|
||||||
|
|
||||||
# ------ IK STUFF ------
|
# ------ IK STUFF ------
|
||||||
remove_custom_type("IK_LookAt")
|
remove_custom_type("IK_LookAt")
|
||||||
remove_custom_type("IK_FABRIK")
|
remove_custom_type("IK_FABRIK")
|
||||||
|
|||||||
@@ -55,16 +55,16 @@ var simple_bullet = preload("res://fps/simple_bullet.tscn")
|
|||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
|
||||||
camera = get_node("CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Camera")
|
camera = get_node("CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Camera")
|
||||||
camera_holder = get_node("CameraHolder")
|
camera_holder = get_node("CameraHolder")
|
||||||
path_follow_node = get_node("CameraHolder/Lean_Path/PathFollow")
|
path_follow_node = get_node("CameraHolder/Lean_Path/PathFollow")
|
||||||
|
|
||||||
anim_player = get_node("CameraHolder/AnimationPlayer")
|
anim_player = get_node("CameraHolder/AnimationPlayer")
|
||||||
anim_player.connect("animation_finished", self, "animation_finished")
|
anim_player.connect("animation_finished", self, "animation_finished")
|
||||||
|
|
||||||
pistol_end = get_node("CameraHolder/Weapon/Pistol/Pistol_end")
|
pistol_end = get_node("CameraHolder/Weapon/Pistol/Pistol_end")
|
||||||
|
|
||||||
set_physics_process(true)
|
set_physics_process(true)
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
set_process_input(true)
|
set_process_input(true)
|
||||||
@@ -76,12 +76,12 @@ func _physics_process(delta):
|
|||||||
|
|
||||||
|
|
||||||
func process_input(delta):
|
func process_input(delta):
|
||||||
|
|
||||||
# Reset dir, so our previous movement does not effect us
|
# Reset dir, so our previous movement does not effect us
|
||||||
dir = Vector3()
|
dir = Vector3()
|
||||||
# Get the camera's global transform so we can use its directional vectors
|
# Get the camera's global transform so we can use its directional vectors
|
||||||
var cam_xform = camera.get_global_transform()
|
var cam_xform = camera.get_global_transform()
|
||||||
|
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Walking
|
# Walking
|
||||||
if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_W):
|
if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_W):
|
||||||
@@ -92,33 +92,33 @@ func process_input(delta):
|
|||||||
dir += -cam_xform.basis[0]
|
dir += -cam_xform.basis[0]
|
||||||
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
|
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
|
||||||
dir += cam_xform.basis[0]
|
dir += cam_xform.basis[0]
|
||||||
|
|
||||||
if Input.is_action_just_pressed("ui_cancel"):
|
if Input.is_action_just_pressed("ui_cancel"):
|
||||||
if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
|
if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
else:
|
else:
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
|
|
||||||
if Input.is_mouse_button_pressed(2):
|
if Input.is_mouse_button_pressed(2):
|
||||||
if right_mouse_down == false:
|
if right_mouse_down == false:
|
||||||
right_mouse_down = true
|
right_mouse_down = true
|
||||||
|
|
||||||
if anim_done == true:
|
if anim_done:
|
||||||
if current_anim != "Aiming":
|
if current_anim != "Aiming":
|
||||||
anim_player.play("Aiming")
|
anim_player.play("Aiming")
|
||||||
current_anim = "Aiming"
|
current_anim = "Aiming"
|
||||||
else:
|
else:
|
||||||
anim_player.play("Idle")
|
anim_player.play("Idle")
|
||||||
current_anim = "Idle"
|
current_anim = "Idle"
|
||||||
|
|
||||||
anim_done = false
|
anim_done = false
|
||||||
else:
|
else:
|
||||||
right_mouse_down = false
|
right_mouse_down = false
|
||||||
|
|
||||||
if Input.is_mouse_button_pressed(1):
|
if Input.is_mouse_button_pressed(1):
|
||||||
if left_mouse_timer <= 0:
|
if left_mouse_timer <= 0:
|
||||||
left_mouse_timer = LEFT_MOUSE_FIRE_TIME
|
left_mouse_timer = LEFT_MOUSE_FIRE_TIME
|
||||||
|
|
||||||
# Create a bullet
|
# Create a bullet
|
||||||
var new_bullet = simple_bullet.instance()
|
var new_bullet = simple_bullet.instance()
|
||||||
get_tree().root.add_child(new_bullet)
|
get_tree().root.add_child(new_bullet)
|
||||||
@@ -127,8 +127,8 @@ func process_input(delta):
|
|||||||
if left_mouse_timer > 0:
|
if left_mouse_timer > 0:
|
||||||
left_mouse_timer -= delta
|
left_mouse_timer -= delta
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Sprinting
|
# Sprinting
|
||||||
if Input.is_key_pressed(KEY_SHIFT):
|
if Input.is_key_pressed(KEY_SHIFT):
|
||||||
@@ -136,7 +136,7 @@ func process_input(delta):
|
|||||||
else:
|
else:
|
||||||
is_sprinting = false
|
is_sprinting = false
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
|
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Jumping
|
# Jumping
|
||||||
if Input.is_key_pressed(KEY_SPACE):
|
if Input.is_key_pressed(KEY_SPACE):
|
||||||
@@ -147,8 +147,8 @@ func process_input(delta):
|
|||||||
else:
|
else:
|
||||||
jump_button_down = false
|
jump_button_down = false
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Leaninng
|
# Leaninng
|
||||||
if Input.is_key_pressed(KEY_Q):
|
if Input.is_key_pressed(KEY_Q):
|
||||||
@@ -164,7 +164,7 @@ func process_input(delta):
|
|||||||
lean_value += 1 * delta
|
lean_value += 1 * delta
|
||||||
if lean_value > 0.5:
|
if lean_value > 0.5:
|
||||||
lean_value = 0.5
|
lean_value = 0.5
|
||||||
|
|
||||||
lean_value = clamp(lean_value, 0, 1)
|
lean_value = clamp(lean_value, 0, 1)
|
||||||
path_follow_node.unit_offset = lean_value
|
path_follow_node.unit_offset = lean_value
|
||||||
if lean_value < 0.5:
|
if lean_value < 0.5:
|
||||||
@@ -177,24 +177,24 @@ func process_input(delta):
|
|||||||
|
|
||||||
|
|
||||||
func process_movement(delta):
|
func process_movement(delta):
|
||||||
|
|
||||||
var grav = norm_grav
|
var grav = norm_grav
|
||||||
|
|
||||||
dir.y = 0
|
dir.y = 0
|
||||||
dir = dir.normalized()
|
dir = dir.normalized()
|
||||||
|
|
||||||
vel.y += delta*grav
|
vel.y += delta*grav
|
||||||
|
|
||||||
var hvel = vel
|
var hvel = vel
|
||||||
hvel.y = 0
|
hvel.y = 0
|
||||||
|
|
||||||
var target = dir
|
var target = dir
|
||||||
if is_sprinting:
|
if is_sprinting:
|
||||||
target *= MAX_SPRINT_SPEED
|
target *= MAX_SPRINT_SPEED
|
||||||
else:
|
else:
|
||||||
target *= MAX_SPEED
|
target *= MAX_SPEED
|
||||||
|
|
||||||
|
|
||||||
var accel
|
var accel
|
||||||
if dir.dot(hvel) > 0:
|
if dir.dot(hvel) > 0:
|
||||||
if is_sprinting == false:
|
if is_sprinting == false:
|
||||||
@@ -203,32 +203,32 @@ func process_movement(delta):
|
|||||||
accel = SPRINT_ACCEL
|
accel = SPRINT_ACCEL
|
||||||
else:
|
else:
|
||||||
accel = DEACCEL
|
accel = DEACCEL
|
||||||
|
|
||||||
hvel = hvel.linear_interpolate(target, accel*delta)
|
hvel = hvel.linear_interpolate(target, accel*delta)
|
||||||
|
|
||||||
vel.x = hvel.x
|
vel.x = hvel.x
|
||||||
vel.z = hvel.z
|
vel.z = hvel.z
|
||||||
|
|
||||||
vel = move_and_slide(vel,Vector3(0,1,0))
|
vel = move_and_slide(vel,Vector3(0,1,0))
|
||||||
|
|
||||||
|
|
||||||
# Mouse based camera movement
|
# Mouse based camera movement
|
||||||
func _input(event):
|
func _input(event):
|
||||||
|
|
||||||
if event is InputEventMouseMotion && Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
if event is InputEventMouseMotion && Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
||||||
|
|
||||||
rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
|
rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
|
||||||
camera_holder.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
|
camera_holder.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
|
||||||
|
|
||||||
# We need to clamp the camera's rotation so we cannot rotate ourselves upside down
|
# We need to clamp the camera's rotation so we cannot rotate ourselves upside down
|
||||||
var camera_rot = camera_holder.rotation_degrees
|
var camera_rot = camera_holder.rotation_degrees
|
||||||
if camera_rot.x < -40:
|
if camera_rot.x < -40:
|
||||||
camera_rot.x = -40
|
camera_rot.x = -40
|
||||||
elif camera_rot.x > 60:
|
elif camera_rot.x > 60:
|
||||||
camera_rot.x = 60
|
camera_rot.x = 60
|
||||||
|
|
||||||
camera_holder.rotation_degrees = camera_rot
|
camera_holder.rotation_degrees = camera_rot
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ func _ready():
|
|||||||
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
var mouse_to_world = project_local_ray_normal(get_viewport().get_mouse_position()) * MOVEMENT_SPEED
|
var mouse_to_world = project_local_ray_normal(get_viewport().get_mouse_position()) * MOVEMENT_SPEED
|
||||||
|
|
||||||
if flip_axis == false:
|
if flip_axis == false:
|
||||||
mouse_to_world.z *= -1
|
mouse_to_world.z *= -1
|
||||||
else:
|
else:
|
||||||
mouse_to_world = -mouse_to_world
|
mouse_to_world = -mouse_to_world
|
||||||
|
|
||||||
targets.transform.origin = mouse_to_world
|
targets.transform.origin = mouse_to_world
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func _unhandled_input(ev):
|
|||||||
zoom += ZOOM_SPEED
|
zoom += ZOOM_SPEED
|
||||||
zoom = clamp(zoom, 2, 8)
|
zoom = clamp(zoom, 2, 8)
|
||||||
camera.translation.z = zoom
|
camera.translation.z = zoom
|
||||||
|
|
||||||
if ev is InputEventMouseMotion and ev.button_mask & MAIN_BUTTONS:
|
if ev is InputEventMouseMotion and ev.button_mask & MAIN_BUTTONS:
|
||||||
# Compensate motion speed to be resolution-independent (based on the window height).
|
# Compensate motion speed to be resolution-independent (based on the window height).
|
||||||
var relative_motion = ev.relative * get_viewport().size.y / base_height
|
var relative_motion = ev.relative * get_viewport().size.y / base_height
|
||||||
|
|||||||
@@ -33,16 +33,16 @@ func _process(delta):
|
|||||||
else:
|
else:
|
||||||
path[path.size() - 1] = pfrom.linear_interpolate(pto, to_walk / d)
|
path[path.size() - 1] = pfrom.linear_interpolate(pto, to_walk / d)
|
||||||
to_walk = 0
|
to_walk = 0
|
||||||
|
|
||||||
var atpos = path[path.size() - 1]
|
var atpos = path[path.size() - 1]
|
||||||
var atdir = to_watch
|
var atdir = to_watch
|
||||||
atdir.y = 0
|
atdir.y = 0
|
||||||
|
|
||||||
var t = Transform()
|
var t = Transform()
|
||||||
t.origin = atpos
|
t.origin = atpos
|
||||||
t = t.looking_at(atpos + atdir, Vector3.UP)
|
t = t.looking_at(atpos + atdir, Vector3.UP)
|
||||||
get_node("RobotBase").set_transform(t)
|
get_node("RobotBase").set_transform(t)
|
||||||
|
|
||||||
if path.size() < 2:
|
if path.size() < 2:
|
||||||
path = []
|
path = []
|
||||||
set_process(false)
|
set_process(false)
|
||||||
@@ -55,11 +55,11 @@ func _input(event):
|
|||||||
var from = get_node("CameraBase/Camera").project_ray_origin(event.position)
|
var from = get_node("CameraBase/Camera").project_ray_origin(event.position)
|
||||||
var to = from + get_node("CameraBase/Camera").project_ray_normal(event.position) * 100
|
var to = from + get_node("CameraBase/Camera").project_ray_normal(event.position) * 100
|
||||||
var p = get_closest_point_to_segment(from, to)
|
var p = get_closest_point_to_segment(from, to)
|
||||||
|
|
||||||
begin = get_closest_point(get_node("RobotBase").get_translation())
|
begin = get_closest_point(get_node("RobotBase").get_translation())
|
||||||
end = p
|
end = p
|
||||||
_update_path()
|
_update_path()
|
||||||
|
|
||||||
if event is InputEventMouseMotion:
|
if event is InputEventMouseMotion:
|
||||||
if event.button_mask & (BUTTON_MASK_MIDDLE + BUTTON_MASK_RIGHT):
|
if event.button_mask & (BUTTON_MASK_MIDDLE + BUTTON_MASK_RIGHT):
|
||||||
camrot += event.relative.x * 0.005
|
camrot += event.relative.x * 0.005
|
||||||
@@ -72,7 +72,7 @@ func _update_path():
|
|||||||
path = Array(p) # Vector3 array too complex to use, convert to regular array.
|
path = Array(p) # Vector3 array too complex to use, convert to regular array.
|
||||||
path.invert()
|
path.invert()
|
||||||
set_process(true)
|
set_process(true)
|
||||||
|
|
||||||
if draw_path:
|
if draw_path:
|
||||||
var im = get_node("Draw")
|
var im = get_node("Draw")
|
||||||
im.set_material_override(m)
|
im.set_material_override(m)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ func _integrate_forces(state):
|
|||||||
|
|
||||||
lv += g * delta # Apply gravity.
|
lv += g * delta # Apply gravity.
|
||||||
var up = -g.normalized()
|
var up = -g.normalized()
|
||||||
|
|
||||||
if dying:
|
if dying:
|
||||||
state.set_linear_velocity(lv)
|
state.set_linear_velocity(lv)
|
||||||
return
|
return
|
||||||
|
|
||||||
for i in range(state.get_contact_count()):
|
for i in range(state.get_contact_count()):
|
||||||
var cc = state.get_contact_collider_object(i)
|
var cc = state.get_contact_collider_object(i)
|
||||||
var dp = state.get_contact_local_normal(i)
|
var dp = state.get_contact_local_normal(i)
|
||||||
|
|
||||||
if cc:
|
if cc:
|
||||||
if cc is preload("res://bullet.gd") and cc.enabled:
|
if cc is preload("res://bullet.gd") and cc.enabled:
|
||||||
set_mode(MODE_RIGID)
|
set_mode(MODE_RIGID)
|
||||||
@@ -43,15 +43,15 @@ func _integrate_forces(state):
|
|||||||
cc.enabled = false
|
cc.enabled = false
|
||||||
get_node("SoundHit").play()
|
get_node("SoundHit").play()
|
||||||
return
|
return
|
||||||
|
|
||||||
var col_floor = get_node("Armature/RayFloor").is_colliding()
|
var col_floor = get_node("Armature/RayFloor").is_colliding()
|
||||||
var col_wall = get_node("Armature/RayWall").is_colliding()
|
var col_wall = get_node("Armature/RayWall").is_colliding()
|
||||||
|
|
||||||
var advance = col_floor and not col_wall
|
var advance = col_floor and not col_wall
|
||||||
|
|
||||||
var dir = get_node("Armature").get_transform().basis[2].normalized()
|
var dir = get_node("Armature").get_transform().basis[2].normalized()
|
||||||
var deaccel_dir = dir
|
var deaccel_dir = dir
|
||||||
|
|
||||||
if advance:
|
if advance:
|
||||||
if dir.dot(lv) < max_speed:
|
if dir.dot(lv) < max_speed:
|
||||||
lv += dir * accel * delta
|
lv += dir * accel * delta
|
||||||
@@ -59,17 +59,17 @@ func _integrate_forces(state):
|
|||||||
else:
|
else:
|
||||||
if prev_advance:
|
if prev_advance:
|
||||||
rot_dir = 1
|
rot_dir = 1
|
||||||
|
|
||||||
dir = Basis(up, rot_dir * rot_speed * delta).xform(dir)
|
dir = Basis(up, rot_dir * rot_speed * delta).xform(dir)
|
||||||
get_node("Armature").set_transform(Transform().looking_at(-dir, up))
|
get_node("Armature").set_transform(Transform().looking_at(-dir, up))
|
||||||
|
|
||||||
var dspeed = deaccel_dir.dot(lv)
|
var dspeed = deaccel_dir.dot(lv)
|
||||||
dspeed -= deaccel * delta
|
dspeed -= deaccel * delta
|
||||||
if dspeed < 0:
|
if dspeed < 0:
|
||||||
dspeed = 0
|
dspeed = 0
|
||||||
|
|
||||||
lv = lv - deaccel_dir * deaccel_dir.dot(lv) + deaccel_dir * dspeed
|
lv = lv - deaccel_dir * deaccel_dir.dot(lv) + deaccel_dir * dspeed
|
||||||
|
|
||||||
state.set_linear_velocity(lv)
|
state.set_linear_velocity(lv)
|
||||||
prev_advance = advance
|
prev_advance = advance
|
||||||
|
|
||||||
|
|||||||
@@ -32,15 +32,15 @@ func _ready():
|
|||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
linear_velocity += gravity * delta
|
linear_velocity += gravity * delta
|
||||||
|
|
||||||
var anim = ANIM_FLOOR
|
var anim = ANIM_FLOOR
|
||||||
|
|
||||||
var vv = linear_velocity.y # Vertical velocity.
|
var vv = linear_velocity.y # Vertical velocity.
|
||||||
var hv = Vector3(linear_velocity.x, 0, linear_velocity.z) # Horizontal velocity.
|
var hv = Vector3(linear_velocity.x, 0, linear_velocity.z) # Horizontal velocity.
|
||||||
|
|
||||||
var hdir = hv.normalized() # Horizontal direction.
|
var hdir = hv.normalized() # Horizontal direction.
|
||||||
var hspeed = hv.length() # Horizontal speed.
|
var hspeed = hv.length() # Horizontal speed.
|
||||||
|
|
||||||
# Player input
|
# Player input
|
||||||
var cam_basis = get_node("Target/Camera").get_global_transform().basis
|
var cam_basis = get_node("Target/Camera").get_global_transform().basis
|
||||||
var dir = Vector3() # Where does the player intend to walk to.
|
var dir = Vector3() # Where does the player intend to walk to.
|
||||||
@@ -50,39 +50,39 @@ func _physics_process(delta):
|
|||||||
dir -= Input.get_action_strength("move_forward") * cam_basis[2]
|
dir -= Input.get_action_strength("move_forward") * cam_basis[2]
|
||||||
dir.y = 0
|
dir.y = 0
|
||||||
dir = dir.normalized()
|
dir = dir.normalized()
|
||||||
|
|
||||||
var jump_attempt = Input.is_action_pressed("jump")
|
var jump_attempt = Input.is_action_pressed("jump")
|
||||||
var shoot_attempt = Input.is_action_pressed("shoot")
|
var shoot_attempt = Input.is_action_pressed("shoot")
|
||||||
|
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
var sharp_turn = hspeed > 0.1 and rad2deg(acos(dir.dot(hdir))) > sharp_turn_threshold
|
var sharp_turn = hspeed > 0.1 and rad2deg(acos(dir.dot(hdir))) > sharp_turn_threshold
|
||||||
|
|
||||||
if dir.length() > 0.1 and !sharp_turn:
|
if dir.length() > 0.1 and !sharp_turn:
|
||||||
if hspeed > 0.001:
|
if hspeed > 0.001:
|
||||||
hdir = adjust_facing(hdir, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
|
hdir = adjust_facing(hdir, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
|
||||||
facing_dir = hdir
|
facing_dir = hdir
|
||||||
else:
|
else:
|
||||||
hdir = dir
|
hdir = dir
|
||||||
|
|
||||||
if hspeed < max_speed:
|
if hspeed < max_speed:
|
||||||
hspeed += accel * delta
|
hspeed += accel * delta
|
||||||
else:
|
else:
|
||||||
hspeed -= deaccel * delta
|
hspeed -= deaccel * delta
|
||||||
if hspeed < 0:
|
if hspeed < 0:
|
||||||
hspeed = 0
|
hspeed = 0
|
||||||
|
|
||||||
hv = hdir * hspeed
|
hv = hdir * hspeed
|
||||||
|
|
||||||
var mesh_xform = get_node("Armature").get_transform()
|
var mesh_xform = get_node("Armature").get_transform()
|
||||||
var facing_mesh = -mesh_xform.basis[0].normalized()
|
var facing_mesh = -mesh_xform.basis[0].normalized()
|
||||||
facing_mesh = (facing_mesh - Vector3.UP * facing_mesh.dot(Vector3.UP)).normalized()
|
facing_mesh = (facing_mesh - Vector3.UP * facing_mesh.dot(Vector3.UP)).normalized()
|
||||||
|
|
||||||
if hspeed > 0:
|
if hspeed > 0:
|
||||||
facing_mesh = adjust_facing(facing_mesh, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
|
facing_mesh = adjust_facing(facing_mesh, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
|
||||||
var m3 = Basis(-facing_mesh, Vector3.UP, -facing_mesh.cross(Vector3.UP).normalized()).scaled(CHAR_SCALE)
|
var m3 = Basis(-facing_mesh, Vector3.UP, -facing_mesh.cross(Vector3.UP).normalized()).scaled(CHAR_SCALE)
|
||||||
|
|
||||||
get_node("Armature").set_transform(Transform(m3, mesh_xform.origin))
|
get_node("Armature").set_transform(Transform(m3, mesh_xform.origin))
|
||||||
|
|
||||||
if not jumping and jump_attempt:
|
if not jumping and jump_attempt:
|
||||||
vv = 7.0
|
vv = 7.0
|
||||||
jumping = true
|
jumping = true
|
||||||
@@ -92,7 +92,7 @@ func _physics_process(delta):
|
|||||||
anim = ANIM_AIR_UP
|
anim = ANIM_AIR_UP
|
||||||
else:
|
else:
|
||||||
anim = ANIM_AIR_DOWN
|
anim = ANIM_AIR_DOWN
|
||||||
|
|
||||||
if dir.length() > 0.1:
|
if dir.length() > 0.1:
|
||||||
hv += dir * (accel * 0.2 * delta)
|
hv += dir * (accel * 0.2 * delta)
|
||||||
if hv.length() > max_speed:
|
if hv.length() > max_speed:
|
||||||
@@ -103,22 +103,22 @@ func _physics_process(delta):
|
|||||||
if hspeed < 0:
|
if hspeed < 0:
|
||||||
hspeed = 0
|
hspeed = 0
|
||||||
hv = hdir * hspeed
|
hv = hdir * hspeed
|
||||||
|
|
||||||
if jumping and vv < 0:
|
if jumping and vv < 0:
|
||||||
jumping = false
|
jumping = false
|
||||||
|
|
||||||
linear_velocity = hv + Vector3.UP * vv
|
linear_velocity = hv + Vector3.UP * vv
|
||||||
|
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
movement_dir = linear_velocity
|
movement_dir = linear_velocity
|
||||||
|
|
||||||
linear_velocity = move_and_slide(linear_velocity, -gravity.normalized())
|
linear_velocity = move_and_slide(linear_velocity, -gravity.normalized())
|
||||||
|
|
||||||
if shoot_blend > 0:
|
if shoot_blend > 0:
|
||||||
shoot_blend -= delta * SHOOT_SCALE
|
shoot_blend -= delta * SHOOT_SCALE
|
||||||
if (shoot_blend < 0):
|
if (shoot_blend < 0):
|
||||||
shoot_blend = 0
|
shoot_blend = 0
|
||||||
|
|
||||||
if shoot_attempt and not prev_shoot:
|
if shoot_attempt and not prev_shoot:
|
||||||
shoot_blend = SHOOT_TIME
|
shoot_blend = SHOOT_TIME
|
||||||
var bullet = preload("res://bullet.tscn").instance()
|
var bullet = preload("res://bullet.tscn").instance()
|
||||||
@@ -127,12 +127,12 @@ func _physics_process(delta):
|
|||||||
bullet.set_linear_velocity(get_node("Armature/Bullet").get_global_transform().basis[2].normalized() * 20)
|
bullet.set_linear_velocity(get_node("Armature/Bullet").get_global_transform().basis[2].normalized() * 20)
|
||||||
bullet.add_collision_exception_with(self) # Add it to bullet.
|
bullet.add_collision_exception_with(self) # Add it to bullet.
|
||||||
get_node("SoundShoot").play()
|
get_node("SoundShoot").play()
|
||||||
|
|
||||||
prev_shoot = shoot_attempt
|
prev_shoot = shoot_attempt
|
||||||
|
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed / max_speed)
|
get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed / max_speed)
|
||||||
|
|
||||||
get_node("AnimationTreePlayer").transition_node_set_current("state", anim)
|
get_node("AnimationTreePlayer").transition_node_set_current("state", anim)
|
||||||
get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0))
|
get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0))
|
||||||
|
|
||||||
@@ -140,15 +140,15 @@ func _physics_process(delta):
|
|||||||
func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn):
|
func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn):
|
||||||
var n = p_target # Normal.
|
var n = p_target # Normal.
|
||||||
var t = n.cross(current_gn).normalized()
|
var t = n.cross(current_gn).normalized()
|
||||||
|
|
||||||
var x = n.dot(p_facing)
|
var x = n.dot(p_facing)
|
||||||
var y = t.dot(p_facing)
|
var y = t.dot(p_facing)
|
||||||
|
|
||||||
var ang = atan2(y,x)
|
var ang = atan2(y,x)
|
||||||
|
|
||||||
if abs(ang) < 0.001: # Too small.
|
if abs(ang) < 0.001: # Too small.
|
||||||
return p_facing
|
return p_facing
|
||||||
|
|
||||||
var s = sign(ang)
|
var s = sign(ang)
|
||||||
ang = ang * s
|
ang = ang * s
|
||||||
var turn = ang * p_adjust_rate * p_step
|
var turn = ang * p_adjust_rate * p_step
|
||||||
@@ -158,5 +158,5 @@ func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn):
|
|||||||
else:
|
else:
|
||||||
a = turn
|
a = turn
|
||||||
ang = (ang - a) * s
|
ang = (ang - a) * s
|
||||||
|
|
||||||
return (n * cos(ang) + t * sin(ang)) * p_facing.length()
|
return (n * cos(ang) + t * sin(ang)) * p_facing.length()
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func _ready():
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
node = node.get_parent()
|
node = node.get_parent()
|
||||||
|
|
||||||
# This detaches the camera transform from the parent spatial node.
|
# This detaches the camera transform from the parent spatial node.
|
||||||
set_as_toplevel(true)
|
set_as_toplevel(true)
|
||||||
|
|
||||||
@@ -25,25 +25,25 @@ func _ready():
|
|||||||
func _physics_process(_delta):
|
func _physics_process(_delta):
|
||||||
var target = get_parent().get_global_transform().origin
|
var target = get_parent().get_global_transform().origin
|
||||||
var pos = get_global_transform().origin
|
var pos = get_global_transform().origin
|
||||||
|
|
||||||
var from_target = pos - target
|
var from_target = pos - target
|
||||||
|
|
||||||
# Check ranges.
|
# Check ranges.
|
||||||
if from_target.length() < min_distance:
|
if from_target.length() < min_distance:
|
||||||
from_target = from_target.normalized() * min_distance
|
from_target = from_target.normalized() * min_distance
|
||||||
elif from_target.length() > max_distance:
|
elif from_target.length() > max_distance:
|
||||||
from_target = from_target.normalized() * max_distance
|
from_target = from_target.normalized() * max_distance
|
||||||
|
|
||||||
# Check upper and lower height.
|
# Check upper and lower height.
|
||||||
if from_target.y > max_height:
|
if from_target.y > max_height:
|
||||||
from_target.y = max_height
|
from_target.y = max_height
|
||||||
if from_target.y < min_height:
|
if from_target.y < min_height:
|
||||||
from_target.y = min_height
|
from_target.y = min_height
|
||||||
|
|
||||||
pos = target + from_target
|
pos = target + from_target
|
||||||
|
|
||||||
look_at_from_position(pos, target, Vector3.UP)
|
look_at_from_position(pos, target, Vector3.UP)
|
||||||
|
|
||||||
# Turn a little up or down
|
# Turn a little up or down
|
||||||
var t = get_transform()
|
var t = get_transform()
|
||||||
t.basis = Basis(t.basis[0], deg2rad(angle_v_adjust)) * t.basis
|
t.basis = Basis(t.basis[0], deg2rad(angle_v_adjust)) * t.basis
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ export var engine_force_value = 40
|
|||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
var fwd_mps = transform.basis.xform_inv(linear_velocity).x
|
var fwd_mps = transform.basis.xform_inv(linear_velocity).x
|
||||||
|
|
||||||
steer_target = Input.get_action_strength("turn_left") - Input.get_action_strength("turn_right")
|
steer_target = Input.get_action_strength("turn_left") - Input.get_action_strength("turn_right")
|
||||||
steer_target *= STEER_LIMIT
|
steer_target *= STEER_LIMIT
|
||||||
|
|
||||||
if Input.is_action_pressed("accelerate"):
|
if Input.is_action_pressed("accelerate"):
|
||||||
engine_force = engine_force_value
|
engine_force = engine_force_value
|
||||||
else:
|
else:
|
||||||
engine_force = 0
|
engine_force = 0
|
||||||
|
|
||||||
if Input.is_action_pressed("reverse"):
|
if Input.is_action_pressed("reverse"):
|
||||||
if (fwd_mps >= -1):
|
if (fwd_mps >= -1):
|
||||||
engine_force = -engine_force_value
|
engine_force = -engine_force_value
|
||||||
@@ -26,7 +26,7 @@ func _physics_process(delta):
|
|||||||
brake = 1
|
brake = 1
|
||||||
else:
|
else:
|
||||||
brake = 0.0
|
brake = 0.0
|
||||||
|
|
||||||
if steer_target < steer_angle:
|
if steer_target < steer_angle:
|
||||||
steer_angle -= STEER_SPEED * delta
|
steer_angle -= STEER_SPEED * delta
|
||||||
if steer_target > steer_angle:
|
if steer_target > steer_angle:
|
||||||
@@ -35,5 +35,5 @@ func _physics_process(delta):
|
|||||||
steer_angle += STEER_SPEED * delta
|
steer_angle += STEER_SPEED * delta
|
||||||
if steer_target < steer_angle:
|
if steer_target < steer_angle:
|
||||||
steer_angle = steer_target
|
steer_angle = steer_target
|
||||||
|
|
||||||
steering = steer_angle
|
steering = steer_angle
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
|
Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. \
|
||||||
Copyright (c) 2014-2020 Godot Engine contributors.
|
Copyright (c) 2014-2021 Godot Engine contributors.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|||||||
32
README.md
32
README.md
@@ -6,22 +6,30 @@ be used with [Godot Engine](https://godotengine.org), the open source
|
|||||||
|
|
||||||
## Godot versions
|
## Godot versions
|
||||||
|
|
||||||
- The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with the latest stable Godot version (currently 3.2).
|
- The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with Godot's `master` development branch (next 4.x release).
|
||||||
- If you are using an older version of Godot, use the appropriate branch for your Godot version:
|
- The [`3.x`](https://github.com/godotengine/godot-demo-projects/tree/3.x) branch is compatible with Godot's `3.x` development branch (next 3.x release).
|
||||||
|
- The other branches are compatible with the matching stable versions of Godot.
|
||||||
|
- [Click here](https://github.com/godotengine/godot-demo-projects/branches) to see all branches.
|
||||||
|
- For example, the [`2.1`](https://github.com/godotengine/godot-demo-projects/tree/2.1)
|
||||||
|
branch is for demos compatible with Godot 2.1.x.
|
||||||
|
|
||||||
- [`3.1`](https://github.com/godotengine/godot-demo-projects/tree/3.1) branch
|
## Importing all demos
|
||||||
for Godot 3.1.x.
|
|
||||||
- [`3.0`](https://github.com/godotengine/godot-demo-projects/tree/3.0) branch
|
To import all demos at once in the project manager:
|
||||||
for Godot 3.0.x.
|
|
||||||
- [`2.1`](https://github.com/godotengine/godot-demo-projects/tree/2.1) branch
|
- Clone this repository or [download a ZIP archive](https://github.com/godotengine/godot-demo-projects/archive/3.1.zip).
|
||||||
for Godot 2.1.x.
|
- If you've downloaded a ZIP archive, extract it somewhere.
|
||||||
|
- Open the Godot project manager and click the **Scan** button on the right.
|
||||||
|
- Choose the path to the folder containing all demos.
|
||||||
|
- All demos should now appear in the project manager.
|
||||||
|
|
||||||
## Useful links
|
## Useful links
|
||||||
|
|
||||||
- [Main website](https://godotengine.org)
|
- [Main website](https://godotengine.org)
|
||||||
- [Source code](https://github.com/godotengine/godot)
|
- [Source code](https://github.com/godotengine/godot)
|
||||||
- [Documentation](http://docs.godotengine.org)
|
- [Documentation](http://docs.godotengine.org)
|
||||||
- [Community hub](https://godotengine.org/community)
|
- [Community hub](https://godotengine.org/community)
|
||||||
|
- [TPS demo](https://github.com/godotengine/tps-demo)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
extends Panel
|
|
||||||
|
|
||||||
const BPM = 116
|
|
||||||
const BARS = 4
|
|
||||||
|
|
||||||
var playing = false
|
|
||||||
const COMPENSATE_FRAMES = 2
|
|
||||||
const COMPENSATE_HZ = 60.0
|
|
||||||
|
|
||||||
const SYNC_SOURCE_SYSTEM_CLOCK = 0
|
|
||||||
const SYNC_SOURCE_SOUND_CLOCK = 1
|
|
||||||
|
|
||||||
var sync_source = SYNC_SOURCE_SYSTEM_CLOCK
|
|
||||||
|
|
||||||
# Used by system clock.
|
|
||||||
var time_begin
|
|
||||||
var time_delay
|
|
||||||
|
|
||||||
|
|
||||||
func strsec(secs):
|
|
||||||
var s = str(secs)
|
|
||||||
if (secs < 10):
|
|
||||||
s = "0" + s
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta):
|
|
||||||
if (!playing or !$Player.playing):
|
|
||||||
return
|
|
||||||
|
|
||||||
var time = 0.0
|
|
||||||
if (sync_source == SYNC_SOURCE_SYSTEM_CLOCK):
|
|
||||||
# Obtain from ticks.
|
|
||||||
time = (OS.get_ticks_usec() - time_begin) / 1000000.0
|
|
||||||
# Compensate.
|
|
||||||
time -= time_delay
|
|
||||||
elif (sync_source == SYNC_SOURCE_SOUND_CLOCK):
|
|
||||||
time = $Player.get_playback_position() + AudioServer.get_time_since_last_mix() - AudioServer.get_output_latency() + (1 / COMPENSATE_HZ) * COMPENSATE_FRAMES
|
|
||||||
|
|
||||||
var beat = int(time * BPM / 60.0)
|
|
||||||
var seconds = int(time)
|
|
||||||
var seconds_total = int($Player.stream.get_length())
|
|
||||||
$Label.text = str("BEAT: ", beat % BARS + 1, "/", BARS, " TIME: ", seconds / 60, ":", strsec(seconds % 60), " / ", seconds_total / 60, ":", strsec(seconds_total % 60))
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PlaySystem_pressed():
|
|
||||||
sync_source = SYNC_SOURCE_SYSTEM_CLOCK
|
|
||||||
time_begin = OS.get_ticks_usec()
|
|
||||||
time_delay = AudioServer.get_time_to_next_mix() + AudioServer.get_output_latency()
|
|
||||||
playing = true
|
|
||||||
$Player.play()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PlaySound_pressed():
|
|
||||||
sync_source = SYNC_SOURCE_SOUND_CLOCK
|
|
||||||
playing = true
|
|
||||||
$Player.play()
|
|
||||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="StreamTexture"
|
|
||||||
path="res://.import/play_sound_button.png-7e88216154de1a5cb6304cbd3751ed46.stex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://play_sound_button.png"
|
|
||||||
dest_files=[ "res://.import/play_sound_button.png-7e88216154de1a5cb6304cbd3751ed46.stex" ]
|
|
||||||
|
|
||||||
[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
|
|
||||||
flags/mipmaps=false
|
|
||||||
flags/anisotropic=false
|
|
||||||
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
|
|
||||||
svg/scale=1.0
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="StreamTexture"
|
|
||||||
path="res://.import/play_sound_button_hl.png-8d86f81fe37a5f2959088b0948283133.stex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://play_sound_button_hl.png"
|
|
||||||
dest_files=[ "res://.import/play_sound_button_hl.png-8d86f81fe37a5f2959088b0948283133.stex" ]
|
|
||||||
|
|
||||||
[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
|
|
||||||
flags/mipmaps=false
|
|
||||||
flags/anisotropic=false
|
|
||||||
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
|
|
||||||
svg/scale=1.0
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="StreamTexture"
|
|
||||||
path="res://.import/play_system_button.png-683c51b4d13189b67bb57e75cbb8ef56.stex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://play_system_button.png"
|
|
||||||
dest_files=[ "res://.import/play_system_button.png-683c51b4d13189b67bb57e75cbb8ef56.stex" ]
|
|
||||||
|
|
||||||
[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
|
|
||||||
flags/mipmaps=false
|
|
||||||
flags/anisotropic=false
|
|
||||||
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
|
|
||||||
svg/scale=1.0
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="StreamTexture"
|
|
||||||
path="res://.import/play_system_button_hl.png-1e926e5d1be4f71f60454646aaa44d20.stex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://play_system_button_hl.png"
|
|
||||||
dest_files=[ "res://.import/play_system_button_hl.png-1e926e5d1be4f71f60454646aaa44d20.stex" ]
|
|
||||||
|
|
||||||
[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
|
|
||||||
flags/mipmaps=false
|
|
||||||
flags/anisotropic=false
|
|
||||||
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
|
|
||||||
svg/scale=1.0
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
[gd_scene load_steps=10 format=2]
|
|
||||||
|
|
||||||
[ext_resource path="res://Control.gd" type="Script" id=1]
|
|
||||||
[ext_resource path="res://lcd.ttf" type="DynamicFontData" id=2]
|
|
||||||
[ext_resource path="res://the_comeback2.ogg" type="AudioStream" id=3]
|
|
||||||
[ext_resource path="res://play_system_button.png" type="Texture" id=4]
|
|
||||||
[ext_resource path="res://play_system_button_hl.png" type="Texture" id=5]
|
|
||||||
[ext_resource path="res://play_sound_button.png" type="Texture" id=6]
|
|
||||||
[ext_resource path="res://play_sound_button_hl.png" type="Texture" id=7]
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=1]
|
|
||||||
bg_color = Color( 0, 0, 0, 1 )
|
|
||||||
|
|
||||||
[sub_resource type="DynamicFont" id=2]
|
|
||||||
size = 40
|
|
||||||
outline_size = 2
|
|
||||||
outline_color = Color( 0.588235, 0.886275, 0.435294, 0.239216 )
|
|
||||||
font_data = ExtResource( 2 )
|
|
||||||
|
|
||||||
[node name="Control" type="Panel"]
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
custom_styles/panel = SubResource( 1 )
|
|
||||||
script = ExtResource( 1 )
|
|
||||||
__meta__ = {
|
|
||||||
"_edit_use_anchors_": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="."]
|
|
||||||
margin_left = 106.895
|
|
||||||
margin_top = 427.158
|
|
||||||
margin_right = 914.895
|
|
||||||
margin_bottom = 488.158
|
|
||||||
custom_fonts/font = SubResource( 2 )
|
|
||||||
custom_colors/font_color = Color( 0.552941, 0.984314, 0.501961, 1 )
|
|
||||||
align = 1
|
|
||||||
|
|
||||||
[node name="Player" type="AudioStreamPlayer" parent="."]
|
|
||||||
stream = ExtResource( 3 )
|
|
||||||
|
|
||||||
[node name="PlaySystem" type="TextureButton" parent="."]
|
|
||||||
margin_left = 214.737
|
|
||||||
margin_top = 187.368
|
|
||||||
margin_right = 342.737
|
|
||||||
margin_bottom = 315.368
|
|
||||||
texture_normal = ExtResource( 4 )
|
|
||||||
texture_pressed = ExtResource( 4 )
|
|
||||||
texture_hover = ExtResource( 5 )
|
|
||||||
|
|
||||||
[node name="PlaySound" type="TextureButton" parent="."]
|
|
||||||
margin_left = 622.105
|
|
||||||
margin_top = 183.158
|
|
||||||
margin_right = 750.105
|
|
||||||
margin_bottom = 311.158
|
|
||||||
texture_normal = ExtResource( 6 )
|
|
||||||
texture_pressed = ExtResource( 6 )
|
|
||||||
texture_hover = ExtResource( 7 )
|
|
||||||
[connection signal="pressed" from="PlaySystem" to="." method="_on_PlaySystem_pressed"]
|
|
||||||
[connection signal="pressed" from="PlaySound" to="." method="_on_PlaySound_pressed"]
|
|
||||||
@@ -1,19 +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="BPM Sync Demo"
|
|
||||||
run/main_scene="res://player.tscn"
|
|
||||||
Binary file not shown.
@@ -1,15 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="ogg_vorbis"
|
|
||||||
type="AudioStreamOGGVorbis"
|
|
||||||
path="res://.import/the_comeback2.ogg-4b85e06ff00ff611cbd6022fc43aade8.oggstr"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://the_comeback2.ogg"
|
|
||||||
dest_files=[ "res://.import/the_comeback2.ogg-4b85e06ff00ff611cbd6022fc43aade8.oggstr" ]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
loop=true
|
|
||||||
loop_offset=0
|
|
||||||
@@ -6,7 +6,7 @@ onready var itemList = get_node("ItemList")
|
|||||||
func _ready():
|
func _ready():
|
||||||
for item in AudioServer.get_device_list():
|
for item in AudioServer.get_device_list():
|
||||||
itemList.add_item(item)
|
itemList.add_item(item)
|
||||||
|
|
||||||
var device = AudioServer.get_device()
|
var device = AudioServer.get_device()
|
||||||
for i in range(itemList.get_item_count()):
|
for i in range(itemList.get_item_count()):
|
||||||
if device == itemList.get_item_text(i):
|
if device == itemList.get_item_text(i):
|
||||||
@@ -16,14 +16,14 @@ func _ready():
|
|||||||
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
var speakerMode = "Stereo"
|
var speakerMode = "Stereo"
|
||||||
|
|
||||||
if AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_31:
|
if AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_31:
|
||||||
speakerMode = "Surround 3.1"
|
speakerMode = "Surround 3.1"
|
||||||
elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_51:
|
elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_51:
|
||||||
speakerMode = "Surround 5.1"
|
speakerMode = "Surround 5.1"
|
||||||
elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_71:
|
elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_71:
|
||||||
speakerMode = "Surround 7.1"
|
speakerMode = "Surround 7.1"
|
||||||
|
|
||||||
$DeviceInfo.text = "Current Device: " + AudioServer.get_device() + "\n"
|
$DeviceInfo.text = "Current Device: " + AudioServer.get_device() + "\n"
|
||||||
$DeviceInfo.text += "Speaker Mode: " + speakerMode
|
$DeviceInfo.text += "Speaker Mode: " + speakerMode
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ var playback: AudioStreamPlayback = null # Actual playback stream, assigned in _
|
|||||||
|
|
||||||
func _fill_buffer():
|
func _fill_buffer():
|
||||||
var increment = pulse_hz / sample_hz
|
var increment = pulse_hz / sample_hz
|
||||||
|
|
||||||
var to_fill = playback.get_frames_available()
|
var to_fill = playback.get_frames_available()
|
||||||
while (to_fill > 0):
|
while (to_fill > 0):
|
||||||
playback.push_frame(Vector2.ONE * sin(phase * TAU)) # Audio frames are stereo.
|
playback.push_frame(Vector2.ONE * sin(phase * TAU)) # Audio frames are stereo.
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func _draw():
|
|||||||
#warning-ignore:integer_division
|
#warning-ignore:integer_division
|
||||||
var w = WIDTH / VU_COUNT
|
var w = WIDTH / VU_COUNT
|
||||||
var prev_hz = 0
|
var prev_hz = 0
|
||||||
for i in range(1, VU_COUNT+1):
|
for i in range(1, VU_COUNT+1):
|
||||||
var hz = i * FREQ_MAX / VU_COUNT;
|
var hz = i * FREQ_MAX / VU_COUNT;
|
||||||
var magnitude: float = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length()
|
var magnitude: float = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length()
|
||||||
var energy = clamp((MIN_DB + linear2db(magnitude)) / MIN_DB, 0, 1)
|
var energy = clamp((MIN_DB + linear2db(magnitude)) / MIN_DB, 0, 1)
|
||||||
|
|||||||
55
file_format.sh
Normal file
55
file_format.sh
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This script ensures proper POSIX text file formatting and a few other things.
|
||||||
|
|
||||||
|
set -uo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
# Loops through all text files tracked by Git.
|
||||||
|
git grep -zIl '' |
|
||||||
|
while IFS= read -rd '' f; do
|
||||||
|
# Exclude some types of files.
|
||||||
|
if [[ "$f" == *"csproj" ]]; then
|
||||||
|
continue
|
||||||
|
elif [[ "$f" == *"hdr" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# Ensure that files are UTF-8 formatted.
|
||||||
|
recode UTF-8 "$f" 2> /dev/null
|
||||||
|
# Ensure that files have LF line endings and do not contain a BOM.
|
||||||
|
dos2unix "$f" 2> /dev/null
|
||||||
|
# Remove trailing space characters and ensures that files end
|
||||||
|
# with newline characters. -l option handles newlines conveniently.
|
||||||
|
perl -i -ple 's/\s*$//g' "$f"
|
||||||
|
# Remove the character sequence "== true" if it has a leading space.
|
||||||
|
perl -i -pe 's/\x20== true//g' "$f"
|
||||||
|
# We don't want to change lines around braces in godot/tscn files.
|
||||||
|
if [[ "$f" == *"godot" ]]; then
|
||||||
|
continue
|
||||||
|
elif [[ "$f" == *"tscn" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# Disallow empty lines after the opening brace.
|
||||||
|
sed -z -i 's/\x7B\x0A\x0A/\x7B\x0A/g' "$f"
|
||||||
|
# Disallow some empty lines before the closing brace.
|
||||||
|
sed -z -i 's/\x0A\x0A\x7D/\x0A\x7D/g' "$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
git diff > patch.patch
|
||||||
|
FILESIZE="$(stat -c%s patch.patch)"
|
||||||
|
MAXSIZE=5
|
||||||
|
|
||||||
|
# If no patch has been generated all is OK, clean up, and exit.
|
||||||
|
if (( FILESIZE < MAXSIZE )); then
|
||||||
|
printf "Files in this commit comply with the formatting rules.\n"
|
||||||
|
rm -f patch.patch
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# A patch has been created, notify the user, clean up, and exit.
|
||||||
|
printf "\n*** The following differences were found between the code "
|
||||||
|
printf "and the formatting rules:\n\n"
|
||||||
|
cat patch.patch
|
||||||
|
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||||
|
rm -f patch.patch
|
||||||
|
exit 1
|
||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -152,4 +152,4 @@ TERMINATION
|
|||||||
This license becomes null and void if any of the above conditions are not met.
|
This license becomes null and void if any of the above conditions are not met.
|
||||||
|
|
||||||
DISCLAIMER
|
DISCLAIMER
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ Copyright (C) 2008 The Android Open Source Project
|
|||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
,en,es,ja
|
,en,es,ja
|
||||||
KEY_HELLO,Hello!,Hola!,こんにちは
|
KEY_HELLO,Hello!,Hola!,こんにちは
|
||||||
KEY_PUSH,Push Me!,Aprétame!,押す
|
KEY_PUSH,Push Me!,Aprétame!,押す
|
||||||
|
|||||||
|
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ func _thread_load(path):
|
|||||||
var total = ril.get_stage_count()
|
var total = ril.get_stage_count()
|
||||||
# Call deferred to configure max load steps.
|
# Call deferred to configure max load steps.
|
||||||
progress.call_deferred("set_max", total)
|
progress.call_deferred("set_max", total)
|
||||||
|
|
||||||
var res = null
|
var res = null
|
||||||
|
|
||||||
while true: #iterate until we have a resource
|
while true: #iterate until we have a resource
|
||||||
# Update progress bar, use call deferred, which routes to main thread.
|
# Update progress bar, use call deferred, which routes to main thread.
|
||||||
progress.call_deferred("set_value", ril.get_stage())
|
progress.call_deferred("set_value", ril.get_stage())
|
||||||
@@ -31,20 +31,20 @@ func _thread_load(path):
|
|||||||
# Not OK, there was an error.
|
# Not OK, there was an error.
|
||||||
print("There was an error loading")
|
print("There was an error loading")
|
||||||
break
|
break
|
||||||
|
|
||||||
# Send whathever we did (or did not) get.
|
# Send whathever we did (or did not) get.
|
||||||
call_deferred("_thread_done", res)
|
call_deferred("_thread_done", res)
|
||||||
|
|
||||||
|
|
||||||
func _thread_done(resource):
|
func _thread_done(resource):
|
||||||
assert(resource)
|
assert(resource)
|
||||||
|
|
||||||
# Always wait for threads to finish, this is required on Windows.
|
# Always wait for threads to finish, this is required on Windows.
|
||||||
thread.wait_to_finish()
|
thread.wait_to_finish()
|
||||||
|
|
||||||
# Hide the progress bar.
|
# Hide the progress bar.
|
||||||
progress.hide()
|
progress.hide()
|
||||||
|
|
||||||
# Instantiate new scene.
|
# Instantiate new scene.
|
||||||
var new_scene = resource.instance()
|
var new_scene = resource.instance()
|
||||||
# Free current scene.
|
# Free current scene.
|
||||||
@@ -54,7 +54,7 @@ func _thread_done(resource):
|
|||||||
get_tree().root.add_child(new_scene)
|
get_tree().root.add_child(new_scene)
|
||||||
# Set as current scene.
|
# Set as current scene.
|
||||||
get_tree().current_scene = new_scene
|
get_tree().current_scene = new_scene
|
||||||
|
|
||||||
progress.visible = false
|
progress.visible = false
|
||||||
|
|
||||||
func load_scene(path):
|
func load_scene(path):
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user