ScreenController issues

I’m trying to do a simple GUI with a joypad integrated on screen for a simple game for android. I have two images to do it, the circle with the bounds and the moving circle on center, something like that.



I’ve reading The Nifty Manual again and again and looking forums and documentation before ask.



I have this code to move a character when click on screen and I want do it on GUI now.

[java]

public void onAction(String binding, boolean value, float tpf) {

if (binding.equals(“touch”))

{

Vector2f click2d = inputManager.getCursorPosition();

float x = click2d.x - settings.getWidth()/2;

float y = click2d.y - settings.getHeight()/2;

double res = Math.atan2(x, y);



Vector3f camDir = cam.getDirection().clone();

Vector3f camLeft = cam.getLeft().clone().negate();

camDir.y = 0; camLeft.y = 0;



camDir.multLocal((float)Math.cos(res));

camLeft.multLocal((float)Math.sin(res));



Vector3f v = camDir.add(camLeft).multLocal(0.1f);

walkDirection.set(v);

}

}

[/java]



I rescale the circles using the width of screen because I don’t want an egg, To do it I need generate the image programatically and not using XML.

[java]

public void simpleInitApp() {



niftyDisplay = new NiftyJmeDisplay(assetManager,

inputManager,

audioRenderer,

guiViewPort);





nifty = niftyDisplay.getNifty();



final int sizeA = Math.round(settings.getWidth()/1024256); //The exterior circle is 256256

final int sizeB = Math.round(settings.getWidth()/102464); //The inner circle is 6464

final int midX = Math.round(sizeA/2 - sizeB/2);

final int midY = Math.round(settings.getHeight() - sizeA/2 - sizeB/2);



screen = new ScreenBuilder(“start”) {{

//controller(new TestWalkingChar());

layer(new LayerBuilder() {{

childLayoutAbsolute();

interactOnClickMouseMove(“move()”);

image(new ImageBuilder() {{

filename(“Interface/padBase.png”);

width(String.valueOf(sizeA));

height(String.valueOf(sizeA));

x(“0px”);

y(String.valueOf(settings.getHeight() - sizeA));

}});

image(new ImageBuilder() {{

filename(“Interface/pad.png”);

width(String.valueOf(sizeB));

height(String.valueOf(sizeB));

x(String.valueOf(midX));

y(String.valueOf(midY));

}});

}});

}}.build(nifty);

[/java]



Ok, can you see the commented line? I am extending from SimpleAplication and implementing ScreenController on this class, my move() function is there. I need access to the cam from my move() function and trying this system I can’t. If I try “controller(this);” the IDE says me something that is out of my knowledge and suggest me create the function “private void controller(ScreenBuilder aThis)”.

Well now I’m lost and try other way. Create a GUI.xml and add the images from code.

[xml]

<?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”>



<screen id=“start” controller=“mygame.TestWalkingChar”>

<layer id=“layer” childLayout=“absolute”>

<interact onClick=“move()”/>

</layer>

</screen>

</nifty>

[/xml]



Now the move() function can access cam and all objects.



[java]

NiftyImage imgA = nifty.getRenderEngine().createImage(“Interface/padBase.png”, false);

NiftyImage imgB = nifty.getRenderEngine().createImage(“Interface/pad.png”, false);



Element niftyElement = nifty.getCurrentScreen().findElementByName(“layer”);

niftyElement.getRenderer(ImageRenderer.class).setImage(imgA);

niftyElement.getRenderer(ImageRenderer.class).setImage(imgB);

[/java]



Ok, I don’t have idea how to resize and relocate. Sorry if the info is so obvious but I can’t find it.

In the element you can do setConstraintsWidth, Height, X, and Y…then once you’ve set them accordingly do element.getParent.layoutElements().

Thanks for answer.



[java]

NiftyImage imgA = nifty.getRenderEngine().createImage(“Interface/padBase.png”, false);

NiftyImage imgB = nifty.getRenderEngine().createImage(“Interface/pad.png”, false);



Element niftyElement = nifty.getCurrentScreen().findElementByName(“layer”);



niftyElement.setConstraintHeight(new SizeValue(“128px”));

niftyElement.setConstraintWidth(new SizeValue(“128px”));



niftyElement.getRenderer(ImageRenderer.class).setImage(imgA);

niftyElement.getRenderer(ImageRenderer.class).setImage(imgB);



niftyElement.getParent().layoutElements();

//niftyElement.layoutElements();

[/java]



I tried the commented line too but nothing happens. Maybe I have not understood you or I’m missing something. Anyway I have to use panes or diferent layers to do it, one for image, don’t?

You don’t have any element called “layer”…and even if you did you are setting both images to it.



You need to name each element as you add them and then call the set on that image. At the moment your find is probably returning a null element (breakpoint it and check).



[java]image(new ImageBuilder(“IMAGE_NAME”) {{

filename(“Interface/pad.png”);

width(String.valueOf(sizeB));

height(String.valueOf(sizeB));

x(String.valueOf(midX));

y(String.valueOf(midY));

}});

[/java]



[java]

Element niftyElement = nifty.getCurrentScreen().findElementByName(“IMAGE_NAME”);

niftyElement.setConstraintHeight(new SizeValue(“128px”));

niftyElement.setConstraintWidth(new SizeValue(“128px”));

niftyElement.getRenderer(ImageRenderer.class).setImage(imgA);



niftyElement.getParent().layoutElements();

[/java]



[java]

Element niftyElement = nifty.getCurrentScreen().findElementByName(“OTHER_IMAGE_NAME”);

niftyElement.setConstraintHeight(new SizeValue(“128px”));

niftyElement.setConstraintWidth(new SizeValue(“128px”));

niftyElement.getRenderer(ImageRenderer.class).setImage(imgB);



niftyElement.getParent().layoutElements();

[/java]



etc.



Btw, if you want square then you don’t want to stretch by screen width and height. You just want to use a fixed width an height. (Compensating for pixel aspect ratio is another matter and not something worth worrying about for most people).

1 Like

Thanks, I’ve found the way just now



Simple example of I’ve been looking for

[java]Screen screen = nifty.getCurrentScreen();

Element niftyElement = screen.findElementByName(“layer”);



Element img = new ImageBuilder() {{

x(“100px”);

y(“100px”);

width(“150px”);

height(“150px”);

filename(“Interface/pad.png”);

}}.build(nifty, screen, niftyElement);[/java]



But your code help me a lot to understand a thing.

Yep, that’s fine so long as you only want to add them and don’t want to remove/move them once added.



(For example I have nifty panels that follow an on-screen spatial around).

The problem has started with this part:

[java]

new ScreenBuilder(“start”) {{

//controller(new TestWalkingChar());

layer(new LayerBuilder() {{

childLayoutAbsolute();

interactOnClickMouseMove(“move()”);

image(new ImageBuilder() {{

filename(“Interface/padBase.png”);

width(String.valueOf(sizeA));

height(String.valueOf(sizeA));

x(“0px”);

y(String.valueOf(settings.getHeight() - sizeA));

}});

image(new ImageBuilder() {{

filename(“Interface/pad.png”);

width(String.valueOf(sizeB));

height(String.valueOf(sizeB));

x(String.valueOf(midX));

y(String.valueOf(midY));

}});

}});

}}.build(nifty);

[/java]



I prefer call it this way but I don’t understand why I have to init a new instance of my class and I can’t do “controller(this);” With ImageBuilder I can work now. This is only a test project, next is order all this and put each part in correct class and functions but I’m using it to undestarnd Nifty and learn to work with it.

I don’t understand your question…but you should format (indent) your code better anyway as that will make it much easier to read.

Ok, sorry.



Don’t worry I’ve solved it. A noob mistake. Thanks for your help.