+10 Red Bones 修两处:①每建一根等一帧(编辑器下一帧才真建,同帧连调只生效一次)②颜色按映射表写 Gp 的 color 字段(混淆名 B),不再取'第一个 Color 字段'
This commit is contained in:
1 parent
b09a7e0659
commit
4000a06d61
1 file changed
+45
-23
@@ -636,41 +636,57 @@ public final class ObjectPanel {
|
|||||||
* 建用编辑器自己的 New Bone(带撤销),建完立刻改该骨骼的 x/y 与 color 字段。
|
* 建用编辑器自己的 New Bone(带撤销),建完立刻改该骨骼的 x/y 与 color 字段。
|
||||||
*/
|
*/
|
||||||
private static void createTenRedBones(final State state) {
|
private static void createTenRedBones(final State state) {
|
||||||
SceneActions.onEditorThread(state.loader, new Runnable() {
|
// ⚠️ 不能整段放在 render 线程里连着调:编辑器是"下一帧"才真正建骨骼的,
|
||||||
@Override
|
// 同一帧连续调 10 次只会生效一次。所以每建一根 -> 回到本线程等一帧 -> 再建下一根。
|
||||||
public void run() {
|
final Object parent = currentTarget(state);
|
||||||
// 父级取"编辑器里的当前选择"(用户是在层级面板里选的,不是点我们列表行)
|
|
||||||
Object parent = currentTarget(state);
|
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
setStatus(state, "+10 Red Bones: select a parent bone first.");
|
setStatus(state, "+10 Red Bones: select a parent bone first.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final Object red;
|
||||||
try {
|
try {
|
||||||
Class<?> colorClass = Class.forName("com.badlogic.gdx.graphics.Color", true, state.loader);
|
Class<?> colorClass = Class.forName("com.badlogic.gdx.graphics.Color", true, state.loader);
|
||||||
Object red = colorClass.getConstructor(float.class, float.class, float.class,
|
red = colorClass.getConstructor(float.class, float.class, float.class, float.class)
|
||||||
float.class).newInstance(Float.valueOf(1f), Float.valueOf(0f), Float.valueOf(0f),
|
.newInstance(Float.valueOf(1f), Float.valueOf(0f), Float.valueOf(0f), Float.valueOf(1f));
|
||||||
Float.valueOf(1f));
|
} catch (Throwable error) {
|
||||||
|
setStatus(state, "+10 Red Bones: 造红色失败 " + error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
int made = 0;
|
int made = 0;
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
java.util.List<Object> before = SceneObjects.listAllNodes(state.loader);
|
final float x = (float) (Math.random() * 400.0 - 200.0);
|
||||||
|
final float y = (float) (Math.random() * 400.0 - 200.0);
|
||||||
|
final int[] ok = new int[1];
|
||||||
|
final java.util.List<Object> before = listQuietly(state);
|
||||||
|
SceneActions.onEditorThread(state.loader, new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
SceneActions.create(state.loader, parent, "Bone");
|
SceneActions.create(state.loader, parent, "Bone");
|
||||||
Object fresh = firstNew(before, SceneObjects.listAllNodes(state.loader));
|
Object fresh = firstNew(before, listQuietly(state));
|
||||||
if (fresh == null) continue;
|
if (fresh == null) return;
|
||||||
float x = (float) (Math.random() * 400.0 - 200.0);
|
|
||||||
float y = (float) (Math.random() * 400.0 - 200.0);
|
|
||||||
setBoneNumber(fresh, "x", x);
|
setBoneNumber(fresh, "x", x);
|
||||||
setBoneNumber(fresh, "y", y);
|
setBoneNumber(fresh, "y", y);
|
||||||
setBoneColor(fresh, red);
|
setBoneColor(fresh, red);
|
||||||
made++;
|
ok[0] = 1;
|
||||||
}
|
|
||||||
setStatus(state, "made " + made + " red bones under " + SceneObjects.nameOf(parent));
|
|
||||||
} catch (Throwable error) {
|
|
||||||
setStatus(state, "+10 Red Bones failed: " + error);
|
|
||||||
error.printStackTrace(System.err);
|
|
||||||
}
|
|
||||||
refreshList(state);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
made += ok[0];
|
||||||
|
try {
|
||||||
|
Thread.sleep(180); // 等编辑器过一帧,下一根才会真的建出来
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setStatus(state, "made " + made + " red bones under " + SceneObjects.nameOf(parent));
|
||||||
|
refreshList(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static java.util.List<Object> listQuietly(State state) {
|
||||||
|
try {
|
||||||
|
return SceneObjects.listAllNodes(state.loader);
|
||||||
|
} catch (Throwable error) {
|
||||||
|
return new ArrayList<Object>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 前后列表对比,取第一个新出现的对象。 */
|
/** 前后列表对比,取第一个新出现的对象。 */
|
||||||
@@ -707,18 +723,24 @@ public final class ObjectPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 骨骼颜色:找类型是 libGDX Color 的字段写进去。 */
|
/**
|
||||||
|
* 骨骼颜色:按映射表写 `Gp` 的 color 字段(混淆名 B,描述符 Lcom/badlogic/gdx/graphics/Color;)。
|
||||||
|
* 表里查不到时才退回"第一个 Color 类型字段"。
|
||||||
|
*/
|
||||||
private static void setBoneColor(Object bone, Object color) {
|
private static void setBoneColor(Object bone, Object color) {
|
||||||
try {
|
try {
|
||||||
|
String obf = obfNameOf("Gp", "Lcom/badlogic/gdx/graphics/Color;", "color");
|
||||||
for (Class<?> type = bone.getClass(); type != null && type != Object.class;
|
for (Class<?> type = bone.getClass(); type != null && type != Object.class;
|
||||||
type = type.getSuperclass()) {
|
type = type.getSuperclass()) {
|
||||||
for (java.lang.reflect.Field field : type.getDeclaredFields()) {
|
for (java.lang.reflect.Field field : type.getDeclaredFields()) {
|
||||||
if (!field.getType().getName().equals("com.badlogic.gdx.graphics.Color")) continue;
|
if (field.getType().getName().equals("com.badlogic.gdx.graphics.Color")) {
|
||||||
|
if (obf != null && !field.getName().equals(obf)) continue;
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
field.set(bone, color);
|
field.set(bone, color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Throwable error) {
|
} catch (Throwable error) {
|
||||||
System.err.println("[panel] 设置颜色失败: " + error);
|
System.err.println("[panel] 设置颜色失败: " + error);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user