Compare commits
7 Commits
232caf2e8b
...
39f20c8e01
Author | SHA1 | Date |
---|---|---|
Martin Felis | 39f20c8e01 | |
Martin Felis | d61ef6ba45 | |
Martin Felis | 53b1f7f414 | |
Martin Felis | 36306b9e01 | |
Martin Felis | 64e7db9800 | |
Martin Felis | 76a7abf22f | |
Martin Felis | 136de4e246 |
|
@ -98,6 +98,23 @@ public class NavigationComponent : Spatial
|
|||
{
|
||||
Debug.Assert(TileWorld != null);
|
||||
}
|
||||
|
||||
public void PlanSmoothedPath(KinematicBody body, Transform fromTransformWorld, NavigationPoint navigationPoint)
|
||||
{
|
||||
if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position)
|
||||
&& navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation))
|
||||
{
|
||||
FindPath(body, fromTransformWorld.origin, navigationPoint);
|
||||
}
|
||||
else if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position))
|
||||
{
|
||||
FindPath(body, fromTransformWorld.origin, navigationPoint.WorldPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void FindPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
||||
{
|
||||
|
@ -124,26 +141,34 @@ public class NavigationComponent : Spatial
|
|||
}
|
||||
|
||||
List<HexCell> path = TileWorld.HexGrid.FindPath(fromCell, toCell);
|
||||
|
||||
// GD.Print("Planning path and have " + TileWorld.HexGrid.Obstacles.Count + " obstacles:");
|
||||
// GD.Print(TileWorld.HexGrid.Obstacles);
|
||||
// foreach (Vector2 coord in TileWorld.HexGrid.Obstacles.Keys)
|
||||
// {
|
||||
// HexCell cell = new HexCell(coord);
|
||||
// GD.Print(" " + cell.OffsetCoords);
|
||||
// }
|
||||
|
||||
|
||||
// Generate grid navigation points
|
||||
_planningPathWorldNavigationPoints = new List<NavigationPoint>();
|
||||
foreach (int index in Enumerable.Range(0, path.Count))
|
||||
{
|
||||
// GD.Print("Step " + index + ": " + path[index].OffsetCoords);
|
||||
_planningPathWorldNavigationPoints.Add(
|
||||
new NavigationPoint(TileWorld.GetHexCenterFromOffset(path[index].OffsetCoords)));
|
||||
}
|
||||
|
||||
// Ensure the last point coincides with the target position
|
||||
if ((_planningPathWorldNavigationPoints.Last().WorldPosition - toPositionWorld).LengthSquared() <
|
||||
0.5f * 0.5f)
|
||||
{
|
||||
_planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1].WorldPosition = toPositionWorld;
|
||||
}
|
||||
|
||||
// Perform smoothing
|
||||
_planningPathSmoothedWorldNavigationPoints = SmoothPath(body, _planningPathWorldNavigationPoints);
|
||||
}
|
||||
|
||||
public void FindPath(KinematicBody body, Vector3 fromPositionWorld, NavigationPoint navigationPoint)
|
||||
{
|
||||
FindPath(body, fromPositionWorld, navigationPoint.WorldPosition);
|
||||
|
||||
_planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1] = navigationPoint;
|
||||
_planningPathSmoothedWorldNavigationPoints[_planningPathSmoothedWorldNavigationPoints.Count - 1] = navigationPoint;
|
||||
}
|
||||
|
||||
public void PlanGridPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
||||
{
|
||||
Vector2 fromPositionOffset = TileWorld.WorldToOffsetCoords(fromPositionWorld);
|
||||
|
|
|
@ -11,11 +11,11 @@ public class Player : Entity, IInteractionInterface
|
|||
{
|
||||
// public members
|
||||
[Export] public NodePath TileWorldNode;
|
||||
|
||||
|
||||
public int GoldCount = 0;
|
||||
|
||||
public TaskQueueComponent TaskQueueComponent;
|
||||
|
||||
|
||||
public NavigationComponent Navigation
|
||||
{
|
||||
get { return _navigationComponent; }
|
||||
|
@ -23,7 +23,7 @@ public class Player : Entity, IInteractionInterface
|
|||
|
||||
[Signal]
|
||||
delegate void GoldCountChanged(int goldCount);
|
||||
|
||||
|
||||
// private members
|
||||
private WorldInfoComponent _worldInfo;
|
||||
private GroundMotionComponent _groundMotion;
|
||||
|
@ -36,6 +36,7 @@ public class Player : Entity, IInteractionInterface
|
|||
private AnimationTree _animationTree;
|
||||
private DebugGeometry _debugGeometry;
|
||||
private InteractionComponent _interactionComponent;
|
||||
|
||||
public InteractionComponent InteractionComponent
|
||||
{
|
||||
get => _interactionComponent;
|
||||
|
@ -50,7 +51,7 @@ public class Player : Entity, IInteractionInterface
|
|||
_navigationComponent = (NavigationComponent)FindNode("Navigation", false);
|
||||
_navigationComponent.TileWorld = GetNode<TileWorld>(TileWorldNode);
|
||||
TaskQueueComponent = new TaskQueueComponent();
|
||||
|
||||
|
||||
_itemAttractorArea = (Area)FindNode("ItemAttractorArea", false);
|
||||
if (_itemAttractorArea == null)
|
||||
{
|
||||
|
@ -61,7 +62,7 @@ public class Player : Entity, IInteractionInterface
|
|||
_itemAttractorArea.Connect("body_entered", this, nameof(OnItemAttractorBodyEntered));
|
||||
_itemAttractorArea.Connect("body_exited", this, nameof(OnItemAttractorBodyExited));
|
||||
}
|
||||
|
||||
|
||||
_itemPickupArea = (Area)FindNode("ItemPickupArea", false);
|
||||
if (_itemPickupArea == null)
|
||||
{
|
||||
|
@ -76,9 +77,10 @@ public class Player : Entity, IInteractionInterface
|
|||
Debug.Assert(_playerAnimationPlayer != null);
|
||||
_animationTree = GetNode<AnimationTree>("Geometry/AnimationTree");
|
||||
Debug.Assert(_animationTree != null);
|
||||
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||
AnimationNodeStateMachinePlayback stateMachine =
|
||||
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||
stateMachine.Start("Idle");
|
||||
|
||||
|
||||
_toolAttachement = (BoneAttachment)FindNode("ToolAttachement");
|
||||
if (_toolAttachement == null)
|
||||
{
|
||||
|
@ -97,7 +99,7 @@ public class Player : Entity, IInteractionInterface
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0)
|
||||
{
|
||||
TaskQueueComponent.Process(this, delta);
|
||||
|
@ -109,13 +111,15 @@ public class Player : Entity, IInteractionInterface
|
|||
if (navigationTask != null && navigationTask.PlanningComplete == false)
|
||||
{
|
||||
// _navigationComponent.PlanGridPath(this, GlobalTransform, navigationTask.NavigationPoint);
|
||||
_navigationComponent.FindPath(this, GlobalTranslation, navigationTask.NavigationPoint.WorldPosition);
|
||||
_navigationComponent.PlanSmoothedPath(this, GlobalTransform, navigationTask.NavigationPoint);
|
||||
|
||||
_navigationComponent.ActivatePlannedPath();
|
||||
navigationTask.PlanningComplete = true;
|
||||
}
|
||||
|
||||
|
||||
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
||||
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld, _navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld);
|
||||
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld,
|
||||
_navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,16 +131,16 @@ public class Player : Entity, IInteractionInterface
|
|||
{
|
||||
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
||||
}
|
||||
|
||||
|
||||
foreach (Node node in _attractedItemList)
|
||||
{
|
||||
if (node is GoldBar)
|
||||
{
|
||||
GoldBar bar = (GoldBar)node;
|
||||
GoldBar bar = (GoldBar)node;
|
||||
bar.SetTarget(GlobalTransform.origin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UpdateDebugGeometry();
|
||||
}
|
||||
|
||||
|
@ -146,16 +150,15 @@ public class Player : Entity, IInteractionInterface
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
_debugGeometry.Clear();
|
||||
_debugGeometry.GlobalTransform = Transform.Identity;
|
||||
|
||||
|
||||
if (_navigationComponent != null)
|
||||
{
|
||||
_navigationComponent.DebugDraw(this, _debugGeometry);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void OnItemAttractorBodyEntered(Node node)
|
||||
|
@ -163,16 +166,17 @@ public class Player : Entity, IInteractionInterface
|
|||
GD.Print("Item entered " + node);
|
||||
_attractedItemList.Add(node);
|
||||
}
|
||||
|
||||
|
||||
public void OnItemAttractorBodyExited(Node node)
|
||||
{
|
||||
GD.Print("Item exited " + node);
|
||||
|
||||
if (node is GoldBar)
|
||||
|
||||
if (node is GoldBar)
|
||||
{
|
||||
GoldBar bar = (GoldBar)node;
|
||||
bar.UnsetTarget();
|
||||
}
|
||||
|
||||
_attractedItemList.Remove(node);
|
||||
}
|
||||
|
||||
|
@ -190,7 +194,7 @@ public class Player : Entity, IInteractionInterface
|
|||
GoldCount++;
|
||||
EmitSignal("GoldCountChanged", GoldCount);
|
||||
}
|
||||
|
||||
|
||||
body.QueueFree();
|
||||
}
|
||||
|
||||
|
@ -200,7 +204,8 @@ public class Player : Entity, IInteractionInterface
|
|||
if (toolName == "Axe")
|
||||
{
|
||||
_toolAttachement.Visible = true;
|
||||
} else if (toolName == "")
|
||||
}
|
||||
else if (toolName == "")
|
||||
{
|
||||
_toolAttachement.Visible = false;
|
||||
}
|
||||
|
@ -208,14 +213,16 @@ public class Player : Entity, IInteractionInterface
|
|||
|
||||
public void OnInteractionStart()
|
||||
{
|
||||
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||
AnimationNodeStateMachinePlayback stateMachine =
|
||||
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||
Debug.Assert(stateMachine != null);
|
||||
|
||||
|
||||
if (_interactionComponent.TargetEntity is Chest)
|
||||
{
|
||||
GD.Print("Player Opening Box");
|
||||
stateMachine.Travel("Interaction");
|
||||
} else if (_interactionComponent.TargetEntity is Tree)
|
||||
}
|
||||
else if (_interactionComponent.TargetEntity is Tree)
|
||||
{
|
||||
GD.Print("Player Chopping Tree");
|
||||
stateMachine.Travel("Hit");
|
||||
|
@ -223,9 +230,10 @@ public class Player : Entity, IInteractionInterface
|
|||
}
|
||||
|
||||
public void OnInteractionEnd()
|
||||
{
|
||||
{
|
||||
GD.Print("Player Stopping Interaction");
|
||||
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||
AnimationNodeStateMachinePlayback stateMachine =
|
||||
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||
Debug.Assert(stateMachine != null);
|
||||
stateMachine.Travel("Idle");
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
[preset.0]
|
||||
|
||||
name="JeremiasPirateGame"
|
||||
name="PirateGame3D"
|
||||
platform="Android"
|
||||
runnable=true
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="export/android/JeremiasPirateGame.apk"
|
||||
export_path="export/PirateGame3D.apk"
|
||||
script_export_mode=1
|
||||
script_encryption_key=""
|
||||
|
||||
|
@ -23,12 +23,12 @@ architectures/armeabi-v7a=true
|
|||
architectures/arm64-v8a=true
|
||||
architectures/x86=false
|
||||
architectures/x86_64=false
|
||||
keystore/debug=""
|
||||
keystore/debug_user=""
|
||||
keystore/debug_password=""
|
||||
keystore/release="/home/martin/love-android.keystore"
|
||||
keystore/release_user="love-android"
|
||||
keystore/release_password="Ae$phoi2la"
|
||||
keystore/debug="/home/martin/projects/GodotComponentTest/android/keystore/debug.keystore"
|
||||
keystore/debug_user="androiddebugkey"
|
||||
keystore/debug_password="android"
|
||||
keystore/release="/home/martin/projects/GodotComponentTest/android/keystore/debug.keystore"
|
||||
keystore/release_user="androiddebugkey"
|
||||
keystore/release_password="android"
|
||||
one_click_deploy/clear_previous_install=true
|
||||
version/code=1
|
||||
version/name="1.0"
|
||||
|
@ -206,7 +206,7 @@ permissions/write_user_dictionary=false
|
|||
|
||||
[preset.1]
|
||||
|
||||
name="JeremiasPirateGame"
|
||||
name="PirateGame3D"
|
||||
platform="HTML5"
|
||||
runnable=true
|
||||
custom_features=""
|
||||
|
|
|
@ -9,17 +9,17 @@
|
|||
config_version=4
|
||||
|
||||
_global_script_classes=[ {
|
||||
"base": "Reference",
|
||||
"base": "Node",
|
||||
"class": "ClickableComponent",
|
||||
"language": "GDScript",
|
||||
"path": "res://components/ClickableComponent.gd"
|
||||
}, {
|
||||
"base": "Reference",
|
||||
"base": "KinematicBody2D",
|
||||
"class": "CollisionLine",
|
||||
"language": "GDScript",
|
||||
"path": "res://utils/CollisionLine.gd"
|
||||
}, {
|
||||
"base": "Reference",
|
||||
"base": "Node",
|
||||
"class": "ColorComponent",
|
||||
"language": "GDScript",
|
||||
"path": "res://components/ColorComponent.gd"
|
||||
|
@ -54,7 +54,7 @@ _global_script_classes=[ {
|
|||
"language": "GDScript",
|
||||
"path": "res://utils/SpringDamper.gd"
|
||||
}, {
|
||||
"base": "Reference",
|
||||
"base": "Sprite",
|
||||
"class": "TintedSpriteComponent",
|
||||
"language": "GDScript",
|
||||
"path": "res://components/TintedSpriteComponent.gd"
|
||||
|
|
|
@ -114,7 +114,8 @@ public class Game : Spatial
|
|||
_streamContainer.Connect("TileHovered", this, nameof(OnTileHovered));
|
||||
_tileWorld.Connect("WorldGenerated", this, nameof(OnWorldGenerated));
|
||||
_generateWorldButton.Connect("pressed", this, nameof(OnGenerateButton));
|
||||
_player.TaskQueueComponent.Connect("StartInteraction", _interactionSystem, nameof(_interactionSystem.OnStartInteraction));
|
||||
_player.TaskQueueComponent.Connect("StartInteraction", _interactionSystem,
|
||||
nameof(_interactionSystem.OnStartInteraction));
|
||||
_player.Connect("GoldCountChanged", this, nameof(OnGoldCountChanged));
|
||||
|
||||
// register entity events
|
||||
|
@ -259,7 +260,7 @@ public class Game : Spatial
|
|||
{
|
||||
_player.InteractionComponent.EmitSignal("InteractionEnd");
|
||||
}
|
||||
|
||||
|
||||
_player.TaskQueueComponent.Reset();
|
||||
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
|
||||
new NavigationComponent.NavigationPoint(tile.GlobalTranslation)));
|
||||
|
@ -273,7 +274,7 @@ public class Game : Spatial
|
|||
_mouseWorldLabel.Text = highlightTransform.origin.ToString();
|
||||
_mouseTileOffsetLabel.Text = tile.OffsetCoords.ToString();
|
||||
_mouseTileCubeLabel.Text = tile.Cell.CubeCoords.ToString();
|
||||
|
||||
|
||||
_player.Navigation.FindPath(_player, _player.GlobalTranslation, tile.GlobalTranslation);
|
||||
}
|
||||
|
||||
|
@ -303,7 +304,7 @@ public class Game : Spatial
|
|||
playerStartTransform.basis.Quat());
|
||||
|
||||
_goldCountLabel.Text = "0";
|
||||
|
||||
|
||||
foreach (Spatial entity in GetNode("Entities").GetChildren())
|
||||
{
|
||||
Transform entityTransform = entity.Transform;
|
||||
|
@ -320,14 +321,14 @@ public class Game : Spatial
|
|||
GD.Print("Using new map. Size: " + (int)_tileWorld.ColormapImage.GetSize().x);
|
||||
|
||||
_goldCountLabel.Text = "0";
|
||||
|
||||
|
||||
UpdateWorldTextures();
|
||||
|
||||
_streamContainer.OnWorldGenerated();
|
||||
|
||||
// Reset player transform to offset 0,0 and at current height
|
||||
ResetGameState();
|
||||
|
||||
|
||||
// Connect all signals of the generated world
|
||||
foreach (Node node in _tileWorld.Entities.GetChildren())
|
||||
{
|
||||
|
@ -341,7 +342,7 @@ public class Game : Spatial
|
|||
private void UpdateWorldTextures()
|
||||
{
|
||||
GD.Print("Updating World textures");
|
||||
|
||||
|
||||
ImageTexture newWorldTexture = new ImageTexture();
|
||||
newWorldTexture.CreateFromImage(_tileWorld.ColormapImage,
|
||||
(uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
||||
|
|
|
@ -70,7 +70,6 @@ align = 2
|
|||
anims/FlashLabel = SubResource( 25 )
|
||||
|
||||
[node name="DebugContainer" type="PanelContainer" parent="."]
|
||||
visible = false
|
||||
self_modulate = Color( 1, 1, 1, 0.443137 )
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
|
|
|
@ -25,10 +25,6 @@ public class HexTile3D : Spatial
|
|||
delegate void TileHovered(HexTile3D tile3d);
|
||||
|
||||
// other member variables
|
||||
private SpatialMaterial _undefinedMaterial;
|
||||
private SpatialMaterial _sandMaterial;
|
||||
private SpatialMaterial _grassMaterial;
|
||||
private SpatialMaterial _deepGrassMaterial;
|
||||
private SpatialMaterial _previousMaterial;
|
||||
|
||||
private HexGrid _hexGrid;
|
||||
|
@ -52,36 +48,7 @@ public class HexTile3D : Spatial
|
|||
}
|
||||
}
|
||||
|
||||
private TileType _type;
|
||||
|
||||
public TileType Type
|
||||
{
|
||||
get { return _type; }
|
||||
|
||||
set
|
||||
{
|
||||
_type = value;
|
||||
|
||||
// switch (_type)
|
||||
// {
|
||||
// case TileType.Undefined:
|
||||
// _mesh.SetSurfaceMaterial(0, _undefinedMaterial);
|
||||
// break;
|
||||
// case TileType.Sand:
|
||||
// _mesh.SetSurfaceMaterial(0, _sandMaterial);
|
||||
// break;
|
||||
// case TileType.Grass:
|
||||
// _mesh.SetSurfaceMaterial(0, _grassMaterial);
|
||||
// break;
|
||||
// case TileType.DeepGrass:
|
||||
// _mesh.SetSurfaceMaterial(0, _deepGrassMaterial);
|
||||
// break;
|
||||
// default:
|
||||
// GD.Print("Invalid tile type: " + value.ToString());
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
public TileType Type { get; set; }
|
||||
|
||||
HexTile3D()
|
||||
{
|
||||
|
@ -98,11 +65,6 @@ public class HexTile3D : Spatial
|
|||
_staticBody.Connect("mouse_entered", this, nameof(OnAreaMouseEntered));
|
||||
_staticBody.Connect("mouse_exited", this, nameof(OnAreaMouseExited));
|
||||
|
||||
_undefinedMaterial = GD.Load<SpatialMaterial>("res://materials/UndefinedTile.tres");
|
||||
_sandMaterial = GD.Load<SpatialMaterial>("res://materials/SandTile.tres");
|
||||
_grassMaterial = GD.Load<SpatialMaterial>("res://materials/GrassTile.tres");
|
||||
_deepGrassMaterial = GD.Load<SpatialMaterial>("res://materials/DeepGrassTile.tres");
|
||||
|
||||
Mesh = GetNode<MeshInstance>("Mesh");
|
||||
Debug.Assert(Mesh != null);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ script = ExtResource( 1 )
|
|||
|
||||
[node name="Mesh" type="MeshInstance" parent="." groups=["GameGeometry"]]
|
||||
transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -2.5, 0 )
|
||||
visible = false
|
||||
mesh = ExtResource( 3 )
|
||||
material/0 = ExtResource( 2 )
|
||||
|
||||
|
@ -36,7 +37,3 @@ shape = SubResource( 5 )
|
|||
visible = false
|
||||
mesh = SubResource( 6 )
|
||||
material/0 = SubResource( 7 )
|
||||
|
||||
[node name="MultiMeshInstance" type="MultiMeshInstance" parent="."]
|
||||
transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -5, 0 )
|
||||
visible = false
|
||||
|
|
|
@ -7,11 +7,15 @@ using GoDotLog;
|
|||
|
||||
public class StreamContainer : Spatial
|
||||
{
|
||||
// readonly variables
|
||||
private readonly Transform _deactivatedTileTransform = new Transform(Basis.Identity, Vector3.Up * 1000);
|
||||
|
||||
// scene nodes
|
||||
private MeshInstance _bounds;
|
||||
private Spatial _activeTiles;
|
||||
private Queue<HexTile3D> _unusedTiles;
|
||||
private TileWorld _tileWorld;
|
||||
public TileWorld TileWorld;
|
||||
private MultiMeshInstance _tileMultiMesh;
|
||||
|
||||
// resources
|
||||
private PackedScene _hexTileScene = GD.Load<PackedScene>("res://scenes/HexTile3D.tscn");
|
||||
|
@ -27,12 +31,12 @@ public class StreamContainer : Spatial
|
|||
delegate void TileHovered(HexTile3D tile3d);
|
||||
|
||||
// other members
|
||||
private Rect2 _worldRect;
|
||||
private Rect2 _currentOffsetCoordRect;
|
||||
private Rect2 _oldOffsetCoordRect;
|
||||
private HexGrid _hexGrid;
|
||||
|
||||
private Dictionary<Vector2, HexTile3D> _coordToTile = new Dictionary<Vector2, HexTile3D>();
|
||||
private Dictionary<Vector2, HexTile3D> _coordToTile = new();
|
||||
private Dictionary<HexTile3D, int> _tileToInstanceIndex = new();
|
||||
public List<Vector2> RemovedCoords = new List<Vector2>();
|
||||
public List<Vector2> AddedCoords = new List<Vector2>();
|
||||
|
||||
|
@ -43,7 +47,7 @@ public class StreamContainer : Spatial
|
|||
|
||||
public void SetWorld(TileWorld tileWorld)
|
||||
{
|
||||
_tileWorld = tileWorld;
|
||||
TileWorld = tileWorld;
|
||||
}
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
|
@ -52,6 +56,14 @@ public class StreamContainer : Spatial
|
|||
_unusedTiles = new Queue<HexTile3D>();
|
||||
_bounds = GetNode<MeshInstance>("Bounds");
|
||||
_activeTiles = GetNode<Spatial>("ActiveTiles");
|
||||
|
||||
_tileMultiMesh = GetNode<MultiMeshInstance>("TileMultiMesh");
|
||||
_tileMultiMesh.Multimesh.InstanceCount = (int)((Dimensions.x + 5) * (Dimensions.y + 5));
|
||||
_tileMultiMesh.Multimesh.InstanceCount = 1810;
|
||||
foreach (int i in Enumerable.Range(0, _tileMultiMesh.Multimesh.InstanceCount))
|
||||
{
|
||||
_tileMultiMesh.Multimesh.SetInstanceTransform(i, _deactivatedTileTransform);
|
||||
}
|
||||
|
||||
_hexGrid = new HexGrid();
|
||||
|
||||
|
@ -59,7 +71,7 @@ public class StreamContainer : Spatial
|
|||
boundsTransform = boundsTransform.Scaled(new Vector3(Dimensions.x, 1, Dimensions.y));
|
||||
_bounds.Transform = boundsTransform;
|
||||
|
||||
_tileWorld = GetNode<TileWorld>(World);
|
||||
TileWorld = GetNode<TileWorld>(World);
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,8 +81,7 @@ public class StreamContainer : Spatial
|
|||
|
||||
Vector2 bottomLeftCoord = centerPlane - new Vector2(Dimensions.x / 2, Dimensions.y / 2);
|
||||
Vector2 topRightCoord = centerPlane + new Vector2(Dimensions.x / 2, Dimensions.y / 2);
|
||||
|
||||
_worldRect = new Rect2(bottomLeftCoord, Dimensions);
|
||||
|
||||
// GD.Print("World rect now: " + _worldRect.ToString() + " center: " + _worldRect.GetCenter());
|
||||
|
||||
// y axis needs to be inverted as HexGrid's offset coordinates use the opposite axis direction
|
||||
|
@ -78,6 +89,10 @@ public class StreamContainer : Spatial
|
|||
HexCell topRightCell = _hexGrid.GetHexAt(new Vector2(topRightCoord.x, bottomLeftCoord.y));
|
||||
_currentOffsetCoordRect = new Rect2(bottomLeftCell.OffsetCoords,
|
||||
topRightCell.OffsetCoords - bottomLeftCell.OffsetCoords + Vector2.One);
|
||||
|
||||
// Vector2 centerOffset = _hexGrid.GetHexAt(centerPlane).OffsetCoords;
|
||||
// _currentOffsetCoordRect = new Rect2(centerOffset + new Vector2(-Dimensions.x / 2, -Dimensions.y / 2),
|
||||
// Dimensions);
|
||||
// GD.Print("Offset rect now: " + _currentOffsetCoordRect.ToString() + " center: " +
|
||||
// _currentOffsetCoordRect.GetCenter());
|
||||
|
||||
|
@ -140,10 +155,8 @@ public class StreamContainer : Spatial
|
|||
if (isInOld && !isInCurrent && _coordToTile.Keys.Contains(coord))
|
||||
{
|
||||
HexTile3D tile3D = _coordToTile[coord];
|
||||
tile3D.Type = HexTile3D.TileType.Undefined;
|
||||
_unusedTiles.Enqueue(tile3D);
|
||||
_coordToTile.Remove(coord);
|
||||
RemovedCoords.Add(coord);
|
||||
|
||||
OnTileDeactivate(tile3D, coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,11 +186,13 @@ public class StreamContainer : Spatial
|
|||
{
|
||||
HexTile3D tile3D = _unusedTiles.Dequeue();
|
||||
tile3D.OffsetCoords = coord;
|
||||
tile3D.Type = _tileWorld.GetTileTypeAtOffset(coord);
|
||||
tile3D.Type = TileWorld.GetTileTypeAtOffset(coord);
|
||||
Transform tileTransform = tile3D.Transform;
|
||||
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(coord);
|
||||
tileTransform.origin.y = TileWorld.GetHeightAtOffset(coord);
|
||||
tile3D.Transform = tileTransform;
|
||||
|
||||
OnTileActivate(tile3D);
|
||||
|
||||
_coordToTile[coord] = tile3D;
|
||||
}
|
||||
}
|
||||
|
@ -202,13 +217,17 @@ public class StreamContainer : Spatial
|
|||
}
|
||||
|
||||
Transform tileTransform = tile3D.Transform;
|
||||
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(offsetCoords);
|
||||
tileTransform.origin.y = TileWorld.GetHeightAtOffset(offsetCoords);
|
||||
tile3D.Transform = tileTransform;
|
||||
tile3D.Type = _tileWorld.GetTileTypeAtOffset(offsetCoords);
|
||||
tile3D.Type = TileWorld.GetTileTypeAtOffset(offsetCoords);
|
||||
|
||||
_tileToInstanceIndex[tile3D] = _tileToInstanceIndex.Count;
|
||||
|
||||
_coordToTile[offsetCoords] = tile3D;
|
||||
}
|
||||
|
||||
OnTileActivate(_coordToTile[offsetCoords]);
|
||||
|
||||
return _coordToTile[offsetCoords];
|
||||
}
|
||||
|
||||
|
@ -231,6 +250,26 @@ public class StreamContainer : Spatial
|
|||
}
|
||||
}
|
||||
|
||||
public void OnTileActivate(HexTile3D tile3D)
|
||||
{
|
||||
int instanceIndex = _tileToInstanceIndex[tile3D];
|
||||
|
||||
Transform instanceTransform = new Transform(tile3D.GlobalTransform.basis.Rotated(Vector3.Up, Mathf.Deg2Rad(30)), tile3D.GlobalTransform.origin + Vector3.Up * -2.5f);
|
||||
|
||||
_tileMultiMesh.Multimesh.SetInstanceTransform(instanceIndex, instanceTransform);
|
||||
}
|
||||
|
||||
public void OnTileDeactivate(HexTile3D tile3D, Vector2 coord)
|
||||
{
|
||||
int instanceIndex = _tileToInstanceIndex[tile3D];
|
||||
_tileMultiMesh.Multimesh.SetInstanceTransform(instanceIndex, _deactivatedTileTransform);
|
||||
|
||||
tile3D.Type = HexTile3D.TileType.Undefined;
|
||||
_unusedTiles.Enqueue(tile3D);
|
||||
_coordToTile.Remove(coord);
|
||||
RemovedCoords.Add(coord);
|
||||
}
|
||||
|
||||
public void OnTileClicked(HexTile3D tile)
|
||||
{
|
||||
EmitSignal("TileClicked", tile);
|
||||
|
@ -252,8 +291,10 @@ public class StreamContainer : Spatial
|
|||
}
|
||||
|
||||
Transform tileTransform = tile.GlobalTransform;
|
||||
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(tile.OffsetCoords);
|
||||
tileTransform.origin.y = TileWorld.GetHeightAtOffset(tile.OffsetCoords);
|
||||
tile.GlobalTransform = tileTransform;
|
||||
|
||||
OnTileActivate(tile);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
[gd_scene load_steps=5 format=2]
|
||||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://scenes/StreamContainer.cs" type="Script" id=1]
|
||||
[ext_resource path="res://assets/Environment/HexTileMesh.tres" type="CylinderMesh" id=2]
|
||||
|
||||
[sub_resource type="CubeMesh" id=1]
|
||||
size = Vector3( 1, 1, 1 )
|
||||
|
@ -12,6 +13,11 @@ albedo_color = Color( 1, 1, 1, 0.156863 )
|
|||
[sub_resource type="BoxShape" id=9]
|
||||
extents = Vector3( 20, 1, 20 )
|
||||
|
||||
[sub_resource type="MultiMesh" id=10]
|
||||
color_format = 2
|
||||
transform_format = 1
|
||||
mesh = ExtResource( 2 )
|
||||
|
||||
[node name="StreamContainer" type="Spatial"]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 2.98023e-08, 0, -2.98023e-08, 1, 0, 0, -4.76837e-07 )
|
||||
script = ExtResource( 1 )
|
||||
|
@ -32,3 +38,6 @@ material/0 = SubResource( 2 )
|
|||
[node name="CollisionShape" type="CollisionShape" parent="Area"]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
|
||||
shape = SubResource( 9 )
|
||||
|
||||
[node name="TileMultiMesh" type="MultiMeshInstance" parent="."]
|
||||
multimesh = SubResource( 10 )
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using Godot;
|
||||
using GodotComponentTest.utils;
|
||||
using GoDotTest;
|
||||
using Xunit;
|
||||
|
||||
namespace GodotComponentTest.tests;
|
||||
|
||||
public class StreamContainerTests : TestClass
|
||||
{
|
||||
private Node _testScene = null;
|
||||
private TileWorld _tileWorld;
|
||||
private StreamContainer _streamContainer;
|
||||
|
||||
private PackedScene _tileWorldScene = GD.Load<PackedScene>("res://scenes/TileWorld.tscn");
|
||||
private PackedScene _streamContainerScene = GD.Load<PackedScene>("res://scenes/StreamContainer.tscn");
|
||||
|
||||
public StreamContainerTests(Node testScene) : base(testScene)
|
||||
{
|
||||
_testScene = testScene;
|
||||
}
|
||||
|
||||
[Setup]
|
||||
public void Setup()
|
||||
{
|
||||
_tileWorld = (TileWorld) _tileWorldScene.Instance();
|
||||
_tileWorld.HexGrid = new HexGrid();
|
||||
_testScene.AddChild(_tileWorld);
|
||||
_streamContainer = (StreamContainer) _streamContainerScene.Instance();
|
||||
|
||||
foreach (Node node in _testScene.GetChildren())
|
||||
{
|
||||
if (node is TileWorld)
|
||||
{
|
||||
_streamContainer.World = node.GetPath();
|
||||
}
|
||||
}
|
||||
|
||||
_testScene.AddChild(_streamContainer);
|
||||
}
|
||||
|
||||
[Cleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
foreach (Node node in _testScene.GetChildren())
|
||||
{
|
||||
node.QueueFree();
|
||||
}
|
||||
|
||||
_streamContainer.QueueFree();
|
||||
_tileWorld.QueueFree();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Plane2DDistSimple()
|
||||
{
|
||||
// _streamContainer.UpdateRects(new Vector2(0, 0));
|
||||
// _streamContainer.UpdateRects(new Vector2(1, 0));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue