2017-08-08 1 views
0

Ich arbeite an einem kleinen rundenbasierten RPG. Bei jedem Zug versucht einer der beiden Charaktere, das andere Zeichen zu treffen, und 2000 ms später startet der Timer erneut die Methode Angriff (um dem Spieler Zeit zu geben, das Ergebnis jedes Zuges zu lesen). Nach dem Kampf geht der Spieler zurück zur Levelkarte, wo er wählen kann, ob er wegziehen oder einen weiteren Kampf beginnen möchte. Hier ist mein Problem: Jedes Mal, wenn der Spieler einen neuen Kampf einleitet, wird die Timer-Verzögerung immer kürzer, so dass der Kampf irgendwann zu schnell vonstatten geht. Erster Kampf, jede Runde wird 2 Sekunden, dann 1 Sekunde, dann 500ms, und so weiter. Hier ist mein Code, was fehlt mir?Java Swing Timer wird immer schneller

public void attack(Character a, Character d) { 


    //Calculations////////////////////////////////////////////// 
    ///////////////////unit a (attacker)//////////////////////// 
    Weapon aWep = (Weapon) a.inventory[0]; 

    double aCritRate = (double) (a.skl/2 + aWep.crit - d.lck)/100; 
    double aHitRate = (double) (aWep.acc + (a.skl * 2) + (a.lck/2))/100; 
    double aAvoidRate = (double) (a.spd * 2 + a.lck)/100; 
    int aAttackPower = (a.pow + aWep.dmg); 
    boolean aTwice = a.spd >= d.spd + 4 ? true : false; 

    ///////////////////unit d (defender)//////////////////////// 
    Weapon dWep = (Weapon) d.inventory[0]; 

    double dCritRate = (double) (d.skl/2 + dWep.crit - a.lck)/100; 
    double dHitRate = (double) (dWep.acc + (d.skl * 2) + (d.lck/2))/100; 
    double dAvoidRate = (double) (d.spd * 2 + d.lck)/100; 
    int dAttackPower = (d.pow + dWep.dmg); 
    boolean dTwice = d.spd >= a.spd + 4 ? true : false; 

    int delay = 2000; 
    Timer timer; 

    ActionListener repeat = new ActionListener() 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      switch(bturn){ 
       case(1):attack(d,a); break; 
       default:break; 


      } 
     } 
    }; 

    timer = new Timer(delay,repeat); 

    //Battle///////////////////////// 

    int aDmg = aAttackPower - d.def; 
    double aHitChance = aHitRate - dAvoidRate; 
    String sound; 

    //Turn 1 

    if (aHitChance >= rngs[rngsIndex]) { 

     if (aCritRate >= rngs[rngsIndex]) { 
      aDmg *= 3; 
      sound="crit.wav"; 
      t.print("Critical Hit! " + a.name + " attacks " + d.name + " for " + aDmg + " damage!"); 
      rngsIndex++; 
     } else { 
      sound="hit.wav"; 
      t.print(a.name + " attacks " + d.name + " for " + aDmg + " damage!"); 
      rngsIndex++; 
     } 

     d.damageHp(aDmg); 
     rngsIndex++; 
    } else { 
     sound = "miss.wav"; 
     t.print(a.name + " has missed."); 
     rngsIndex++; 
    } 

    playSound(sound); 

    if (d.isDead) { 
     String add = t.text.getText(); 
     add+=" " + d.name + " has been killed."; 
     t.print(add); 
     a.xp+=35; 
     charPane.set(a); 
     grid[d.x][d.y].removeMouseListener(grid[d.x][d.y].hover); 
     killUnit(d, grid[d.x][d.y]); 
    } 

    if (d.faction.equals("e")) { 
     enemPane.set(d); 
    } else { 
     charPane.set(d); 
    } 

    //Turn 2 
    bturn++; 
    if(!d.isDead && bturn==1){ 
     System.out.println("REACHED"); 
     timer.start(); 
    } 

    else{ 
     timer.stop(); 
     bturn = 0; 
     grid[d.x][d.y].removeActionListener(grid[d.x][d.y].targetable); 
     clearGrid(); 
     loop(); 
    } 


} 
+1

Sie haben fast eine Rekursion geht hier bekommen, wo der Angriff Methode wird eine Timer-Instanz zu schaffen, die dann Angriff ruft die dann ** eine andere Instanz ** Timer erzeugt, welches Angriff nennt ..., und ich denke nicht, dass du das tun willst. Sie müssen diesen Code überdenken und dann neu verdrahten. –

+0

Beachten Sie, dass Sie den Timer an keiner Stelle stoppen, also werden viele Timer laufen, während dieses Programm läuft. –

+0

@HovercraftFullOfEels Ich habe einen Timer.stop(); in der letzten _else_ Anweisung – Nihilish

Antwort

0

Versuchen Sie zu protokollieren, welche Instanz von ActionListener den Angriff verursacht hat. Ich denke, Sie werden sehen, dass die Beschleunigung durch mehr Instanzen von Timer und ActionListener verursacht wird, als Sie möchten.

Nach jedem Durchlauf verdoppelt sich die Anzahl dieser Instanzen, daher das exponentielle Wachstum der Anzahl der Umdrehungen pro Sekunde.

In Abwesenheit von Logger:

public void actionPerformed(ActionEvent e) 
    { 
     System.out.println("" + LocalDateTime.now() + " " + this); 
     switch(bturn){