[SOLVED] Beginner question - implement player code from separate class

Hi, I have 2 separate classes that I’m trying to work with and implement into the same scene so I can see my objects while also being able to control the “Player” aka teapot. The two classes are my Main class which holds the scene and such, and the other Player class holds all the info for the player model, camera, and all the necessary code to make it controllable (I used example code from the wiki).

This is my code:

Main

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.shadow.DirectionalLightShadowRenderer;

public class Main extends SimpleApplication {

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        flyCam.setEnabled(false);
        
        viewPort.setBackgroundColor(ColorRGBA.Black);

        AmbientLight amb = new AmbientLight();
        amb.setColor(ColorRGBA.White.mult(0.1f));
        rootNode.addLight(amb);
        
        DirectionalLight sun = new DirectionalLight();
        sun.setColor(ColorRGBA.White);
        sun.setDirection(new Vector3f(-.5f,-.5f,-.5f));
        rootNode.addLight(sun);
        
        DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(assetManager, 2048, 4);
        dlsr.setLight(sun);
        dlsr.setShadowIntensity(0.8f);
        viewPort.addProcessor(dlsr);
        
/*
        FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
        SSAOFilter ssaoFilter = new SSAOFilter(12.94f, 43.92f, 0.33f, 0.61f);
        fpp.addFilter(ssaoFilter);
        viewPort.addProcessor(fpp);
*/

        Box b = new Box(1, 2, 1);
        Geometry geom = new Geometry("Box", b);
        Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        mat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/brick.jpg"));
        geom.setMaterial(mat);
        geom.setShadowMode(RenderQueue.ShadowMode.Cast);
        rootNode.attachChild(geom);
        
        Box b2 = new Box(10, 0.001f, 10);
        Geometry geom2 = new Geometry("Floor", b2);
        Material mat2 = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        mat2.setBoolean("UseMaterialColors", true);
        mat2.setColor("Ambient", ColorRGBA.White);
        mat2.setColor("Diffuse", ColorRGBA.White);
        mat2.setColor("Specular", ColorRGBA.White);
        geom2.setMaterial(mat2);
        geom2.setShadowMode(RenderQueue.ShadowMode.Receive);
        geom2.move(0,-2,0);
        rootNode.attachChild(geom2);
    }
    
    @Override
    public void simpleUpdate(float tpf) {
        
    }

    @Override
    public void simpleRender(RenderManager rm) {
        
    }
}

Player

package mygame;

import com.jme3.input.MouseInput;
import com.jme3.input.controls.*;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.control.CameraControl.ControlDirection;

public class Player extends Main implements AnalogListener, ActionListener {

    private Geometry teaGeom;
    private Node teaNode;
    CameraNode camNode;
    boolean rotate = false;
    Vector3f direction = new Vector3f();

    @Override
    public void simpleInitApp() {
        teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
        teaGeom.setMaterial(mat);
        teaNode = new Node("teaNode");
        teaNode.attachChild(teaGeom);
        rootNode.attachChild(teaNode);

        camNode = new CameraNode("CamNode", cam);
        camNode.setControlDir(ControlDirection.SpatialToCamera);
        teaNode.attachChild(camNode);
        camNode.setLocalTranslation(new Vector3f(-10, 0, 0));
        camNode.lookAt(teaNode.getLocalTranslation(), Vector3f.UNIT_Y);

        registerInput();
  }

    public void registerInput() {
    inputManager.addMapping("moveForward", new KeyTrigger(keyInput.KEY_W));
    inputManager.addMapping("moveBackward", new KeyTrigger(keyInput.KEY_S));
    inputManager.addMapping("moveRight", new KeyTrigger(keyInput.KEY_D));
    inputManager.addMapping("moveLeft", new KeyTrigger(keyInput.KEY_A));
    inputManager.addMapping("toggleRotate", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
    inputManager.addMapping("rotateRight", new MouseAxisTrigger(MouseInput.AXIS_X, true));
    inputManager.addMapping("rotateLeft", new MouseAxisTrigger(MouseInput.AXIS_X, false));
    inputManager.addListener(this, "moveForward", "moveBackward", "moveRight", "moveLeft");
    inputManager.addListener(this, "rotateRight", "rotateLeft", "toggleRotate");
  }

  @Override
  public void onAnalog(String name, float value, float tpf) {
    direction.set(cam.getDirection()).normalizeLocal();
    if (name.equals("moveForward")) {
      direction.multLocal(5 * tpf);
      teaNode.move(direction);
    }
    if (name.equals("moveBackward")) {
      direction.multLocal(-5 * tpf);
      teaNode.move(direction);
    }
    if (name.equals("moveRight")) {
      direction.crossLocal(Vector3f.UNIT_Y).multLocal(5 * tpf);
      teaNode.move(direction);
    }
    if (name.equals("moveLeft")) {
      direction.crossLocal(Vector3f.UNIT_Y).multLocal(-5 * tpf);
      teaNode.move(direction);
    }
    if (name.equals("rotateRight") && rotate) {
      teaNode.rotate(0, 5 * tpf, 0);
    }
    if (name.equals("rotateLeft") && rotate) {
      teaNode.rotate(0, -5 * tpf, 0);
    }

  }

  @Override
  public void onAction(String name, boolean keyPressed, float tpf) {
    if (name.equals("toggleRotate") && keyPressed) {
      rotate = true;
      inputManager.setCursorVisible(false);
    }
    if (name.equals("toggleRotate") && !keyPressed) {
      rotate = false;
      inputManager.setCursorVisible(true);
    }

  }
}

My question is how do I implement the player code into the game so I can use it? It currently does not affect the game and only the Main code takes effect. Sorry for the beginner question, I realize I should probably read up on some Java tutorials but I decided to give this a swing for the fun of it haha. Thanks in advance :slight_smile:

Right now you have two applications in your application. It doesn’t really make any sense.

Unfortunately, your problem is not really a JME problem but a “how to develop in Java” problem. I recommend looking at some examples.

But to be clear, your problem is that your “Main” program never does anything with your Player… never creates it, uses it, etc… there is no magic background thing to create all of that for you. (And Player should absolutely not extend Main… as said, it makes no sense at all. “I want my steering wheel to extend Car…” Nonsense.)

So what would I need to add to my Main class so I can implement the Player class? I understand there has to be some way to bring it into the code so it actually recognizes it, I’m just not exactly sure how to do it with any effectiveness.

I see what you mean when you say I have two applications (simpleInitApp?), I’m just unsure how to keep the code separate from the Main class without essentially making the Player class useless code. I extended Main because I had no other idea how to keep the code from throwing errors left and right, but I do understand that isn’t really the way to go.

I don’t want a full writeup on how to do this and that, just a few pointers on how I should be going around this. I can follow examples and tutorials from there on and be fine. If it requires more than what you can tell me here, I’ll definitely get some more knowledge on this whole subject and figure it out from there. Thanks for the help so far though haha.

I mean, the problem is that these are super-beginner Java/programming questions.

I can answer this one. In your Main class, somewhere do something like:
Player player = new Player();
…and then use it for stuff.

…but that’s really only going to open up 20 more questions which will each lead to a 100 more questions and so on. Jumping right off into the deep end of the shark-infested ocean is like that, though.

Go through the examples, tutorials, break them, fix them, change them. Realize them.

JME is easy to use, but you do need to have some basic Java/programming skills or you’ll get nothing but frustration. I realize that you want to learn programming by making a simple game (and that’s certainly a fun way to do it), but you need to know the basics first. Start out with some super-simple single class Java tutorials, and break down the code line by line so that you understand what’s happening. Then try something a little more complicated. Once you understand what classes are and how to use them, then try again with jME. It’ll still be a challenge, but you’ll have enough of a foundation to get started.

Alright, looks like I’ll have to learn a little more about Java in general I suppose before I really dig into this kind of stuff. Thanks for the help guys, I appreciate it. :slight_smile: