Moving sun code

assetManager is a field of the Main class, which it inherited from a superclass.

In order to access it from another class, you must either copy the reference or have reference to an object that provides access.

Perhaps what you need is a Java tutorial:
Trail: Learning the Java Language (The Java™ Tutorials)

You should pass the app in the constructor of other classes. Then you can use:

app.getAssetManager();

This is my code now.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mygame;

import com.jme3.asset.AssetKey;
import com.jme3.asset.AssetManager;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.control.AbstractControl;
import static com.jme3.texture.Texture.WrapAxis.T;

/**
 *
 * @author Gebruiker
 */
public class SunControl extends AbstractControl{
    
    AssetManager assetManager;
    
    float time;
    Camera cam = new Camera(1,1);
    Vector3f position = new Vector3f();
    DirectionalLight directionalLight = new DirectionalLight();
    float timeFactor = 1f;
    ColorRGBA dayColor = new ColorRGBA(3f,3f,3f,0f);
    ColorRGBA eveningColor = new ColorRGBA(2f,2f,2f,0f);
    ColorRGBA sunColor= new ColorRGBA(1f,1f,1f,0f);
    float height;
    Main app;
    
    public SunControl(){
       
    }
        
    @Override
    public void controlUpdate(float tpf){
        
        cam.setLocation(new Vector3f(1f,1f,1f));
        float x = FastMath.cos(time) * 10f;
        float z = FastMath.sin(time) * 10f;
        float y = FastMath.sin(time) * 5f;
        position.set(x, y, z);
        spatial.setLocalTranslation((cam.getLocation().add(position)));
        spatial.lookAt(cam.getLocation(), Vector3f.UNIT_Y);
        directionalLight.setDirection(position.negate());
        time += tpf * timeFactor;
        time = time % FastMath.TWO_PI;
        height = y / 2;
        sunColor.interpolateLocal(eveningColor, dayColor, FastMath.sqr(height));
        directionalLight.setColor(sunColor);
        app.getAssetManager();
        Geometry geo = (Geometry) spatial;
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        geo.setMaterial(mat);
        
        //Material mat = geo.getMaterial();
        mat.setColor("Color", sunColor);
        
        //((Geometry)spatial).getMaterial().setColor("Color", sunColor);
        
    }   
    
    float getHeight(){
        return height;
    }
    
    public void controlRender(RenderManager rm, ViewPort vp){
        
    }
    
    
    
}

Still getting an NullPointerException on the following lines:

app.getAssetManager();

and

Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

That’s because you don’t know how to program software, and whilst it sounds like fun writing a game to learn, it’s probably the hardest way to go.

You really need to learn the basics first, like passing objects around, using constructors and assigning variables - which are all somewhere in the very beginning of learning any language.

We all started knowing nothing. We all have to learn. You must understand that you do, too. Please go and do some beginner tutorials. Make a calculator. A notepad. An image/file downloader. All of the skills you will learn will be transferable.

Change your constructor to something like this:

public SunControl(Main app) {
     this.app = app;
}

This allows you to pass your app to your control object so it can access it’s methods and variables.

Once you use the above constructor and pass your app to the control, the app you declared in the controls class will no longer be null so you successfully call app.getAssetManager();

EDIT:
you also are not doing anything by simply calling getAssetManager() you must return the value to your assetManager variable.

1 Like

Since controlUpdate(tpf) is being called every tick, and the Geometry and Material only need to be set once, so the following lines could be moved out of update (maybe moved to constructor);

        Geometry geo = (Geometry) spatial;
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        geo.setMaterial(mat);

… but you may need to begin with setting an initial color to the material that will likely be needed before the update is called.

Edit: Although, theoretically, you might want to apply the material to the spatial at it’s creation, before this control is even attached to it, and the color can be set from the control’s update each tick.

Second Edit: Also, I am not certain if there is a existing reason for creating an entirely new Camera just for this control, rather than using the Camera provided by your Main app (once it has been passed into constructor, like @JDC suggested);
cam = app.getCamera();

1 Like