Hello all,
Working on an RTS like game, and I want to be able to dynamically put the available actions on the screen depending on what the player has selected. I have something that works, but it’s horribly inefficient and produces duplicate ID warnings whenever it changes.
My current code looks like this:
[java]
public void replaceActionButtons(){
availableEntityActions.clear();//this gets the actions available based on the player’s currently selected units
for(int i = 0; i<selected.size(); i++){
if(i==0){
availableEntityActions.addAll(selected.get(i).getAvailableActions());
} else {
availableEntityActions.retainAll(selected.get(i).getAvailableActions());
}
}
Nifty nifty = app.getNifty();
Screen s = nifty.getCurrentScreen();
Element layer = s.findElementByName(“actionPanel”);//remove all rows of buttons
for(Element e : layer.getElements()){
e.markForRemoval();
}
nifty.executeEndOfFrameElementActions();//force removal
PanelCreator rowpc = new PanelCreator();//creator for the row panels
rowpc.setWidth("100%");
rowpc.setHeight("10%");
rowpc.setChildLayout("horizontal");
rowpc.setAlign("left");
rowpc.setVAlign("top");
int colsPerRow = 6;
PanelCreator actpc = new PanelCreator();//creator for the panel for each button (will be the actual button)
actpc.setWidth(100/colsPerRow + "%");
actpc.setHeight("100%");
actpc.setChildLayout("vertical");
actpc.setAlign("center");
actpc.setVAlign("top");
actpc.setBackgroundColor("#000a");
String worldActInteractFmt = "selectWorldAction(%s,%s)";//format strings for callback methods and image locations
String entActInteractFmt = "selectEntAction(%s,%s)";
String worldActImgFmt = "/Interface/actions/world/%s.png";
String entActImgFmt = "/Interface/actions/entity/%s.png";
ImageCreator ic = new ImageCreator();//creator for image
ic.setWidth("100%");
ic.setHeight("75%");
TextCreator tc = new TextCreator("");//creator for the text
tc.setStyle("nifty-label");
tc.setColor("#00ff");
tc.setWidth("100%");
tc.setHeight("25%");
int row = 0;
int col = 0;
int index = 0;
Element rowE=null;
for(WorldAction act : availableWorldActions){//world action buttons
if(index%colsPerRow==0){
rowE = rowpc.create(nifty, s, layer);//create new row
col=0;
row++;
}
String actpcid = "row"+row+"col"+col;
actpc.setId(actpcid);
actpc.setInteractOnClick(String.format(worldActInteractFmt, act.getName(),actpcid));
Element actE = actpc.create(nifty, s, rowE);//create button
ic.setFilename(String.format(worldActImgFmt,act.getName()));
ic.create(nifty, s, actE);//create image
tc.setText(act.getName());
tc.create(nifty, s, actE);//create text
index++;
col++;
}
for(EntityAction act : availableEntityActions){//same as above but for entity related actions
if(index%colsPerRow==0){
rowE = rowpc.create(nifty, s, layer);
col=0;
row++;
}
String actpcid = "row"+row+"col"+col;
actpc.setId(actpcid);
actpc.setInteractOnClick(String.format(entActInteractFmt, act.getName(),actpcid));
Element actE = actpc.create(nifty, s, rowE);
ic.setFilename(String.format(entActImgFmt,act.getName()));
ic.create(nifty, s, actE);
tc.setText(act.getName());
tc.create(nifty, s, actE);
index++;
col++;
}
}
[/java]
My question is, I’d like to pre-create all the buttons for every possible action in the game and just attach and detach them as needed, but I cannot find a way to create elements without providing a parent element in the docs. Is there a way to pre-generate these elements programmatically? eg:
[java]
//constructor
for all actions in game {
create button elements // How do I do THIS?
put button element in map from action id to Element
}
//in the replace buttons method
find actions that have been displayed but are no longer available
remove those actions from display // Mark for removal should work
find actions that have not been displayed but are now available
add those actions to display using elements from map created before // How do I do THIS?
[/java]
This scheme would prevent the new creation of elements over and over, and would alleviate the need for the executeEndOfFrameElementActions call. Is there a way to accomplish this that I’m not seeing in the docs?