2013-04-29 44 views
0

使用我當前的代碼,我有一個角色加載到動畫的精靈表中。我運行代碼時出現問題。遊戲運行良好,除了玩家加載/騎自行車的精靈方式太快。我相信這源於整體遊戲時機/更新。我應該說,遊戲正在通過一個小程序。我收集了一些關於SwingerWorkers的信息,但我不知道如何操縱它以滿足我的需求。如果有人可以看看我的代碼,並讓我知道我能做什麼,我會很感激。SwingerWorker for Applet中的角色動畫?

播放器的構造函數:

public Player(Image pic, ImageObserver IO){ 

    positionX=200; 
    positionY=200; 
    destinationX=(int)positionX; 
    destinationY=(int)positionY; 
    speed = 2.3; 

    girlImage=pic; 
    this.io=IO; 
    width=120; 
    height=100; 
    //this.playerImage=playerImage; 

    // Gets each sprite 
    BufferedImage img = createImage(); 

    for(int j=0;j<4;j++) 
    { 
     for(int i = 0; i < frameCount; i++) { 
      girlAll[j][i] = girl[j].getSubimage(imgWidth*i, 0, imgWidth, imgHeight); 
     }//end of for 
    }//end of for 
} 

    // Image loader 
private BufferedImage createImage(){ 
    //BufferedImage bufferedImage; 
    try { 
     girl[0] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northeast_walk.png")); 
     girl[1] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northwest.png")); 
     girl[2] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southeast.png")); 
     girl[3] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southwest.png")); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

繪製方法:

public void draw(Graphics g){ 
    //g.drawImage(girlImage, (int)positionX,(int) positionY,io); 

    picNum = (picNum + 1) % frameCount; 
    pics = girlAll[x]; 
    if (x==0) 
     g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io); 
    if (x==1) 
     g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io); 
    if (x==2) 
     g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io); 
    if (x==3) 
     g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io); 
} 

SwingWorker的嘗試:

SwingWorker worker = new SwingWorker<BufferedImage[], Void>() { 

    public BufferedImage[] doInBackground(){ 
     //BufferedImage bufferedImage; 
     try { 
      girl[0] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northeast_walk.png")); 
      girl[1] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northwest.png")); 
      girl[2] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southeast.png")); 
      girl[3] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southwest.png")); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    public void loadImg() { 

     doInBackground(); 

     for(int j=0;j<4;j++) 
     { 
      for(int i = 0; i < frameCount; i++) { 
       girlAll[j][i] = girl[j].getSubimage(imgWidth*i, 0, imgWidth, imgHeight); 
      }//end of for 
     }//end of for 

    } 

}; 

} 

奔跑遊戲(從 '遊戲' 類):

public void init(){ 
    //Execute a job on the event-dispatching thread: 
    //creating this applet's GUI. 
    try { 
     SwingUtilities.invokeAndWait(new Runnable() { 
      public void run() { 
       createGUI(); 
      } 
     }); 
    } catch (Exception e) { 
     System.err.println("createGUI didn't successfully complete"); 
    }  

} 

線程處理:

private void gameStuff(){ 
    try {Thread.sleep(sleepTime);} 
    catch (InterruptedException e) {} 

    mouseClicked=false; 
} 

遊戲渲染:

public void update (Graphics g) 
{ 
//  initialize buffer 
    if (dbImage == null) 
    { 
     dbImage = createImage (this.getSize().width, this.getSize().height); 
     dbg = dbImage.getGraphics(); 

    } 

//  clear screen in background 
    dbg.setColor (getBackground()); 
    dbg.fillRect (0, 0, this.getSize().width, this.getSize().height); 

//  draw elements in background 
    //dbg.setColor (getForeground()); 
    paint (dbg); 

//  draw image on the screen 
    g.drawImage (dbImage, 0, 0, this); 

} 

另一種渲染方法:

private void hud(Graphics g){ 
    g.setColor(Color.orange); 
    g.fillRect(300, 0, 500, 80); 
    g.fillRect(200, 0, 100, 80); 

    //SHOVEL IMAGE AND BUTTON 
    g.drawImage(shovelImage,  520,0,this); 
    g.setColor(Color.black); 
    g.drawRect(520, 0, 60, 80);//show boundaries 
    if(mouseClicked && new Rectangle(520, 0, 60, 80).contains(mx,my)) 
     toolSelected=1; //sets tool selected to shovel 

    //ROCKS IMAGE AND BUTTON 
    g.drawImage(rocksImage,  600,0, this); 
    g.drawRect(600, 0, 60, 80);//show boundaries 
    if(mouseClicked && new Rectangle(600, 0, 60, 80).contains(mx,my)) 
     toolSelected=2; //sets tool selected to shovel 

    //JACKHAMMER IMAGE AND BUTTON 
    g.drawImage(jackHammerImage, 680,0, this); 
    g.drawRect(680, 0, 60, 80);//show boundaries 
    if(mouseClicked && new Rectangle(680, 0, 60, 80).contains(mx,my)) 
     toolSelected=3; //sets tool selected to shovel 

    if(timer.getAngle()<360){ 
    timer.draw(g); 
    } 
    if(timer.getAngle()==360){ 
     raining=true; 
     timer.reset(); 
     addDrops(); 
     roundNum++; 
     puddles(); 

    } 
    drawProgressBar(g); 

    if(toolSelected == 1) 
    { 
     Message = "Native Delaware plants"; 
     Message2 = "are good"; 
    } 
    else if(toolSelected == 2) 
    { 
     Message = "Rocks with Runoff"; 
     Message2 = " "; 
    } 
    else if(toolSelected == 3) 
    { 
     Message = "Permeated Driveways"; 
     Message2 = "help with excesse water"; 
    } 
    else{ 
     Message = "Play On"; 
     Message2 = " "; 
    } 
    g.drawString("Round "+roundNum, 350, 30); 
    g.drawString(Message, 205, 40); 
    g.drawString(Message2, 205, 55); 

    drawTiles(g); 

} 
+0

你是如何控制的時機?角色如何呈現在屏幕上? – MadProgrammer 2013-04-29 02:07:36

+0

同意 - 我的代碼中沒有看到任何遊戲控制循環。 – 2013-04-29 02:08:26

+0

我添加了一些我相信處理時間的代碼。 – blutuu 2013-04-29 02:11:12

回答

3
  • 使用的SwingWorker,如果你想要做的是一個時間之前控制簡單的遊戲循環,改爲使用Swing Timer
  • 如果我正在交換精靈圖片,我會考慮將JLabel中的圖標交換爲我想嘗試的最簡單的第一件事。
  • 請勿爲Swing GUI重寫update(Graphics g)。這用於AWT,但Swing不適用。圖形教程會告訴你這一點。
  • 請勿直接撥打paint(...)paintComponent(...)。有關更多詳情,請查看basic Swing drawing tutorial以及a more advanced article關於AWT和Swing中的繪畫。

例如:

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.lang.reflect.InvocationTargetException; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class SpriteAnimationApplet extends JApplet { 
    private static final String SPRITE_SHEET_SPEC = "http://www.funorb.com/img/images/game/" 
     + "central/dev_diary/sprite_sheet_full.gif"; 
    private static final int SPRITE_ROWS = 8; // an 8 x 8 sprite sheet 

    @Override 
    public void init() { 
     try { 
     final Icon[] icons = SpriteIO.getSprites(SPRITE_SHEET_SPEC, SPRITE_ROWS); 
     SwingUtilities.invokeAndWait(new Runnable() { 
      public void run() { 
       SpriteAnimationPanel spritePanel = new SpriteAnimationPanel(icons); 
       getContentPane().add(spritePanel); 
       spritePanel.startAnimation(); 
      } 
     }); 
     } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
     System.exit(-1); 
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     System.exit(-1); 
     } catch (MalformedURLException e) { 
     e.printStackTrace(); 
     System.exit(-1); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     System.exit(-1); 
     } 
    } 

} 

class SpriteIO { 
    public static Icon[] getSprites(String spriteSheetSpec, int spriteRows) 
     throws MalformedURLException, IOException { 
     Icon[] icons = new Icon[spriteRows * spriteRows]; 
     URL spriteSheetUrl = new URL(spriteSheetSpec); 
     BufferedImage spriteSheet = ImageIO.read(spriteSheetUrl); 
     double wD = (double) spriteSheet.getWidth()/spriteRows; 
     double hD = (double) spriteSheet.getHeight()/spriteRows; 
     int w = (int) wD; 
     int h = (int) hD; 
     for (int i = 0; i < spriteRows; i++) { 
     for (int j = 0; j < spriteRows; j++) { 
      int x = (int) (i * wD); 
      int y = (int) (j * hD); 
      BufferedImage img = spriteSheet.getSubimage(x, y, w, h); 

      icons[j * spriteRows + i] = new ImageIcon(img); 
     } 
     } 
     return icons; 
    } 
} 

@SuppressWarnings("serial") 
class SpriteAnimationPanel extends JPanel { 
    private static final int TIMER_DELAY = 200; 
    private Icon[] icons; 
    private JLabel animationLabel = new JLabel(); 

    public SpriteAnimationPanel(Icon[] icons) { 
     this.icons = icons; 
     setLayout(new BorderLayout()); 
     add(animationLabel); 
    } 

    public void startAnimation() { 
     Timer spriteTimer = new Timer(TIMER_DELAY, new ActionListener() { 
     private int iconIndex = 0; 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      animationLabel.setIcon(icons[iconIndex]); 
      iconIndex++; 
      iconIndex %= icons.length; 
     } 
     }); 
     spriteTimer.start(); 
    } 
} 
+0

像這樣的工作與一個小程序? – blutuu 2013-04-29 02:35:55

+0

@blutuu:在問這個問題之前,你看過我的代碼嗎?我問的原因是因爲我的代碼***以上***是一個小程序! – 2013-04-29 02:36:28

+0

請注意,這隻適用於沙盒或'沒有安全管理器'的小程序,因爲它試圖跨越SPRITE_SHEET_SPEC值的域。這是使小應用程序的SSCCE變得更加困難的原因之一。順便說一句 - OP,顯然這個URL可以改變,如果它指向'主服務器'的代碼將運行時,砂箱。 – 2013-04-29 02:41:20