-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Stephen Agbete (Steph155) <bgsteph15@mail.com>
- Loading branch information
1 parent
47be86a
commit 5906046
Showing
154 changed files
with
5,293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Lines starting with '#' are comments. | ||
# Each line is a file pattern followed by one or more owners. | ||
# Owners can be @users, @org/teams or emails | ||
|
||
/misc/2.5d @aaronfranke | ||
/mono/2.5d @aaronfranke | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# 2.5D Demo Project (GDScript) | ||
|
||
This demo project is an example of how a 2.5D game could be created in Godot. | ||
|
||
Controls: WASD to move, Space to jump, R to reset, and UIOPKL to change view modes. | ||
|
||
Note: There is a Mono C# version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/mono/2.5d). | ||
|
||
## How does it work? | ||
|
||
Custom node types are added in a Godot plugin to allow 2.5D objects. Node25D serves as the base for all 2.5D objects; its first child must be a Spatial, which is used to calculate its position. It also adds YSort25D to sort Node25D nodes, and ShadowMath25D for calculating a shadow (a simple KinematicBody that tries to cast downward). | ||
|
||
It uses math inside of Node25D to calculate 2D positions from 3D ones. For getting a 3D position, this project uses KinematicBody and StaticBody (3D), but these only exist for math - the camera is 2D and all sprites are 2D. You are able to use any Spatial node for math. | ||
|
||
To display the objects, add a Sprite or any other Node2D-derived children to your Node25D objects. Some nodes are unsuitable, such as 2D physics nodes. Keep in mind that the first child must be Spatial-derived for math purposes. | ||
|
||
Several view modes are implemented, including top down, front side, 45 degree, isometric, and two oblique modes. To implement a different view angle, all you need to do is create a new set of basis vectors in Node25D, use it on all instances, and of course create textures to display that object in 2D. | ||
|
||
## Screenshots |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Currently broken due to this issue: | ||
# https://github.com/godotengine/godot/issues/21461 | ||
|
||
# Basis25D structure for performing 2.5D transform math. | ||
# Note: All code assumes that Y is UP in 3D, and DOWN in 2D. | ||
# Meaning, a top-down view has a Y axis component of (0, 0), with a Z axis component of (0, 1). | ||
# For a front side view, Y is (0, -1) and Z is (0, 0). | ||
# Remember that Godot's 2D mode has the Y axis pointing DOWN on the screen. | ||
|
||
class_name Basis25D | ||
|
||
var x : Vector2 = Vector2() | ||
var y : Vector2 = Vector2() | ||
var z : Vector2 = Vector2() | ||
|
||
static func top_down(): | ||
return init(1, 0, 0, 0, 0, 1) | ||
|
||
static func front_side(): | ||
return init(1, 0, 0, -1, 0, 0) | ||
|
||
static func forty_five(): | ||
return init(1, 0, 0, -0.70710678118, 0, 0.70710678118) | ||
|
||
static func isometric(): | ||
return init(0.86602540378, 0.5, 0, -1, -0.86602540378, 0.5) | ||
|
||
static func oblique_y(): | ||
return init(1, 0, -1, -1, 0, 1) | ||
|
||
static func oblique_z(): | ||
return init(1, 0, 0, -1, -1, 1) | ||
|
||
# Creates a Dimetric Basis25D from the angle between the Y axis and the others. | ||
# Dimetric(2.09439510239) is the same as Isometric. | ||
# Try to keep this number away from a multiple of Tau/4 (or Pi/2) radians. | ||
static func dimetric(angle): | ||
var sine = sin(angle) | ||
var cosine = cos(angle) | ||
return init(sine, -cosine, 0, -1, -sine, -cosine) | ||
|
||
static func init(xx, xy, yx, yy, zx, zy): | ||
var xv = Vector2(xx, xy) | ||
var yv = Vector2(yx, yy) | ||
var zv = Vector2(zx, zy) | ||
return Basis25D.new(xv, yv, zv) | ||
|
||
func _init(xAxis : Vector2, yAxis : Vector2, zAxis : Vector2): | ||
x = xAxis | ||
y = yAxis | ||
z = zAxis |
21 changes: 21 additions & 0 deletions
21
misc/2.5d/addons/node25d/.broken-gdscripts/Transform25D.gd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Currently broken due to this issue: | ||
# https://github.com/godotengine/godot/issues/21461 | ||
|
||
# Calculates the 2D transformation from a 3D position and a Basis25D. | ||
|
||
class_name Transform25D | ||
|
||
var spatial_position : Vector3 = Vector3() | ||
var basis# : Basis25D | ||
|
||
func flat_transform(): | ||
return Transform2D(0, flat_position()) | ||
|
||
func flat_position(): | ||
var pos = spatial_position.x * basis.x | ||
pos += spatial_position.y * basis.y | ||
pos += spatial_position.z * basis.z | ||
return pos | ||
|
||
func _init(basis25d): | ||
basis = basis25d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# This node converts a 3D position to 2D using a 2.5D transformation matrix. | ||
# The transformation of its 2D form is controlled by its 3D child. | ||
tool | ||
extends Node2D | ||
class_name Node25D, "res://addons/node25d/icons/node25d_icon.png" | ||
|
||
# 32 in this code is the number of 2D units in one 3D unit. | ||
# The Godot logo is 64x64 and I made the box extents=1 so I used 32 here. | ||
const SCALE = 32 | ||
|
||
var _spatial_node : Spatial | ||
|
||
# GDScript throws errors when Basis25D is its own structure. | ||
# There is a broken implementation in a hidden folder. | ||
# https://github.com/godotengine/godot/issues/21461 | ||
var _basisX : Vector2 | ||
var _basisY : Vector2 | ||
var _basisZ : Vector2 | ||
var spatial_position : Vector3 | ||
|
||
# These are separated in case anyone wishes to easily extend Node25D | ||
func _ready(): | ||
Node25D_ready() | ||
|
||
func _process(_delta): | ||
Node25D_process() | ||
|
||
# Call this method in _Ready, or before you run Node25DProcess. | ||
func Node25D_ready(): | ||
_spatial_node = get_child(0) | ||
_basisX = SCALE * Vector2(1, 0) | ||
_basisY = SCALE * Vector2(0, -0.70710678118) | ||
_basisZ = SCALE * Vector2(0, 0.70710678118) | ||
# Changing the values here will change the default for all Node25D instances. | ||
|
||
# Call this method in _Process, or whenever the position of this object changes. | ||
func Node25D_process(): | ||
_check_view_mode() | ||
if _spatial_node == null: | ||
return | ||
spatial_position = _spatial_node.translation | ||
|
||
var flat_pos = spatial_position.x * _basisX | ||
flat_pos += spatial_position.y * _basisY | ||
flat_pos += spatial_position.z * _basisZ | ||
|
||
global_position = flat_pos | ||
|
||
# Check if anyone presses the view mode buttons and change the basis accordingly. | ||
# This can be changed or removed in actual games where you only need one view mode. | ||
func _check_view_mode(): | ||
if Input.is_action_just_pressed("TopDownMode"): | ||
_basisX = SCALE * Vector2(1, 0) | ||
_basisY = SCALE * Vector2(0, 0) | ||
_basisZ = SCALE * Vector2(0, 1) | ||
elif Input.is_action_just_pressed("FrontSideMode"): | ||
_basisX = SCALE * Vector2(1, 0) | ||
_basisY = SCALE * Vector2(0, -1) | ||
_basisZ = SCALE * Vector2(0, 0) | ||
elif Input.is_action_just_pressed("FortyFiveMode"): | ||
_basisX = SCALE * Vector2(1, 0) | ||
_basisY = SCALE * Vector2(0, -0.70710678118) | ||
_basisZ = SCALE * Vector2(0, 0.70710678118) | ||
elif Input.is_action_just_pressed("IsometricMode"): | ||
_basisX = SCALE * Vector2(0.86602540378, 0.5) | ||
_basisY = SCALE * Vector2(0, -1) | ||
_basisZ = SCALE * Vector2(-0.86602540378, 0.5) | ||
elif Input.is_action_just_pressed("ObliqueYMode"): | ||
_basisX = SCALE * Vector2(1, 0) | ||
_basisY = SCALE * Vector2(-1, -1) | ||
_basisZ = SCALE * Vector2(0, 1) | ||
elif Input.is_action_just_pressed("ObliqueZMode"): | ||
_basisX = SCALE * Vector2(1, 0) | ||
_basisY = SCALE * Vector2(0, -1) | ||
_basisZ = SCALE * Vector2(-1, 1) | ||
|
||
func get_basis(): | ||
return [_basisX, _basisY, _basisZ] | ||
|
||
# Used by YSort25D | ||
static func y_sort(a : Node25D, b : Node25D): | ||
return a.spatial_position.y < b.spatial_position.y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Adds a simple shadow below an object. | ||
# Place this ShadowMath25D node as a child of a Shadow25D, which | ||
# is below the target object in the scene tree (not as a child). | ||
tool | ||
extends KinematicBody | ||
class_name ShadowMath25D, "res://addons/node25d/icons/shadowmath25d_icon.png" | ||
|
||
# The maximum distance below objects that shadows will appear. | ||
var shadow_length : float = 1000.0 | ||
var _shadow_root : Node25D | ||
var _target_math : Spatial | ||
|
||
func _ready(): | ||
_shadow_root = get_parent() | ||
var index = _shadow_root.get_position_in_parent() | ||
if (index > 0): # Else, Shadow is not in a valid place. | ||
_target_math = _shadow_root.get_parent().get_child(index - 1).get_child(0) | ||
|
||
func _process(_delta): | ||
if _target_math == null: | ||
if _shadow_root != null: | ||
_shadow_root.visible = false | ||
return # Shadow is not in a valid place or you're viewing the Shadow25D scene. | ||
|
||
translation = _target_math.translation | ||
var k = move_and_collide(Vector3.DOWN * shadow_length) | ||
if k == null: | ||
_shadow_root.visible = false | ||
else: | ||
_shadow_root.visible = true | ||
global_transform = transform |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Sorts all Node25D children of its parent. | ||
# This is different from the C# version of this project | ||
# because the execution order is different and otherwise | ||
# sorting is delayed by one frame. | ||
tool | ||
extends Node # Note: NOT Node2D, Node25D, or YSort | ||
class_name YSort25D, "res://addons/node25d/icons/ysort25d_icon.png" | ||
|
||
# Whether or not to automatically call sort() in _process(). | ||
export (bool) var sort_enabled : bool = true | ||
var _parent_node : Node2D # NOT Node25D | ||
|
||
func _ready(): | ||
_parent_node = get_parent() | ||
|
||
func _process(_delta): | ||
if sort_enabled: | ||
sort() | ||
|
||
# Call this method in _process, or whenever you want to sort children. | ||
func sort(): | ||
if _parent_node == null: | ||
return # _ready() hasn't been run yet | ||
var parent_children = _parent_node.get_children() | ||
if parent_children.size() > 4000: | ||
# The Z index only goes from -4096 to 4096, and we want room for objects having multiple layers. | ||
printerr("Sorting failed: Max number of YSort25D nodes is 4000. ") | ||
return | ||
|
||
# We only want to get Node25D children. | ||
# Currently, it also grabs Node2D children. | ||
var node25d_nodes = [] | ||
for n in parent_children: | ||
if (n.get_class() == "Node2D"): | ||
node25d_nodes.append(n) | ||
node25d_nodes.sort_custom(Node25D, "y_sort") | ||
|
||
var zIndex : int = -4000 | ||
for i in range(0, node25d_nodes.size()): | ||
node25d_nodes[i].z_index = zIndex | ||
zIndex += 2 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions
34
misc/2.5d/addons/node25d/icons/kinematic_body_25d.png.import
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="StreamTexture" | ||
path="res://.import/kinematic_body_25d.png-c455d5ccb8ec7543b62fff6e803eee7c.stex" | ||
metadata={ | ||
"vram_texture": false | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://addons/node25d/icons/kinematic_body_25d.png" | ||
dest_files=[ "res://.import/kinematic_body_25d.png-c455d5ccb8ec7543b62fff6e803eee7c.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 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="StreamTexture" | ||
path="res://.import/node25d.png-deca325dc1330ad07256305d79ddc3ba.stex" | ||
metadata={ | ||
"vram_texture": false | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://addons/node25d/icons/node25d.png" | ||
dest_files=[ "res://.import/node25d.png-deca325dc1330ad07256305d79ddc3ba.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 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="StreamTexture" | ||
path="res://.import/node25d_icon.png-075c4b266c832f0f269670bad017ac93.stex" | ||
metadata={ | ||
"vram_texture": false | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://addons/node25d/icons/node25d_icon.png" | ||
dest_files=[ "res://.import/node25d_icon.png-075c4b266c832f0f269670bad017ac93.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 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.