[New] Trouble when check the picking results & [SOLVED] Trouble in putting many models(will be operated) together

What do you mean “with only OptionPanel”.

Do you know how to find the code?

Style is the style. null for default style. message is the message. Not sure how else to describe the “text that appears in the message box”.

You have to make one. Add a text field, etc…

There are lots of applications that use Lemur if you want to look at examples. I suspect that it will be too much for you to look at because you seem to want to do as little reading as possible… and unfortunately, I do not have time for one-on-one “walk you through every step” tech support today.

I think all of these examples use Lemur in some way:

…some even have pop-up message boxes for entering text.

For a really complex example, you can also look here:

…but in the end, you will create a container, add the stuff you want to it, position it on screen, then GuiGlobals.getInstance().showModalPopup(yourContainer)

Container LoadWin=new Container();
                guiNode.attachChild(LoadWin);
                LoadWin.setLocalTranslation(300, 300, 0);
                LoadWin.scale(50.0f,50.0f,0);
                LoadWin.addChild(new Label("Save Or Load"));

                OptionPanel optionPanel=new OptionPanel("Option Panel Demo",
                        JOptionPane.showInputDialog(this), Styles.ROOT_STYLE
                        ,new CallMethodAction("Ok", this, "close"));

                String fileName = optionPanel.getMessage();
                System.out.println("fileName :"+fileName);

I use JOptionPane here since I don’t how to set dialog box in the Lemur

That’s swing. Totally different. You might as well bang on your screen with a hammer.

Anyway, I’ve given you all that you need to figure it out. I have to do real work now.

Good luck.

A small question for now : since I will use crosshair to take the scene in my game , so I need to ban the cursor when enter the scene. So I’m asking for the method to it.

And a small request that help me check why my listener broke down there. I’ve build a new thread to load model, then enqueue it to the main thread. And I don’t have any idea about that, I thought your check would be helpful. The source code is as below:

https://github.com/BAO-Jiale/3D-MineSweeping/blob/3D-Mine-Sweeping/3D_MineSweeping/src/MainFrame.java

Very appreciated!

And when I tried to load the model in another thread then enqueue it to the main thread by give the value to it, it told that the spatial should be final. Why it would be final? And is there any solution to slove it?

It not reacted. I guess the problems might be at the method I reload it (in the code it’s called reDraw), but I have idea what is going wrong.

I thought maybe also need your help :blush:

Because you are using local variable inside a lambda expression, or anonymous classes (Runnable class)…local vars are protected from being used outside their major scope, if you need to force their use (although I don’t like to), specify a final pointer(array) from outside the runnable then fill it with values according to your needs.

Such a way(Pointers ) would be like :

private void loadShip(){
//specify a final pointer with fixed storage in memory, ie no future use of new keyword
final Spatial[] pointer = new Spatial[1];
app.enqueue(()->{

pointer[0] = assetManager.loadModel(model);//dereference the pointer here

});
}

Yeah, I think its better to :

  • Open a new thread for each separate problem, specifying the category, main problem, image or code.

  • Ask only one question per thread, so people won’t get lost, & respond quickly, plus others who know the answer would be notified of your question.

Because, I see this thread has over 3-4 questions from Nodes, collisions/physics, then lemur & now local vars, unless I read each comment here, I cannot help you out.

Could help me to check those methods? It cannot respond to my click.
It seems that the reDraw method or the listener get wrong but I can’t figure it out.

The first block here is the method I initialize & update the scene(the Spatial [][] that called temp [][])

//To load model according to the Status
    public Spatial draw(int row,int col){
        Spatial g = drawGrass();
        if (status[row][col].equals(Status.Covered_with_Mine)|status[row][col].equals(Status.Covered_without_Mine)){
            g=drawGrass();
        }
        if (status[row][col]==Status.Mine){
            g=drawMine();
        }
        if (status[row][col]==Status.Flag){g=drawFlag();g.scale(0.25f);}
        if (status[row][col]==Status.Clear){
            g=drawNum(row,col);
        }
        //set location
        g.scale(0.5f);
        g.center();
        float m=(float)(10.0*(row-5)+5.0);
        float n=(float)(10.0*(col-5)+5.0);
        g.setLocalTranslation(m,0.0f,-n);

        return g;
    }

    //To reload each model
    public void reDraw(int row,int col) {
        new Thread () {
            public void run() {
                final Spatial tem= draw(row,col);
                enqueue(new Runnable() {
                    public void run() {
                        temp[row][col]=tem;
                    }
                });
            }
        }.start();
    }

And this is the method I add the picking listener

public void addListenerToSpatial(Spatial g,int row,int col){
        MouseEventControl.addListenersToSpatial(g,
                new DefaultMouseListener() {
                    @Override
                    protected void click(MouseButtonEvent event, Spatial target, Spatial capture ) {
                        if( event.getButtonIndex() == MouseInput.BUTTON_LEFT ) {onOpen(row,col);}
                        if( event.getButtonIndex() == MouseInput.BUTTON_RIGHT ) {onMark(row,col);}
                    }
                });
    }

And these are my method responding to the events

public void onOpen(int i,int j){
        //prevent getting mine at the first try
        if (gameController.getOpenCount()==1){
            while (status[i][j].equals(Status.Covered_with_Mine)){mineField.resetMine();}
            if (status[i][j].equals(Status.Covered_without_Mine)){status[i][j]=Status.Clear;}
            gameController.addOpenCount();
        }else {
            if (status[i][j].equals(Status.Covered_with_Mine)){
                gameController.find_mine();
                gameController.getOnTurnPlayer().costScore();
                makeExplosion(i,j);
                status[i][j]=Status.Mine;
                reDraw(i,j);
            }
            if (status[i][j].equals(Status.Covered_without_Mine)){status[i][j]=Status.Clear;}
            gameController.addOpenCount();
        }
        reDraw(i,j);

        gameController.nextTurn();
    }
    public void onMark(int i,int j){
        if (status[i][j].equals(Status.Covered_with_Mine)){
            gameController.find_mine();
            status[i][j]=Status.Flag;
            gameController.getOnTurnPlayer().addScore();
        }
        if (status[i][j].equals(Status.Covered_without_Mine)){
            gameController.getOnTurnPlayer().addMistake();
            status[i][j]=Status.Clear;
        }
        reDraw(i,j);
        gameController.nextTurn();
    }

The total project is at 3D-MineSweeping/3D_MineSweeping at 3D-Mine-Sweeping · BAO-Jiale/3D-MineSweeping (github.com)

Do System.err.println(“Left Click Working”); here instead of this to be sure at first that the mouse clicks are working.

Try Testing those methods using your keyboard maps

So you can find where is the problem.

If your game has proper logging, you wouldn’t have been in that situation.

The mouse clicks in picking method is working now.
So I thought the reload method is wrong since I’ve check that by write a restart method

Also, when I run the project, I got an warning:
log4j:WARN No appenders could be found for logger (com.simsilica.lemur.GuiGlobals).
log4j:WARN Please initialize the log4j system properly.

What is that about? I’ve add log4j to my dependency

You can Ignore them, log4j is a logging library, I don’t know if it offers extras or not, have not used before.

If you look at any of the examples I provided in their build.gradle you can see the log4j related dependencies that you would need to make those warnings go away.

So I’m focusing on solve the reload method now.

Maybe should I put the reload method into update Or render method? But that seems make no sense.

Why are you using a custom thread to load the reDraw or tiles ?

I found that on a tutorial at 第九章:用户交互, it tolds that we should firstly load the model in new thread then take it to the main thread by the method “enqueue”.

Did I took it wrong? And what’s right here?

that is a tutorial on Chinese JME blog

Yeh I can read this in English, but I have no idea about that site, all I know is when I do enqueue, it adds a new Callable FutureTask to an AppTasks stack via a runnable wrapper then pass that to the update method where each task when reaches its end it get closed & notifies the proceeding task to execute over…so when you do enqueue its already a thread…

What are the FutureTask & AppTasks? The classes with load methods?
Maybe you can show me some examples about what you do to get this.