06 mainly defines some key events, inherits the KeyAdapter class, and the getKeyCode() method in KeyEvent can monitor what keys are pressed.
For the events of touching the left and right sides, the judgment is mainly made by the value of x. For continuously pressing the "Down" key, it is controlled by the sleep() parameter of Thread.
TetrisClient class:
import java.awt.*; import java.awt.event.*; public class TetrisClient extends Frame{ //declare the variable, where the window appears int x = 300; int y = 100; // game window width and height public static final int WIDTH = 400; public static final int HEIGHT = 480; //correct value public static final int CORRECT_X = 110; public static final int CORRECT_Y = 50; // size of the game area public static final int GAME_WIDTH = 200; public static final int GAME_HEIGHTH = 400; Shape s = new Shape(CORRECT_X + 60, CORRECT_Y + 60, 3); public void lancher() { //appear position this.setLocation(x,y); //size this.setSize(WIDTH, HEIGHT); //set title this.setTitle("Tetris Game"); // not resizable this.setResizable(false); // layout properties this.setLayout(null); //Set the game background color this.setBackground(new Color(255, 239, 213)); //Add window close event this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); // start a refresh thread new Thread(new paintThread()).start(); //visibility this.setVisible(true); //Add button monitoring this.addKeyListener(new keyMonitor()); } @Override public void paint(Graphics g) { Color c = g.getColor(); g.drawRect(CORRECT_X, CORRECT_Y, GAME_WIDTH, GAME_HEIGHTH); g.setColor(c); //Test about Shape s.draw(g); s.changeStatus(); if(!s.stopped) { s.drop(); } } public static void main(String[] args) { new TetrisClient().lancher(); } //Refresh class (inner class) - thread public class paintThread implements Runnable{ @Override public void run() { while(true) { repaint(); // refresh interval try { //"Down" key press to accelerate if(!s.speedUp) { Thread.sleep(300); } Thread.sleep(20); } catch (InterruptedException e) { e.getStackTrace(); } } } } //Inner class for key event private class keyMonitor extends KeyAdapter{ @Override public void keyPressed(KeyEvent e) { s.keyPressed(e); } @Override public void keyReleased(KeyEvent e) { s.keyReleased(e); } } }
Unit class:
import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; public class Unit { // where it appears private int x,y; //size public static final int SIZE = 20; //fall step public static final int SPEED = 20; //stop state public boolean stopped = false; //Shape color private Color color = Color.BLACK; //Constructor public Unit() { } public Unit(int x,int y) { this.x = x; this.y = y; } public Unit(int x,int y,Color color) { this(x,y); this.color = color; } // draw your own method public void draw(Graphics g) { //Color c = g.getColor(); //g.setColor(Color.BLUE); Graphics2D g2 = (Graphics2D)g; g2.setStroke(new BasicStroke(3.0f)); g.drawRect(x, y, SIZE - 5, SIZE - 5); g.fillRect(x + 2, y + 2, SIZE - 10, SIZE - 10); } public void drop() { y += SPEED; } //check the current state public void changeStatus() { if(y + SIZE >= TetrisClient.CORRECT_Y + TetrisClient.GAME_HEIGHTH) { stopped = true; } } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY () { return y; } public void setY(int y) { this.y = y; } public void moveLeft() { x -= SIZE; } public void moveRight() { x += SIZE; } public boolean hitLeft() { if(x <= TetrisClient.CORRECT_X) return true; return false; } public boolean hitRight() { if(x >= TetrisClient.CORRECT_X + TetrisClient.GAME_WIDTH - Unit.SIZE) return true; return false; } }
Shape类:
import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; import java.util.Random; public class Shape { int x,y; //Types of int type; //whether press "down" boolean speedUp = false; //whether to stop public boolean stopped = false; //image color private Color color = null; // color array public static Color[] ColorArr = { //new Color(255, 250, 205), new Color(230, 230, 250), new Color(238, 210, 238), new Color(106, 90, 205), new Color(192, 255, 62), new Color(162, 205, 90), new Color(255, 246, 143), new Color(255, 165, 0) }; //random class object Random r = new Random(); int colorIndex = r.nextInt(ColorArr.length); //type of graph int[][][] data= { {//0. One font {0,0,0,0}, {0,0,0,0}, {2,2,2,2}, {0,0,0,0} }, {//1. Tian font {0,0,0,0}, {0,2,2,0}, {0,2,2,0}, {0,0,0,0} }, {//2. L-shaped {0,0,0,0}, {0,2,0,0}, {0,2,0,0}, {0,2,2,0} }, {//3. Reverse L shape {0,0,0,0}, {0,2,0,0}, {0,2,0,0}, {2,2,0,0} }, {//4. Z shape {0,0,0,0}, {2,2,0,0}, {0,2,2,0}, {0,0,0,0} }, {//5. Reverse zigzag {0,0,0,0}, {0,0,2,2}, {0,2,2,0}, {0,0,0,0} }, {//6. Pin font {0,0,0,0}, {0,2,0,0}, {2,2,2,0}, {0,0,0,0} }, }; //Container that can hold Unit List<Unit> units = new ArrayList<Unit>(); //Construction method public Shape(int x,int y,int type) { this.x = x; this.y = y; this.type = type; // use random color this.color = ColorArr[colorIndex]; //Instantiate 4 unit objects for(int i = 0;i < 4;++i) { units.add(new Unit()); } createByType(); } private void createByType() { int count = 0; for(int i = 0;i < data[type].length;++i) { for(int j = 0;j < data[type][i].length;++j) { if(data[type][i][j] == 2) { units.get(count).setX(x + j * Unit.SIZE); units.get(count).setY(y + i * Unit.SIZE); count++; } } } } // draw public void draw(Graphics g) { g.setColor(color); for(int i = 0;i < units.size();++i) { units.get(i).draw(g); } } // drop method public void drop() { y += Unit.SPEED; for(int i = 0;i < units.size();++i) { units.get(i).drop(); } } //Check if it is stopped public void changeStatus() { //If each unit is judged to be stopped, modify the stop status for(int i = 0;i < units.size();++i) { Unit u = units.get(i); u.changeStatus(); if(u.stopped) { stopped = true; return; } } } // key event public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); switch(key) { case KeyEvent.VK_LEFT: if(!hitLeft()) moveLeft(); break; case KeyEvent.VK_RIGHT: if(!hitRight()) moveRight(); break; case KeyEvent.VK_DOWN: speedUp = true; } } private void moveRight() { x -= Unit.SIZE; for(int i = 0;i < units.size();++i) { units.get(i).moveRight(); } } private void moveLeft() { x += Unit.SIZE; for(int i = 0;i < units.size();++i) { units.get(i).moveLeft(); } } //Determine whether to touch the left public boolean hitLeft() { boolean b = false; for(int i = 0;i < units.size();++i) { if(units.get(i).hitLeft()) { b = true; break; } } return b; } // Determine whether to touch the right side public boolean hitRight() { boolean b = false; for(int i = 0;i < units.size();++i) { if(units.get(i).hitRight()) { b = true; break; } } return b; } public void keyReleased(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_DOWN) { speedUp = false; } } }