2014-10-03 128 views
0

你好,我有一个图形编程纸的作业,它需要你设计一个类似Tetris的游戏。他们给你一个框架代码,以便我在下面发布。我的问题是关于最后的两个接口。我在哪里为接口中声明的函数编写函数定义,或者如何使用/实现这些函数?接口的函数定义

public class Tetris { 

    public static void createGUI() 
    { 
     final JFrame frame = new JFrame("159.235 - A2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final JPanel contentPane = new JPanel(new BorderLayout()); 
     frame.setContentPane(contentPane); 

    final GameBoard gameBoard = new GameBoard(); 
    contentPane.add(gameBoard, BorderLayout.CENTER); 

    frame.addKeyListener(new KeyListener() { 

     @Override 
     public void keyTyped(KeyEvent e) 
     { 
      gameBoard.keyTyped(e); 
     } 

     @Override 
     public void keyReleased(KeyEvent e) 
     { 
      gameBoard.keyReleased(e); 
     } 

     @Override 
     public void keyPressed(KeyEvent e) 
     { 
      switch (e.getKeyChar()) { 
      case KeyEvent.VK_ESCAPE: 
       gameBoard.pauseGame(); 
       System.exit(0); 
       break; 
      default: 
       gameBoard.keyPressed(e); 
      } 
     } 
    }); 

    frame.pack(); 
    frame.setResizable(false); 
    frame.setVisible(true); 

    // Note: you might want to add a button to start, pause, or resume the 
    // game instead of automatically starting it here 
    gameBoard.startGame(); 
} 

public static void main(String[] args) 
{ 
    SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() 
     { 
      createGUI(); 
     } 
    }); 
} 



class GameBoard extends JPanel implements KeyListener { 

private static final long serialVersionUID = 1L; 

// the number of rows and columns on the game board 
public static final int NUM_COLS = 10; 
public static final int NUM_ROWS = 20; 

// the size of each cell in pixels 
public static final int CELL_SIZE = 20; 

// the game board size in pixels 
public static final int GAME_FIELD_WIDTH = NUM_COLS * CELL_SIZE; 
public static final int GAME_FIELD_HEIGHT = NUM_ROWS * CELL_SIZE; 

// the interval between game state updates 
private int m_updateInterval = 500; 

// a random number generator 
private Random m_rng = new Random(); 

// the game timer initiates an upate to the game state 
private final Timer m_gameTimer = new Timer(m_updateInterval, 
     new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       advanceGameState(); 
      } 
     }); 

// the game board, with [0][0] being the bottom left cell 
private final Block[][] m_cells = new Block[NUM_ROWS][NUM_COLS]; 

// the currently active shape 
private Shape m_currentShape = null; 

private boolean m_gameOver = false; 

public GameBoard() 
{ 
    setMinimumSize(new Dimension(GAME_FIELD_WIDTH + 1, GAME_FIELD_HEIGHT)); 
    setPreferredSize(new Dimension(GAME_FIELD_WIDTH + 1, GAME_FIELD_HEIGHT)); 
    setOpaque(true); 

    // set-up the timer for the render loop 
    m_gameTimer.setInitialDelay(m_updateInterval); 
    m_gameTimer.setRepeats(true); 
} 

@Override 
public void keyPressed(KeyEvent e) 
{ 
    switch (e.getKeyCode()) { 
    case KeyEvent.VK_UP: 
     rotateShape(m_currentShape); 
     break; 
    case KeyEvent.VK_DOWN: // move down 
     break; 
    case KeyEvent.VK_LEFT: // move left 
     break; 
    case KeyEvent.VK_RIGHT: // move right 
     break; 
    case KeyEvent.VK_SPACE: // toggle pause/resume 
     if (m_gameTimer.isRunning()) pauseGame(); 
     else startGame(); 
     break; 
    } 
} 

@Override 
public void keyReleased(KeyEvent e) 
{ 
    switch (e.getKeyCode()) { 
    case KeyEvent.VK_DOWN: // disable down key 
     break; 
    case KeyEvent.VK_LEFT: // disable left key 
     break; 
    case KeyEvent.VK_RIGHT: // disable right key 
     break; 
    } 
} 

@Override 
public void keyTyped(KeyEvent e) 
{} 

public void startGame() 
{ 
    if (!m_gameOver) m_gameTimer.start(); 
} 

public void pauseGame() 
{ 
    m_gameTimer.stop(); 
} 

/** 
* Returns a randomly chosen shape. 
*/ 
private Shape createRandomShape() 
{ 
    final int numShapes = 7; 
    // generate a random number 
    final int shapeId = m_rng.nextInt(numShapes); 
    // create a new instance of the shape with this ID 
    final Shape shape = null; // e.g. new LineShape(); 
    return shape; 
} 

/** 
* Advances the game state by one time step. 
*/ 
private void advanceGameState() 
{ 
    if (m_gameOver) return; 

    if (m_currentShape == null) { 
     m_currentShape = createRandomShape(); 
    } 

    // move the current shape down by one row if possible; check for full 
    // rows when the shape can no longer move 
} 

/** 
* Rotates the given shape by one quadrant. 
* 
* @return True on success, false if the move is not possible. 
*/ 
private boolean rotateShape(final Shape shape) 
{ 
    // final float theta = (float) (Math.PI/2.); // 90 degree CCW 
    // shape.rotate(theta); 
    return true; 
} 

@Override 
protected void paintComponent(final Graphics g) 
{ 
    final Graphics2D g2 = (Graphics2D) g.create(); 
    final int height = getHeight(); 

    // flip the y-axis and translate to move (0,0) to the bottom left corner 
    g2.transform(AffineTransform.getTranslateInstance(0., height)); 
    g2.transform(AffineTransform.getScaleInstance(1., -1.)); 

    // paint all occupied cells 
    for (int row = 0; row < m_cells.length; ++row) { 
     for (int col = 0; col < m_cells[row].length; ++col) { 
      if (m_cells[row][col] != null) m_cells[row][col].draw(g2); 
     } 
    } 

    // this might be a good place to paint all animated blocks... 

    g2.dispose(); 
} 
} 


interface Block { 

/** 
* Returns the {@link Shape} this block belongs to. 
*/ 
Shape getShape(); 

/** 
* The row index of this block on the game board. 
*/ 
int getRow(); 

/** 
* The column index of this block on the game board. 
*/ 
int getColumn(); 

/** 
* Update the row index. 
*/ 
void setRow(int row); 

/** 
* Update the column index. 
*/ 
void setColumn(int column); 

/** 
* Apply the given transformation to the model space coordinates of this 
* block. 
*/ 
void transform(AffineTransform transform); 

/** 
* Draw this block in its current position on the game board. 
*/ 
void draw(Graphics2D g2); 

/** 
* The given transform, along with any additional animation related effects, 
* are applied to this draw only. They do not have a permanent affect on the 
* state of the block. 
* 
* @param g2 
*   The graphics instance. 
* @param transform 
*   The transform to apply on top of any existing transforms. 
* @param progress 
*   The animation progress in the range [0.0, 1.0]. 
*/ 
void animateAndDraw(Graphics2D g2, AffineTransform transform, 
     float progress); 
} 


interface Shape { 
/** 
* Returns the {@link Block}s that make up this shape. 
*/ 
Block[] getBlocks(); 

/** 
* Returns the shape's paint. 
*/ 
Paint getPaint(); 

/** 
* Rotates the shape by the specified amount. 
* 
* @param theta 
*   Angle in radians. 
*/ 
void rotate(float theta); 

}

+0

在'JFrame'上使用'KeyListener',哇,这不会很好结束 – MadProgrammer 2014-10-03 01:39:54

回答

0

你需要创建一个实现该接口,这意味着它包括在接口中定义的方法,并做一些事情与他们有用的一类。

class MyShape implements Shape { 

    @Override 
    public Block[] getBlocks() { 
     // Code that returns Block array 
    } 

    @Override 
    public Paint getPaint() { 
     // Code that returns Paint object 
    } 
} 

您可以阅读有关接口here的更多信息。