/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package GUI;
import CameraAndMouse.CamAndMouseCur;
import CameraAndMouse.SelectUnit;
import SelectUnit.UnitGlobalData;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import static com.jme3.app.SimpleApplication.INPUT_MAPPING_EXIT;
import com.jme3.app.StatsAppState;
import com.jme3.app.StatsView;
import com.jme3.app.state.BaseAppState;
import com.jme3.app.state.ScreenshotAppState;
import com.jme3.asset.AssetManager;
import com.jme3.asset.DesktopAssetManager;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.export.binary.BinaryExporter;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;
import com.jme3.util.BufferUtils;
import com.simsilica.lemur.Axis;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Checkbox;
import com.simsilica.lemur.Command;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.FillMode;
import com.simsilica.lemur.GridPanel;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Insets3f;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.LayerComparator;
import com.simsilica.lemur.Panel;
import com.simsilica.lemur.PasswordField;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.event.CursorButtonEvent;
import com.simsilica.lemur.event.CursorEventControl;
import com.simsilica.lemur.event.CursorMotionEvent;
import com.simsilica.lemur.event.DefaultCursorListener;
import com.simsilica.lemur.event.MouseEventControl;
import static com.simsilica.lemur.focus.FocusNavigationFunctions.F_ACTIVATE;
import com.simsilica.lemur.input.AnalogFunctionListener;
import com.simsilica.lemur.input.FunctionId;
import com.simsilica.lemur.input.InputMapper;
import com.simsilica.lemur.input.InputState;
import com.simsilica.lemur.input.StateFunctionListener;
import com.simsilica.lemur.style.Attributes;
import com.simsilica.lemur.style.BaseStyles;
import com.simsilica.lemur.style.Styles;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import mygame.Main;
import static scenario.scenarioState.mapGrid3D;
/**
* 游戏UI部分
*
* @author Icyboxs
*/
public class UI extends BaseAppState implements AnalogFunctionListener, StateFunctionListener{
private static Logger log = Logger.getLogger(UI.class.toString());
private InputManager inputManager;
private InputMapper inputMapper;
private AssetManager assetManager;
private SimpleApplication simpleApp;
private BitmapFont font;
private Camera cam;
private Node iMap = new Node("miniMap");
private Node info = new Node("infowindow");
private Node directive = new Node("directive");
private Node checkboxUI= new Node("checkboxUI");
private BitmapText bt;
private ViewPort vp;
private Quaternion camQuaternion = new Quaternion();
private CollisionResults results = new CollisionResults();
private CollisionResults iresults = new CollisionResults();
float[] vertices = new float[4 * 3];
short[] indices = {0, 1, 2, 3, 0};
private Mesh mesh = new Mesh();
private Camera cam4;
private float CamLeftMax = mapGrid3D.getXLength() - (mapGrid3D.getXLength() * 0.1f);
private float CamRightMin = mapGrid3D.getXLength() * 0.1f;
private float CamUpMax = mapGrid3D.getZWidth() - (mapGrid3D.getZWidth() * 0.1f);
private float CamBackwardMin = -(mapGrid3D.getZWidth() * 0.01f);
public static final FunctionId FidQ = new FunctionId("KEY", "Q");
@Override
protected void initialize(Application aplctn) {
simpleApp = (SimpleApplication) aplctn;
assetManager = aplctn.getAssetManager();
inputManager = aplctn.getInputManager();
inputManager.deleteMapping(INPUT_MAPPING_EXIT);
cam = simpleApp.getCamera();
GuiGlobals.initialize(simpleApp);
if( inputMapper == null ){
inputMapper = GuiGlobals.getInstance().getInputMapper();
}
inputMapper.map( FidQ,KeyInput.KEY_Q);
StatsAppState statsState = simpleApp.getStateManager().getState(StatsAppState.class);
BitmapText fps = statsState.getFpsText();
StatsView stats = statsState.getStatsView();
fps.setLocalTranslation(0, cam.getHeight(), 0);
fps.setColor(ColorRGBA.Blue);
stats.setLocalTranslation(0, cam.getHeight() - 165, 0);
//simpleApp.getRootNode().attachChild(MapUIBox);
// Setup fourth view
float farPlane = 4096.0f;
cam4 = cam.clone();
//调整这里增加便宜了可以调整Texture2D texture的边距
cam4.setViewPort(0, (cam.getWidth() / 4f) / cam.getWidth(), 0, (cam.getWidth() / 4f) / cam.getWidth());
cam4.setLocation(new Vector3f(1024, 300, 1024));
camQuaternion = camQuaternion.fromAngleAxis(90 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X);
cam4.setRotation(cam4.getRotation().set(camQuaternion));
cam4.setFrustumFar(farPlane);
float frustumScale = 8;
cam4.setFrustumLeft(cam4.getFrustumLeft() * frustumScale);
cam4.setFrustumRight(cam4.getFrustumRight() * frustumScale);
cam4.setFrustumTop(cam4.getFrustumTop() * frustumScale);
cam4.setFrustumBottom(cam4.getFrustumBottom() * frustumScale);
cam4.resize(cam.getHeight(), cam.getHeight(), true);
System.out.println(cam4.getWidth() + "," + cam4.getHeight() + "--cam4");
//vp = simpleApp.getRenderManager().createMainView("Top Right", cam4);
vp = simpleApp.getRenderManager().createPreView("MiniMapCam", cam4);
vp.setBackgroundColor(ColorRGBA.Blue);
vp.setClearFlags(true, true, true);
vp.attachScene(simpleApp.getRootNode().getChild("MapNode"));
vp.attachScene(Main.MapUIBox);
//simpleApp.getRootNode().attachChild(Main.MapUIBox);
// simpleApp.getViewPort().detachScene(simpleApp.getRootNode());
// simpleApp.getViewPort().attachScene(simpleApp.getRootNode().getChild("MapNode"));
//
// for (int i = 0; i < simpleApp.getRootNode().getChildren().size(); i++) {
// System.out.println(simpleApp.getRootNode().getChild(i));
// simpleApp.getViewPort().attachScene(simpleApp.getRootNode().getChild(i));
// }
// simpleApp.getViewPort().detachScene(MapUIBox);
// simpleApp.getViewPort().detachScene(simpleApp.getRootNode().getChild("quadBox"));
//Object Url = assetManager.loadAsset("Textures/UI/myCoolStyle.groovy");
// Texture t1= assetManager.loadTexture("Textures/UI/Steampunk_UI_Buttons_1.png");
// BaseStyles.loadStyleResources("groovy/glass-styles.groovy");
BaseStyles.loadStyleResources("/Textures/UI/myCoolStyle.groovy");
GuiGlobals.getInstance().getStyles().setDefaultStyle("myglass");
// BaseStyles.loadGlassStyle();
// GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
font = assetManager.loadFont("Textures/font/FontCJK/fontCJK.fnt");
GuiGlobals.getInstance().getStyles().setDefault(font);
inputMapper.addAnalogListener(this, FidQ);
//inputMapper.addStateListener(this, FidQ);
}
@Override
protected void cleanup(Application app) {
}
@Override
protected void onEnable() {
//vp.attachScene(simpleApp.getRootNode().getChild("MiniCam"));
mesh.setMode(Mesh.Mode.LineStrip);
Geometry gridGeometry = new Geometry("camT", mesh);
Material Material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material.setColor("Color", ColorRGBA.White);
Material.getAdditionalRenderState().setWireframe(true);
gridGeometry.setMaterial(Material);
Main.MapUIBox.attachChild(gridGeometry);
// Container checkbox = new Container("myglass");
// checkboxUI.attachChild(checkbox);
// simpleApp.getGuiNode().attachChild(checkboxUI);
// checkbox.setPreferredSize(new Vector3f(cam.getWidth(), cam.getHeight(), 0));
// checkbox.setLocalTranslation(cam.getWidth() / 1.25f, cam.getHeight() / 4, 0);
// checkbox.setBackground(new QuadBackgroundComponent(ColorRGBA.Red));
Container checkbox = new Container();
checkboxUI.attachChild(checkbox);
simpleApp.getGuiNode().attachChild(checkboxUI);
checkbox.setPreferredSize(new Vector3f(cam.getWidth(), cam.getHeight(), 0));
checkbox.setLocalTranslation(0, cam.getHeight(), 0);
checkbox.setBackground(new QuadBackgroundComponent(ColorRGBA.fromRGBA255(0, 0, 0, 0)));
////信息栏
//
//
// Container infoWindow = new Container("containerStyle");
// simpleApp.getGuiNode().attachChild(info);
// info.attachChild(infoWindow);
// infoWindow.setPreferredSize(new Vector3f(cam.getWidth() / 2, cam.getHeight() / 4, 0));
// infoWindow.setLocalTranslation(cam.getWidth() / 4f, cam.getHeight() / 4, 0);
// infoWindow.setBackground(new QuadBackgroundComponent(ColorRGBA.White));
//小地图
initialisationMiniMap();
Texture texture = assetManager.loadTexture("/Textures/UI/button.png");
ButtonStyle buttonStyle = new ButtonStyle(GuiGlobals.getInstance().getStyles(), texture);
//
//命令栏
Container directiveWindow = new Container("myglass");
directive.attachChild(directiveWindow);
simpleApp.getGuiNode().attachChild(directive);
directive.getLocalTranslation().setZ(1);
directiveWindow.setPreferredSize(new Vector3f(cam.getWidth() / 5f, cam.getHeight() / 4, 0));
directiveWindow.setLocalTranslation(cam.getWidth() / 1.25f, cam.getHeight() / 4, 0);
directiveWindow.setBackground(new QuadBackgroundComponent(ColorRGBA.Red));
CommandButton(directiveWindow);
}
@Override
protected void onDisable() {
}
private void checkCollisionWithRay(Ray ray, CollisionResults results) {
Main.MapUIBox.getChild("quadBox").collideWith(ray, results);
}
/**
* 绘制小地图上的梯形
*
* @param results
* @param vertices
* @param indexX
* @param indexY
* @param indexZ
*/
private void setMiniMapTrapezoidalMesh(CollisionResults results, float[] vertices, int indexX, int indexY, int indexZ) {
CollisionResult closest = results.getClosestCollision();
if (closest != null) {
Vector3f contactPoint = closest.getContactPoint();
// System.err.println(contactPoint + "," + indexX + "," + indexY + "," + indexZ);
if (contactPoint != null) {
float x = contactPoint.x;
float z = contactPoint.z;
if (x > 2048) {
x = 2048;
} else if (x < 0) {
x = 0;
}
if (z > 2048) {
z = 2048;
} else if (z < 0) {
z = 0;
}
vertices[indexX] = x;
vertices[indexY] = 1;
vertices[indexZ] = z;
}
} else {
if (indexZ == 2) {
vertices[indexZ] = vertices[5];
}
if (indexZ == 5) {
vertices[indexZ] = vertices[2];
}
if (indexZ == 8) {
vertices[indexZ] = vertices[11];
}
if (indexZ == 11) {
vertices[indexZ] = vertices[8];
}
if (indexX == 0) {
vertices[indexX] = vertices[9];
}
if (indexX == 3) {
vertices[indexX] = vertices[6];
}
if (indexX == 6) {
vertices[indexX] = vertices[3];
}
if (indexX == 9) {
vertices[indexX] = vertices[0];
}
}
iresults.clear();
}
@Override
public void update(float tpf) {
// 获取屏幕上的点的世界坐标
Vector3f click3d0 = cam.getWorldCoordinates(new Vector2f(0, 0), 0f);
Vector3f click3d1 = cam.getWorldCoordinates(new Vector2f(cam.getWidth(), 0), 0f);
Vector3f click3d2 = cam.getWorldCoordinates(new Vector2f(cam.getWidth(), cam.getHeight()), 0f);
Vector3f click3d3 = cam.getWorldCoordinates(new Vector2f(0, cam.getHeight()), 0f);
// Vector3f CamMid = cam.getWorldCoordinates(new Vector2f(cam.getWidth()/2, cam.getHeight()/2), 0f);
// 计算方向
Vector3f dir0 = click3d0.subtract(cam.getLocation());
Vector3f dir1 = click3d1.subtract(cam.getLocation());
Vector3f dir2 = click3d2.subtract(cam.getLocation());
Vector3f dir3 = click3d3.subtract(cam.getLocation());
// Vector3f dir4 = click3d3.subtract(cam.getLocation());
dir0.normalizeLocal();
dir1.normalizeLocal();
dir2.normalizeLocal();
dir3.normalizeLocal();
// dir4.normalizeLocal();
// 创建射线并进行碰撞检测
checkCollisionWithRay(new Ray(click3d0, dir0), iresults);
setMiniMapTrapezoidalMesh(iresults, vertices, 0, 1, 2);
checkCollisionWithRay(new Ray(click3d1, dir1), iresults);
setMiniMapTrapezoidalMesh(iresults, vertices, 3, 4, 5);
checkCollisionWithRay(new Ray(click3d2, dir2), iresults);
setMiniMapTrapezoidalMesh(iresults, vertices, 6, 7, 8);
checkCollisionWithRay(new Ray(click3d3, dir3), iresults);
setMiniMapTrapezoidalMesh(iresults, vertices, 9, 10, 11);
mesh.setBuffer(VertexBuffer.Type.Position, 3, vertices);
mesh.setBuffer(VertexBuffer.Type.Index, 3, BufferUtils.createShortBuffer(indices));
mesh.updateBound();
}
public void initialisationMiniMap() {
Container window = new Container("containerStyle");
FrameBuffer framebuffer = new FrameBuffer(cam4.getWidth(), cam4.getHeight(), 1);
Texture2D texture = new Texture2D(cam4.getHeight() / 4, cam4.getHeight() / 4, 1, Image.Format.RGBA8);
framebuffer.addColorTarget(FrameBuffer.FrameBufferTarget.newTarget(texture));
vp.setOutputFrameBuffer(framebuffer);
iMap.attachChild(window);
iMap.getLocalTranslation().setZ(1);
//iMap.attachChild(minimap);
simpleApp.getGuiNode().attachChild(iMap);
// window.addChild(minimap);
window.setLocalTranslation(0, cam.getHeight() / 4, 0);
window.setPreferredSize(new Vector3f(cam.getHeight() / 4, cam.getHeight() / 4, 0));
window.addChild(new Container("myglass"));
window.setBackground(new QuadBackgroundComponent(ColorRGBA.White));
//创建一个 Panel 作为背景
Container BackgroundPanel = new Container("containerStyle");
BackgroundPanel.setPreferredSize(window.getPreferredSize()); // 设置大小
BackgroundPanel.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
System.out.println(window.getPreferredSize());
System.out.println(iMap.getChildren());
// 设置容器的边界留白
Insets3f insets = new Insets3f(cam.getHeight() / 4 * 0.05f, cam.getHeight() / 4 * 0.05f, cam.getHeight() / 4 * 0.05f, cam.getHeight() / 4 * 0.05f);
BackgroundPanel.setInsets(insets);
//创建一个 Panel 作为小地图纹理填充
Container MiniMapPanel = new Container("containerStyle");
MiniMapPanel.setPreferredSize(BackgroundPanel.getPreferredSize());
MiniMapPanel.setBackground(new QuadBackgroundComponent(texture));
BackgroundPanel.addChild(MiniMapPanel);
// 将边框添加到容器中
window.addChild(BackgroundPanel);
CursorEventControl.addListenersToSpatial(BackgroundPanel, new DefaultCursorListener() {
boolean pressed = false;
@Override
protected void click(CursorButtonEvent event, Spatial target, Spatial capture) {
}
@Override
public void cursorButtonEvent(CursorButtonEvent event, Spatial target, Spatial capture) {
System.err.println("cursorButtonEvent," + event);
if (event.getButtonIndex() == 0) {
pressed = event.isPressed();
} else {
event.setConsumed();
}
}
@Override
public void cursorEntered(CursorMotionEvent event, Spatial target, Spatial capture) {
}
@Override
public void cursorExited(CursorMotionEvent event, Spatial target, Spatial capture) {
}
@Override
public void cursorMoved(CursorMotionEvent event, Spatial target, Spatial capture) {
if (pressed) {
float widthScale = (float) 2048 / BackgroundPanel.getPreferredSize().x;
float heightScale = (float) 2048 / BackgroundPanel.getPreferredSize().y;
// 获取相机当前位置
Vector3f camLocation = cam.getLocation();
// 根据比例更新相机位置
float newX = 2048 - event.getX() * widthScale;
float newZ = event.getY() * heightScale - 200;
if (newX >= CamLeftMax) {
newX = CamLeftMax;
}
if (newX <= CamRightMin) {
newX = CamRightMin;
}
if (newZ >= CamUpMax) {
newZ = CamUpMax;
}
if (newZ <= CamBackwardMin) {
newZ = CamBackwardMin;
}
// 设置相机的新位置
cam.setLocation(new Vector3f(newX, camLocation.y, newZ));
// System.err.println(widthScale+","+heightScale);
}
}
});
}
public void CommandButton(Container directiveWindow) {
Button Q = directiveWindow.addChild(new Button("Q", "ButtonGlass"), 0, 0);
Button W = directiveWindow.addChild(new Button("W", "ButtonGlass"), 0, 1);
Button E = directiveWindow.addChild(new Button("E", "ButtonGlass"), 0, 2);
Button R = directiveWindow.addChild(new Button("R", "ButtonGlass"), 0, 3);
Button T = directiveWindow.addChild(new Button("T", "ButtonGlass"), 0, 4);
}
@Override
public void valueActive(FunctionId func, double value, double tpf) {
System.err.println(func);
if (func == FidQ) {
System.err.println("Pressed Q on the keyboard.");
}
}
@Override
public void valueChanged(FunctionId func, InputState value, double tpf) {
if (func == FidQ) {
System.err.println("Pressed Q on the keyboard.");
}
}
}
I’m so sorry to bother you again.
I didn’t succeed to use inputMapper, I don’t know why he didn’t work, I tried to write it like the demo but it didn’t work.
I tried to initialise inputMapper using these
public static final FunctionId FidQ = new FunctionId("KEY", "Q");
GuiGlobals.initialize(simpleApp);
if( inputMapper == null ){
inputMapper = GuiGlobals.getInstance().getInputMapper();
}
inputMapper.map( FidQ,KeyInput.KEY_Q);
inputMapper.addAnalogListener(this, FidQ);
inputMapper.addStateListener(this, FidQ);
@Override
public void valueActive(FunctionId func, double value, double tpf) {
System.err.println(func);
if (func == FidQ) {
System.err.println("Pressed Q on the keyboard.");
}
}
@Override
public void valueChanged(FunctionId func, InputState value, double tpf) {
if (func == FidQ) {
System.err.println("Pressed Q on the keyboard.");
}
}
But when I press Q, nothing seems to happen.