Új hozzászólás Aktív témák

  • Oppenheimer

    nagyúr

    Érdekes problémába ütköztem, nem tudom mi lehet a gond. Van az űrhajós játékomban 5 féle ellenség. Mindegyik más-más frekvenciával és amplitúdóval cikázik jobbra-balra. Legalábbis kellene nekik, de tök érthetetlenül mozognak.

    x és y int változók tárolják a pillanatnyi helyüket, de oly módon, hogy elvileg csak 0 és 100 közötti értéket vehetnek fel, mert ez alapján relatívan számolom ki a pozíciójukat az ablak méretétől függően.

    A GameArea (ami a JPanel leszármazottja) osztály drawEnemies() metódusa iterál végig az ellenséges hajókat tároló listán, és rajzolja ki őket.

    public void drawEnemies (Graphics g) {
    Iterator<Enemy> it = EnemyList.iterator();

    while (it.hasNext()) {
    Enemy enemy = (Enemy) it.next();

    if (enemy.getHealth() > 0)
    g.drawImage (enemy.getImage(), (int) (this.getWidth()*enemy.getX()/100), (int) (this.getHeight()*enemy.getY()/100), (int) (this.getWidth()*0.05), (int) (this.getHeight()*0.05), this);
    else
    DestroyEnemy (enemy);
    }
    }

    Amikor csak 1-1 hajót rajzolgattam ki, akkor ez rendben is működött, mindig ott volt a kép kirajzolva ahova terveztem, úgyhogy ezzel elvileg nincsen gond.

    Mind az összes "Enemy"-nek van egy saját Move() metódusa, amit ha 20 milliszekundumonként hívnak meg, akkor ennek elvileg az általam tervezett módon kéne az űrhajó koordinátáit módosítania. Például itt van az Enemy0 Move() methodja:

    // this method has to be called in every 20 milliseconds
    public void Move () {
    // in even seconds this enemy will go right
    long time = System.currentTimeMillis();
    if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
    x = (int) (x + GA.getWidth()*0.003);
    y = (int) (y + GA.getHeight()*0.001);
    }
    // else it will go left
    else {
    x = (int) (x - GA.getWidth()*0.003);
    y = (int) (y + GA.getHeight()*0.001);
    }
    }

    Ennek elvileg a páros másodpercekben jobbra, a páratlanokban balra kéne mennie, és egy másodperc alatt oldalirányban az ablak szélességének 15%-át megtennie.

    Pl. legyen az ablak 540*540-es felbontású. Ekkor az 1 másodperc alatti horizontális irányú elmozdulás pixelben kifejezve 540*0.003*1000/20 = 81, és 81/540 = 0,15, tehát az ablak szélességének 15%-a.

    1000/20-szal való szorzás úgy jött, hogy mint ahogy azt már említettem, 20ms-onként kell meghívódnia. Ami meg is történik itt:

    public void run() {
    while (true) {
    repaint();
    animator.animationCycle();

    try {
    Thread.sleep(20);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    Az animator ismeri a tárolót amiben az Enemy-k vannak, és végigiterálva rajtuk, meghívja mindnek a Move() metódusát az animationCycle() metóduson belül. Ezt megteszi minden 20ms-os alvás között.

    Mégis a következő képpen mozognak az ellenséges hajók:

    Az A-val jelölt hajók egy pillanat alatt lejönnek fentről, és kimennek a pályáról, a B-vel jelöltek meg abban a magasságban cikáznak jobbra balra, de jóval nagyobb amplitúdóval és sebességgel, mint amire számítottam a kód alapján. Ezt a képet csak úgy tudtam megcsinálni, hogy 900-ra állítottam a Thread.sleep()-et a run metódusban. Egyébként túl gyorsan cikáznának, főleg az A-val jelöltek, mert azok egyből el is repülnek.

    Ha 20ms-os alvással futtatom, akkor a B csoport hajói egy másodpercenként visszajönnek a látható pályára, egyszer jobb-, egyszer baloldalról érkezve, ugyanis akkora az amplitúdójuk, hogy idejük nagyját a pályán kívül töltik.

    Van valakinek ötlete, hogy kéne ezt debuggolni? :D

    Bemásolom még az ötféle Enemy Move() metódusát:

    Elsőé:
    // this method has to be called in every 20 milliseconds
    public void Move () {
    // in even seconds this enemy will go right
    long time = System.currentTimeMillis();
    if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
    x = (int) (x + GA.getWidth()*0.003);
    y = (int) (y + GA.getWidth()*0.001);
    }
    // else it will go left
    else {
    x = (int) (x - GA.getWidth()*0.003);
    y = (int) (y + GA.getWidth()*0.001);
    }
    }

    Másodiké:
    // this method has to be called in every 20 milliseconds
    public void Move () {
    // in uneven seconds this enemy will go right
    long time = System.currentTimeMillis();
    if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 1) {
    x = (int) (x + GA.getWidth()*0.0045);
    y = (int) (y + GA.getWidth()*0.002);
    }
    // else it will go left
    else {
    x = (int) (x - GA.getWidth()*0.0045);
    y = (int) (y + GA.getWidth()*0.002);
    }
    }

    Harmadiké:
    public void Move () {
    // in even seconds this enemy will go right
    long time = System.currentTimeMillis();
    if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
    x = (int) (x + GA.getWidth()*0.01);
    y = (int) (y + GA.getWidth()*0.0015);
    }
    // else it will go left
    else {
    x = (int) (x - GA.getWidth()*0.01);
    y = (int) (y + GA.getWidth()*0.0015);
    }
    }

    Negyediké:
    public void Move () {
    // in even seconds this enemy will go right
    long time = System.currentTimeMillis();
    if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
    x = (int) (x + GA.getWidth()*0.012);
    y = (int) (y + GA.getWidth()*0.002);
    }
    // else it will go left
    else {
    x = (int) (x - GA.getWidth()*0.012);
    y = (int) (y + GA.getWidth()*0.002);
    }
    }

    Ötödiké:
    public void Move () {
    // in even seconds this enemy will go right
    long time = System.currentTimeMillis();
    if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
    x = (int) (x + GA.getWidth()*0.012);
    y = (int) (y + GA.getWidth()*0.002);
    }
    // else it will go left
    else {
    x = (int) (x - GA.getWidth()*0.012);
    y = (int) (y + GA.getWidth()*0.002);
    }
    }

    B csoportba az van első és a harmadik Enemy, A csoportban a többi 3.

Új hozzászólás Aktív témák

Hirdetés