实例介绍
【实例简介】
java基础编写的俄罗斯方块
【实例截图】
【核心代码】
package com.akxy.yp.tetris; //Frame 框, 相框 JFrame窗口框 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.util.Arrays; import java.util.Timer; import java.util.TimerTask; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; /** * 俄罗斯方块 * 俄罗斯方块 扩展了 空白面板, 添加了属性: 墙, 正在下落 * 的方块和下一个方块. */ public class Tetris extends JPanel { private int score;//累计分数 private int lines;//销毁的行数 private Cell[][] wall;//(墙 20行X10列) private Tetromino tetromino;//正在下落的(4格方块,有7种形态) private Tetromino nextOne;//下一个准备下落的方块 /** 背景图片 */ private static BufferedImage background; private static BufferedImage overImage; public static BufferedImage T; public static BufferedImage S; public static BufferedImage I; public static BufferedImage L; public static BufferedImage J; public static BufferedImage O; public static BufferedImage Z; public static final int ROWS = 20;//行 public static final int COLS = 10;//列 //将图片素材, 复制到包中. /** 使用静态代码块加载静态的图片 */ static{ try{ //Tetris.class的同一个包中找 "tetris.png" background=ImageIO.read( Tetris.class.getResource("tetris.png")); overImage=ImageIO.read( Tetris.class.getResource("game-over.png")); T=ImageIO.read( Tetris.class.getResource("T.png")); I=ImageIO.read( Tetris.class.getResource("I.png")); S=ImageIO.read( Tetris.class.getResource("S.png")); Z=ImageIO.read( Tetris.class.getResource("Z.png")); J=ImageIO.read( Tetris.class.getResource("J.png")); L=ImageIO.read( Tetris.class.getResource("L.png")); O=ImageIO.read( Tetris.class.getResource("O.png")); }catch(Exception e){ e.printStackTrace(); } } /** JPanel paint() paint画 * 重写 paint() 修改原有的绘制方法 **/ @Override public void paint(Graphics g) { //画背景, 画墙, 画正在下落的方块 画下一个方块... g.drawImage(background, 0, 0, null); g.translate(15, 15);//坐标系平移 paintWall(g);//画墙 paintTetromino(g);//画正在下落的方块 paintNextOne(g); paintScore(g); g.translate(-15, -15); if(gameOver){ g.drawImage(overImage, 0, 0, null); } //g.setColor(new Color(0x0000ff)); //g.drawRect(10, 10, 50, 80); } public static final int FONT_COLOR=0x667799; public static final int FONT_SIZE=30; private void paintScore(Graphics g) { int x = 290; int y = 160; g.setColor(new Color(FONT_COLOR)); Font font = g.getFont();//取得g当前字体 font = new Font(font.getName(), font.getStyle(), FONT_SIZE); g.setFont(font);//更改了g的字体 String str = "SCORE:" score; g.drawString(str, x, y); y =56; str = "LINES:" lines; g.drawString(str, x, y); y =56; str = "[P]Pause"; if(pause){ str = "[C]Continue"; } if(gameOver){ str = "[S]Start!"; } g.drawString(str, x, y); } private void paintNextOne(Graphics g) { if(nextOne==null){ return; } //将每个格子的row,col 换算为x,y 然后贴图 Cell[] cells = nextOne.cells; for(int i=0; i<cells.length; i ){ //i = 0 1 2 3 Cell cell = cells[i]; //cell 每个格子 int x = (cell.getCol() 10)*CELL_SIZE; int y = (cell.getRow() 1)*CELL_SIZE; g.drawImage(cell.getImage(), x-1, y-1, null); } } public void paintTetromino(Graphics g){ //System.out.println("paint:" tetromino); if(tetromino==null){ return; } //将每个格子的row,col 换算为x,y 然后贴图 Cell[] cells = tetromino.cells; for(int i=0; i<cells.length; i ){ //i = 0 1 2 3 Cell cell = cells[i]; //cell 每个格子 int x = cell.getCol() * CELL_SIZE; int y = cell.getRow() * CELL_SIZE; g.drawImage(cell.getImage(), x-1, y-1, null); } } public static final int CELL_SIZE = 26; /** 画墙 */ private void paintWall(Graphics g){ for(int row=0; row<wall.length; row ){ Cell[] line = wall[row]; //line 代表墙上的每一行 for(int col=0; col<line.length; col ){ Cell cell = line[col]; //cell 代表墙上的每个格子 int x=col*CELL_SIZE; int y=row*CELL_SIZE; if(cell==null){ //g.drawRect(x,y,CELL_SIZE,CELL_SIZE); }else{ g.drawImage(cell.getImage(), x-1, y-1, null); } } } } /** 在Tetris 添加启动方法 action() */ public void action(){ wall = new Cell[ROWS][COLS]; startAction(); // wall[2][2] = new Cell(2,2, T); // tetromino = Tetromino.randomOne(); // System.out.println( // "After rendomOne:" tetromino); // nextOne = Tetromino.randomOne(); //处理键盘按下事件, 在按下按键时候执行下落方法 KeyAdapter l = new KeyAdapter(){ @Override //key 按键 Pressed按下了 public void keyPressed(KeyEvent e) { int key = e.getKeyCode();//[c] if(key==KeyEvent.VK_Q){ System.exit(0);//结束Java进程 } if(gameOver){ if(key==KeyEvent.VK_S){ startAction(); repaint(); } return; } if(pause){//pause = true if(key==KeyEvent.VK_C){ continueAction(); repaint(); } return; } switch (key) { case KeyEvent.VK_DOWN:softDropAction();break; case KeyEvent.VK_RIGHT:moveRightAction();break; case KeyEvent.VK_LEFT:moveLeftAction();break; case KeyEvent.VK_SPACE:hardDropAction();break; case KeyEvent.VK_UP:rotateRightAction();break; case KeyEvent.VK_P:pauseAction();break; } repaint();//再画一次! } }; // 下落流程: 监听键盘事件->如果下箭头按下-> // 执行下落算法tetromino.softDrop()-> // 修改每个格子对象的数据->调用repaint()-> // 尽快调用paint()->paint方法会根据当前的数据 // 重新绘制界面 -> 看到移动以后的方块了 //绑定事件到当前面板 this.requestFocus(); this.addKeyListener(l); } /** 在Tetris 类上添加方法, 向右移动的流程控制 */ public void moveRightAction(){ //尝试先向右移动, 如果发现超出了边界, 就 //向左移动, 修正回来. tetromino.moveRight();//coincide重叠 if(outOfBounds() || coincide()){ tetromino.moveLeft(); } } /** 检查正在下落的方块是否与墙上的砖块重叠 */ private boolean coincide() { Cell[] cells = tetromino.cells; for(int i=0; i<cells.length; i ){ Cell cell = cells[i]; int row = cell.getRow(); int col = cell.getCol(); //如果墙的row,col位置上有格子,就重叠了! if(row>=0 && row<ROWS && col>=0 && col<=COLS && wall[row][col]!=null){ return true;//重叠 } } return false; } /** 检查当前正在下落的方块是否出界了 */ private boolean outOfBounds(){ Cell[] cells = tetromino.cells; for(int i=0; i<cells.length; i ){ Cell cell = cells[i]; int col = cell.getCol(); if(col<0 || col>=COLS){ return true; } } return false; } public void moveLeftAction(){ tetromino.moveLeft(); if(outOfBounds() || coincide()){ tetromino.moveRight(); } } /** 下落流程控制 */ public void softDropAction(){ if(canDrop()){ tetromino.softDrop(); }else{ landIntoWall(); destoryLines(); checkGameOverAction(); tetromino = nextOne; nextOne = Tetromino.randomOne(); } } private static int[] scoreTable ={0,1,10,50,100}; // 0 1 2 3 4 private void destoryLines() { int lines = 0; for(int row=0; row<wall.length; row ){ if(fullCells(row)){ deleteRow(row); lines ; } } this.score = scoreTable[lines]; this.lines =lines; } private void deleteRow(int row) { for(int i=row; i>=1; i--){ System.arraycopy( wall[i-1], 0, wall[i], 0, COLS); } Arrays.fill(wall[0], null); } /** 检查当前行的每个格子, 如果有null返回false * 否则返回 true */ private boolean fullCells(int row) { Cell[] line = wall[row]; for(Cell cell: line){ if(cell==null){ return false; } } return true; } private void landIntoWall() { Cell[] cells = tetromino.cells; for(int i=0; i<cells.length; i ){ Cell cell = cells[i]; int row = cell.getRow(); int col = cell.getCol(); wall[row][col]=cell; } } /** 检查当前的方块是否能够下落, 返回true能够下落 */ private boolean canDrop() { Cell[] cells = tetromino.cells; for(int i=0; i<cells.length; i ){ Cell cell = cells[i]; int row = cell.getRow(); if(row == ROWS-1){ return false; } } for(Cell cell: cells){//Java 5 以后可以使用 int row = cell.getRow() 1; int col = cell.getCol(); if(row>=0 && row<ROWS && col>=0 && col<=COLS && wall[row][col]!=null){ return false; } } return true; } /** 硬下落流程, 下落到不能下落为止 * 绑定到 空格(VK_SPACE)事件上 * */ public void hardDropAction(){ while(canDrop()){ tetromino.softDrop(); } landIntoWall(); destoryLines(); checkGameOverAction(); tetromino = nextOne; nextOne = Tetromino.randomOne(); } /** 在Tetris类中添加 旋转流程控制方法 */ public void rotateRightAction(){ tetromino.rotateRight(); if(outOfBounds() || coincide()){ tetromino.rotateLeft(); } } private Timer timer; private boolean pause; private boolean gameOver; private long interval = 600;//间隔时间 /** 在Tetris类中添加 开始流程控制 */ public void startAction(){ pause = false; gameOver = false; score = 0; lines=0; clearWall(); tetromino = Tetromino.randomOne(); nextOne = Tetromino.randomOne(); timer = new Timer(); timer.schedule(new TimerTask(){ public void run(){ softDropAction(); repaint(); } }, interval, interval); } private void clearWall() { //Arrays.fill(wall, null); for(Cell[] line: wall){ Arrays.fill(line, null); } // for(int i=0; i<wall.length; i ){ // Arrays.fill(wall[i], null); // } } /** 在Tetris类中添加暂停方法 */ public void pauseAction(){ timer.cancel(); pause = true; } public void continueAction(){ timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { softDropAction(); repaint(); } }, interval, interval); pause = false; } public void checkGameOverAction(){ if(wall[0][4]!=null){ gameOver = true; timer.cancel(); } } public static void main(String[] args) { JFrame frame = new JFrame(); //在加载Tetris类的时候, 会执行静态代码块 //静态代码块,装载了图片素材, 为图片对象 Tetris tetris = new Tetris(); //tetris.setBackground(new Color(0x0000ff)); frame.add(tetris); frame.setSize(530, 580); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); frame.setVisible(true);//在显示窗口时候,会"尽快" tetris.action(); //的调用paint()方法绘制界面 } }
标签: 俄罗斯方块
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论