[java] problem z używaniem zmiennych w różnych klasach

Witam,

mam dosyć skomplikowany problem, ale będę starał się wytłumaczyć to jak najlepiej :slight_smile:

Otóż mam 4 klasy: klasa Main.java, Data.java, Functions.java oraz OnDraw.java.

Main.java to klasa w której dokonywane są wszystkie ustawienia: od samego wyświetlania do ustawiania perspektywy itd.

Data.java - klasa zawierająca TYLKO zmienne, które są używane przez cały program.

Functions.java - wszelkie funkcje od odczytywania pozycji myszki do sterowania przeciwnikami.

OnDraw.java - klasa która wyświetla ostatecznie wszystkie obrazy z uwzględnieniem obliczeń z klasy functions.


Problem zaczął się kiedy wprowadziłem klasę Data.java. Wprowadziłem ją żebym wszystkie zmienne miał jako tako w jednym miejscu. Od tej pory, jeżeli chcę korzystać z jakiejś zmiennej muszę zrobić tak:

data.zmienna += 1;

zamiast:

zmienna += 1;

No dobra wszystko jest wporzo, żadnych błędów. Niestety okazuje się, że dostęp do obliczonych danych ma tylko klasa Functions.java. Dlaczego?

jako pierwsze (po main.java oczywiście) wykonują się funkcje w Functions.java. One to pobierają zmienne z Data.java. Wykonują się obliczenia itp. Potem czas na rysowanie i wykonują się funkcje z OnDraw, ale niestety one także pobierają zmeinne z Data.java. Tyle że Data.java nie miała okazji “zaaktualizować” zmiennych po obliczeniach z Functions. Czyli do OnDraw docierają zmienne o treści “0” lub “null”.


Więc: co zrobić aby do klasy onDraw dotarły zmienne z danymi obliczonymi z Functions?

Z góry dzięki za odpowiedzi i fatygę :wink:

Pokaż kod, albo chociaż fragmenty. Z opisu mogę domyślać się, że tworzysz odrębne instancje klasy Data, a zmienne nie są statyczne.

Oto klasa Data.java: tu są wszystkie zmienne.

package javaapplication2;


/**

 *

 * @author piotrek

 */

public class Data {

    String map[][] = {

        {"0nb0na0nb0na0nb0pa","0nb0na0nb0pb0nb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"},

        {"0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa","0nb0na0nb0pb0pb0pa"}

    };


    public float posPlayerX; //pozycja gracza w osi X

    public float posPlayerZ; //pozycja gracza w osi Z

    public float posPlayerY; //pozycja gracza w osi Y


    public static final int DISPLAY_HEIGHT = 800;

    public static final int DISPLAY_WIDTH = 800;


    boolean error = false;

    boolean load = false;

    public float LposX;

    public float LposY;

    public float lookUD; //pozycja kamery (z góry na dół)

    public float lookLR; //pozycja kamery (z lewej do prawej)

    public float scenerotation; // obrót sceny

    float piover180 = 0.0174532925f;

    float xpos;

    float zpos;

}

i OnDraw:

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */


package javaapplication2;


import static org.lwjgl.opengl.GL11.*;

import org.lwjgl.opengl.GL11;



/**

 *

 * @author piotrek

 */

public class OnDraw{

    Data data = new Data();


    Functions func;

    Main m;



    public OnDraw(){

        func = new Functions();

    }


    public void draw(){

        func.processMouse();

        func.processKeyboard();

        if(data.load == false){

            func.init();

            data.load = true;

        }


        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);

        GL11.glLoadIdentity();

        //Draw a basic square

                             // Move Into The Screen 5 Units

        glColor3f(1.0f,1.0f,1.0f);


        data.scenerotation = 360 - data.lookLR;

        GL11.glRotatef(data.lookUD,1.0f,0.0f,0.0f); //Rotate on the X axis

        GL11.glRotatef(data.scenerotation,0.0f,1.0f,0.0f); //Rotate on the Y axis

        //GL11.glRotatef(zrot,0.0f,0.0f,1.0f); //Rotate on the Z axis


        GL11.glTranslatef(0.0f+data.posPlayerX,0.0f,0.0f+data.posPlayerZ);

        //collision(1, data.map);

        func.drawMap(data.map);

    }

myślę że tyle wam wystarczy :slight_smile:

Problem polega na tym, że pozycja gracza (która jest obliczana w functions) nie dociera do OnDraw. Tzn. np. w OnDraw posPlayerX jest równe 0.

Nie widzę abyś gdziekolwiek przekazywał data do func, poza func.drawMap(data.map); Nie jest przypadkiem tak, że klasa Functions ma osobną instancję typu Data? Pokaż jeszcze Functions, szczególnie funkcje, które wg Ciebie powinny zmieniać dane.

package javaapplication2;

import org.lwjgl.opengl.GL11;

import org.newdawn.slick.opengl.Texture;

import org.newdawn.slick.opengl.TextureLoader;

import java.io.FileInputStream;

import java.io.IOException;

import org.lwjgl.input.Keyboard;

import org.lwjgl.input.Mouse;

import java.lang.Math;



/**

 *

 * @author piotrek

 */

public class Functions{

    //tutaj jest kilka zmiennych jeszcze nie przeniesionych do Data.java ^^

    public static final int DISPLAY_HEIGHT = 600;

    public static final int DISPLAY_WIDTH = 850;

    Texture trawa;

    Texture skrzynia;

    int c1, c2,c3, c4, c5, c6;

    String l1, l2, l3, l4, l5, l6;

    String l1a, l2a, l3a, l4a, l5a, l6a;


    Data data = new Data();


    //private Main m = new Main();

    /*

    public Functions(){

        m = new Main();

    }

     */

    [...]

public void processMouse() {

    data.LposX = Mouse.getX();

    data.LposY = Mouse.getY();

    //System.out.println("" + LposX);

    Mouse.setCursorPosition(50, 50);

    if(data.LposX > 47){data.lookLR -= 3.5f;}

    if(data.LposX < 53){data.lookLR += 3.5f;}

    if(data.LposY > 47){data.lookUD -= 3.5f;}

    if(data.LposY < 53){data.lookUD += 3.5f;}

    if(data.lookLR < 0){

        data.lookLR = 360;

    }

    if(data.lookLR > 360){

        data.lookLR = 0;

    }

  }

  [...]

podaję tylko jedną funkcję, która myślę że wystarczy…

Wygląda to dokładnie tak jak pisałem w dwóch poprzednich postach: masz dwie instancje klasy Data, dwa różne zestawy danych.

to ja tez wiem. ale co mam zrobic zeby bylo dobrze?

Nie znam tak dobrze Javy, ale przychodzą mi co najmniej 3 rozwiązania do głowy:

  • wszystkie pola w klasie Data statyczne (nie potrzebujesz w ogóle instancji klasy)

  • przekazywać konstruktorom wszystkich klas, które mają korzystać z tych samych danych tą samą instancję klasy Data

  • zrobić z klasy Data singleton

1 i 3 rozwiązanie odpada, jeśli chcesz mieć wiele zestawów danych.

Singletony są czasami niezbyt wygodne, ale jeżeli te dane tam są dość często zmieniane, to powinien być singletonem i dbać o synchronizację.

Daj wszystkie pola static. W Javie nie ma czegoś takiego jak zmienna/obiekt globalny, można jedynie zrobić jakąś publiczną klasę ze statycznymi metodami/polami/własną instancją.

Dzięki ci wielkie :slight_smile: Śmiga jak marzenie :slight_smile: