Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5759e8dbc6 | |||
| 433fa315b2 | |||
| 89899a3799 | |||
| 77fe539809 | |||
| 5d78244ef0 | |||
| b16e8d7820 | |||
| 2686136f72 | |||
| cfa9e279e5 | |||
| ed376a4825 | |||
| a753cf4998 |
12
.vscode/launch.json
vendored
Normal file
12
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Attach (squirrel) to localhost:2222",
|
||||||
|
"type": "squirrel",
|
||||||
|
"request": "attach",
|
||||||
|
"port": 2222,
|
||||||
|
"address": "localhost"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -8,64 +8,65 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {ActiveObject} obj
|
* @param {CharacterObject} obj
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function checkCanChangeState_Character_Move(obj) {
|
function checkCanChangeState_Character_Move(obj) {
|
||||||
//获取当前状态
|
//获取当前状态
|
||||||
local CurState = obj.GetState();
|
local CurState = obj.GetState()
|
||||||
//得到摇杆的数据 X 和 Y的范围 -1.0 ~ 1.0
|
//得到摇杆的数据 X 和 Y的范围 -1.0 ~ 1.0
|
||||||
local arr = obj.GetVars("_move_data_", "float");
|
local arr = obj.GetVars("_move_data_", "float")
|
||||||
if (fabs(arr[0]) > 0.35 || fabs(arr[1]) > 0.35) {
|
if (fabs(arr[0]) > 0.35 || fabs(arr[1]) > 0.35) {
|
||||||
return true;
|
return true
|
||||||
} else return false;
|
} else return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {ActiveObject} obj
|
* @param {CharacterObject} obj
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function SetState_Character_Move(obj) {
|
function SetState_Character_Move(obj) {
|
||||||
//获取移动数据
|
//获取移动数据
|
||||||
local arr = obj.GetVars("_move_data_", "float");
|
local arr = obj.GetVars("_move_data_", "float")
|
||||||
|
|
||||||
//设置人物朝向 摇杆X轴大于0则朝右,小于0则朝左
|
//设置人物朝向 摇杆X轴大于0则朝右,小于0则朝左
|
||||||
local SetValue = arr[0] > 0 ? 0 : 1;
|
local SetValue = arr[0] > 0 ? 0 : 1
|
||||||
if (SetValue != obj.GetDirection()) {
|
if (SetValue != obj.GetDirection()) {
|
||||||
if (fabs(arr[0]) > 0.35) obj.SetDirection(SetValue);
|
if (fabs(arr[0]) > 0.35) obj.SetDirection(SetValue)
|
||||||
//设置动作
|
//设置动作
|
||||||
obj.SetAction("move");
|
obj.SetAction("move")
|
||||||
} else {
|
} else {
|
||||||
if (obj.GetState() != 1) obj.SetAction("move");
|
if (obj.GetState() != 1) obj.SetAction("move")
|
||||||
}
|
}
|
||||||
|
|
||||||
local Speed = 250;
|
local Speed = 250
|
||||||
local Dir = obj.GetDirection();
|
local Dir = obj.GetDirection();
|
||||||
local Pos = obj.GetPosition();
|
local Pos = obj.GetPosition();
|
||||||
local XOffset = null;
|
local XOffset
|
||||||
if (fabs(arr[0]) > 0.35) XOffset = arr[0] > 0 ? Speed : -Speed;
|
if (fabs(arr[0]) > 0.35) XOffset = arr[0] > 0 ? Speed : -Speed
|
||||||
else XOffset = 0;
|
else XOffset = 0
|
||||||
local YOffset = null;
|
local YOffset
|
||||||
//当摇杆Y轴大于0.35或小于-0.35时,设置Y轴偏移量
|
//当摇杆Y轴大于0.35或小于-0.35时,设置Y轴偏移量
|
||||||
if (fabs(arr[1]) > 0.35) YOffset = arr[1] > 0 ? Speed : -Speed;
|
if (fabs(arr[1]) > 0.35) YOffset = arr[1] > 0 ? Speed : -Speed
|
||||||
else YOffset = 0;
|
else YOffset = 0
|
||||||
|
|
||||||
obj.SetSpeed(XOffset, YOffset, null);
|
obj.SetSpeed(XOffset, YOffset, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {ActiveObject} obj
|
* @param {CharacterObject} obj
|
||||||
* @param {integer} DeltaTime
|
* @param {integer} DeltaTime
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function ProcState_Character_Move(obj, DeltaTime) {
|
function ProcState_Character_Move(obj, DeltaTime) {
|
||||||
//获取移动数据
|
//获取移动数据
|
||||||
local arr = obj.GetVars("_move_data_", "float");
|
local arr = obj.GetVars("_move_data_", "float")
|
||||||
if (arr[0] == 0 && arr[1] == 0) {
|
if (arr[0] == 0 && arr[1] == 0) {
|
||||||
obj.SetState(0);
|
obj.SetState(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,23 @@
|
|||||||
文件用途:角色站立状态
|
文件用途:角色站立状态
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {CharacterObject} obj
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
function checkCanChangeState_Character_Rest(obj) {
|
function checkCanChangeState_Character_Rest(obj) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {CharacterObject} obj
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
function SetState_Character_Rest(obj) {
|
function SetState_Character_Rest(obj) {
|
||||||
//设置动作
|
//设置动作
|
||||||
obj.SetAction("rest");
|
obj.SetAction("rest");
|
||||||
@@ -17,6 +29,13 @@ function SetState_Character_Rest(obj) {
|
|||||||
obj.SetSpeed(0, 0, null);
|
obj.SetSpeed(0, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {CharacterObject} obj
|
||||||
|
* @param {integer} DeltaTime
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
function ProcState_Character_Rest(obj, DeltaTime) {
|
function ProcState_Character_Rest(obj, DeltaTime) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Description placeholder
|
* Description placeholder
|
||||||
* @global
|
|
||||||
* @param {*} Object
|
* @param {*} Object
|
||||||
*/
|
*/
|
||||||
class ActiveObject extends BaseObject {
|
class ActiveObject extends BaseObject {
|
||||||
@@ -9,7 +8,7 @@ class ActiveObject extends BaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 设置三轴速度
|
||||||
* @function
|
* @function
|
||||||
* @param {integer} x
|
* @param {integer} x
|
||||||
* @param {integer} y
|
* @param {integer} y
|
||||||
@@ -25,7 +24,7 @@ class ActiveObject extends BaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 获取三轴速度
|
||||||
* @function
|
* @function
|
||||||
* @returns {any}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,16 +11,16 @@ class BaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 获取坐标
|
||||||
* @function
|
* @function
|
||||||
* @returns {any}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
function GetPosition() {
|
function GetPosition() {
|
||||||
return sq_GetPosition(C_Object);
|
return sq_GetPosition(C_Object);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
/**
|
/**
|
||||||
*
|
* 设置坐标
|
||||||
* @function
|
* @function
|
||||||
* @param {integer} x
|
* @param {integer} x
|
||||||
* @param {integer} y
|
* @param {integer} y
|
||||||
@@ -32,22 +32,22 @@ class BaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 获取储存器
|
||||||
* @function
|
* @function
|
||||||
* @param {string} Name
|
* @param {string} Name
|
||||||
* @param {any} Type
|
* @param {string} Type
|
||||||
* @returns {any}
|
* @returns {array}
|
||||||
*/
|
*/
|
||||||
function GetVars(Name, Type) {
|
function GetVars(Name, Type) {
|
||||||
return sq_GetVars(C_Object, Name, Type);
|
return sq_GetVars(C_Object, Name, Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 设置储存器
|
||||||
* @function
|
* @function
|
||||||
* @param {string} Name
|
* @param {string} Name
|
||||||
* @param {any} Type
|
* @param {any} Type
|
||||||
* @param {any} Value
|
* @param {array} Value
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function SetVars(Name, Type, Value) {
|
function SetVars(Name, Type, Value) {
|
||||||
@@ -55,7 +55,7 @@ class BaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 获取方向
|
||||||
* @function
|
* @function
|
||||||
* @returns {integer}
|
* @returns {integer}
|
||||||
*/
|
*/
|
||||||
@@ -64,7 +64,7 @@ class BaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 设置方向
|
||||||
* @function
|
* @function
|
||||||
* @param {integer} Dir
|
* @param {integer} Dir
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
|||||||
@@ -4,35 +4,35 @@
|
|||||||
*/
|
*/
|
||||||
class CharacterObject extends ActiveObject {
|
class CharacterObject extends ActiveObject {
|
||||||
constructor(Object) {
|
constructor(Object) {
|
||||||
base.constructor(Object);
|
base.constructor(Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 获取状态
|
||||||
* @function
|
* @function
|
||||||
* @returns {*}
|
* @returns {integer} 状态编号
|
||||||
*/
|
*/
|
||||||
function GetState() {
|
function GetState() {
|
||||||
return sq_GetState(C_Object);
|
return sq_GetState(C_Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 设置状态
|
||||||
* @function
|
* @function
|
||||||
* @param {integer} State
|
* @param {integer} State
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function SetState(State) {
|
function SetState(State) {
|
||||||
sq_SetState(C_Object, State);
|
sq_SetState(C_Object, State)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 设置动作
|
||||||
* @function
|
* @function
|
||||||
* @param {any} key
|
* @param {string} key
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function SetAction(key) {
|
function SetAction(key) {
|
||||||
sq_SetAction(C_Object, key);
|
sq_SetAction(C_Object, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class StateMachine {
|
|||||||
/**
|
/**
|
||||||
* 静态方法:获取唯一实例
|
* 静态方法:获取唯一实例
|
||||||
* @function
|
* @function
|
||||||
* @returns {table}
|
* @returns {StateMachine}
|
||||||
*/
|
*/
|
||||||
function GetInstance() {
|
function GetInstance() {
|
||||||
if (!getroottable().rawin("__StateMachine__")) {
|
if (!getroottable().rawin("__StateMachine__")) {
|
||||||
@@ -91,6 +91,7 @@ function StateMachine_SetState(C_Object, Job, State) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function StateMachine_ProcState(C_Object, Job, State, DeltaTime) {
|
function StateMachine_ProcState(C_Object, Job, State, DeltaTime) {
|
||||||
//获取状态信息
|
//获取状态信息
|
||||||
local StateInfo = StateMachine.GetInstance().GetStateInfo(Job, State);
|
local StateInfo = StateMachine.GetInstance().GetStateInfo(Job, State);
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
enum.nut
|
enum.nut
|
||||||
|
Tool/Math.nut
|
||||||
|
Tool/Json.nut
|
||||||
|
Tool/Common.nut
|
||||||
|
|
||||||
|
|
||||||
Game/StateMachine/StateMachine.nut
|
Game/StateMachine/StateMachine.nut
|
||||||
@@ -12,5 +15,26 @@ Game/CharacterScript/Common/Rest.nut
|
|||||||
Game/CharacterScript/Common/Move.nut
|
Game/CharacterScript/Common/Move.nut
|
||||||
|
|
||||||
|
|
||||||
|
UI/ObjectClass/BaseNode.nut
|
||||||
|
UI/ObjectClass/Actor.nut
|
||||||
|
UI/ObjectClass/WindowNode.nut
|
||||||
|
UI/ObjectClass/GameWindow.nut
|
||||||
|
UI/ObjectClass/GameWidget.nut
|
||||||
|
UI/ObjectClass/Text.nut
|
||||||
|
UI/ObjectClass/Sprite.nut
|
||||||
|
UI/ObjectClass/Canvas.nut
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UI/Windows/Widget/BaseWidget.nut
|
||||||
|
UI/Windows/Widget/TripleCav.nut
|
||||||
|
UI/Windows/Widget/NineGridCav.nut
|
||||||
|
|
||||||
|
|
||||||
|
UI/Windows/System/Cursor.nut
|
||||||
|
UI/Windows/System/NotiBox.nut
|
||||||
|
UI/Windows/HUD/Window_hud.nut
|
||||||
|
|
||||||
UI/MainUI.nut
|
UI/MainUI.nut
|
||||||
main.nut
|
main.nut
|
||||||
41
Tool/Common.nut
Normal file
41
Tool/Common.nut
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
文件名:Common.nut
|
||||||
|
路径:Tool/Common.nut
|
||||||
|
创建日期:2025-10-25 00:05
|
||||||
|
文件用途:工具类
|
||||||
|
*/
|
||||||
|
function print(Object) {
|
||||||
|
switch (typeof Object) {
|
||||||
|
case "table":
|
||||||
|
case "array": {
|
||||||
|
local str = Json.Encode(Object);
|
||||||
|
sq_OutPutTable(str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "string":
|
||||||
|
case "integer": {
|
||||||
|
output(Object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
output(Object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回颜色的十六进制数
|
||||||
|
* @function
|
||||||
|
* @param {any} R
|
||||||
|
* @param {any} G
|
||||||
|
* @param {any} B
|
||||||
|
* @param {any} A
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function sq_RGBA(R, G, B, A) {
|
||||||
|
R = R.tointeger();
|
||||||
|
G = G.tointeger();
|
||||||
|
B = B.tointeger();
|
||||||
|
A = A.tointeger();
|
||||||
|
return (A << 24) + (R << 16) + (G << 8) + B;
|
||||||
|
}
|
||||||
702
Tool/Json.nut
Normal file
702
Tool/Json.nut
Normal file
@@ -0,0 +1,702 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* JSON Parser
|
||||||
|
* @package JSONParser
|
||||||
|
*/
|
||||||
|
class JSONParser {
|
||||||
|
|
||||||
|
// should be the same for all components within JSONParser package
|
||||||
|
static version = "1.0.1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse JSON string into data structure
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @param {function({string} value[, "number"|"string"])|null} converter
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
function parse(str, converter = null) {
|
||||||
|
|
||||||
|
local state;
|
||||||
|
local stack = []
|
||||||
|
local container;
|
||||||
|
local key;
|
||||||
|
local value;
|
||||||
|
|
||||||
|
// actions for string tokens
|
||||||
|
local string = {
|
||||||
|
go = function() {
|
||||||
|
state = "ok";
|
||||||
|
},
|
||||||
|
firstokey = function() {
|
||||||
|
key = value;
|
||||||
|
state = "colon";
|
||||||
|
},
|
||||||
|
okey = function() {
|
||||||
|
key = value;
|
||||||
|
state = "colon";
|
||||||
|
},
|
||||||
|
ovalue = function() {
|
||||||
|
value = this._convert(value, "string", converter);
|
||||||
|
state = "ocomma";
|
||||||
|
}.bindenv(this),
|
||||||
|
firstavalue = function() {
|
||||||
|
value = this._convert(value, "string", converter);
|
||||||
|
state = "acomma";
|
||||||
|
}.bindenv(this),
|
||||||
|
avalue = function() {
|
||||||
|
value = this._convert(value, "string", converter);
|
||||||
|
state = "acomma";
|
||||||
|
}.bindenv(this)
|
||||||
|
};
|
||||||
|
|
||||||
|
// the actions for number tokens
|
||||||
|
local number = {
|
||||||
|
go = function() {
|
||||||
|
state = "ok";
|
||||||
|
},
|
||||||
|
ovalue = function() {
|
||||||
|
value = this._convert(value, "number", converter);
|
||||||
|
state = "ocomma";
|
||||||
|
}.bindenv(this),
|
||||||
|
firstavalue = function() {
|
||||||
|
value = this._convert(value, "number", converter);
|
||||||
|
state = "acomma";
|
||||||
|
}.bindenv(this),
|
||||||
|
avalue = function() {
|
||||||
|
value = this._convert(value, "number", converter);
|
||||||
|
state = "acomma";
|
||||||
|
}.bindenv(this)
|
||||||
|
};
|
||||||
|
|
||||||
|
// action table
|
||||||
|
// describes where the state machine will go from each given state
|
||||||
|
local action = {
|
||||||
|
|
||||||
|
"{": {
|
||||||
|
go = function() {
|
||||||
|
stack.push({
|
||||||
|
state = "ok"
|
||||||
|
});
|
||||||
|
container = {};
|
||||||
|
state = "firstokey";
|
||||||
|
},
|
||||||
|
ovalue = function() {
|
||||||
|
stack.push({
|
||||||
|
container = container,
|
||||||
|
state = "ocomma",
|
||||||
|
key = key
|
||||||
|
});
|
||||||
|
container = {};
|
||||||
|
state = "firstokey";
|
||||||
|
},
|
||||||
|
firstavalue = function() {
|
||||||
|
stack.push({
|
||||||
|
container = container,
|
||||||
|
state = "acomma"
|
||||||
|
});
|
||||||
|
container = {};
|
||||||
|
state = "firstokey";
|
||||||
|
},
|
||||||
|
avalue = function() {
|
||||||
|
stack.push({
|
||||||
|
container = container,
|
||||||
|
state = "acomma"
|
||||||
|
});
|
||||||
|
container = {};
|
||||||
|
state = "firstokey";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"}": {
|
||||||
|
firstokey = function() {
|
||||||
|
local pop = stack.pop();
|
||||||
|
value = container;
|
||||||
|
container = ("container" in pop) ? pop.container : null;
|
||||||
|
key = ("key" in pop) ? pop.key : null;
|
||||||
|
state = pop.state;
|
||||||
|
},
|
||||||
|
ocomma = function() {
|
||||||
|
local pop = stack.pop();
|
||||||
|
container[key] <- value;
|
||||||
|
value = container;
|
||||||
|
container = ("container" in pop) ? pop.container : null;
|
||||||
|
key = ("key" in pop) ? pop.key : null;
|
||||||
|
state = pop.state;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"[": {
|
||||||
|
go = function() {
|
||||||
|
stack.push({
|
||||||
|
state = "ok"
|
||||||
|
});
|
||||||
|
container = [];
|
||||||
|
state = "firstavalue";
|
||||||
|
},
|
||||||
|
ovalue = function() {
|
||||||
|
stack.push({
|
||||||
|
container = container,
|
||||||
|
state = "ocomma",
|
||||||
|
key = key
|
||||||
|
});
|
||||||
|
container = [];
|
||||||
|
state = "firstavalue";
|
||||||
|
},
|
||||||
|
firstavalue = function() {
|
||||||
|
stack.push({
|
||||||
|
container = container,
|
||||||
|
state = "acomma"
|
||||||
|
});
|
||||||
|
container = [];
|
||||||
|
state = "firstavalue";
|
||||||
|
},
|
||||||
|
avalue = function() {
|
||||||
|
stack.push({
|
||||||
|
container = container,
|
||||||
|
state = "acomma"
|
||||||
|
});
|
||||||
|
container = [];
|
||||||
|
state = "firstavalue";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"]": {
|
||||||
|
firstavalue = function() {
|
||||||
|
local pop = stack.pop();
|
||||||
|
value = container;
|
||||||
|
container = ("container" in pop) ? pop.container : null;
|
||||||
|
key = ("key" in pop) ? pop.key : null;
|
||||||
|
state = pop.state;
|
||||||
|
},
|
||||||
|
acomma = function() {
|
||||||
|
local pop = stack.pop();
|
||||||
|
container.push(value);
|
||||||
|
value = container;
|
||||||
|
container = ("container" in pop) ? pop.container : null;
|
||||||
|
key = ("key" in pop) ? pop.key : null;
|
||||||
|
state = pop.state;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
":": {
|
||||||
|
colon = function() {
|
||||||
|
// Check if the key already exists
|
||||||
|
// NOTE previous code used 'if (key in container)...'
|
||||||
|
// but this finds table ('container') member methods too
|
||||||
|
local err = false;
|
||||||
|
foreach(akey, avalue in container) {
|
||||||
|
if (akey == key) err = true;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (err) throw "Duplicate key \"" + key + "\"";
|
||||||
|
state = "ovalue";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
",": {
|
||||||
|
ocomma = function() {
|
||||||
|
container[key] <- value;
|
||||||
|
state = "okey";
|
||||||
|
},
|
||||||
|
acomma = function() {
|
||||||
|
container.push(value);
|
||||||
|
state = "avalue";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"true": {
|
||||||
|
go = function() {
|
||||||
|
value = true;
|
||||||
|
state = "ok";
|
||||||
|
},
|
||||||
|
ovalue = function() {
|
||||||
|
value = true;
|
||||||
|
state = "ocomma";
|
||||||
|
},
|
||||||
|
firstavalue = function() {
|
||||||
|
value = true;
|
||||||
|
state = "acomma";
|
||||||
|
},
|
||||||
|
avalue = function() {
|
||||||
|
value = true;
|
||||||
|
state = "acomma";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"false": {
|
||||||
|
go = function() {
|
||||||
|
value = false;
|
||||||
|
state = "ok";
|
||||||
|
},
|
||||||
|
ovalue = function() {
|
||||||
|
value = false;
|
||||||
|
state = "ocomma";
|
||||||
|
},
|
||||||
|
firstavalue = function() {
|
||||||
|
value = false;
|
||||||
|
state = "acomma";
|
||||||
|
},
|
||||||
|
avalue = function() {
|
||||||
|
value = false;
|
||||||
|
state = "acomma";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"null": {
|
||||||
|
go = function() {
|
||||||
|
value = null;
|
||||||
|
state = "ok";
|
||||||
|
},
|
||||||
|
ovalue = function() {
|
||||||
|
value = null;
|
||||||
|
state = "ocomma";
|
||||||
|
},
|
||||||
|
firstavalue = function() {
|
||||||
|
value = null;
|
||||||
|
state = "acomma";
|
||||||
|
},
|
||||||
|
avalue = function() {
|
||||||
|
value = null;
|
||||||
|
state = "acomma";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
state = "go";
|
||||||
|
stack = [];
|
||||||
|
|
||||||
|
// current tokenizeing position
|
||||||
|
local start = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
local
|
||||||
|
result,
|
||||||
|
token,
|
||||||
|
tokenizer = _JSONTokenizer();
|
||||||
|
|
||||||
|
while (token = tokenizer.nextToken(str, start)) {
|
||||||
|
|
||||||
|
if ("ptfn" == token.type) {
|
||||||
|
// punctuation/true/false/null
|
||||||
|
action[token.value][state]();
|
||||||
|
} else if ("number" == token.type) {
|
||||||
|
// number
|
||||||
|
value = token.value;
|
||||||
|
number[state]();
|
||||||
|
} else if ("string" == token.type) {
|
||||||
|
// string
|
||||||
|
value = tokenizer.unescape(token.value);
|
||||||
|
string[state]();
|
||||||
|
}
|
||||||
|
|
||||||
|
start += token.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
state = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check is the final state is not ok
|
||||||
|
// or if there is somethign left in the str
|
||||||
|
if (state != "ok" || regexp("[^\\s]").capture(str, start)) {
|
||||||
|
local min = @(a, b) a< b ? a : b;
|
||||||
|
local near = str.slice(start, min(str.len(), start + 10));
|
||||||
|
throw "JSON Syntax Error near `" + near + "`";
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert strings/numbers
|
||||||
|
* Uses custom converter function
|
||||||
|
*
|
||||||
|
* @param {string} value
|
||||||
|
* @param {string} type
|
||||||
|
* @param {function|null} converter
|
||||||
|
*/
|
||||||
|
function _convert(value, type, converter) {
|
||||||
|
if ("function" == typeof converter) {
|
||||||
|
|
||||||
|
// # of params for converter function
|
||||||
|
|
||||||
|
local parametercCount = 2;
|
||||||
|
|
||||||
|
// .getinfos() is missing on ei platform
|
||||||
|
if ("getinfos" in converter) {
|
||||||
|
parametercCount = converter.getinfos().parameters.len() -
|
||||||
|
1 /* "this" is also included */ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parametercCount == 1) {
|
||||||
|
return converter(value);
|
||||||
|
} else if (parametercCount == 2) {
|
||||||
|
return converter(value, type);
|
||||||
|
} else {
|
||||||
|
throw "Error: converter function must take 1 or 2 parameters"
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ("number" == type) {
|
||||||
|
return (value.find(".") == null && value.find("e") == null && value.find("E") == null) ? value.tointeger() : value.tofloat();
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON Tokenizer
|
||||||
|
* @package JSONParser
|
||||||
|
*/
|
||||||
|
class _JSONTokenizer {
|
||||||
|
|
||||||
|
_ptfnRegex = null;
|
||||||
|
_numberRegex = null;
|
||||||
|
_stringRegex = null;
|
||||||
|
_ltrimRegex = null;
|
||||||
|
_unescapeRegex = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
// punctuation/true/false/null
|
||||||
|
this._ptfnRegex = regexp("^(?:\\,|\\:|\\[|\\]|\\{|\\}|true|false|null)");
|
||||||
|
|
||||||
|
// numbers
|
||||||
|
this._numberRegex = regexp("^(?:\\-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)");
|
||||||
|
|
||||||
|
// strings
|
||||||
|
this._stringRegex = regexp("^(?:\\\"((?:[^\\r\\n\\t\\\\\\\"]|\\\\(?:[\"\\\\\\/trnfb]|u[0-9a-fA-F]{4}))*)\\\")");
|
||||||
|
|
||||||
|
// ltrim pattern
|
||||||
|
this._ltrimRegex = regexp("^[\\s\\t\\n\\r]*");
|
||||||
|
|
||||||
|
// string unescaper tokenizer pattern
|
||||||
|
this._unescapeRegex = regexp("\\\\(?:(?:u\\d{4})|[\\\"\\\\/bfnrt])");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get next available token
|
||||||
|
* @param {string} str
|
||||||
|
* @param {integer} start
|
||||||
|
* @return {{type,value,length}|null}
|
||||||
|
*/
|
||||||
|
function nextToken(str, start = 0) {
|
||||||
|
|
||||||
|
local
|
||||||
|
m,
|
||||||
|
type,
|
||||||
|
token,
|
||||||
|
value,
|
||||||
|
length,
|
||||||
|
whitespaces;
|
||||||
|
|
||||||
|
// count # of left-side whitespace chars
|
||||||
|
whitespaces = this._leadingWhitespaces(str, start);
|
||||||
|
start += whitespaces;
|
||||||
|
|
||||||
|
if (m = this._ptfnRegex.capture(str, start)) {
|
||||||
|
// punctuation/true/false/null
|
||||||
|
value = str.slice(m[0].begin, m[0].end);
|
||||||
|
type = "ptfn";
|
||||||
|
} else if (m = this._numberRegex.capture(str, start)) {
|
||||||
|
// number
|
||||||
|
value = str.slice(m[0].begin, m[0].end);
|
||||||
|
type = "number";
|
||||||
|
} else if (m = this._stringRegex.capture(str, start)) {
|
||||||
|
// string
|
||||||
|
value = str.slice(m[1].begin, m[1].end);
|
||||||
|
type = "string";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = {
|
||||||
|
type = type,
|
||||||
|
value = value,
|
||||||
|
length = m[0].end - m[0].begin + whitespaces
|
||||||
|
};
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count # of left-side whitespace chars
|
||||||
|
* @param {string} str
|
||||||
|
* @param {integer} start
|
||||||
|
* @return {integer} number of leading spaces
|
||||||
|
*/
|
||||||
|
function _leadingWhitespaces(str, start) {
|
||||||
|
local r = this._ltrimRegex.capture(str, start);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
return r[0].end - r[0].begin;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unesacape() replacements table
|
||||||
|
_unescapeReplacements = {
|
||||||
|
"b": "\b",
|
||||||
|
"f": "\f",
|
||||||
|
"n": "\n",
|
||||||
|
"r": "\r",
|
||||||
|
"t": "\t"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unesacape string escaped per JSON standard
|
||||||
|
* @param {string} str
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function unescape(str) {
|
||||||
|
|
||||||
|
local start = 0;
|
||||||
|
local res = "";
|
||||||
|
|
||||||
|
while (start< str.len()) {
|
||||||
|
local m = this._unescapeRegex.capture(str, start);
|
||||||
|
|
||||||
|
if (m) {
|
||||||
|
local token = str.slice(m[0].begin, m[0].end);
|
||||||
|
|
||||||
|
// append chars before match
|
||||||
|
local pre = str.slice(start, m[0].begin);
|
||||||
|
res += pre;
|
||||||
|
|
||||||
|
if (token.len() == 6) {
|
||||||
|
// unicode char in format \uhhhh, where hhhh is hex char code
|
||||||
|
// todo: convert \uhhhh chars
|
||||||
|
res += token;
|
||||||
|
} else {
|
||||||
|
// escaped char
|
||||||
|
// @see http://www.json.org/
|
||||||
|
local char = token.slice(1);
|
||||||
|
|
||||||
|
if (char in this._unescapeReplacements) {
|
||||||
|
res += this._unescapeReplacements[char];
|
||||||
|
} else {
|
||||||
|
res += char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// append the rest of the source string
|
||||||
|
res += str.slice(start);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = m[0].end;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class JSONEncoder {
|
||||||
|
|
||||||
|
static VERSION = "2.0.0";
|
||||||
|
|
||||||
|
// max structure depth
|
||||||
|
// anything above probably has a cyclic ref
|
||||||
|
static _maxDepth = 32;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode value to JSON
|
||||||
|
* @param {table|array|*} value
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function encode(value) {
|
||||||
|
return this._encode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {table|array} val
|
||||||
|
* @param {integer=0} depth – current depth level
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function _encode(val, depth = 0) {
|
||||||
|
|
||||||
|
// detect cyclic reference
|
||||||
|
if (depth > this._maxDepth) {
|
||||||
|
throw "Possible cyclic reference";
|
||||||
|
}
|
||||||
|
|
||||||
|
local
|
||||||
|
r = "",
|
||||||
|
s = "",
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
switch (typeof val) {
|
||||||
|
|
||||||
|
case "table":
|
||||||
|
case "class":
|
||||||
|
s = "";
|
||||||
|
|
||||||
|
// serialize properties, but not functions
|
||||||
|
foreach(k, v in val) {
|
||||||
|
if (typeof v != "function") {
|
||||||
|
s += ",\"" + k + "\":" + this._encode(v, depth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s.len() > 0 ? s.slice(1) : s;
|
||||||
|
r += "{" + s + "}";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "array":
|
||||||
|
s = "";
|
||||||
|
|
||||||
|
for (i = 0; i< val.len(); i++) {
|
||||||
|
s += "," + this._encode(val[i], depth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = (i > 0) ? s.slice(1) : s;
|
||||||
|
r += "[" + s + "]";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "integer":
|
||||||
|
case "float":
|
||||||
|
case "bool":
|
||||||
|
r += val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "null":
|
||||||
|
r += "null";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "instance":
|
||||||
|
|
||||||
|
if ("_serializeRaw" in val && typeof val._serializeRaw == "function") {
|
||||||
|
|
||||||
|
// include value produced by _serializeRaw()
|
||||||
|
r += val._serializeRaw().tostring();
|
||||||
|
|
||||||
|
} else if ("_serialize" in val && typeof val._serialize == "function") {
|
||||||
|
|
||||||
|
// serialize instances by calling _serialize method
|
||||||
|
r += this._encode(val._serialize(), depth + 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
s = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// iterate through instances which implement _nexti meta-method
|
||||||
|
foreach(k, v in val) {
|
||||||
|
s += ",\"" + k + "\":" + this._encode(v, depth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
// iterate through instances w/o _nexti
|
||||||
|
// serialize properties, but not functions
|
||||||
|
foreach(k, v in val.getclass()) {
|
||||||
|
if (typeof v != "function") {
|
||||||
|
s += ",\"" + k + "\":" + this._encode(val[k], depth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s.len() > 0 ? s.slice(1) : s;
|
||||||
|
r += "{" + s + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "blob":
|
||||||
|
// This is a workaround for a known bug:
|
||||||
|
// on device side Blob.tostring() returns null
|
||||||
|
// (instaead of an empty string)
|
||||||
|
r += "\"" + (val.len() ? this._escape(val.tostring()) : "") + "\"";
|
||||||
|
break;
|
||||||
|
|
||||||
|
// strings and all other
|
||||||
|
default:
|
||||||
|
r += "\"" + this._escape(val.tostring()) + "\"";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape strings according to http://www.json.org/ spec
|
||||||
|
* @param {string} str
|
||||||
|
*/
|
||||||
|
function _escape(str) {
|
||||||
|
local res = "";
|
||||||
|
|
||||||
|
for (local i = 0; i< str.len(); i++) {
|
||||||
|
|
||||||
|
local ch1 = (str[i] & 0xFF);
|
||||||
|
|
||||||
|
if ((ch1 & 0x80) == 0x00) {
|
||||||
|
// 7-bit Ascii
|
||||||
|
|
||||||
|
ch1 = format("%c", ch1);
|
||||||
|
|
||||||
|
if (ch1 == "\"") {
|
||||||
|
res += "\\\"";
|
||||||
|
} else if (ch1 == "\\") {
|
||||||
|
res += "\\\\";
|
||||||
|
} else if (ch1 == "/") {
|
||||||
|
res += "\\/";
|
||||||
|
} else if (ch1 == "\b") {
|
||||||
|
res += "\\b";
|
||||||
|
} else if (ch1 == "\f") {
|
||||||
|
res += "\\f";
|
||||||
|
} else if (ch1 == "\n") {
|
||||||
|
res += "\\n";
|
||||||
|
} else if (ch1 == "\r") {
|
||||||
|
res += "\\r";
|
||||||
|
} else if (ch1 == "\t") {
|
||||||
|
res += "\\t";
|
||||||
|
} else if (ch1 == "\0") {
|
||||||
|
res += "\\u0000";
|
||||||
|
} else {
|
||||||
|
res += ch1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if ((ch1 & 0xE0) == 0xC0) {
|
||||||
|
// 110xxxxx = 2-byte unicode
|
||||||
|
local ch2 = (str[++i] & 0xFF);
|
||||||
|
res += format("%c%c", ch1, ch2);
|
||||||
|
} else if ((ch1 & 0xF0) == 0xE0) {
|
||||||
|
// 1110xxxx = 3-byte unicode
|
||||||
|
local ch2 = (str[++i] & 0xFF);
|
||||||
|
local ch3 = (str[++i] & 0xFF);
|
||||||
|
res += format("%c%c%c", ch1, ch2, ch3);
|
||||||
|
} else if ((ch1 & 0xF8) == 0xF0) {
|
||||||
|
// 11110xxx = 4 byte unicode
|
||||||
|
local ch2 = (str[++i] & 0xFF);
|
||||||
|
local ch3 = (str[++i] & 0xFF);
|
||||||
|
local ch4 = (str[++i] & 0xFF);
|
||||||
|
res += format("%c%c%c%c", ch1, ch2, ch3, ch4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Json {
|
||||||
|
|
||||||
|
function Encode(Table) {
|
||||||
|
return JSONEncoder.encode(Table);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decode(Str) {
|
||||||
|
return JSONParser.parse(Str);
|
||||||
|
}
|
||||||
|
}
|
||||||
125
Tool/Math.nut
Normal file
125
Tool/Math.nut
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
文件名:Math.nut
|
||||||
|
路径:Tool/Math.nut
|
||||||
|
创建日期:2025-10-21 18:10
|
||||||
|
文件用途:数学工具
|
||||||
|
*/
|
||||||
|
class Math {
|
||||||
|
/**
|
||||||
|
* 取随机值 左闭右闭
|
||||||
|
* @function
|
||||||
|
* @param {integer} Min
|
||||||
|
* @param {integer} Max
|
||||||
|
* @returns {integer}
|
||||||
|
*/
|
||||||
|
function Rand(Min, Max) {
|
||||||
|
local In = rand();
|
||||||
|
local Ret = (Min + (Max - Min + 1) * (In / (RAND_MAX + 1).tofloat())).tointeger();
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 随机返回数组中的任意一个数
|
||||||
|
* @function
|
||||||
|
* @param {array} arr
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
function GetRandomElementFromArray(arr) {
|
||||||
|
if (arr.len() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 生成一个0到数组长度-1之间的随机索引
|
||||||
|
local randomIndex = Math.Rand(0, arr.len() - 1);
|
||||||
|
return arr[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过坐标获得两点旋转角度
|
||||||
|
* @function
|
||||||
|
* @param {integer} x1
|
||||||
|
* @param {integer} y1
|
||||||
|
* @param {integer} x2
|
||||||
|
* @param {integer} y2
|
||||||
|
* @returns {float}
|
||||||
|
*/
|
||||||
|
function GetRorateAngleByPos(x1, y1, x2, y2) {
|
||||||
|
return (atan2((y2 - y1).tofloat(), (x2 - x1).tofloat()) * 180) / PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {integer} x1
|
||||||
|
* @param {aintegerny} y1
|
||||||
|
* @param {integer} x2
|
||||||
|
* @param {integer} y2
|
||||||
|
* @returns {float}
|
||||||
|
*/
|
||||||
|
function GetDistanceByPos(x1, y1, x2, y2) {
|
||||||
|
return sqrt(pow((x2 - x1).tofloat(), 2) + pow((y2 - y1).tofloat(), 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得两值随时间的匀速运动值
|
||||||
|
* @function
|
||||||
|
* @param {any} sv
|
||||||
|
* @param {any} ev
|
||||||
|
* @param {float} currentRate
|
||||||
|
* @param {float} maxRate
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function GetUniformVelocity(sv, ev, currentRate, maxRate) {
|
||||||
|
local rate = currentRate.tofloat() / maxRate.tofloat();
|
||||||
|
local varyValue = ev - sv;
|
||||||
|
return sv + varyValue * rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得两值随时间的变速运动值
|
||||||
|
* @function
|
||||||
|
* @param {any} sv
|
||||||
|
* @param {any} ev
|
||||||
|
* @param {float} currentRate
|
||||||
|
* @param {float} maxRate
|
||||||
|
* @param {any} increaseFeature
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function GetAccel(sv, ev, currentRate, maxRate, increaseFeature) {
|
||||||
|
local rate = currentRate.tofloat() / maxRate.tofloat();
|
||||||
|
local varyValue = ev - sv;
|
||||||
|
local increaseRate = 1.0;
|
||||||
|
if (increaseFeature) {
|
||||||
|
increaseRate = pow(50, rate) / 50.0; //慢->快
|
||||||
|
} else {
|
||||||
|
// 修正后的减速逻辑计算,例如采用线性变换结合幂次运算来实现更合理的减速效果
|
||||||
|
// 先将rate映射到一个更合适的范围(这里从[0,1]映射到[0.1, 1],可调整)
|
||||||
|
local mappedRate = rate * 0.9 + 0.1;
|
||||||
|
increaseRate = pow(mappedRate, 2); // 幂次可调整,这里取2来让减速更明显,可根据实际情况修改
|
||||||
|
}
|
||||||
|
return sv + varyValue * increaseRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算两个矩形是否相交
|
||||||
|
* @function
|
||||||
|
* @param {any} x1
|
||||||
|
* @param {any} y1
|
||||||
|
* @param {any} width1
|
||||||
|
* @param {any} height1
|
||||||
|
* @param {any} x2
|
||||||
|
* @param {any} y2
|
||||||
|
* @param {any} width2
|
||||||
|
* @param {any} height2
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function IsIntersectRect(x1, y1, width1, height1, x2, y2, width2, height2) {
|
||||||
|
// 计算矩形1的边界
|
||||||
|
local right1 = x1 + width1;
|
||||||
|
local bottom1 = y1 + height1;
|
||||||
|
// 计算矩形2的边界
|
||||||
|
local right2 = x2 + width2;
|
||||||
|
local bottom2 = y2 + height2;
|
||||||
|
// 检查是否有重叠
|
||||||
|
return !(right1 < x2 || bottom1 < y2 || x1 > right2 || y1 > bottom2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,19 +4,54 @@
|
|||||||
创建日期:2025-10-11 11:21
|
创建日期:2025-10-11 11:21
|
||||||
文件用途:主界面UI
|
文件用途:主界面UI
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Actora <- null;
|
||||||
//主界面UI初始化回调
|
//主界面UI初始化回调
|
||||||
function _MainUI_Enter_()
|
function _MainUI_Enter_(UI_Scene) {
|
||||||
{
|
if (!_SYS_UI_SCENE_Instance_) _SYS_UI_SCENE_Instance_ = Actor(UI_Scene);
|
||||||
|
|
||||||
|
//初始化鼠标
|
||||||
|
Game_Cursor.GetInstance();
|
||||||
|
|
||||||
|
local TestWindow = sq_CreaterWindowInstance("HUD窗口", Window_hud, 0, 0, 1280, 720, 0);
|
||||||
|
TestWindow.ResetFoucus();
|
||||||
|
|
||||||
|
// local Tc = GameWidget_TripleCav("sprite/interface/lenheartwindowcommon.img",175,300);
|
||||||
|
// _SYS_UI_SCENE_Instance_.AddChild(Tc);
|
||||||
|
// Tc.SetPos(400,300);
|
||||||
|
|
||||||
|
// local NgC = GameWidget_NineGridCav("sprite/interface/lenheartwindowcommon.img", 97, 300, 300);
|
||||||
|
// _SYS_UI_SCENE_Instance_.AddChild(NgC);
|
||||||
|
// NgC.SetPos(400, 300);
|
||||||
|
|
||||||
|
// local T = sq_GetPng("sprite/item/avatar/swordman/0sm_acap.img",0);
|
||||||
|
// print(T);
|
||||||
|
|
||||||
|
local Test1 = sq_CreaterWindowInstance("测试窗口", Window_NotiBox, 150, 150, 364, 356, 20);
|
||||||
|
Test1.ResetFoucus();
|
||||||
|
|
||||||
|
local act = Actor();
|
||||||
|
// local Canv = Canvas(600, 600);
|
||||||
|
// _SYS_UI_SCENE_Instance_.AddChild(Canv);
|
||||||
|
|
||||||
|
// for (local i = 0; i < 10000; i++) {
|
||||||
|
// Canv.DrawImg("sprite/item/avatar/swordman/0sm_acap.img", 0, i % 600, i / 600 * 28);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
//主界面UI事件回调
|
//主界面UI事件回调
|
||||||
function _MainUI_HandleEvents_(event)
|
function _MainUI_HandleEvents_(EventType, EventData) {
|
||||||
{
|
_Global_Windows_Events_(EventType, EventData);
|
||||||
|
if (EventType == UI_EVENT.MOUSEBUTTONDOWN) {
|
||||||
|
if (Actora) {
|
||||||
|
_SYS_UI_SCENE_Instance_.RemoveChild(Actora);
|
||||||
|
Actora = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//主界面UI更新回调
|
//主界面UI更新回调
|
||||||
function _MainUI_Update_(deltaTime)
|
function _MainUI_Update_(deltaTime) {
|
||||||
{
|
_Global_Windows_Logic_(deltaTime);
|
||||||
}
|
}
|
||||||
//主界面UI退出回调
|
//主界面UI退出回调
|
||||||
function _MainUI_Exit_()
|
function _MainUI_Exit_() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
204
UI/ObjectClass/Actor.nut
Normal file
204
UI/ObjectClass/Actor.nut
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
文件名:Actor.nut
|
||||||
|
路径:UI/ObjectClass/Actor.nut
|
||||||
|
创建日期:2025-10-18 16:33
|
||||||
|
文件用途:
|
||||||
|
*/
|
||||||
|
class Actor extends BaseNode {
|
||||||
|
function _typeof() {
|
||||||
|
return "Actor";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(obj = null) {
|
||||||
|
if (obj) {
|
||||||
|
base.constructor(obj, false);
|
||||||
|
} else {
|
||||||
|
base.constructor(sq_CreateActor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置名字
|
||||||
|
* @function
|
||||||
|
* @param {string} Name
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetName(Name) {
|
||||||
|
sq_SetName(this.C_Object, Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取名字
|
||||||
|
* @function
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function GetName() {
|
||||||
|
return sq_GetName(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加子对象
|
||||||
|
* @function
|
||||||
|
* @param {Actor} Act
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function AddChild(Act) {
|
||||||
|
sq_AddChild(this.C_Object, Act.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除子对象
|
||||||
|
* @function
|
||||||
|
* @param {Actor} Act
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function RemoveChild(Act) {
|
||||||
|
sq_RemoveChild(this.C_Object, Act.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置层级
|
||||||
|
* @function
|
||||||
|
* @param {integer} Order
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetZOrder(Order) {
|
||||||
|
sq_SetZOrder(this.C_Object, Order);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取层级
|
||||||
|
* @function
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function GetZOrder() {
|
||||||
|
return sq_GetZOrder(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**设置坐标 */
|
||||||
|
function SetPos(...) {
|
||||||
|
if (vargv.len() == 1) {
|
||||||
|
sq_SetPos(this.C_Object, vargv[0]);
|
||||||
|
} else if (vargv.len() == 2) {
|
||||||
|
sq_SetPos(this.C_Object, vargv[0], vargv[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取坐标
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function GetPos() {
|
||||||
|
return sq_GetPos(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取世界坐标
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function GetWorldPos() {
|
||||||
|
return sq_GetWorldPos(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置透明度
|
||||||
|
* @function
|
||||||
|
* @param {integer} Alpha
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetAlpha(Alpha) {
|
||||||
|
sq_SetAlpha(this.C_Object, Alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取透明度
|
||||||
|
* @function
|
||||||
|
* @returns {integer}
|
||||||
|
*/
|
||||||
|
function GetAlpha() {
|
||||||
|
return sq_GetAlpha(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置缩放
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function SetScale(Value, ...) {
|
||||||
|
if (vargv.len() == 0) sq_SetScale(this.C_Object, Value);
|
||||||
|
else if (vargv.len() == 1) sq_SetScale(this.C_Object, Value, vargv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缩放
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function GetScale() {
|
||||||
|
return sq_GetScale(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置旋转角度
|
||||||
|
* @function
|
||||||
|
* @param {float} Angle
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetRotation(Angle) {
|
||||||
|
sq_SetRotation(this.C_Object, Angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取旋转角度
|
||||||
|
* @function
|
||||||
|
* @returns {float}
|
||||||
|
*/
|
||||||
|
function GetRotation() {
|
||||||
|
return sq_GetRotation(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置大小
|
||||||
|
* @function
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetSize(Value, ...) {
|
||||||
|
if (vargv.len() == 0) sq_SetScale(this.C_Object, Value);
|
||||||
|
else if (vargv.len() == 1) sq_SetScale(this.C_Object, Value, vargv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取大小
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function GetSize() {
|
||||||
|
return sq_GetSize(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置可见性
|
||||||
|
* @function
|
||||||
|
* @param {boolean} Flag
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetVisible(Flag) {
|
||||||
|
sq_SetVisible(this.C_Object, Flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取可见性
|
||||||
|
* @function
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function GetVisible() {
|
||||||
|
return sq_GetVisible(this.C_Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {BLENDMODE} BlendMode
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetBlendMode(BlendMode) {
|
||||||
|
sq_SetBlendMode(this.C_Object, BlendMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
UI/ObjectClass/BaseNode.nut
Normal file
17
UI/ObjectClass/BaseNode.nut
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
文件名:BaseNode.nut
|
||||||
|
路径:UI/ObjectClass/BaseNode.nut
|
||||||
|
创建日期:2025-10-18 20:43
|
||||||
|
文件用途:
|
||||||
|
*/
|
||||||
|
class BaseNode {
|
||||||
|
/** @private */
|
||||||
|
C_Object = null
|
||||||
|
|
||||||
|
constructor(CObject, DestructFlag = true) {
|
||||||
|
this.C_Object = CObject
|
||||||
|
//析构对象
|
||||||
|
if (DestructFlag) sq_RegisterDestruction(C_Object, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
44
UI/ObjectClass/Canvas.nut
Normal file
44
UI/ObjectClass/Canvas.nut
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
文件名:Canvas.nut
|
||||||
|
路径:UI/ObjectClass/Canvas.nut
|
||||||
|
创建日期:2025-10-24 22:00
|
||||||
|
文件用途:画布类
|
||||||
|
*/
|
||||||
|
class Canvas extends Actor {
|
||||||
|
function _typeof() {
|
||||||
|
return "Canvas";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(Width, Height) {
|
||||||
|
C_Object = sq_CreateCanvas(Width, Height);
|
||||||
|
sq_RegisterDestruction(C_Object, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制Img
|
||||||
|
* @function
|
||||||
|
* @param {string} Img img路径
|
||||||
|
* @param {integer} Index img编号
|
||||||
|
* @param {integer} X X坐标
|
||||||
|
* @param {integer} Y Y坐标
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function DrawImg(Img, Index, X, Y) {
|
||||||
|
sq_Canvas_DrawImg(C_Object, Img, Index, { x = X, y = Y });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据矩形绘制Img
|
||||||
|
* @function
|
||||||
|
* @param {string} Img img路径
|
||||||
|
* @param {integer} Index img编号
|
||||||
|
* @param {integer} X X坐标
|
||||||
|
* @param {integer} Y Y坐标
|
||||||
|
* @param {any} Width 宽度
|
||||||
|
* @param {any} Height 高度
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function DrawImgRect(Img, Index, X, Y, Width, Height) {
|
||||||
|
sq_Canvas_DrawImgRect(C_Object, Img, Index, { x = X, y = Y, w = Width, h = Height });
|
||||||
|
}
|
||||||
|
}
|
||||||
80
UI/ObjectClass/GameWidget.nut
Normal file
80
UI/ObjectClass/GameWidget.nut
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
文件名:GameWidget.nut
|
||||||
|
路径:UI/ObjectClass/GameWidget.nut
|
||||||
|
创建日期:2025-10-21 22:05
|
||||||
|
文件用途:
|
||||||
|
*/
|
||||||
|
class GameWidget extends WindowNode {
|
||||||
|
//组件ID
|
||||||
|
ObjectId = null;
|
||||||
|
|
||||||
|
//本地坐标
|
||||||
|
Localtion_X = 0;
|
||||||
|
Localtion_Y = 0;
|
||||||
|
|
||||||
|
//是否按下
|
||||||
|
isLBDown = false;
|
||||||
|
//是否悬停
|
||||||
|
isInRect = false;
|
||||||
|
|
||||||
|
//点击事件
|
||||||
|
OnClick = null;
|
||||||
|
//点击音效
|
||||||
|
ClickSound = null;
|
||||||
|
//悬停音效
|
||||||
|
HoverSound = null;
|
||||||
|
HoverSoundFlag = false;
|
||||||
|
|
||||||
|
constructor(x, y, width, height) {
|
||||||
|
this.Localtion_X = x;
|
||||||
|
this.Localtion_Y = y;
|
||||||
|
this.Width = width;
|
||||||
|
this.Height = height;
|
||||||
|
this.X = x;
|
||||||
|
this.Y = y;
|
||||||
|
|
||||||
|
ObjectId = clock();
|
||||||
|
base.constructor();
|
||||||
|
SetPos(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OnMouseEvent(Type, Data, EventInteractiveFlag) {
|
||||||
|
if (!Visible) return;
|
||||||
|
//鼠标移动事件
|
||||||
|
if (Type == UI_EVENT.MOUSEMOTION) {
|
||||||
|
local Pos = GetWorldPos();
|
||||||
|
if (Math.IsIntersectRect(Data[0], Data[1], 1, 1, Pos.x, Pos.y, Width, Height)) {
|
||||||
|
//如果有配置悬停音效
|
||||||
|
if (HoverSound && !HoverSoundFlag) {
|
||||||
|
HoverSoundFlag = true;
|
||||||
|
//TODO 音效系统
|
||||||
|
// Sq_PlaySoundEffect(HoverSound);
|
||||||
|
}
|
||||||
|
isInRect = true;
|
||||||
|
} else {
|
||||||
|
HoverSoundFlag = false;
|
||||||
|
isInRect = false;
|
||||||
|
}
|
||||||
|
} else if (Type == UI_EVENT.MOUSEBUTTONDOWN) {
|
||||||
|
local IMouse = Game_Cursor.GetInstance();
|
||||||
|
local Pos = GetWorldPos();
|
||||||
|
if (Math.IsIntersectRect(IMouse.MouseX, IMouse.MouseY, 1, 1, Pos.x, Pos.y, Width, Height)) {
|
||||||
|
isLBDown = true;
|
||||||
|
}
|
||||||
|
} else if (Type == UI_EVENT.MOUSEBUTTONUP) {
|
||||||
|
local IMouse = Game_Cursor.GetInstance();
|
||||||
|
local Pos = GetWorldPos();
|
||||||
|
if (isLBDown && Math.IsIntersectRect(IMouse.MouseX, IMouse.MouseY, 1, 1, Pos.x, Pos.y, Width, Height)) {
|
||||||
|
if (OnClick) this.OnClick.call(this,this);
|
||||||
|
if (ClickSound) {
|
||||||
|
//TODO 音效系统
|
||||||
|
// Sq_PlaySoundEffect(ClickSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isLBDown = false;
|
||||||
|
}
|
||||||
|
foreach (Window in Childrens) {
|
||||||
|
if (Window instanceof WindowNode) Window.OnMouseEvent(Type, Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
129
UI/ObjectClass/GameWindow.nut
Normal file
129
UI/ObjectClass/GameWindow.nut
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
文件名:GameWindow.nut
|
||||||
|
路径:UI/ObjectClass/GameWindow.nut
|
||||||
|
创建日期:2025-10-18 20:58
|
||||||
|
文件用途:游戏窗口类
|
||||||
|
*/
|
||||||
|
|
||||||
|
class GameWindow extends WindowNode {
|
||||||
|
//窗口名称
|
||||||
|
WindowName = "undefined";
|
||||||
|
//是否活动窗口Flag
|
||||||
|
IsActiveFlag = false;
|
||||||
|
|
||||||
|
//标题高度
|
||||||
|
TitleH = null;
|
||||||
|
//鼠标相对位置
|
||||||
|
M_Xpos = null;
|
||||||
|
M_Ypos = null;
|
||||||
|
//移动Flag
|
||||||
|
MoveFlag = false;
|
||||||
|
|
||||||
|
//是否为独立窗口
|
||||||
|
IsIndependent = true;
|
||||||
|
//是否为顶层窗口
|
||||||
|
IsTop = false;
|
||||||
|
|
||||||
|
function _typeof() {
|
||||||
|
return "GameWindow";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(WindowName, gX, gY, gWidth, gHeight, gTitleHeight) {
|
||||||
|
base.constructor();
|
||||||
|
//窗口名字
|
||||||
|
this.WindowName = WindowName;
|
||||||
|
//宽度
|
||||||
|
Width = gWidth;
|
||||||
|
//高度
|
||||||
|
Height = gHeight;
|
||||||
|
//标题高度
|
||||||
|
TitleH = gTitleHeight;
|
||||||
|
|
||||||
|
//X坐标
|
||||||
|
X = gX;
|
||||||
|
//Y坐标
|
||||||
|
Y = gY;
|
||||||
|
SetPos(X, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ResetFoucus() {
|
||||||
|
SetVisible(true);
|
||||||
|
//遍历全局窗口数组将自己移除重新添加在末尾
|
||||||
|
foreach (Index, WindowObj in _SYS_WINDOW_LIST_) {
|
||||||
|
if (WindowObj.WindowName == this.WindowName) {
|
||||||
|
_SYS_WINDOW_LIST_.remove(Index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SYS_WINDOW_LIST_.append(this);
|
||||||
|
SetZOrder(_SYS_WINDOW_LIST_.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
//关闭窗口 -并没有销毁只是隐藏
|
||||||
|
function CloseWindow() {
|
||||||
|
this.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//销毁全局UI中的窗口 子窗口只要父窗口被销毁就会被销毁
|
||||||
|
function DestroyWindow() {
|
||||||
|
this.Visible = false;
|
||||||
|
this.DestroyFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Proc(Dt) {
|
||||||
|
base.Proc(Dt);
|
||||||
|
foreach (Window in Childrens) {
|
||||||
|
if (Window instanceof WindowNode) Window.Proc(Dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//鼠标事件回调
|
||||||
|
function OnMouseEvent(Type, Data, EventInteractiveFlag) {
|
||||||
|
if (!Visible) return;
|
||||||
|
foreach (Window in Childrens) {
|
||||||
|
if ("OnMouseEvent" in Window) Window.OnMouseEvent(Type, Data,EventInteractiveFlag);
|
||||||
|
}
|
||||||
|
//鼠标移动事件
|
||||||
|
if (Type == UI_EVENT.MOUSEMOTION) {
|
||||||
|
if (MoveFlag) {
|
||||||
|
//左键拖动
|
||||||
|
X = B_X - (M_Xpos - Data[0]);
|
||||||
|
Y = B_Y - (M_Ypos - Data[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//鼠标按下事件
|
||||||
|
else if (Type == UI_EVENT.MOUSEBUTTONDOWN) {
|
||||||
|
local IMouse = Game_Cursor.GetInstance();
|
||||||
|
//如果点击事件在窗口内
|
||||||
|
if (Math.IsIntersectRect(IMouse.MouseX, IMouse.MouseY, 1, 1, X, Y, Width, Height) && !EventInteractiveFlag) {
|
||||||
|
if (IsIndependent) ResetFoucus();
|
||||||
|
//如果点下去在标题栏
|
||||||
|
if (Math.IsIntersectRect(IMouse.MouseX, IMouse.MouseY, 1, 1, X, Y, Width, TitleH)) {
|
||||||
|
MoveFlag = true;
|
||||||
|
M_Xpos = IMouse.MouseX; //原始鼠标位置数据
|
||||||
|
M_Ypos = IMouse.MouseY;
|
||||||
|
B_X = X; //原始窗口位置
|
||||||
|
B_Y = Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//鼠标弹起事件
|
||||||
|
else if (Type == UI_EVENT.MOUSEBUTTONUP) {
|
||||||
|
if (MoveFlag) {
|
||||||
|
MoveFlag = false;
|
||||||
|
M_Xpos = null;
|
||||||
|
M_Ypos = null;
|
||||||
|
B_X = null;
|
||||||
|
B_Y = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//键盘事件回调
|
||||||
|
function OnKeyEvent(Type, Data, EventInteractiveFlag) {
|
||||||
|
if (!Visible) return;
|
||||||
|
foreach (Window in Childrens) {
|
||||||
|
if ("OnKeyEvent" in Window) Window.OnKeyEvent(Type, Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
UI/ObjectClass/Sprite.nut
Normal file
16
UI/ObjectClass/Sprite.nut
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
文件名:Sprite.nut
|
||||||
|
路径:UI/ObjectClass/Sprite.nut
|
||||||
|
创建日期:2025-10-18 19:51
|
||||||
|
文件用途:精灵类
|
||||||
|
*/
|
||||||
|
class Sprite extends Actor {
|
||||||
|
function _typeof() {
|
||||||
|
return "Sprite"
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(ImgPath, Idx) {
|
||||||
|
C_Object = sq_CreateSprite(ImgPath, Idx);
|
||||||
|
sq_RegisterDestruction(C_Object,this);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
UI/ObjectClass/Text.nut
Normal file
16
UI/ObjectClass/Text.nut
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
文件名:Text.nut
|
||||||
|
路径:UI/ObjectClass/Text.nut
|
||||||
|
创建日期:2025-10-25 15:40
|
||||||
|
文件用途:
|
||||||
|
*/
|
||||||
|
class Text extends Actor {
|
||||||
|
function _typeof() {
|
||||||
|
return "Text"
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(Str, FontIndex,Color) {
|
||||||
|
C_Object = sq_CreateText(Str, FontIndex, Color);
|
||||||
|
sq_RegisterDestruction(C_Object,this);
|
||||||
|
}
|
||||||
|
}
|
||||||
126
UI/ObjectClass/WindowNode.nut
Normal file
126
UI/ObjectClass/WindowNode.nut
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
文件名:WindowNode.nut
|
||||||
|
路径:UI/ObjectClass/WindowNode.nut
|
||||||
|
创建日期:2025-10-18 20:54
|
||||||
|
文件用途:窗口节点类
|
||||||
|
*/
|
||||||
|
_SYS_UI_SCENE_Instance_ <- null;
|
||||||
|
_SYS_WINDOW_LIST_ <- [];
|
||||||
|
class WindowNode extends Actor {
|
||||||
|
//演出状态
|
||||||
|
PerformanceState = false;
|
||||||
|
//子控件
|
||||||
|
Childrens = null;
|
||||||
|
//刷新函数
|
||||||
|
UpdateFunc = null;
|
||||||
|
//是否可见
|
||||||
|
Visible = true;
|
||||||
|
//宽度
|
||||||
|
Width = null;
|
||||||
|
//高度
|
||||||
|
Height = null;
|
||||||
|
//销毁Flag
|
||||||
|
DestroyFlag = false;
|
||||||
|
|
||||||
|
//X坐标
|
||||||
|
X = null;
|
||||||
|
B_X = null;
|
||||||
|
//Y坐标
|
||||||
|
Y = null;
|
||||||
|
B_Y = null;
|
||||||
|
|
||||||
|
function _typeof() {
|
||||||
|
return "WindowNode";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
base.constructor();
|
||||||
|
|
||||||
|
//子控件list初始化
|
||||||
|
Childrens = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetVisible(Flag) {
|
||||||
|
Visible = Flag;
|
||||||
|
base.SetVisible(Flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AddChild(Act) {
|
||||||
|
base.AddChild(Act);
|
||||||
|
Childrens.push(Act);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Proc(Dt){
|
||||||
|
if (UpdateFunc != null) this.UpdateFunc(Dt);
|
||||||
|
SetPos(X, Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {any} WindowName
|
||||||
|
* @param {GameWindow} WindowClass
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
function sq_CreaterWindowInstance(WindowName, WindowClass, gX, gY, gWidth, gHeight, gTitleHeight) {
|
||||||
|
foreach (idx, val in _SYS_WINDOW_LIST_) {
|
||||||
|
if (val.WindowName == WindowName) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local NewWindow = WindowClass(WindowName, gX, gY, gWidth, gHeight, gTitleHeight);
|
||||||
|
getroottable()._SYS_WINDOW_LIST_.push(NewWindow);
|
||||||
|
return NewWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {float} Dt
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function _Global_Windows_Logic_(Dt) {
|
||||||
|
if (_SYS_UI_SCENE_Instance_) {
|
||||||
|
for (local i = 0; i < _SYS_WINDOW_LIST_.len(); i++) {
|
||||||
|
local Window = _SYS_WINDOW_LIST_[i];
|
||||||
|
//如果窗口不可见并且 处于演出状态
|
||||||
|
if (!Window.Visible && Window.PerformanceState) {
|
||||||
|
Window.PerformanceState = false;
|
||||||
|
_SYS_UI_SCENE_Instance_.RemoveChild(Window);
|
||||||
|
if (Window.DestroyFlag) {
|
||||||
|
_SYS_WINDOW_LIST_.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
} else if (Window.Visible && !Window.PerformanceState) {
|
||||||
|
_SYS_UI_SCENE_Instance_.AddChild(Window);
|
||||||
|
Window.PerformanceState = true;
|
||||||
|
}
|
||||||
|
//无论窗口是否显示都需要调用Proc
|
||||||
|
Window.Proc(Dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _Global_Windows_Events_(EventType, EventData) {
|
||||||
|
//先传递鼠标事件
|
||||||
|
local IMouse = Game_Cursor.GetInstance();
|
||||||
|
IMouse.Event(EventType, EventData);
|
||||||
|
//事件是否被响应Flag
|
||||||
|
local EventInteractiveFlag = false;
|
||||||
|
for (local i = _SYS_WINDOW_LIST_.len() - 1; i > -1; i--) {
|
||||||
|
local Window = _SYS_WINDOW_LIST_[i];
|
||||||
|
if (Window.Visible) {
|
||||||
|
if (EventType == UI_EVENT.MOUSEMOTION || EventType == UI_EVENT.MOUSEBUTTONDOWN || EventType == UI_EVENT.MOUSEBUTTONUP) {
|
||||||
|
Window.OnMouseEvent(EventType, EventData, EventInteractiveFlag);
|
||||||
|
} else if (EventType == UI_EVENT.KEYDOWN || EventType == UI_EVENT.KEYUP) {
|
||||||
|
Window.OnKeyEvent(EventType, EventData, EventInteractiveFlag);
|
||||||
|
}
|
||||||
|
if (Math.IsIntersectRect(IMouse.MouseX, IMouse.MouseY, 1, 1, Window.X, Window.Y, Window.Width, Window.Height)) {
|
||||||
|
EventInteractiveFlag = Window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
UI/Windows/HUD/Window_hud.nut
Normal file
41
UI/Windows/HUD/Window_hud.nut
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
文件名:Window_hud.nut
|
||||||
|
路径:UI/Windows/HUD/Window_hud.nut
|
||||||
|
创建日期:2025-10-19 20:36
|
||||||
|
文件用途:
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Window_hud extends GameWindow {
|
||||||
|
constructor(Name, gX, gY, gWidth, gHeight, gTitleHeight) {
|
||||||
|
base.constructor(Name, gX, gY, gWidth, gHeight, gTitleHeight);
|
||||||
|
|
||||||
|
InitSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
function InitSprite() {
|
||||||
|
local Sp = Sprite("sprite/interface2/hud/hud.img", 0);
|
||||||
|
Sp.SetPos((1280 - 403) / 2, 720 - 75);
|
||||||
|
AddChild(Sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 鼠标事件重载函数
|
||||||
|
* @function override
|
||||||
|
* @param {any} Type
|
||||||
|
* @param {any} Data
|
||||||
|
* @param {boolean} EventInteractiveFlag
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function OnMouseEvent(Type, Data, EventInteractiveFlag) {
|
||||||
|
base.OnMouseEvent(Type, Data, EventInteractiveFlag);
|
||||||
|
if (Type == UI_EVENT.MOUSEBUTTONDOWN) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重载ResetFoucus函数本窗口不需要改变焦点
|
||||||
|
* @function
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function ResetFoucus() {}
|
||||||
|
}
|
||||||
81
UI/Windows/System/Cursor.nut
Normal file
81
UI/Windows/System/Cursor.nut
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
文件名:Cursor.nut
|
||||||
|
路径:UI/Windows/System/Cursor.nut
|
||||||
|
创建日期:2025-10-21 18:46
|
||||||
|
文件用途:
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Game_Cursor extends GameWindow {
|
||||||
|
//鼠标精灵数组
|
||||||
|
MouseSprite = null;
|
||||||
|
//当前鼠标工作ID
|
||||||
|
CurrentMouseTaskId = 0;
|
||||||
|
|
||||||
|
//鼠标X坐标
|
||||||
|
MouseX = -100;
|
||||||
|
//鼠标Y坐标
|
||||||
|
MouseY = -100;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (getroottable().rawin("__Game_Cursor__")) {
|
||||||
|
// 防止重复实例化
|
||||||
|
throw "Game_Cursor 不能重复实例化!";
|
||||||
|
}
|
||||||
|
base.constructor("系统鼠标", 0, 0, 1280, 720, 0);
|
||||||
|
|
||||||
|
Init();
|
||||||
|
//设置鼠标的层级最高
|
||||||
|
this.SetZOrder(10000000);
|
||||||
|
_SYS_UI_SCENE_Instance_.AddChild(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 静态方法:获取唯一实例
|
||||||
|
* @function
|
||||||
|
* @returns {Game_Cursor}
|
||||||
|
*/
|
||||||
|
function GetInstance() {
|
||||||
|
if (!getroottable().rawin("__Game_Cursor__")) {
|
||||||
|
// 首次调用时创建实例
|
||||||
|
getroottable()["__Game_Cursor__"] <- Game_Cursor();
|
||||||
|
}
|
||||||
|
return getroottable()["__Game_Cursor__"];
|
||||||
|
}
|
||||||
|
|
||||||
|
function Init() {
|
||||||
|
MouseSprite = [];
|
||||||
|
for (local i = 0; i < 254; i++) {
|
||||||
|
//初始化鼠标精灵
|
||||||
|
local Buffer = Sprite("sprite/interface/newstyle/windows/cursor.img", i);
|
||||||
|
MouseSprite.push(Buffer);
|
||||||
|
}
|
||||||
|
SetNormalTask(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置鼠标的普通任务
|
||||||
|
* @function
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function SetNormalTask(TaskId) {
|
||||||
|
RemoveChild(MouseSprite[CurrentMouseTaskId]);
|
||||||
|
CurrentMouseTaskId = TaskId;
|
||||||
|
AddChild(MouseSprite[CurrentMouseTaskId]);
|
||||||
|
MouseSprite[CurrentMouseTaskId].SetPos(MouseX, MouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 鼠标窗口是独立的事件函数
|
||||||
|
* @function
|
||||||
|
* @param {any} EventType
|
||||||
|
* @param {any} EventData
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function Event(EventType, EventData) {
|
||||||
|
if (EventType == UI_EVENT.MOUSEMOTION) {
|
||||||
|
MouseX = EventData[0];
|
||||||
|
MouseY = EventData[1];
|
||||||
|
MouseSprite[CurrentMouseTaskId].SetPos(MouseX, MouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
UI/Windows/System/NotiBox.nut
Normal file
39
UI/Windows/System/NotiBox.nut
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
文件名:NotiBox.nut
|
||||||
|
路径:UI/Windows/System/NotiBox.nut
|
||||||
|
创建日期:2025-10-21 21:50
|
||||||
|
文件用途:
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Window_NotiBox extends GameWindow {
|
||||||
|
testvalue = 666;
|
||||||
|
|
||||||
|
constructor(Name, gX, gY, gWidth, gHeight, gTitleHeight) {
|
||||||
|
base.constructor(Name, gX, gY, gWidth, gHeight, gTitleHeight);
|
||||||
|
|
||||||
|
InitSprite();
|
||||||
|
// InitButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function InitSprite() {
|
||||||
|
local Sp = Sprite("sprite/hud/newantonui.img", 0);
|
||||||
|
Sp.SetBlendMode(1);
|
||||||
|
AddChild(Sp);
|
||||||
|
|
||||||
|
local Textobj = Text("测试文本",0,sq_RGBA(255,255,255,255));
|
||||||
|
AddChild(Textobj);
|
||||||
|
local Textobj2 = Text("测试文本",1,sq_RGBA(255,255,255,255));
|
||||||
|
Textobj2.SetPos(0,50);
|
||||||
|
AddChild(Textobj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function InitButton() {
|
||||||
|
local Btn = GameWidget_BaseButton(40, 40, 56, 24, "sprite/interface/lenheartwindowcommon.img", 12);
|
||||||
|
Btn.OnClick = function(btn){
|
||||||
|
// print(testvalue);
|
||||||
|
print(this);
|
||||||
|
print(btn);
|
||||||
|
}.bindenv(this);
|
||||||
|
AddChild(Btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
78
UI/Windows/Widget/BaseWidget.nut
Normal file
78
UI/Windows/Widget/BaseWidget.nut
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
文件名:BaseWidget.nut
|
||||||
|
路径:UI/Windows/Widget/BaseWidget.nut
|
||||||
|
创建日期:2025-10-21 22:29
|
||||||
|
文件用途:基础控件
|
||||||
|
*/
|
||||||
|
|
||||||
|
class GameWidget_BaseButton extends GameWidget {
|
||||||
|
//按钮状态
|
||||||
|
ButtonState = 0;
|
||||||
|
//Img路径
|
||||||
|
Path = null;
|
||||||
|
//Img索引
|
||||||
|
Idx = null;
|
||||||
|
|
||||||
|
//帧集合
|
||||||
|
FrameList = null;
|
||||||
|
//精灵状态
|
||||||
|
SpriteState = -1;
|
||||||
|
|
||||||
|
//按下时的模拟偏移
|
||||||
|
DownSimulateOffset = true;
|
||||||
|
|
||||||
|
constructor(X, Y, W, H, Path, Idx) {
|
||||||
|
this.Path = Path;
|
||||||
|
this.Idx = Idx;
|
||||||
|
base.constructor(X, Y, W, H);
|
||||||
|
|
||||||
|
FrameList = [];
|
||||||
|
|
||||||
|
//构造4个精灵
|
||||||
|
for (local i = 0; i < 4; i++) {
|
||||||
|
local Buffer = Sprite(this.Path, this.Idx + i);
|
||||||
|
Buffer.SetVisible(false);
|
||||||
|
FrameList.push(Buffer);
|
||||||
|
AddChild(Buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ChangeFrame() {
|
||||||
|
//状态更改 刷新精灵帧
|
||||||
|
if (ButtonState != SpriteState) {
|
||||||
|
//按下时模拟偏移的Flag 如果按下 调整Y坐标向下一个单位
|
||||||
|
if (DownSimulateOffset) {
|
||||||
|
if (ButtonState == 2) {
|
||||||
|
Y += 1;
|
||||||
|
SetPos(X, Y);
|
||||||
|
} else if (SpriteState == 2) {
|
||||||
|
Y -= 1;
|
||||||
|
SetPos(X, Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SpriteState != -1) FrameList[SpriteState].SetVisible(false);
|
||||||
|
SpriteState = ButtonState;
|
||||||
|
FrameList[SpriteState].SetVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Proc(Dt) {
|
||||||
|
//不可用
|
||||||
|
if (ButtonState == 3) {
|
||||||
|
} else {
|
||||||
|
//按下
|
||||||
|
if (isLBDown) {
|
||||||
|
ButtonState = 2;
|
||||||
|
}
|
||||||
|
//悬停
|
||||||
|
else if (isInRect) {
|
||||||
|
ButtonState = 1;
|
||||||
|
}
|
||||||
|
//普通
|
||||||
|
else {
|
||||||
|
ButtonState = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ChangeFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
63
UI/Windows/Widget/NineGridCav.nut
Normal file
63
UI/Windows/Widget/NineGridCav.nut
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
文件名:NineGridCav.nut
|
||||||
|
路径:UI/Windows/Widget/NineGridCav.nut
|
||||||
|
创建日期:2025-10-25 00:35
|
||||||
|
文件用途:九宫格画布
|
||||||
|
*/
|
||||||
|
class GameWidget_NineGridCav extends Canvas {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {string} ImgPath Img路径
|
||||||
|
* @param {integer} ImgStart Img起始索引
|
||||||
|
* @param {integer} Width 总宽度
|
||||||
|
* @param {integer} Height 总高度
|
||||||
|
* @returns {gamewidget_ninegridcav}
|
||||||
|
*/
|
||||||
|
constructor(ImgPath, ImgStart, Width, Height) {
|
||||||
|
//获取九宫格各部分原始尺寸
|
||||||
|
local topLeft = sq_GetPng(ImgPath, ImgStart);
|
||||||
|
local topMid = sq_GetPng(ImgPath, ImgStart + 1);
|
||||||
|
local topRight = sq_GetPng(ImgPath, ImgStart + 2);
|
||||||
|
local midLeft = sq_GetPng(ImgPath, ImgStart + 3);
|
||||||
|
local midMid = sq_GetPng(ImgPath, ImgStart + 4);
|
||||||
|
local midRight = sq_GetPng(ImgPath, ImgStart + 5);
|
||||||
|
local bottomLeft = sq_GetPng(ImgPath, ImgStart + 6);
|
||||||
|
local bottomMid = sq_GetPng(ImgPath, ImgStart + 7);
|
||||||
|
local bottomRight = sq_GetPng(ImgPath, ImgStart + 8);
|
||||||
|
|
||||||
|
//初始化画布尺寸
|
||||||
|
base.constructor(Width, Height);
|
||||||
|
|
||||||
|
//计算中间拉伸区域尺寸
|
||||||
|
local midWidth = Width - topLeft.Width - topRight.Width;
|
||||||
|
local midHeight = Height - topLeft.Height - bottomLeft.Height;
|
||||||
|
|
||||||
|
//绘制左上角
|
||||||
|
DrawImg(ImgPath, ImgStart, 0, 0);
|
||||||
|
|
||||||
|
//绘制上中(横向拉伸)
|
||||||
|
DrawImgRect(ImgPath, ImgStart + 1, topLeft.Width, 0, midWidth, topMid.Height);
|
||||||
|
|
||||||
|
//绘制右上角
|
||||||
|
DrawImg(ImgPath, ImgStart + 2, Width - topRight.Width, 0);
|
||||||
|
|
||||||
|
//绘制左中(纵向拉伸)
|
||||||
|
DrawImgRect(ImgPath, ImgStart + 3, 0, topLeft.Height, midLeft.Width, midHeight);
|
||||||
|
|
||||||
|
//绘制中间(双向拉伸)
|
||||||
|
DrawImgRect(ImgPath, ImgStart + 4, topLeft.Width, topLeft.Height, midWidth, midHeight);
|
||||||
|
|
||||||
|
//绘制右中(纵向拉伸)
|
||||||
|
DrawImgRect(ImgPath, ImgStart + 5, Width - midRight.Width, topLeft.Height, midRight.Width, midHeight);
|
||||||
|
|
||||||
|
//绘制左下角
|
||||||
|
DrawImg(ImgPath, ImgStart + 6, 0, Height - bottomLeft.Height);
|
||||||
|
|
||||||
|
//绘制下中(横向拉伸)
|
||||||
|
DrawImgRect(ImgPath, ImgStart + 7, topLeft.Width, Height - bottomMid.Height, midWidth, bottomMid.Height);
|
||||||
|
|
||||||
|
//绘制右下角
|
||||||
|
DrawImg(ImgPath, ImgStart + 8, Width - bottomRight.Width, Height - bottomRight.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
UI/Windows/Widget/TripleCav.nut
Normal file
30
UI/Windows/Widget/TripleCav.nut
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
文件名:TripleCav.nut
|
||||||
|
路径:UI/Windows/Widget/TripleCav.nut
|
||||||
|
创建日期:2025-10-24 23:15
|
||||||
|
文件用途:三联画布
|
||||||
|
*/
|
||||||
|
class GameWidget_TripleCav extends Canvas {
|
||||||
|
/**
|
||||||
|
* 创建三联图画布
|
||||||
|
* @function
|
||||||
|
* @param {string} ImgPath Img路径
|
||||||
|
* @param {integer} ImgStart Img起始索引
|
||||||
|
* @param {integer} Width 总宽度
|
||||||
|
* @returns {gamewidget_triplecav}
|
||||||
|
*/
|
||||||
|
constructor(ImgPath, ImgStart, Width) {
|
||||||
|
local Left_Width = sq_GetPng(ImgPath, ImgStart).Width;
|
||||||
|
local Height = sq_GetPng(ImgPath, ImgStart).Height;
|
||||||
|
local Right_Width = sq_GetPng(ImgPath, ImgStart + 2).Width;
|
||||||
|
|
||||||
|
base.constructor(Width, Height);
|
||||||
|
|
||||||
|
//绘制左侧
|
||||||
|
DrawImg(ImgPath, ImgStart, 0, 0);
|
||||||
|
//绘制中间
|
||||||
|
DrawImgRect(ImgPath, ImgStart + 1, Left_Width, 0, Width - Left_Width - Right_Width, Height);
|
||||||
|
//绘制右侧
|
||||||
|
DrawImg(ImgPath, ImgStart + 2, Width - Right_Width, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
88
enum.nut
88
enum.nut
@@ -6,22 +6,72 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
enum CHARACTERJOB {
|
enum CHARACTERJOB {
|
||||||
SWORDMAN // 男鬼剑士
|
/**男鬼剑士 */
|
||||||
FIGHTER // 女格斗家
|
SWORDMAN,
|
||||||
GUNNER // 男神枪手
|
/**女格斗家 */
|
||||||
MAGE // 女魔法师
|
FIGHTER,
|
||||||
PRIEST // 男圣职者
|
/**男神枪手 */
|
||||||
AT_GUNNER // 女神枪手
|
GUNNER,
|
||||||
THIEF // 暗夜使者
|
/**女魔法师 */
|
||||||
AT_FIGHTER // 男格斗家
|
MAGE,
|
||||||
AT_MAGE // 男魔法师
|
/**男圣职者 */
|
||||||
DEMONIC_SWORDMAN // 黑暗武士
|
PRIEST,
|
||||||
CREATOR_MAGE // 缔造者
|
/**女神枪手 */
|
||||||
AT_SWORDMAN // 女鬼剑士
|
AT_GUNNER,
|
||||||
KNIGHT // 守护者
|
/**暗夜使者 */
|
||||||
DEMONIC_LANCER // 魔枪士
|
THIEF,
|
||||||
AT_PRIEST // 女圣职者
|
/**男格斗家 */
|
||||||
GUN_BLADER // 枪剑士
|
AT_FIGHTER,
|
||||||
ARCHER // 弓箭手
|
/**男魔法师 */
|
||||||
MAX // 无
|
AT_MAGE,
|
||||||
};
|
/**黑暗武士 */
|
||||||
|
DEMONIC_SWORDMAN,
|
||||||
|
/**缔造者 */
|
||||||
|
CREATOR_MAGE,
|
||||||
|
/**女鬼剑士 */
|
||||||
|
AT_SWORDMAN,
|
||||||
|
/**守护者 */
|
||||||
|
KNIGHT,
|
||||||
|
/**魔枪士 */
|
||||||
|
DEMONIC_LANCER,
|
||||||
|
/**女圣职者 */
|
||||||
|
AT_PRIEST,
|
||||||
|
/**枪剑士 */
|
||||||
|
GUN_BLADER,
|
||||||
|
/**弓箭手 */
|
||||||
|
ARCHER,
|
||||||
|
/**无 */
|
||||||
|
MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UI_EVENT {
|
||||||
|
/**鼠标移动 */
|
||||||
|
MOUSEMOTION,
|
||||||
|
/**鼠标按下 */
|
||||||
|
MOUSEBUTTONDOWN,
|
||||||
|
/**鼠标释放 */
|
||||||
|
MOUSEBUTTONUP,
|
||||||
|
/**鼠标滚轮 */
|
||||||
|
MOUSEWHEEL,
|
||||||
|
/**键盘按下 */
|
||||||
|
KEYDOWN,
|
||||||
|
/**键盘释放 */
|
||||||
|
KEYUP
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BLENDMODE {
|
||||||
|
/**无 */
|
||||||
|
BLENDMODE_NONE,
|
||||||
|
/**线性减淡 */
|
||||||
|
BLENDMODE_LINEARDODGE,
|
||||||
|
/**减淡 */
|
||||||
|
BLENDMODE_DODGE,
|
||||||
|
/**变暗 */
|
||||||
|
BLENDMODE_DARK,
|
||||||
|
/**异或 */
|
||||||
|
BLENDMODE_XOR,
|
||||||
|
/**灰度模式 */
|
||||||
|
BLENDMODE_MONOCHROME,
|
||||||
|
/**扭曲 */
|
||||||
|
BLENDMODE_SPACE_DISTORT
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,5 +31,62 @@
|
|||||||
},
|
},
|
||||||
"UI/MainUI.nut": {
|
"UI/MainUI.nut": {
|
||||||
"description": "UI入口"
|
"description": "UI入口"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass": {
|
||||||
|
"description": "对象类"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/Actor.nut": {
|
||||||
|
"description": "演员类"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/Sprite.nut": {
|
||||||
|
"description": "精灵类"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/BaseNode.nut": {
|
||||||
|
"description": "基础节点"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/WindowNode.nut": {
|
||||||
|
"description": "窗口节点"
|
||||||
|
},
|
||||||
|
"UI/Windows": {
|
||||||
|
"description": "窗口集合"
|
||||||
|
},
|
||||||
|
"UI/Windows/HUD": {
|
||||||
|
"description": "血槽"
|
||||||
|
},
|
||||||
|
"UI/Windows/HUD/Window_hud.nut": {
|
||||||
|
"description": "血槽窗口"
|
||||||
|
},
|
||||||
|
"Tool": {
|
||||||
|
"description": "工具类"
|
||||||
|
},
|
||||||
|
"UI/Windows/System": {
|
||||||
|
"description": "系统"
|
||||||
|
},
|
||||||
|
"UI/Windows/System/Cursor.nut": {
|
||||||
|
"description": "鼠标"
|
||||||
|
},
|
||||||
|
"UI/Windows/Widget": {
|
||||||
|
"description": "控件"
|
||||||
|
},
|
||||||
|
"UI/Windows/Widget/BaseWidget.nut": {
|
||||||
|
"description": "基础控件"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/GameWidget.nut": {
|
||||||
|
"description": "游戏_控件类"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/GameWindow.nut": {
|
||||||
|
"description": "游戏_窗口类"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/Canvas.nut": {
|
||||||
|
"description": "画布类"
|
||||||
|
},
|
||||||
|
"UI/Windows/Widget/TripleCav.nut": {
|
||||||
|
"description": "三联图画布"
|
||||||
|
},
|
||||||
|
"UI/Windows/Widget/NineGridCav.nut": {
|
||||||
|
"description": "九宫格画布"
|
||||||
|
},
|
||||||
|
"UI/ObjectClass/Text.nut": {
|
||||||
|
"description": "文本类"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {any} C_Object
|
* @param {any} C_Object
|
||||||
* @param {integer} state
|
* @param {integer} state 状态编号
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function sq_SetState(C_Object, state) {}
|
function sq_SetState(C_Object, state) {}
|
||||||
@@ -11,8 +11,7 @@ function sq_SetState(C_Object, state) {}
|
|||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {any} C_Object
|
* @param {any} C_Object
|
||||||
* @param {any} key
|
* @param {string} key 动作名称
|
||||||
*
|
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function sq_SetAction(C_Object, key) {}
|
function sq_SetAction(C_Object, key) {}
|
||||||
@@ -59,8 +58,8 @@ function sq_SetPosition(C_Object, x, y, z) {}
|
|||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {any} C_Object
|
* @param {any} C_Object
|
||||||
* @param {string} Name
|
* @param {string} Name 储存器名称
|
||||||
* @param {any} Type
|
* @param {string} Type 数据类型(int,float,string,bool)
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function sq_GetVars(C_Object, Name, Type) {}
|
function sq_GetVars(C_Object, Name, Type) {}
|
||||||
@@ -69,8 +68,8 @@ function sq_GetVars(C_Object, Name, Type) {}
|
|||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {any} C_Object
|
* @param {any} C_Object
|
||||||
* @param {string} Name
|
* @param {string} Name 储存器名称
|
||||||
* @param {any} Type
|
* @param {string} Type 数据类型(int,float,string,bool)
|
||||||
* @param {any} Value
|
* @param {any} Value
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
@@ -82,14 +81,68 @@ function sq_SetVars(C_Object, Name, Type, Value) {}
|
|||||||
* @param {any} C_Object
|
* @param {any} C_Object
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function sq_GetDirection(C_Object) {
|
function sq_GetDirection(C_Object) {}
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {any} C_Object
|
* @param {any} C_Object
|
||||||
* @param {integer} Dir
|
* @param {integer} Dir 方向(0左 1右)
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function sq_SetDirection(C_Object, Dir) {}
|
function sq_SetDirection(C_Object, Dir) {}
|
||||||
|
|
||||||
|
function sq_CreateActor() {}
|
||||||
|
function sq_RegisterDestruction(a, b) {}
|
||||||
|
function sq_CreateSprite(a, b) {}
|
||||||
|
function sq_CreateCanvas(a, b) {}
|
||||||
|
function sq_CreateText(a, b, c) {}
|
||||||
|
function sq_AddChild(a, b) {}
|
||||||
|
function sq_RemoveChild(a, b) {}
|
||||||
|
function sq_SetZOrder(a, b) {}
|
||||||
|
|
||||||
|
function sq_SetPos(a, ...) {}
|
||||||
|
function sq_SetScale(a, ...) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {any} a
|
||||||
|
* @param {any} b
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
function pow(a, b) {}
|
||||||
|
|
||||||
|
function sq_GetWorldPos(a) {
|
||||||
|
local t = { x = 1, y = 1 };
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
function sq_SetVisible(a, b) {}
|
||||||
|
function sq_SetAlpha(a, b) {}
|
||||||
|
function sq_SetName(a, b) {}
|
||||||
|
function sq_SetSize(...) {}
|
||||||
|
function sq_SetRotation(a, b) {}
|
||||||
|
function sq_GetName(a) {}
|
||||||
|
function sq_GetVisible(a) {}
|
||||||
|
function sq_GetSize(a) {
|
||||||
|
local t = { x = 1, y = 1 };
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
function sq_GetRotation(a) {}
|
||||||
|
function sq_GetAlpha(a) {}
|
||||||
|
function sq_GetScale(a) {
|
||||||
|
local t = { x = 1, y = 1 };
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
function sq_GetZOrder(a) {}
|
||||||
|
function sq_SetBlendMode(a, b) {}
|
||||||
|
function sq_Canvas_DrawImg(a, b, c, d) {}
|
||||||
|
function sq_Canvas_DrawImgRect(a, b, c, d) {}
|
||||||
|
function sq_GetImg(a) {}
|
||||||
|
function sq_GetPng(a, b) {}
|
||||||
|
function sq_OutPutTable(...) {}
|
||||||
|
|
||||||
|
function sq_GetPos(a) {
|
||||||
|
local t = { x = 1, y = 1 };
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
function output(...) {}
|
||||||
|
|||||||
11
main.nut
11
main.nut
@@ -1,4 +1,15 @@
|
|||||||
|
function _InitFont_() {
|
||||||
|
return [
|
||||||
|
{ path = "Fonts/VonwaonBitmap-12px.ttf", size = 12 },
|
||||||
|
{ path = "Fonts/VonwaonBitmap-12px.ttf", size = 24 },
|
||||||
|
{ path = "Fonts/NotoSansSC-Light.otf", size = 12 }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
//初始化随机数种子
|
||||||
|
srand(time());
|
||||||
|
|
||||||
local SM = StateMachine.GetInstance();
|
local SM = StateMachine.GetInstance();
|
||||||
|
|
||||||
SM.RegisterState(CHARACTERJOB.SWORDMAN, "Character_Rest", 0);
|
SM.RegisterState(CHARACTERJOB.SWORDMAN, "Character_Rest", 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user