Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Uuden instanssin luonti ajon aikana Javassa

Sivun loppuun

Mobel [07.12.2007 18:55:07]

#

Luokkien yksi perusajatuksistahan on niiden pohjalta instanssien luominen. Nyt kuitenkin törmäsin ongelmaan instanssien kanssa. Tavallisestihan uusi luokka määriteltäisiin tässä tapauksessa näin: NPC botti=new NPC(); Nyt tarvittava määrä instansseja luokasta tulisikin määritellä ajon aikana skriptitiedoston ohjeiden mukaan.

Minulla on skriptitulkki, joka tulkkaa skriptikielen ja luo sen pohjalta NPCitä peliini. Olen luonut luokan NPC, jonka pelkistetty koodi löytyy alta. Ongelmaksi muodostuu uuden instanssin luominen "vauhdissa". Eli kun kutsutaan SkriptiTulkki-luokan createNPC()-metodia pitäisi pystyä luomann uusi instanssi NPC-luokasta. Miten mahtaa tämä onnistua, sillä eikös tämä ole yksi luokka-ajattelun tärkeimmistä eduista, joten kaipa se Javassakin onnistuu.

public class NPC {

	static int npcX=0, npcY=0, npcId=0;

	int[][] npcTaulukko=new int[10][2]; //luodaan taulukko, jonne laitetaan NPC:iden koordinaatteja (muutetaan vektoriksi)

	public void setX(int NPCKoordX){
		//asetetaan NPCn x-koordinaatti
		npcX=NPCKoordX;
	}

	public void setY(int NPCKoordY){
		//asetetaan NPCn y-koordinaatti
		npcY=NPCKoordY;
	}

	public void setId(int NPCId){
		//asetetaan NPCn Id
		npcId=NPCId;
	}


	public int getX(){
		return npcX; //palautetaan NPC:n x-korodinaatti
	}
	public int getY(){
		return npcY; //palautetaan NPC:n y-korodinaatti
	}
	public int getId(){
		return npcId; //palautetaan NPC:n id-numero
	}

	public boolean exists(int npcKoordX, int npcKoordY){ //metodi palauttaa arvon true jos koordinaateista löytyi NPC
		if(npcKoordX==npcX && npcKoordY==npcY){
			return true;
		}
		else return false;
	}


	public void addPuhe(String lisättäväPuhe){
           //lisätään puhepinkkaan parametrinä annettu puhe
           //koodi tähän

	}

	public String getPuhe(){
	   //palautetaan puheet
           //koodi tähän
	}
}

Muoks.
Itse itselleni vastaten mietin vaihtoehdoksi taulukkoa. Eli luodaan taulukko luokasta NPC ja sen avulla saadaan joku rajattu määrä NPCitä yhdelle kartalle.

Mutta onko mitään parempaa keinoa tähän ongelmaan?

kayttaja-2499 [07.12.2007 19:19:15]

#

Etkö ole törmännyt Javan Collectioneihin? http://java.sun.com/docs/books/tutorial/collections/index.html
Eli listoihin, pinoihin ja muihin?

Tuossa voisi käyttää vaikka java.util.Vector-luokkaa.

Mobel [08.12.2007 11:25:07]

#

Kiitos vastauksesta!

Kyllähän noita vastaan on tullut, ja olen niitä käyttänytkin, mutta kun tuli ongelma yllättäen vastaan eivät Collectionit tulleet heti mieleen. Ehkä vähän hätiköiden tännekin postasin. Tuohan vastaa vähän tuota taulukkotyyliä, jota itse ajattelin. Tietysti Vektori-luokalla homma hoituu ilman rajoituksia.

En kylläkään tähän tarkoitukseen noita Collectioneita ole käyttänyt, tai edes ajatellut asiaa, mutta aina oppii uutta.

Pitää nyt vielä kokeilla implementoida tätä koodiin, mutta toivottavasti onnistuu.

Sami [08.12.2007 13:24:34]

#

Lyhyesti se voisi mennä näin:

Vector<NPC> npcvektori = new Vector<NPC>();
NPC npc;
while ((npc = hae_seuraava_npc()) != null) {
  npcvektori.add(npc);
}

Tässä esimerkissä hae_seuraava_npc() palauttaa NPC-olion ja sitten kun NPC-data on loppunut niin nullin.

Mobel [08.12.2007 15:20:35]

#

Ajattelin tehdä selkeän kokeiluohjelman, joka demonstroisi vektorien toimintaa, mutta nyt vektorin kaikki solut muuttuvat yhtä vaihdettaessa. Tässä vielä linkki jos kokeilla haluaa: http://user.personal.fi/atk/Kaakeliuuni/Container-testi/bin/Vektori.html

Lähdekoodi:

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.Vector;

public class ContainerTesti extends Applet implements ActionListener{

	/**
	 * Pyrkii demonstroimaan vektorien toimintaa
	 */
	private static final long serialVersionUID = 1L;


	Vector<Auto> autoVektori = new Vector<Auto>(); //vektori autoille
	Auto vehe=new Auto(); //Auto-luokka

	//GUI
	Button nappi1=new Button();
	Button nappi2=new Button();
	Button nappi3=new Button();

	TextArea teksti=new TextArea(); //tekstikenttä näyttää arvoja

	public void init(){

		this.setSize(370, 370);

		//lisätään napit ja asetetaaan niille tapahtumakuuntelijat
		add(nappi1=new Button("Henkilöauto"));
		nappi1.addActionListener(this);

		add(nappi2=new Button("Kuorma-auto"));
		nappi2.addActionListener(this);

		add(nappi3=new Button("Urheiluauto"));
		nappi3.addActionListener(this);


		add(teksti); //lisätään myös tekstikenttä

		repaint();
	}

	public void paint(Graphics g){
		//piiretään GUI
		nappi1.setBounds(10, 20, 80, 20);
		nappi2.setBounds(100, 20, 80, 20);
		nappi3.setBounds(190, 20, 80, 20);
		teksti.setBounds(10, 50, 360, 180);
	}

	public void actionPerformed(ActionEvent e) {

		//riippuen napista kutsutaan createAuto-metodia eri parametreillä
		if(e.getActionCommand().equals("Henkilöauto")){
			teksti.setText("");
			autoVektori.add(createAtuo("Henkilöauto"));
			tulostaVektori(autoVektori);
		}
		if(e.getActionCommand().equals("Kuorma-auto")){
			teksti.setText("");
			autoVektori.add(createAtuo("Kuorma-auto"));
			tulostaVektori(autoVektori);
		}
		if(e.getActionCommand().equals("Urheiluauto")){
			teksti.setText("");
			autoVektori.add(createAtuo("Urheiluauto"));
			tulostaVektori(autoVektori);
		}

	}

	public Auto createAtuo(String tyyli){ //varmaankin tämän metodin toimintaa pitäisi muuttaa
		vehe.setMalli(tyyli);
		return vehe;
	}

	public void tulostaVektori(Vector<Auto> vektori){ //tulostaa vektorin
		int pituus=vektori.size();
		for(int i=0; i<pituus; i++){
			teksti.setText(teksti.getText()+" "+vektori.get(i).getMalli());
		}
	}

}

Auto-luokka:

public class Auto {

	private String autonMalli;


	public void setMalli(String malli){
		autonMalli=malli;
	}

	public String getMalli(){
		return autonMalli;
	}

}

Metabolix [08.12.2007 15:23:05]

#

No niin tekevät, kun käytät kaikissa samaa Auto-luokan edustajaa, jonka olet luonut muuttujaan vehe. Pitäisi joka kerta createAtuo-funktiossa luoda uusi Auto.

Olio a = new Olio();
Olio b;
a.muuttuja = 1;
b = a;
b.muuttuja = 2;
if (a.muuttuja == b.muuttuja) {
  // Tännehän tässäkin päädytään, koska a ja b viittaavat samaan olioon.
}

Mobel [08.12.2007 16:20:58]

#

Tietystihän tuo oli noin.
Kiitokset taas kärsivällisyydestä!

Sami [08.12.2007 16:29:17]

#

Jos haluat ensin kopioida Auto-olion ja asettaa kopiolle vain osan tiedoista toisiksi, niin voit lisätä kopiokonstruktorin, esim. näin:

public class Auto {

    private String autonMalli;

    public Auto(Auto kopioitava) {
        this.autonMalli = new String(kopioitava.autonMalli);
        // Ja jos luokalla on muita jäsenmuuttujia, niin nekin tietysti kopioidaan tässä... Siis kopioidaan koko olio muuttujineen, eikä vain viittauksia.
    }

    public void setMalli(String malli){
        autonMalli=malli;
    }

    public String getMalli(){
        return autonMalli;
    }

}

Ja tätähän voi sitten käyttää näin:

public Auto createAtuo(String tyyli){
    Auto uusiVehe = new Auto(vehe)
    uusiVehe.setMalli(tyyli);
    return uusiVehe;
}

Mobel [08.12.2007 16:36:39]

#

Jep. Sainkin tuon jo toimimaan niin kuin halusin. Ja tuo laittamasi esimerkkikin oli ihan hyödyllinen.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta