runOnStartup(async runtime =>
{
// This code runs on startup with
// the 'runtime' variable available
});
runOnStartup(async runtime =>
{
runtime.addEventListener("beforeprojectstart", () => OnBeforeProjectStart(runtime));
});
async function OnBeforeProjectStart(runtime)
{
runtime.addEventListener("tick", () => Tick(runtime));
}
function Tick(runtime)
{
// Code to run every tick
}
{"is-c3-clipboard-data":true,"type":"events","items":[{"functionName":"hasAnimation","functionDescription":"","functionCategory":"","functionReturnType":"number","functionCopyPicked":false,"functionIsAsync":false,"functionParameters":[{"name":"objectType","type":"string","initialValue":"","comment":""},{"name":"name","type":"string","initialValue":"","comment":""}],"eventType":"function-block","conditions":[],"actions":[{"type":"script","script":"runtime.setReturnValue(runtime.objects[localVars.objectType].getAllAnimations().some(a => a.name.includes(localVars.name)) ? 1 : 0);"}]}]}
{"is-c3-clipboard-data":true,"type":"events","items":[{"functionName":"hasLayoutName","functionDescription":"","functionCategory":"","functionReturnType":"number","functionCopyPicked":false,"functionIsAsync":false,"functionParameters":[{"name":"name","type":"string","initialValue":"","comment":""}],"eventType":"function-block","conditions":[],"actions":[{"type":"script","script":"try {\n runtime.getLayout(localVars.name);\n runtime.setReturnValue(1);\n} catch (error) {\n runtime.setReturnValue(0);\n}"}]}]}
方法二: 遍历所有对象
{"is-c3-clipboard-data":true,"type":"events","items":[{"functionName":"hasLayoutName","functionDescription":"","functionCategory":"","functionReturnType":"number","functionCopyPicked":false,"functionIsAsync":false,"functionParameters":[{"name":"name","type":"string","initialValue":"","comment":""}],"eventType":"function-block","conditions":[],"actions":[{"type":"script","script":"const result = +runtime.getAllLayouts().some(({ name }) => name.includes(localVars.name));\n\nruntime.setReturnValue(result);"}]}]}
{"is-c3-clipboard-data":true,"type":"events","items":[{"functionName":"getEffectParameter","functionDescription":"","functionCategory":"","functionReturnType":"any","functionCopyPicked":false,"functionIsAsync":false,"functionParameters":[{"name":"UID","type":"number","initialValue":"0","comment":""},{"name":"effectName","type":"string","initialValue":"","comment":""},{"name":"parameterIndex","type":"number","initialValue":"0","comment":""}],"eventType":"function-block","conditions":[],"actions":[{"type":"script","script":"const inst = runtime.getInstanceByUid(localVars.UID);\n\nconst effect = inst.effects.find(e => e.name === localVars.effectName);\n\nif (!effect) return;\n\nconst param = effect.getParameter(localVars.parameterIndex);\n\nconst result = Array.isArray(param) ? param.map(v => Math.round(v * 255)).join(',') : param * 100;\n\nruntime.setReturnValue(result);"}]}]}
StringSub("{0} objects | {1} FPS | {2}% CPU | {3}% GPU | {4}", objectcount,PlatformInfo.TicksPerSecond, roundToDp(cpuutilisation*100,1), roundToDp(gpuutilisation*100,1), PlatformInfo.Renderer)
{"is-c3-clipboard-data":true,"type":"events","items":[{"functionName":"expDecay","functionDescription":"","functionCategory":"","functionReturnType":"number","functionCopyPicked":false,"functionIsAsync":false,"functionParameters":[{"name":"a","type":"number","initialValue":"0","comment":""},{"name":"b","type":"number","initialValue":"1","comment":""},{"name":"decay","type":"number","initialValue":"16","comment":"1-25"}],"eventType":"function-block","conditions":[],"actions":[{"id":"set-function-return-value","objectClass":"Functions","parameters":{"value":"b + (a-b) * exp(-decay*dt)"}}]}]}
发送信号
runtime.signal("tag");
等待信号
runtime.waitForSignal("tag");
用脚本获取全局变量。直接对它进行赋值操作也是可以的。
runtime.globalVars.Variable1
在事件条范围内,用脚本获取本地变量。备注,函数的传入参数(`Function parameter`) 也是通过它来获取。
localVars.Variable2
提示,在某些情况下,变量名称可能不是有效的标识符,例如可能跟保留关键字冲突了。此时你还可以用字符串来引用这个变量。
runtime.globalVars["Variable1"]
localVars["Variable2"]
instVars["Variable3"]
调用事件表的自定义函数
调用函数
runtime.callFunction("add", 1)
设置函数返回值
runtime.setReturnValue(value);
获取函数的参数
localVars.Parameter0
解构赋值
const { a, b } = localVars;
在 HTML 调用 C3 Function
c3_callFunction("Function1");
通过字符串调用函数
const function = "AddValue, 123, ABC"
runtime.callFunction(...localVars["command"]
.split(",").map(e => e.trim()))
.map(e => (isNaN(e) ? e : Number(e)))
);
触发事件
const event = C3.Event("")
const object = runtime.objects.Sprite.getFirstInstance();
object.dispatchEvent(event);
按UID挑选
runtime.getInstanceByUid();
按名称挑选
runtime.objects["Sprite"];
获取第一个实例对象(First Instance Object)
runtime.objects.Sprite.getFirstInstance()
获取所有实例对象(All Instances objects)
runtime.objects.Sprite.getAllInstances()
获取实例对象的实例变量
const player = runtime.objects.Sprite.getFirstInstance();
const score = player.instVars["Score"];
// console.log(score)
获取实例对象的滤镜参数
这里封装了一个 function,返回 any 类型。带有 3 个参数: UID, effectName, parameterIndexconst inst = runtime.getInstanceByUid(localVars.UID);
const effect = inst.effects.find(e => e.name === localVars.effectName);
if (!effect) return;
const param = effect.getParameter(localVars.parameterIndex);
const result = Array.isArray(param) ? param.map(v => Math.round(v * 255)).join(',') : param;
runtime.setReturnValue(result);
{"is-c3-clipboard-data":true,"type":"events","items":[{"functionName":"getEffectParameter","functionDescription":"","functionCategory":"","functionReturnType":"any","functionCopyPicked":false,"functionIsAsync":false,"functionParameters":[{"name":"UID","type":"number","initialValue":"0","comment":""},{"name":"effectName","type":"string","initialValue":"","comment":""},{"name":"parameterIndex","type":"number","initialValue":"0","comment":""}],"eventType":"function-block","conditions":[],"actions":[{"type":"script","script":"const inst = runtime.getInstanceByUid(localVars.UID);\n\nconst effect = inst.effects.find(e => e.name === localVars.effectName);\n\nif (!effect) return;\n\nconst param = effect.getParameter(localVars.parameterIndex);\n\nconst result = Array.isArray(param) ? param.map(v => Math.round(v * 255)).join(',') : param;\n\nruntime.setReturnValue(result);"}]}]}
更改实例对象的滤镜参数
const player = runtime.objects.Sprite.getFirstInstance();
player.effects[0].setParameter(0, 100);
获取实例对象的行为属性(Instance behaviors)
const player = runtime.objects.Sprite.getFirstInstance();
const playerBehavior = player.behaviors.Platform;
// console.log(playerBehavior.maxSpeed)
在某些情况下,有些名称可能不是有效的标识符,此时,还可以用字符串来引用。
instance.behaviors["8Direction"]["maxSpeed"]
遍历所有实例对象的实例变量
遍历所有 Sprite 对象的实例变量 Score,同时销毁所有变量小于 60 的实例。for (const obj of runtime.objects.Sprite.instances())
{
const score = obj.instVars["Score"];
if (score <= 60)
{
obj.destroy();
}
}
在某些情况下,有些名称可能不是有效的标识符,此时,还可以用字符串来引用。
const textObject = runtime.objects.Text;
const textInstance = textObject.getFirstPickedInstance();
textInstance.text = "Hello World"
也可以通过 filter来实现条件筛选。
例如下方的代码,用于选出布尔型 foobar 是开启状态下 obj 实例对象。
const instances = runtime.objects.Sprite.getAllInstances();
const picked = instances.filter(obj => obj.instVars.foobar); // filter based on instance Variable
获取所有满足条件的实例
// 获取所有 Sprite 实例
const instances = runtime.objects.Sprite.getAllInstances();
// 使用筛选逻辑过滤实例
const picked = instances.filter(obj => {
const score = obj.instVars["Score"]; // 获取每个实例的分数
return score <= 60; // 返回分数小于或等于60的实例
});
获取碰撞框
const instance = runtime.objects.Sprite.getFirstInstance();
console.log(instance.getBoundingBox())
检测对象是否可以被另一个对象完全重叠
for (const inst of runtime.objects.Sprite.pickedInstances()) {
const instBBox = inst.getBoundingBox();
const candidates = runtime.collisions.getCollisionCandidates(runtime.objects.Sprite2, instBBox)
for (const candidateInst of candidates) {
const candidateBBox = candidateInst.getBoundingBox();
if (candidateBBox.left <= instBBox.left && candidateBBox.right >= instBBox.right && candidateBBox.top <= instBBox.top && candidateBBox.bottom >= instBBox.bottom) {
inst.destroy()
}
}
}
const textObject = runtime.objects.Text;
const textInstance = textObject.getFirstPickedInstance();
textInstance.text = "Hello World"
}
在脚本中代替事件表AJAX加载文件的操作。
async function OnBeforeProjectStart(runtime)
{
const InfoData = await runtime.assets.fetchJson('info.json')
runtime.objects.JSON.getFirstInstance().setJsonDataCopy(InfoData);
}
}
const response = await fetch("file.json");
const myJson = await response.json();
console.log("Fetched JSON: ", myJson);
const dataInst = runtime.objects.JSON.getFirstInstance();
const data = dataInst.getJsonDataCopy();
console.log(data['Name'])
const dataInst = runtime.objects.JSON.getFirstInstance();
const data = dataInst.getJsonDataCopy();
data.name = localVars.name;
dataInst.setJsonDataCopy(filterItems);
const myArray = runtime.objects.Array.getFirstInstance();
myArray.setAt(0, 1)
console.log(myArray.getAt(0, 0))
const myData = runtime.objects.Dictionary.getFirstInstance().getDataMap();
console.log(MyData.get('Key'))
遍历字典数据
const data = runtime.objects.Dictionary.getFirstInstance().getDataMap();
for (const [key, value] of data) {
console.log(`${key}: ${value}`);
}
const array = JSON.parse(localVars.arrayJson);
const [width, height, depth] = array["size"];
array["size"] = [height, width, depth];
array["data"] = array["data"][0].map((_, y) => array["data"].map(row => row[y]));
runtime.setReturnValue(JSON.stringify(array));
将C3的Array文件转换成JSON
在一个 Function 中的脚本块,Function 带有一个 String 类型的参数 c3ArrayFile
,用于从在 AJAX 加载 Array文件时,将 AJAX.LastData 数据传入到这个 Function 中。
Function 具有 String 类型的返回值,传出的是一个可被解析为 JSON 的字符串,用于在 JSON 对象中使用 Parse JSON string 动作时,使用 Functions.convertC3ArrayToJson(AJAX.LastData) 进行解析。
const { size, data } = JSON.parse(localVars.c3ArrayFile);
const [, totalRows] = size;
let output = [];
const columnHeaders = data.map(column => column[0][0].trim());
for (let rowIndex = 1; rowIndex < totalRows; rowIndex++) {
let rowObject = {};
columnHeaders.forEach((header, columnIndex) => {
if (!header) return;
let cellValue = data[columnIndex][rowIndex][0];
rowObject[header] = typeof cellValue === 'string' ? cellValue.trim() : cellValue;
});
if (Object.values(rowObject).some(value => value !== "")) {
output.push(rowObject);
}
}
runtime.setReturnValue(JSON.stringify(output));
globalThis.Variable1 = 1
// getMousePosition(layer);
const [mouseX, mouseY] = runtime.mouse.getMousePosition(0);
const keyboard = runtime.keyboard;
if (keyboard.isKeyDown("ArrowRight"))
{
player.x += playerSpeed * dt;
player.angleDegrees = 0;
}
屏蔽特定按键
window.addEventListener("keydown", e =>
{
if (e.key === "Tab")
e.preventDefault();
});
const randInt = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
// 例子
let a = randInt(1, 10); // 生成 1 到 10 之间的随机整数
let b = randInt(50, 100); // 生成 50 到 100 之间的随机整数
let c = randInt(-10, 10); // 生成 -10 到 10 之间的随机整数
console.log(c);