2017-08-08 84 views
0

我正在做一個基於小回合的RPG遊戲。對於每一回合,兩個角色中的一個嘗試在2000ms後擊中另一個角色,定時器重新開始攻擊方法(給玩家時間以讀取每回合的結果)。戰鬥結束後,玩家會回到水平地圖,在那裏他可以選擇離開或開始另一場戰鬥。這是我的問題:每當玩家發起一場新的戰鬥時,計時器延遲越來越短,所以在某個時刻戰鬥發生得太快。第一次戰鬥,每回合將是2秒,然後1秒,然後500毫秒,依此類推。這是我的代碼,我錯過了什麼?Java Swing Timer變得越來越快

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

你已經有了將近遞歸會在這裏,這裏的攻擊方法是創建一個Timer實例,然後調用攻擊,然後創建** **另一個定時器實例,這就是所謂的攻擊...,我不認爲你想這樣做。您需要重新思考,然後重新連線此代碼。 –

+0

請注意,不管您在哪裏停止計時器,所以在此程序運行時您將有許多計時器正在運行。 –

+0

@HovercraftFullOfEels我有一個timer.stop();在最後_else_語句 – Nihilish

回答

0

嘗試記錄哪個ActionListener重複實例導致了攻擊。我想你會看到,加速是由於有更多的Timer和ActionListener實例,然後你想要的。

每次運行後,這些實例的數量會翻倍,因此每秒轉數的指數級增長。

在無記錄的:

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