基础准备
首先创建一个类,继承ModSystem,无特殊需求UI类也可以丢这个类里面,成为内部类。由于UI只需要在客户端就行了,所以使用特性标记,仅在客户端加载[Autoload(Side = ModSide.Client)]
| 方法 |
说明 |
| Load() |
用来载入UI |
| UpdateUI() |
用来更新UI |
| ModifyInterfaceLayers((List layers) |
用来确定UI所在层级,并注册UI层级 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[Autoload(Side = ModSide.Client)]
class UISystem : ModSystem
{
public override void Load()
{
base.Load();
}
public override void UpdateUI(GameTime gameTime)
{
base.UpdateUI(gameTime);
}
public override void ModifyInterfaceLayers(List<GameInterfaceLayer> layers)
{
base.ModifyInterfaceLayers(layers);
}
}
|
创建UI
我们创建一个ModSystem的内部类,并继承UIState / UIElement,只需要重写OnInitialize()方法即可。在这个方法里面我们进行界面的创建 布局等。
1
2
3
4
5
6
7
|
public class BzaUI : UIState
{
public override void OnInitialize()
{
base.OnInitialize();
}
}
|
原版有很多的控件供给我们使用,在Terraria.GameContent.UI.Elements名称空间下。我们使用UIImageButton创建一个自定义图像的按钮,并加入到画布中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class BzaUI : UIState
{
private UIImageButton MyButton;
public override void OnInitialize()
{
//导入图片资源
Asset<Texture2D> tex2d = Request<Texture2D>("ModName/xxxxx/imageName");
//使用图片资源创建控件
MyButton = new UIImageButton(tex2d);
//将控件添加到父组件 如果想要自定义画布可以使用UIPanel类
Append(MyButton);
base.OnInitialize();
}
}
|
使用UI
在UI类创建完成后,就需要在ModSystem进行加载了,先创建一个我们自己的UI实例,然后创建UserInterface用来承载我们的UI。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[Autoload(Side = ModSide.Client)]
class UISystem : ModSystem
{
public BzaUI bzaUI;//自己的UI
public UserInterface userInterface;//用户接口
public override void Load()
{
bzaUI = new BzaUI();
bzaUI.Activate();//激活
userInterface = new UserInterface();
userInterface.SetState(bzaUI);//将接口状态设置为我们的UI
base.Load();
}
public override void UpdateUI(GameTime gameTime)
{
//每帧都更新UI
userInterface?.Update(gameTime);
base.UpdateUI(gameTime);
}
}
|
对于ModifyInterfaceLayers单独拉出来说,layers包含原版以及模组的全部UI层级。每个层级都有自己的名字。并且按照先后顺序进行绘制。具体可以使用ModderTool这个模组的一个用户接口层选项进行查看,我们就不定义他在谁之上谁之下了。直接往0处插入我们自己的图层。
使用List(集合)中的Insert()方法可以往指定索引处插入数据。这边我指定0,然后创建一个LegacyGameInterfaceLayer就是图层。
1
2
3
4
5
6
7
8
9
10
11
12
|
public override void ModifyInterfaceLayers(List<GameInterfaceLayer> layers)
{
layers.Insert
(
0,
new LegacyGameInterfaceLayer(
"GensokyoWPNACC:Bza", //我们层的名字
() =>{ bzaUI.Draw(Main.spriteBatch); return true;}, //一个func委托,里面是UI绘制的逻辑,返回UI是否可见
InterfaceScaleType.UI) //我们图层的类型
);
base.ModifyInterfaceLayers(layers);
}
|
现在进入游戏应该就能在不起眼的小角落看到你的按钮了 当然他现在什么也干不了
添加点击事件
设置我们UI的Top和Left属性可以更改UI的位置
1
2
3
4
5
|
public override void OnInitialize()
{
Top.Pixels = Main.screenHeight - 100;
Left.Pixels = Main.screenWidth / 5;
}
|
现在我们为按钮添加点击事件(伪代码)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public override void OnInitialize()
{
Asset<Texture2D> tex2d = Request<Texture2D>("ModName/xxxxx/imageName");
MyButton = new UIImageButton(tex2d);
//添加事件
XAddIB.OnLeftClick += new MouseEvent(this.XAdd);
Append(MyButton);
}
private void XAdd(UIMouseEvent evt, UIElement listeningElement)
{
//方法逻辑
}
|
这样我们单机按钮就会触发你的方法逻辑了 使用Visual Studio查看MyButton其中小闪电的就代表事件
绘制鼠标悬停文本
直接上代码了,这个确实是没什么好讲的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
public override void ModifyInterfaceLayers(List<GameInterfaceLayer> layers)
{
layers.Insert
(
0,
new LegacyGameInterfaceLayer
(
"GensokyoWPNACC:Bza",
() =>{
var sb = Main.spriteBatch;
var font = FontAssets.MouseText.Value;
var ms = Main.MouseScreen + new Vector2(0, -20);
var color = Color.White;
var rot = 0f;
var origin = Vector2.Zero;
var scale = new Vector2(1.2f, 1.2f);
var drawText = "6666";
bzaUI.Draw(Main.spriteBatch);
//字体绘制
//isOnButton使用OnMouseOver事件控制
if (BzaUI.isOnButton)
{
ChatManager.DrawColorCodedStringWithShadow(sb, font, drawText, ms, color, rot, origin, scale);
}
return true;
},
InterfaceScaleType.UI
)
);
base.ModifyInterfaceLayers(layers);
}
|