using System; using System.Collections.Generic; using System.Linq; using Godot; /// /// 办公格子/图块对象 /// public partial class Cube : StaticBody2D, ITileDraggable { // 定义各种家具的占用区域 private static readonly Rect2I tableRect = new(0, 0, 3, 2); private static readonly Rect2I table2Rect = new(0, -1, 3, 1); private static readonly Rect2I chairRect = new(1, 1, 1, 2); private static readonly Rect2I chair2Rect = new(1, -2, 1, 2); private static readonly Rect2I equipRect = new(0, 0, 3, 2); private static readonly Rect2I equip2Rect = new(0, -1, 3, 1); // 定义桌子的主题映射 private static readonly TileMapping[] tableThemes = { new(new Vector2I(1, 30), tableRect), new(new Vector2I(4, 30), tableRect), new(new Vector2I(7, 30), tableRect), new(new Vector2I(7, 28), tableRect), new(new Vector2I(10, 28), tableRect) }; // 定义第二种桌子的主题映射 private static readonly TileMapping[] table2Themes = { new(new Vector2I(1, 31), table2Rect), new(new Vector2I(4, 31), table2Rect), new(new Vector2I(7, 31), table2Rect), new(new Vector2I(7, 29), table2Rect), new(new Vector2I(10, 29), table2Rect) }; // 定义椅子的主题映射 private static readonly TileMapping[] chairThemes = { new(new Vector2I(-1, 7), chairRect), new(new Vector2I(0, 7), chairRect), new(new Vector2I(-1, 9), chairRect), new(new Vector2I(0, 9), chairRect) }; // 定义第二种椅子的主题映射 private static readonly TileMapping[] chair2Themes = { new(new Vector2I(-1, 10), chair2Rect), new(new Vector2I(0, 10), chair2Rect), new(new Vector2I(-1, 12), chair2Rect), new(new Vector2I(0, 12), chair2Rect) }; // 定义设备的主题映射 private static readonly TileMapping[] equipThemes = { // 一台笔记本电脑 new(new Vector2I(13, 26), equipRect), // 一台笔记本电脑加一台显示器 new(new Vector2I(7, 26), equipRect), // 一台台式机 new(new Dictionary { [new Vector2I(0, 0)] = new(11, 17), [new Vector2I(1, 0)] = new(8, 32), [new Vector2I(2, 0)] = new(9, 32), [new Vector2I(0, 1)] = new(11, 18), [new Vector2I(1, 1)] = new(8, 33), [new Vector2I(2, 1)] = new(9, 33) }), // 一台台式机加一台显示器 new(new Vector2I(7, 32), equipRect) }; // 定义第二种设备的主题映射 private static readonly TileMapping[] equip2Themes = { // 一台笔记本电脑 new(new Vector2I(13, 31), equip2Rect), // 一台笔记本电脑加一台显示器 new(new Dictionary { [new Vector2I(0, -1)] = new(13, 32), [new Vector2I(1, -1)] = new(10, 7), [new Vector2I(2, -1)] = new(15, 32) }), // 一台台式机 new(new Dictionary { [new Vector2I(0, -1)] = new(13, 32), [new Vector2I(1, -1)] = new(14, 32), [new Vector2I(2, -1)] = new(15, 30) }), // 一台台式机加一台显示器 new(new Vector2I(13, 33), equip2Rect) }; private static readonly Rect2I tileRect = new(-1, -2, 4, 5); private static readonly ITileDraggable.SpecialTile[] specialTiles = { new(new Vector2I(1, -1), Lab.MapNodeType.SeatDown | Lab.MapNodeType.Walkable), new(new Vector2I(1, 2), Lab.MapNodeType.SeatUp | Lab.MapNodeType.Walkable) }; private static readonly HashSet blockerTiles = new(new Vector2I[] { new(0, 0), new(1, 0), new(2, 0), new(0, 1), new(1, 1), new(2, 1) }); private int _chair2ThemeIdx; private int _chairThemeIdx; private bool _draggable; private int _equip2ThemeIdx; private int _equipThemeIdx; private bool _isCollided = true; private Vector2I _mouseOffset; private int _table2ThemeIdx; private int _tableThemeIdx; /// /// 是否可拖拽 /// public bool Draggable { get => _draggable; set { if (value == _draggable) return; _draggable = value; } } /// /// 唯一标识符 /// public Guid Id { get; } = Guid.NewGuid(); /// /// 在网格中的位置 /// public Vector2I TilePosition { get; set; } = new(5, 5); /// /// 是否处于碰撞状态(显示红色背景) /// public bool IsCollided { get => _isCollided; set { if (_isCollided == value) return; _isCollided = value; if (value) GetNode("RedBG").Show(); else GetNode("RedBG").Hide(); } } /// /// 占用矩形区域 /// public Rect2I TileRect => tileRect; /// /// 鼠标拖拽偏移 /// public Vector2I MouseOffset => _mouseOffset; /// /// 特殊图块(如座位) /// public ITileDraggable.SpecialTile[] SpecialTiles => specialTiles; /// /// 获取指定位置的图块类型 /// /// 相对位置 /// 图块类型 public Lab.MapNodeType GetTileType(Vector2I pos) { GD.Print($"query position of {pos}"); if (blockerTiles.Contains(pos)) return Lab.MapNodeType.Blocker; if (specialTiles.Any(t => t.Position == pos)) return specialTiles.First(t => t.Position == pos).NodeType; return Lab.MapNodeType.Walkable; } // Called when the node enters the scene tree for the first time. /// /// 节点进入场景树时调用 /// public override void _Ready() { RandomChangeTheme(); IsCollided = false; } /// /// 处理输入事件 /// /// 视口 /// 输入事件 /// 形状索引 public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx) { if (@event.IsActionPressed("mouse_left_press")) { if (Draggable) { var parent = GetParent(); parent.Pickup(this); var desk = GetNode("Desk"); _mouseOffset = desk.LocalToMap(GetLocalMousePosition()); GD.Print($"_mouseOffset = {_mouseOffset}"); } } else if (@event.IsActionReleased("mouse_left_press")) { if (_isCollided) return; var parent = GetParent(); parent.PutDown(this); } base._InputEvent(viewport, @event, shapeIdx); } // Called every frame. 'delta' is the elapsed time since the previous frame. /// /// 每帧处理 /// /// 时间间隔 public override void _Process(double delta) { GlobalPosition = TilePosition * 48; } /// /// 随机更换主题样式 /// public void RandomChangeTheme() { _tableThemeIdx = GD.RandRange(0, tableThemes.Length - 1); _chairThemeIdx = GD.RandRange(0, chairThemes.Length - 1); _equipThemeIdx = GD.RandRange(0, equipThemes.Length - 1); _table2ThemeIdx = GD.RandRange(0, table2Themes.Length - 1); _chair2ThemeIdx = GD.RandRange(0, chair2Themes.Length - 1); _equip2ThemeIdx = GD.RandRange(0, equip2Themes.Length - 1); tableThemes[_tableThemeIdx].Apply(GetNode("Desk")); chairThemes[_chairThemeIdx].Apply(GetNode("Chair")); equipThemes[_equipThemeIdx].Apply(GetNode("Equip")); table2Themes[_table2ThemeIdx].Apply(GetNode("Desk2")); chair2Themes[_chair2ThemeIdx].Apply(GetNode("Chair2")); equip2Themes[_equip2ThemeIdx].Apply(GetNode("Equip2")); } /// /// 设置椅子朝向(待实现) /// /// 目标位置 /// 索引 public void ChairFaceTo(Vector2I target, int idx) { if (idx == 0) { var theme = chairThemes[_chairThemeIdx]; } } }