Hi, I’m new to Java, jMonkeyEngine and Nifty GUI. I’m still learning.
I’ve just complete a minigame, and was trying to make a start menu for it.
I’ve follow this tutorial: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_overlay from the beginning, and also code from the “NiftyGUIDemo” example.
I’ve succeded in creating that menu, 2 button do what they mean to do very well. But on the second screen (which is my actual game), there’s nothing show up.
I know it’s running, because i can fire the bullet, and can hear the sound whenever a bullet is fired. But not a single image shown up.
I don’t know what wrong with my code. Please help me. Thank you.
Here are my codes:
MainMenuLayout.xml
[java]<?xml version=“1.0” encoding=“UTF-8”?>
<nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>
<useStyles filename=“nifty-default-styles.xml” />
<useControls filename=“nifty-default-controls.xml” />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ →
<!-- This demo shows a two-screen layout in Nifty’s XML syntax. →
<!-- You see two screens with two layers each, contain several panels. →
<!-- The panels contain images, text, and controls (label and buttons). →
<!-- Buttons have an interaction defined, and some of the text →
<!-- is dynamically defined, using the MyStartScreen controller. →
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ →
<!-- +++++++++++++++++++++++++++++++++++++++ →
<!-- lay out the start screen/layers/panels →
<!-- +++++++++++++++++++++++++++++++++++++++ →
<screen id=“start” controller=“neonwarships.MyStartScreen”>
<layer id=“background” childLayout=“center”>
<image filename=“Interface/start-background.png”></image>
</layer>
<layer id=“foreground” childLayout=“vertical”>
<panel id=“panel_top” height=“25%” width=“75%” align=“center” childLayout=“center”>
<text text="${CALL.getPlayerName()}'s Cool Game" font=“Interface/Fonts/Default.fnt” width=“100%” height=“100%” />
</panel>
<panel id=“panel_mid” height=“50%” width=“75%” align=“center” childLayout=“center”>
<text text=“Here goes some text describing the game and the rules and stuff. Incidentally, the text is quite long and needs to wrap at the end of lines. Here goes some text describing the game and the rules and stuff. Incidentally, the text is quite long and needs to wrap at the end of lines. Here goes some text describing the game and the rules and stuff. Incidentally, the text is quite long and needs to wrap at the end of lines.”
font=“Interface/Fonts/Default.fnt” width=“100%” height=“100%” wrap=“true” />
</panel>
<panel id=“panel_bottom” height=“25%” width=“75%” align=“center” childLayout=“horizontal”>
<panel id=“panel_bottom_left” height=“50%” width=“50%” valign=“center” childLayout=“center”>
<control name=“button” label=“Start” id=“StartButton” align=“center” valign=“center”
visibleToMouse=“true”>
<interact onClick=“startGame(hud1)” />
</control>
</panel>
<panel id=“panel_bottom_right” height=“50%” width=“50%” valign=“center” childLayout=“center”>
<control name=“button” label=“Quit” id=“QuitButton” align=“center” valign=“center”
visibleToMouse=“true” >
<interact onClick=“quitGame()”/>
</control>
</panel>
</panel>
</layer>
</screen>
<!-- +++++++++++++++++++++++++++++++++++++++ →
<!-- lay out the HUD screen/layers/panels →
<!-- +++++++++++++++++++++++++++++++++++++++ →
<screen id=“hud1” controller=“neonwarships.MyStartScreen”>
<layer id=“background” childLayout=“center”>
</layer>
<layer id=“foreground” childLayout=“horizontal”>
</layer>
</screen>
</nifty>[/java]
MyStartScreen.java:
[java]/*
- To change this template, choose Tools | Templates
- and open the template in the editor.
*/
package neonwarships;
/**
*
-
@author Theo
*/
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.elements.render.TextRenderer;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
public class MyStartScreen extends AbstractAppState implements ScreenController {
private Nifty nifty;
private Application app;
private Screen screen;
/** custom methods */
public MyStartScreen() {
/** You custom constructor, can accept arguments */
}
public void startGame(String nextScreen) {
nifty.gotoScreen(nextScreen); // switch to another screen
}
public void quitGame() {
app.stop();
}
public String getPlayerName() {
return System.getProperty("user.name");
}
public void bind(Nifty nifty, Screen screen) {
this.nifty = nifty;
this.screen = screen;
}
public void onStartScreen() {
}
public void onEndScreen() {
}
/** jME3 AppState methods */
@Override
public void initialize(AppStateManager stateManager, Application app) {
this.app = app;
}
}[/java]
Main.java:
[java]package neonwarships;
import com.jme3.app.SimpleApplication;
import com.jme3.cursors.plugins.JmeCursor;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.system.AppSettings;
import com.jme3.texture.Texture2D;
import com.jme3.ui.Picture;
import java.awt.Rectangle;
import java.util.Random;
import com.jme3.niftygui.NiftyJmeDisplay;
import de.lessvoid.nifty.Nifty;
/**
- Urheberrecht (c) 2013, Daniel Gallenberger
- MonkeyBlaster is a Port of Shape Blaster by Michael Hoffmann.
- Shape Blaster is a Clone of Geometry Wars.
*/
public class MonkeyBlasterMain extends SimpleApplication implements ActionListener, AnalogListener {
private Hud hud;
private Sound sound;
private ParticleManager particleManager;
private Grid grid;
private long bulletCooldown;
private long enemySpawnCooldown;
private float enemySpawnChance = 80;
private long spawnCooldownBlackHole;
private Spatial player;
private Node bulletNode;
private Node enemyNode;
private Node blackHoleNode;
private Node particleNode;
private boolean gameOver = false;
private MyStartScreen startScreen;
public static void main(String[] args) {
AppSettings settings = new AppSettings(true);
settings.setResolution(640, 480);
MonkeyBlasterMain app = new MonkeyBlasterMain();
app.setShowSettings(false); // splashscreen
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
// setup camera for 2D games
cam.setParallelProjection(true);
cam.setLocation(new Vector3f(0,0,0.5f));
getFlyByCamera().setEnabled(false);
// turn off stats (you can leave it on, if you want)
setDisplayStatView(false);
setDisplayFps(false);
// initializing the bloom filter
FilterPostProcessor fpp=new FilterPostProcessor(assetManager);
BloomFilter bloom=new BloomFilter();
bloom.setBloomIntensity(2f);
bloom.setExposurePower(2);
bloom.setExposureCutOff(0f);
bloom.setBlurScale(1.5f);
fpp.addFilter(bloom);
guiViewPort.addProcessor(fpp);
guiViewPort.setClearColor(true);
// setup input handling
inputManager.setMouseCursor((JmeCursor) assetManager.loadAsset(“Textures/Pointer.ico”));
inputManager.addMapping("mousePick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "mousePick");
inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("return", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(this, "left");
inputManager.addListener(this, "right");
inputManager.addListener(this, "up");
inputManager.addListener(this, "down");
inputManager.addListener(this, "return");
// setup the hud
hud = new Hud(assetManager, rootNode, settings.getWidth(), settings.getHeight());
hud.reset();
// sounds
sound = new Sound(assetManager);
sound.startMusic();
sound.spawn();
// particles
particleManager = new ParticleManager(rootNode, getSpatial(“Laser”), getSpatial(“Glow”), settings.getWidth(), settings.getHeight());
// grid
Rectangle size = new Rectangle(0, 0, settings.getWidth(), settings.getHeight());
Vector2f spacing = new Vector2f(25,25);
grid = new Grid(size, spacing, rootNode, assetManager);
// setup the player
player = getSpatial(“Player”);
player.setUserData(“alive”,true);
player.move(settings.getWidth()/2, settings.getHeight()/2, 0);
player.addControl(new PlayerControl(settings.getWidth(), settings.getHeight(), particleManager));
rootNode.attachChild(player);
// setup the bulletNode
bulletNode = new Node(“bullets”);
rootNode.attachChild(bulletNode);
// setup the enemyNode
enemyNode = new Node(“enemies”);
rootNode.attachChild(enemyNode);
// setup the blackholeNode
blackHoleNode = new Node(“black_holes”);
rootNode.attachChild(blackHoleNode);
// setup the particleNode
particleNode = new Node(“particles”);
rootNode.attachChild(particleNode);
/**
* Activate the Nifty-JME integration:
*/
startScreen = new MyStartScreen();
stateManager.attach(startScreen);
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(
assetManager, inputManager, audioRenderer, guiViewPort);
Nifty nifty = niftyDisplay.getNifty();
nifty.fromXml("Interface/MainMenuLayout.xml", "start", startScreen);
guiViewPort.addProcessor(niftyDisplay);
//nifty.setDebugOptionPanelColors(true);
flyCam.setDragToRotate(true); // you need the mouse for clicking now
}
@Override
public void simpleUpdate(float tpf) {
if ((Boolean) player.getUserData("alive")) {
spawnEnemies();
spawnBlackHoles();
handleCollisions();
handleGravity(tpf);
} else if (System.currentTimeMillis() - (Long) player.getUserData("dieTime") > 4000f && !gameOver) {
// spawn player
player.setLocalTranslation(500,500,0);
rootNode.attachChild(player);
player.setUserData("alive",true);
sound.spawn();
grid.applyDirectedForce(new Vector3f(0,0,5000), player.getLocalTranslation(), 100);
}
grid.update(tpf);
hud.update();
}
public String getPlayerName() {
return System.getProperty("user.name");
}
private void spawnEnemies() {
if (System.currentTimeMillis() - enemySpawnCooldown >= 17) {
enemySpawnCooldown = System.currentTimeMillis();
if (enemyNode.getQuantity() < 50) {
if (new Random().nextInt((int) enemySpawnChance) == 0) {
createSeeker();
}
if (new Random().nextInt((int) enemySpawnChance) == 0) {
createWanderer();
}
}
//increase Spawn Time
if (enemySpawnChance >= 1.1f) {
enemySpawnChance -= 0.005f;
}
}
}
private void createSeeker() {
Spatial seeker = getSpatial("Seeker");
seeker.setLocalTranslation(getSpawnPosition());
seeker.addControl(new SeekerControl(player));
seeker.setUserData("active",false);
enemyNode.attachChild(seeker);
}
private void createWanderer() {
Spatial wanderer = getSpatial("Wanderer");
wanderer.setLocalTranslation(getSpawnPosition());
wanderer.addControl(new WandererControl(settings.getWidth(), settings.getHeight()));
wanderer.setUserData("active",false);
enemyNode.attachChild(wanderer);
}
private void spawnBlackHoles() {
if (blackHoleNode.getQuantity() < 2) {
if (System.currentTimeMillis() - spawnCooldownBlackHole > 10f) {
spawnCooldownBlackHole = System.currentTimeMillis();
if (new Random().nextInt(1000) == 0) {
createBlackHole();
}
}
}
}
private void createBlackHole() {
Spatial blackHole = getSpatial("Black Hole");
blackHole.setLocalTranslation(getSpawnPosition());
blackHole.addControl(new BlackHoleControl(particleManager, grid));
blackHole.setUserData("active",false);
blackHoleNode.attachChild(blackHole);
}
private Vector3f getSpawnPosition() {
Vector3f pos;
do {
pos = new Vector3f(new Random().nextInt(settings.getWidth()), new Random().nextInt(settings.getHeight()),0);
} while (pos.distanceSquared(player.getLocalTranslation()) < 8000);
return pos;
}
private void handleCollisions() {
// should the player die?
for (int i=0; i<enemyNode.getQuantity(); i++) {
if ((Boolean) enemyNode.getChild(i).getUserData("active")) {
if (checkCollision(player,enemyNode.getChild(i))) {
killPlayer();
}
}
}
//should an enemy die?
int i=0;
while (i < enemyNode.getQuantity()) {
int j=0;
while (j < bulletNode.getQuantity()) {
if (checkCollision(enemyNode.getChild(i),bulletNode.getChild(j))) {
// add points depending on the type of enemy
if (enemyNode.getChild(i).getName().equals("Seeker")) {
hud.addPoints(2);
} else if (enemyNode.getChild(i).getName().equals("Wanderer")) {
hud.addPoints(1);
}
particleManager.enemyExplosion(enemyNode.getChild(i).getLocalTranslation());
enemyNode.detachChildAt(i);
bulletNode.detachChildAt(j);
sound.explosion();
break;
}
j++;
}
i++;
}
//is something colliding with a black hole?
for (i=0; i<blackHoleNode.getQuantity(); i++) {
Spatial blackHole = blackHoleNode.getChild(i);
if ((Boolean) blackHole.getUserData("active")) {
//player
if (checkCollision(player,blackHole)) {
killPlayer();
}
//enemies
int j=0;
while (j < enemyNode.getQuantity()) {
if (checkCollision(enemyNode.getChild(j),blackHole)) {
particleManager.enemyExplosion(enemyNode.getChild(j).getLocalTranslation());
enemyNode.detachChildAt(j);
}
j++;
}
//bullets
j=0;
while (j < bulletNode.getQuantity()) {
if (checkCollision(bulletNode.getChild(j),blackHole)) {
bulletNode.detachChildAt(j);
blackHole.getControl(BlackHoleControl.class).wasShot();
particleManager.blackHoleExplosion(blackHole.getLocalTranslation());
if (blackHole.getControl(BlackHoleControl.class).isDead()) {
blackHoleNode.detachChild(blackHole);
sound.explosion();
}
}
j++;
}
}
}
}
private boolean checkCollision(Spatial a, Spatial b) {
float distance = a.getLocalTranslation().distance(b.getLocalTranslation());
float maxDistance = (Float)a.getUserData("radius") + (Float)b.getUserData("radius");
return distance <=maxDistance;
}
private void killPlayer() {
player.removeFromParent();
player.getControl(PlayerControl.class).reset();
player.setUserData("alive", false);
player.setUserData("dieTime", System.currentTimeMillis());
enemyNode.detachAllChildren();
blackHoleNode.detachAllChildren();
particleManager.playerExplosion(player.getLocalTranslation());
if (!hud.removeLife()) {
hud.endGame();
gameOver = true;
}
}
private void handleGravity(float tpf) {
for (int i=0; i<blackHoleNode.getQuantity(); i++) {
if (!(Boolean)blackHoleNode.getChild(i).getUserData("active")) {continue;}
int radius = 250;
// check Player
if (isNearby(player,blackHoleNode.getChild(i),radius)) {
applyGravity(blackHoleNode.getChild(i), player, tpf);
}
// check Bullets
for (int j=0; j<bulletNode.getQuantity(); j++) {
if (isNearby(bulletNode.getChild(j),blackHoleNode.getChild(i),radius)) {
applyGravity(blackHoleNode.getChild(i), bulletNode.getChild(j), tpf);
}
}
// check Enemies
for (int j=0; j<enemyNode.getQuantity(); j++) {
if (!(Boolean)enemyNode.getChild(j).getUserData("active")) {continue;}
if (isNearby(enemyNode.getChild(j),blackHoleNode.getChild(i),radius)) {
applyGravity(blackHoleNode.getChild(i), enemyNode.getChild(j), tpf);
}
}
// check Particles
for (int j=0; j<particleNode.getQuantity(); j++) {
if (particleNode.getChild(j).getUserData("affectedByGravity")) {
applyGravity(blackHoleNode.getChild(i), particleNode.getChild(j), tpf);
}
}
}
}
private boolean isNearby(Spatial a, Spatial b, float distance) {
Vector3f pos1 = a.getLocalTranslation();
Vector3f pos2 = b.getLocalTranslation();
return pos1.distanceSquared(pos2) <= distance * distance;
}
private void applyGravity(Spatial blackHole, Spatial target, float tpf) {
Vector3f difference = blackHole.getLocalTranslation().subtract(target.getLocalTranslation());
Vector3f gravity = difference.normalize().multLocal(tpf);
float distance = difference.length();
if (target.getName().equals("Player")) {
gravity.multLocal(250f/distance);
target.getControl(PlayerControl.class).applyGravity(gravity.mult(80f));
} else if (target.getName().equals("Bullet")) {
gravity.multLocal(250f/distance);
target.getControl(BulletControl.class).applyGravity(gravity.mult(-0.8f));
} else if (target.getName().equals("Seeker")) {
target.getControl(SeekerControl.class).applyGravity(gravity.mult(150000));
} else if (target.getName().equals("Wanderer")) {
target.getControl(WandererControl.class).applyGravity(gravity.mult(150000));
} else if (target.getName().equals("Laser") || target.getName().equals("Glow")) {
target.getControl(ParticleControl.class).applyGravity(gravity.mult(15000), distance);
}
}
@Override
public void simpleRender(RenderManager rm) {}
public void onAction(String name, boolean isPressed, float tpf) {
if ((Boolean) player.getUserData("alive")) {
if (name.equals("up")) {
player.getControl(PlayerControl.class).up = isPressed;
} else if (name.equals("down")) {
player.getControl(PlayerControl.class).down = isPressed;
} else if (name.equals("left")) {
player.getControl(PlayerControl.class).left = isPressed;
} else if (name.equals("right")) {
player.getControl(PlayerControl.class).right = isPressed;
}
}
}
public void onAnalog(String name, float value, float tpf) {
if ((Boolean) player.getUserData("alive")) {
if (name.equals("mousePick")) {
//shoot Bullet
if (System.currentTimeMillis() - bulletCooldown > 83f) {
bulletCooldown = System.currentTimeMillis();
Vector3f aim = getAimDirection();
Vector3f offset = new Vector3f(aim.y/3,-aim.x/3,0);
// init bullet 1
Spatial bullet = getSpatial(“Bullet”);
Vector3f finalOffset = aim.add(offset).mult(30);
Vector3f trans = player.getLocalTranslation().add(finalOffset);
bullet.setLocalTranslation(trans);
bullet.addControl(new BulletControl(aim, settings.getWidth(), settings.getHeight(), particleManager, grid));
bulletNode.attachChild(bullet);
// init bullet 2
Spatial bullet2 = getSpatial(“Bullet”);
finalOffset = aim.add(offset.negate()).mult(30);
trans = player.getLocalTranslation().add(finalOffset);
bullet2.setLocalTranslation(trans);
bullet2.addControl(new BulletControl(aim, settings.getWidth(), settings.getHeight(), particleManager, grid));
bulletNode.attachChild(bullet2);
sound.shoot();
}
}
}
}
private Vector3f getAimDirection() {
Vector2f mouse = inputManager.getCursorPosition();
Vector3f playerPos = player.getLocalTranslation();
Vector3f dif = new Vector3f(mouse.x-playerPos.x,mouse.y-playerPos.y,0);
return dif.normalizeLocal();
}
public static float getAngleFromVector(Vector3f vec) {
Vector2f vec2 = new Vector2f(vec.x,vec.y);
return vec2.getAngle();
}
public static Vector3f getVectorFromAngle(float angle) {
return new Vector3f(FastMath.cos(angle),FastMath.sin(angle),0);
}
private Spatial getSpatial(String name) {
Node node = new Node(name);
// load picture
Picture pic = new Picture(name);
Texture2D tex = (Texture2D) assetManager.loadTexture(“Textures/”+name+".png");
pic.setTexture(assetManager,tex,true);
// adjust picture
float width = tex.getImage().getWidth();
float height = tex.getImage().getHeight();
pic.setWidth(width);
pic.setHeight(height);
pic.move(-width/2f,-height/2f,0);
// add a material to the picture
Material picMat = new Material(assetManager, “Common/MatDefs/Gui/Gui.j3md”);
picMat.getAdditionalRenderState().setBlendMode(BlendMode.AlphaAdditive);
node.setMaterial(new Material());
// set the radius of the spatial
// (using width only as a simple approximation)
node.setUserData(“radius”, width/2);
// attach the picture to the node and return it
node.attachChild(pic);
return node;
}
public AppSettings getSettings() {return settings;}
}[/java]