scg/ch13/core/BlockDrop

From FANG

Jump to: navigation, search

001 package scg.ch13.core;
002 
003 import java.awt.event.KeyEvent;
004 
005 import fang2.core.Game;
006 import fang2.sprites.StringSprite;
007 
008 import scg.ch13.highscore.HighScoreLevel;
009 
010 /**
011  * The {@link BlockDrop} game. Creates board, score, and next piece
012  * sprites and then just pumps the board sprite (calls its advance
013  * method).
014  */
015 @SuppressWarnings("serial")
016 public class BlockDrop
017   extends Game {
018   /** delay in seconds between down movement of blocks at level 1 */
019   private static final double INITIAL_MOVE_DELAY = 0.25;
020 
021   /** number of lines to clear to go up one level */
022   private static final int LINES_PER_LEVEL = 10;
023 
024   /** how much does the delay speed up at each level */
025   private static final double SPEED_UP_FACTOR = 1.05;
026 
027   /** the board where the game is played rules live there */
028   private Board board;
029 
030   /** display the current level */
031   private StringSprite displayLevel;
032 
033   /** what is the current level? */
034   private int level;
035 
036   /** countdown timer for moving the block */
037   private double moveClock;
038 
039   /** the time between block moves */
040   private double moveDelay;
041 
042   /** box showing the next piece */
043   private NextPieceBox nextPiece;
044 
045   /** sprite keeping and showing the score */
046   private ScoreSprite score;
047 
048   /**
049    * Create new game starting at level 1.
050    */
051   public BlockDrop() {
052     this(1);
053   }
054 
055   /**
056    * Create new game starting at the given level
057    *
058    @param  startLevel  level number to start at.
059    */
060   public BlockDrop(int startLevel{
061     moveDelay = INITIAL_MOVE_DELAY;
062     level = 0;
063     while (level != startLevel{
064       nextLevel();
065     }
066   }
067 
068   /**
069    * Advance to the next frame.
070    *
071    @param  dT  the time since the last advance
072    */
073   @Override
074   public void advance(double dT{
075     int oldScore = score.getScore();
076 
077     moveClock -= dT;
078     if (moveClock <= 0.0{
079       updateBoard();
080       moveClock += moveDelay;
081     }
082 
083     checkKeyPressed();
084 
085     int newScore = score.getScore();
086     updateLevel(oldScore, newScore);
087   }
088 
089   /**
090    * Setup the game by adding all the sprites.
091    */
092   @Override
093   public void setup() {
094     score = new ScoreSprite();
095     score.setScale(0.10);
096     score.setLocation(0.200.10);
097     addSprite(score);
098 
099     displayLevel = new StringSprite();
100     displayLevel.setScale(0.10);
101     displayLevel.setColor(getColor("green"));
102     displayLevel.setLocation(0.100.10);
103     displayLevel.setText(Integer.toString(level));
104     addSprite(displayLevel);
105 
106     board = new Board(score, 3010);
107     board.setLocation(0.50.5);
108     board.setScale(0.9);
109     addSprite(board);
110 
111     // scale nextPiece to match the piece scale of the board
112     double nextPieceSize = board.getBlockSize() * board.getScale();
113     nextPiece = new NextPieceBox(nextPieceSize);
114     nextPiece.setLocation(0.80.5);
115     nextPiece.nextPiece();
116     addSprite(nextPiece);
117 
118     board.add(nextPiece.getPiece());
119     nextPiece.nextPiece();
120   }
121 
122   /**
123    * Check if a key was pressed; if it was, handle it. Moved out of
124    {@link #advance(double)} to simplify reading that method.
125    */
126   private void checkKeyPressed() {
127     if (keyPressed()) {
128       char key = getKeyPressed();
129       if ((key == KeyEvent.VK_LEFT|| (key == KeyEvent.VK_KP_LEFT)) {
130         board.moveLeftIfPossible();
131       } else if ((key == KeyEvent.VK_RIGHT||
132           (key == KeyEvent.VK_KP_RIGHT)) {
133         board.moveRightIfPossible();
134       } else if ((key == KeyEvent.VK_DOWN||
135           (key == KeyEvent.VK_KP_DOWN)) {
136         board.moveDownIfPossible();
137       } else if ((key == KeyEvent.VK_UP||
138           (key == KeyEvent.VK_KP_UP)) {
139         board.rotateCCWIfPossible();
140       } else if ((key == ' ')) {
141         board.drop();
142         board.add(nextPiece.getPiece());
143         nextPiece.nextPiece();
144       }
145     }
146   }
147 
148   /**
149    * Actually end the current game. Check if we have a new high score
150    * and handle that if necessary. In any case, create a {@link
151    * HighScoreLevel} to show the high scores (and let the player start
152    * over if they wish)
153    */
154   private void endThisGame() {
155     HighScoreLevel attract = new HighScoreLevel(score.getScore());
156     addGame(attract);
157     finishGame();
158   }
159 
160   /**
161    * Move to the next level. Speed up, too.
162    */
163   private void nextLevel() {
164     ++level;
165     moveDelay /= SPEED_UP_FACTOR;
166     if (displayLevel != null{
167       displayLevel.setText(Integer.toString(level));
168     }
169   }
170 
171   /**
172    * Have the board try to move the current piece down. If it can't then
173    * the piece was frozen (by the board). Check if it ended the game. If
174    * it didn't, get a piece from the next piece generator and have it
175    * make a new piece. As long as the game has not ended, reset the move
176    * clock.
177    */
178   private void updateBoard() {
179     if (!board.moveDownIfPossible()) {
180       if (board.isGameOver()) {
181         endThisGame();
182         return;
183       }
184       board.add(nextPiece.getPiece());
185       nextPiece.nextPiece();
186     }
187   }
188 
189   /**
190    * Update the displayed level on the screen. The level is the number
191    * of times {@link #LINES_PER_LEVEL} rows have been cleared since the
192    * game started (plus the starting level). The level has changed if
193    * the integer quotient of the old score and the integer quotient of
194    * the new score, each divided by the lines per level, are different.
195    * If they are different, then the {@link #nextLevel()} method is
196    * called. It increments the level and speeds up the game.
197    *
198    @param  oldScore  score before the current play
199    @param  newScore  score after the current play
200    */
201   private void updateLevel(int oldScore, int newScore{
202     int oldScoreLevel = oldScore / LINES_PER_LEVEL;
203     int newScoreLevel = newScore / LINES_PER_LEVEL;
204     while (newScoreLevel > oldScoreLevel{
205       nextLevel();
206       ++oldScoreLevel;
207     }
208   }
209 }
210 
211 //Uploaded on Mon Mar 29 21:41:13 EDT 2010


Download/View scg/ch13/core/BlockDrop.java





Views
Personal tools
Add to 
del.icio.usAdd to 
diggAdd to 
FacebookAdd to 
favoritesAdd to 
GoogleAdd to 
MySpaceAdd to 
PrintAdd to 
SlashdotAdd to 
StumbleUponAdd to 
Twitter

Games
Games