258 lines
8.6 KiB
C#
258 lines
8.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Godot;
|
|
|
|
/// <summary>
|
|
/// 办公格子/图块对象
|
|
/// </summary>
|
|
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<Vector2I, Vector2I> {
|
|
[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<Vector2I, Vector2I> {
|
|
[new Vector2I(0, -1)] = new(13, 32),
|
|
[new Vector2I(1, -1)] = new(10, 7),
|
|
[new Vector2I(2, -1)] = new(15, 32)
|
|
}),
|
|
// 一台台式机
|
|
new(new Dictionary<Vector2I, Vector2I> {
|
|
[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<Vector2I> 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;
|
|
|
|
/// <summary>
|
|
/// 是否可拖拽
|
|
/// </summary>
|
|
public bool Draggable {
|
|
get => _draggable;
|
|
set {
|
|
if (value == _draggable) return;
|
|
_draggable = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 唯一标识符
|
|
/// </summary>
|
|
public Guid Id { get; } = Guid.NewGuid();
|
|
|
|
/// <summary>
|
|
/// 在网格中的位置
|
|
/// </summary>
|
|
public Vector2I TilePosition { get; set; } = new(5, 5);
|
|
|
|
/// <summary>
|
|
/// 是否处于碰撞状态(显示红色背景)
|
|
/// </summary>
|
|
public bool IsCollided {
|
|
get => _isCollided;
|
|
set {
|
|
if (_isCollided == value) return;
|
|
_isCollided = value;
|
|
if (value)
|
|
GetNode<Polygon2D>("RedBG").Show();
|
|
else
|
|
GetNode<Polygon2D>("RedBG").Hide();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 占用矩形区域
|
|
/// </summary>
|
|
public Rect2I TileRect => tileRect;
|
|
|
|
/// <summary>
|
|
/// 鼠标拖拽偏移
|
|
/// </summary>
|
|
public Vector2I MouseOffset => _mouseOffset;
|
|
|
|
|
|
/// <summary>
|
|
/// 特殊图块(如座位)
|
|
/// </summary>
|
|
public ITileDraggable.SpecialTile[] SpecialTiles => specialTiles;
|
|
|
|
/// <summary>
|
|
/// 获取指定位置的图块类型
|
|
/// </summary>
|
|
/// <param name="pos">相对位置</param>
|
|
/// <returns>图块类型</returns>
|
|
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.
|
|
/// <summary>
|
|
/// 节点进入场景树时调用
|
|
/// </summary>
|
|
public override void _Ready() {
|
|
RandomChangeTheme();
|
|
IsCollided = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 处理输入事件
|
|
/// </summary>
|
|
/// <param name="viewport">视口</param>
|
|
/// <param name="event">输入事件</param>
|
|
/// <param name="shapeIdx">形状索引</param>
|
|
public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx) {
|
|
if (@event.IsActionPressed("mouse_left_press")) {
|
|
if (Draggable) {
|
|
var parent = GetParent<Lab>();
|
|
parent.Pickup(this);
|
|
var desk = GetNode<TileMapLayer>("Desk");
|
|
_mouseOffset = desk.LocalToMap(GetLocalMousePosition());
|
|
GD.Print($"_mouseOffset = {_mouseOffset}");
|
|
}
|
|
}
|
|
else if (@event.IsActionReleased("mouse_left_press")) {
|
|
if (_isCollided) return;
|
|
var parent = GetParent<Lab>();
|
|
parent.PutDown(this);
|
|
}
|
|
|
|
base._InputEvent(viewport, @event, shapeIdx);
|
|
}
|
|
|
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
/// <summary>
|
|
/// 每帧处理
|
|
/// </summary>
|
|
/// <param name="delta">时间间隔</param>
|
|
public override void _Process(double delta) {
|
|
GlobalPosition = TilePosition * 48;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 随机更换主题样式
|
|
/// </summary>
|
|
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<TileMapLayer>("Desk"));
|
|
chairThemes[_chairThemeIdx].Apply(GetNode<TileMapLayer>("Chair"));
|
|
equipThemes[_equipThemeIdx].Apply(GetNode<TileMapLayer>("Equip"));
|
|
table2Themes[_table2ThemeIdx].Apply(GetNode<TileMapLayer>("Desk2"));
|
|
chair2Themes[_chair2ThemeIdx].Apply(GetNode<TileMapLayer>("Chair2"));
|
|
equip2Themes[_equip2ThemeIdx].Apply(GetNode<TileMapLayer>("Equip2"));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置椅子朝向(待实现)
|
|
/// </summary>
|
|
/// <param name="target">目标位置</param>
|
|
/// <param name="idx">索引</param>
|
|
public void ChairFaceTo(Vector2I target, int idx) {
|
|
if (idx == 0) {
|
|
var theme = chairThemes[_chairThemeIdx];
|
|
}
|
|
}
|
|
} |