package russia.game.square;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;
import javax.swing.*;
/**
 * 游戏界面类 思路 当方块落到底部时用二维数组储存
 * 
 * @author lyj
 * 
 */
public class RussiaGame extends JPanel implements Serializable, KeyListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 数组的行数和列数 初始话界面的大小为 22行 12列
	 */
	private static final int ROW_SIZE = 22, COLUMN_SIZE = 12;
	/**
	 * 界面宽度
	 */
	private static final int WIDTH_SIZE = 344;
	/**
	 * 界面高度
	 */
	private static final int HEIGHT_SIZE = 375;
	/**
	 * 储存格子的数组
	 */
	private static int[][] shapeMap = new int[ROW_SIZE][COLUMN_SIZE];
	int[][] random;// 用来装载随机形状的二维数组
	/**
	 * 用来记载移动的坐标
	 */
	private int move_x = 5, move_y = -2;
	/**
	 * 方块大小
	 */
	private static final int SQUARE_SIZE = 20;
	/**
	 * 方块矩阵的大小
	 */
	private static final int MATRIX_SIZE = 5;
	/**
	 * 分数
	 */
	private int scores = 0;
	/**
	 * 判断游戏是否结束的标志
	 */
	private boolean canPlay = true;
	/**
	 * 休眠时间
	 */
	private int SLEEP_TIME = 500;
	/**
	 * 暂停游戏
	 */
	private boolean SLEEPGAME = true;
	/**
	 * ENTER 建的值用来标记暂停事件
	 */
	static final int VK_ENTER = 10;
	/**
	 * 下一个方块
	 * 
	 */
	static int[][] next;
	/**
	 * 用来装载当期方块和下一个方块
	 */
	private LinkedList<int[][]> shapeList = new LinkedList<int[][]>();
	
	  private Map<Points, Color> colorMap=new HashMap<Points, Color>();
    /**
     * 当前方块的颜色
     */
	  private Color randomColor=null;
	  /**
	   * 下个方块的颜色
	   */
	  private Color nextColor=null;
	
	  
	  
	  private LinkedList<Color> colors=new LinkedList<Color>();
	 public RussiaGame() {
		randomShape();
		randomColor();
		colorMap=FileHelpers.readColor();
		scores=FileHelpers.getScores();
		randomColorList();
		initShape();
		javax.swing.Timer time = new Timer(SLEEP_TIME, new GameLitsner());
		time.start();
		setBackground(Color.DARK_GRAY);
		setSize(new Dimension(WIDTH_SIZE, HEIGHT_SIZE));
	}
	private void initShape() {
		shapeMap = FileHelpers.read(ROW_SIZE, COLUMN_SIZE);
	}
	
	/**
	 * 判断是否能旋转 如果下一个图形所在的坐标没有越界和没有
	 * 
	 * @return true转换 false 不转换
	 */
	private boolean canTurnChange(int[][] newRandom) {
		boolean canTurn = true;
		if (move_y >=0){
			for (int i = MATRIX_SIZE - 1; i >= 0; i--) {
				for (int j = 0; j < MATRIX_SIZE; j++) {
					if (newRandom[i][j] == 1) {
						if (shapeMap[move_y + i][move_x + j] == 1
					    || shapeMap[move_y + i][move_x + j] == 2) {
							canTurn = false;
							break;
						}
					}
				}
			}
		}
	
		return canTurn;
	}
	/**
	 * 消行
	 * 
	 * @return
	 */
	private int[][] delteLine() {
		int count = 0;
		for (int i = ROW_SIZE - 2; i >= 1; i--) {
			if (canDelete(shapeMap[i])) {
				scores += 10;
				for (int j = 1; j <= 10; j++) {
					shapeMap[i][j] = 0;
					count++;
				
				}
			}
			if(count>=1){
				for (int j = 1; j <= 10; j++) {
					Points down=new Points(i,j);
					Points up =new Points(i-1,j);
					Color cor=colorMap.get(up);
				     if(cor!=null){
				     colorMap.remove(down);
				     colorMap.put(down,cor);
				     colorMap.remove(up);
				     }
					
				
				}
			}
			if (count >= 1) {
				int[] temp = shapeMap[i];
				shapeMap[i] = shapeMap[i - 1];
				shapeMap[i - 1] = temp;
			}
		}
		return shapeMap;
	}
	protected boolean canDelete(int[] line) {
		for (int i = 1, size = 10; i <= size; i++) {
			if (line[i] == 0) {
				return false;
			}
		}
		return true;
	}
	
	
	/**
	 * 重新开始游戏
	 */
	private void restart() {
		for (int i = 0; i <= 20; i++) {
			for (int j = 1; j <= 10; j++) {
				shapeMap[i][j] = 0;
			}
		}
		canPlay = true;
	}
	/**
	 * 判断游戏是否结束
	 * 
	 * @return
	 */
	private boolean gameOver() {
		int[] top = shapeMap[0];// 获得顶部
		for (int i = 1; i < COLUMN_SIZE - 1; i++) {
			if (top[i] == 1) {
				return true;
			}
		}
		return false;
	}
	/**
	 * 盘能是否能下落
	 * 
	 * @return
	 */
	private boolean canDown() {
		boolean canDown = true;
		int x = move_x == -1 ? move_x + 2 : move_x + 1;
		int len = shapeLength();
		if (move_y >= 0 && move_x < 12)
			for (int i = MATRIX_SIZE - 1; i >= 0; i--) {
				for (int j = 0; j < MATRIX_SIZE; j++) {
					if (random[i][j] == 1&&move_y+i+1<=21) {
						if (shapeMap[move_y + i + 1][move_x + j] == 1) {
							canDown = false;
							break;
						}
					}
				}
			}
		if (move_y >= 0 && x < 12 && shapeMap[move_y + len][x] == 2) {
			canDown = false;
		}
		return canDown;
	}
	/**
	 * 判断是否能左移
	 * 
	 * @return
	 */
	private boolean canLeft() {
		boolean canLeft = true;
		if(move_y>=0)
		for (int i = MATRIX_SIZE - 1; i >= 0; i--) {
			for (int j = 0; j < MATRIX_SIZE; j++) {
				if (random[i][j] == 1) {
					if (shapeMap[move_y + i][move_x + j - 1] == 1
							|| shapeMap[move_y + i][move_x + j - 1] == 2) {
						canLeft = false;
						break;
					}
				}
			}
		}
		return canLeft;
	}
	/**
	 * 获得方块的长度
	 */
	private int shapeLength() {
		for (int leng = 5; leng >= 1; leng--) {
			int[] number = random[leng - 1];
			for (int index = 0; index < 5; index++) {
				if (number[index] == 1) {
					return leng;
				}
			}
		}
		return -1;
	}
	/**
	 * 画当前方块
	 * 
	 * @param gs
	 */
	private void paintCurr(java.awt.Graphics gs, int[][] randoms) {
		gs.setColor(randomColor);
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (randoms[i][j] == 1) {
					gs.fill3DRect(j * SQUARE_SIZE + move_x * SQUARE_SIZE, i
							* SQUARE_SIZE + move_y * SQUARE_SIZE, SQUARE_SIZE,
							SQUARE_SIZE, true);
				}
			}
		}
	}
	private void paintNext(java.awt.Graphics gs) {
		gs.setColor(nextColor);
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (next[i][j] == 1) {
					gs.fill3DRect(j * SQUARE_SIZE + 250, i * SQUARE_SIZE,
							SQUARE_SIZE, SQUARE_SIZE,true);
				}
			}
		}
	}
	/**
	 * 画走马灯
	 * @param gs
	 */
	private void paintTwinkLight(java.awt.Graphics gs){
		int index=0;
		gs.setColor(Color.BLACK);
		for (int i = 1; i <= 22; i++) {
			gs.setColor(colorList.get(index));
		gs.fillOval(3, (i-1)* SQUARE_SIZE+2, 15, 15);
		index++;
		
		}
		for (int j = 1; j <=10; j++) {
			gs.setColor(colorList.get(index));
			gs.fillOval( j*SQUARE_SIZE+3, 21* SQUARE_SIZE+2, 15, 15);
			index++;
		}
	for (int i = 22; i >=1; i--) {
		gs.setColor(colorList.get(index));
		gs.fillOval( 11*SQUARE_SIZE+3,  (i-1)*SQUARE_SIZE+2, 15, 15);
		index++;
	}
	}
	
	private static LinkedList<Color> colorList=new LinkedList<Color>();
	private  static void randomColorList(){
		int index=0;
    for(int i=1;i<=54;i++){
    colorList.add(Shapes.shapeColors[index]);
    if(index==7){
    	index=0;
    }
    index++;
  }		
		
	}
	@Override
	// 画组建的方法
	protected void paintComponent(java.awt.Graphics g) {
		super.paintComponent(g);
		Image bc = new ImageIcon("save/333.jpg").getImage();
		g.drawImage(bc, 0, 0, getWidth(), getHeight(), this);
		g.setColor(Color.red);
		g.drawString("分数" + scores, 250, 150);
		g.drawString("F5 清屏重新开始  ", 250, 190);
		g.drawString("ENTER 暂停\\开始游戏", 250, 230);
		g.drawString("ESC 退出并保存", 250, 270);
		paintNext(g);
		paintTwinkLight(g);
		// 绘制当前方块
		paintCurr(g, random);
		// 画已经落下的方块
		for (int j = 0; j < ROW_SIZE; j++) {
			for (int i = 0; i < COLUMN_SIZE; i++) {
				if (shapeMap[j][i] == 1) {
					Points p=new Points(j,i);
					if(colorMap.get(p)!=null){
					g.setColor(colorMap.get(p));
					}
					
					g.fill3DRect(i * SQUARE_SIZE, j * SQUARE_SIZE, SQUARE_SIZE,
							SQUARE_SIZE, true);
				}
				if (shapeMap[j][i] == 2) {
					g.setColor(Color.black);
					g.drawRect(i * SQUARE_SIZE, j * SQUARE_SIZE, SQUARE_SIZE,
							SQUARE_SIZE);
				}
			}
		}
	};
	/**
	 * 生成随机形状
	 * 
	 * @return
	 */
	private void randomShape() {
		Random ran = new Random();
		int len=Shapes.shapeAry.length;
		if (shapeList.size() == 2) {
			shapeList.removeFirst();
			shapeList.addLast(Shapes.shapeAry[ran.nextInt(len)]);
		} else {
			shapeList.addFirst(Shapes.shapeAry[ran.nextInt(len)]);
			shapeList.addLast(Shapes.shapeAry[ran.nextInt(len)]);
		}
		random = shapeList.getFirst();
		next = shapeList.getLast();
	}
	
	private void randomColor(){
		Random ran = new Random();
		if(colors.size()==2){
			colors.removeFirst();
			colors.addLast(Shapes.shapeColors[ran.nextInt(Shapes.shapeColors.length)]);
			
		}
		else{
			colors.addFirst(Shapes.shapeColors[ran.nextInt(Shapes.shapeColors.length)]);
			colors.addLast(Shapes.shapeColors[ran.nextInt(Shapes.shapeColors.length)]);
		}
		randomColor=colors.getFirst();
		nextColor=colors.getLast();
	}
	
	/**
	 * 画墙壁的方法
	 */
	private void clearMap() {
		shapeMap = new int[ROW_SIZE][COLUMN_SIZE];
		for (int i = 0; i < ROW_SIZE; i++) {
			shapeMap[i][0] = 2;
			shapeMap[i][COLUMN_SIZE - 1] = 2;
		}
		// 画底部的格子
		for (int j = 0; j < COLUMN_SIZE; j++) {
			shapeMap[ROW_SIZE - 1][j] = 2;
		}
	}
	private void turnLef() {
		if (move_y>=0&&canLeft()) {
			move_x--;
			shapeMap = delteLine();
			repaint();
		}
	}
	/**
	 * 判断是否能右移
	 * 
	 * @return
	 */
	private boolean canRight() {
		boolean canRight = true;
		if(move_y>=0)
		for (int i = MATRIX_SIZE - 1; i >= 0; i--) {
			for (int j = 0; j < MATRIX_SIZE; j++) {
				if (random[i][j] == 1) {
					if (shapeMap[move_y + i][move_x + j + 1] == 1
							|| shapeMap[move_y + i][move_x + j + 1] == 2) {
						canRight = false;
						break;
					}
				}
			}
		}
		return canRight;
	}
	private void turnRight() {
		if (move_y>=0&&canRight()) {
			move_x++;
			shapeMap = delteLine();
			repaint();
		}
	}
	private void turnUp() {
		int[][] newRandom = rounding();
		if (canTurnChange(newRandom)) {
			random = newRandom;
		}
		shapeMap = delteLine();
		repaint();
	}
	private void turnDown() {
		if (canDown())
			move_y++;
		shapeMap = delteLine();
		repaint();
	}
	/**
	 * 旋转矩阵
	 * 
	 * @return
	 */
	public int[][] rounding() {
		int[][] newRandom = new int[random.length][random[0].length];
		if (random == Shapes.shapeAry[2]                          ) {
			return random;
		}
		else if(random == Shapes.shapeAry[5]){
			return  Shapes.shapeAry[6];
		}
		else if(random == Shapes.shapeAry[6]){
			return  Shapes.shapeAry[5];
		}
		
		for (int i = 0; i < random.length; i++) {
			for (int j = 0; j < random[0].length; j++) {
				newRandom[j][random[0].length - i - 1] = random[i][j];
			}
		}
		return newRandom;
	}
	
	class GameLitsner implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (SLEEPGAME)
				if (gameOver() == false) {
					if (canDown()) {
						move_y++;
						shapeMap = delteLine();
						Color first=colorList.getFirst();
						colorList.removeFirst();
						colorList.addLast(first);
						repaint();
					} else {
						shapeMap = delteLine();
						addShapeAndColor();
						Color first=colorList.getFirst();;
						colorList.removeFirst();
						colorList.addLast(first);
						move_x = 5;
						move_y = -5;
						randomShape();
						randomColor();
						repaint();
					}
				}
				else
					canPlay = false;
		}
	}
/**
 * 添加下落好的方块和颜色
 */
	private void addShapeAndColor() {
		int len = shapeLength();
		int index = len == 3 ? 3 : 4;
		for (int i = 0; i < 5; i++, index--) {
			for (int j = 0; j < 5; j++) {
				 if (random[i][j] == 1 && move_y + len - index >= 0) {
					shapeMap[move_y + len - index][move_x + j] = 1;
					Points ps=new Points(move_y + len - index,move_x + j);
					colorMap.put(ps, randomColor);
				}
			}
		}
	}
	public void keyPressed(KeyEvent key) {
		if (canPlay && SLEEPGAME)
			switch (key.getKeyCode()) {
			// 改变形状
			case KeyEvent.VK_UP:
			case KeyEvent.VK_W:
				turnUp();
				break;
			// 下落
			case KeyEvent.VK_DOWN:
			case KeyEvent.VK_S:
				turnDown();
				break;
			// 左移
			case KeyEvent.VK_LEFT:
			case KeyEvent.VK_A:
				turnLef();
				break;
			// 右移
			case KeyEvent.VK_RIGHT:
			case KeyEvent.VK_D:
				turnRight();
				break;
			case KeyEvent.VK_ESCAPE:
			int isSave=JOptionPane.showConfirmDialog(null, "是否保存游戏", null, JOptionPane.YES_NO_OPTION);
				if (isSave == 0) {
					FileHelpers.wirte(shapeMap, ROW_SIZE, COLUMN_SIZE);
				     FileHelpers.write(colorMap,scores);
				} else {
					clearMap();
					FileHelpers.wirte(shapeMap, ROW_SIZE, COLUMN_SIZE);
				    FileHelpers.write(null,0);
				}
				System.exit(1000);
				break;
			}
		if (key.getKeyCode() == KeyEvent.VK_F5) {
			restart();
		}
		if (key.getKeyCode() == VK_ENTER) {
			SLEEPGAME = SLEEPGAME == true ? false : true;
		} else if (canPlay == false) {
			JOptionPane.showMessageDialog(null, "Game Over!");
			scores = 0;
		}
	}
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
	}
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
	}
}
最近下载更多
                
                solotoo     LV2
                2021年11月13日
            
            
        
                heiqiang198603     LV1
                2021年9月18日
            
            
        
                睡前亲口月亮     LV1
                2020年10月2日
            
            
        
                小学期gogo     LV2
                2020年7月6日
            
            
        
                chen519168     LV9
                2020年6月1日
            
            
        
                GG思密达da     LV9
                2020年1月15日
            
            
        
                爱心12345     LV1
                2020年1月9日
            
            
        
                我就笑笑     LV12
                2019年12月16日
            
            
        
                矿泉水     LV30
                2019年8月26日
            
            
        
                sagdsshhs     LV2
                2019年6月26日
            
            
        
最近浏览更多
                
                小张java    
                2024年7月3日
            
            
                    暂无贡献等级
            
        
                鬼屋报道     LV3
                2024年6月4日
            
            
        
                微信网友_6775263012638720     LV1
                2023年12月12日
            
            
        
                微信网友_6699076084797440     LV7
                2023年10月30日
            
            
        
                小安同学     LV7
                2023年5月11日
            
            
        
                微信网友_6268131861106688     LV5
                2022年12月21日
            
            
        
                3272047233     LV1
                2022年12月14日
            
            
        
                balabalawuyu     LV6
                2022年11月26日
            
            
        
                迷迭香     LV10
                2022年9月21日
            
            
        
                tree1112666     LV1
                2022年8月19日
            
            
        
                
                
                