zoukankan      html  css  js  c++  java
  • 俄罗斯方块

    package cn.hncu.games;

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;

    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.Timer;

    public class Tetris extends JFrame{
    private TetrisPanel tp;
    public Tetris() {
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setLocation(700, 200);
    this.setSize(220, 275);
    this.setResizable(false);
    tp = new TetrisPanel();
    this.getContentPane().add(tp);

    //添加菜单
    JMenuBar menubar = new JMenuBar();
    this.setJMenuBar(menubar);
    JMenu menuGame = new JMenu("游戏");
    menubar.add(menuGame);

    JMenuItem itemNew = new JMenuItem("新游戏");
    itemNew.setActionCommand("new");
    JMenuItem itemPause = new JMenuItem("暂停");
    itemPause.setActionCommand("pause");
    JMenuItem itemContinue = new JMenuItem("继续");
    itemContinue.setActionCommand("continue");

    menuGame.add(itemNew);
    menuGame.add(itemPause);
    menuGame.add(itemContinue);

    MenuListener menuListener = new MenuListener();
    itemNew.addActionListener(menuListener);
    itemPause.addActionListener(menuListener);
    itemContinue.addActionListener(menuListener);


    //让整个JFrame添加键盘监听
    this.addKeyListener( tp.listener );
    }
    public static void main(String[] args) {
    Tetris te = new Tetris();
    te.setVisible(true);
    //如果在界面中添加了编辑框等会抢占焦点的控件,则需要用下面的代码
    //te.requestFocus(true);//让游戏面板获得焦点--抢到键盘的监听
    }

    class MenuListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
    if(e.getActionCommand().equals("new")){
    tp.newGame();
    }
    }
    }
    }

    class TetrisPanel extends JPanel{
    // 方块的形状:
    // 第一维代表方块类型(包括7种:S、Z、L、J、I、O、T)
    // 第二维代表旋转次数
    // 第三四维代表方块矩阵
    // shapes[type][turnState][i] i--> block[i/4][i%4]
    int shapes[][][] = new int[][][] {
    /*
    * 模板 { {0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0}, {0,0,0,0,0,0,0,0, 0,0,0,0,
    * 0,0,0,0}, {0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0}, {0,0,0,0,0,0,0,0,
    * 0,0,0,0, 0,0,0,0} }
    */
    // I (※把版本1中的横条从第1行换到第2行)
    { { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
    { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } },
    // S
    { { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
    { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 } },
    // Z
    { { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } },
    // J
    { { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
    // O
    { { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
    // L
    { { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
    // T
    { { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }
    };

    private int blockType;//方块类型
    private int turnState;//旋转状态
    private int x;//方块的位置x--列的位置--列号
    private int y;//方块的位置y--行的位置--行号

    private int map[][]=new int[13][23];//地图:12列22行。为防止越界,数组开成:13列23行

    private Timer timer;
    private int delay=1000;
    public TimerKeyLister listener=new TimerKeyLister();

    private int score=0;//分数

    public TetrisPanel(){
    newGame();
    nextBlock();
    //timer = new Timer(delay,listener);
    //timer.start();
    }

    public void newGame() {
    for( int i=0;i<12;i++){//走列
    for(int j=0;j<21;j++){//走行
    if(i==0 || i==11){//3为界面边框的格
    map[i][j]=3;//按理只要用0和1以外的整数就可以,但这里用3有特殊作用--后面用
    }else{
    map[i][j]=0;
    }
    }
    map[i][21]=3;//3为界面边框的格
    }

    if(timer!=null){
    timer.stop();
    }

    delay=1000;
    timer = new Timer(delay,listener);
    timer.start();
    }

    private void nextBlock() {
    blockType = (int)(Math.random()*1000)%7;
    turnState = (int)(Math.random()*1000)%4;
    x=4;
    y=0;
    //game Over
    if(crash(x,y,blockType,turnState)==0){
    timer.stop();
    int option = JOptionPane.showConfirmDialog(this,
    "Game Over!!,还敢来吗...");
    if (option == JOptionPane.OK_OPTION) {
    newGame();
    } else if (option == JOptionPane.NO_OPTION) {
    System.exit(0);
    }
    }
    }

    private void down() {
    if( crash(x,y+1,blockType,turnState)==0 ){//注意,这里用y+1,是判断块往下掉一格后,map中对应位置是否为堆积块或框架
    add(x,y,blockType,turnState);//把当前方块的信息保存到地图
    nextBlock();
    }else{
    y++;
    }
    repaint();
    }
    private void left() {
    if(x>=0){
    x -= crash(x-1,y,blockType,turnState);
    }
    repaint();
    }
    private void right() {
    if(x<8){
    x += crash(x+1,y,blockType,turnState);
    }
    repaint();
    }
    private void turn() {
    if(crash(x,y,blockType,(turnState+1)%4)==1 ){
    turnState = (turnState+1)%4;
    }
    repaint();
    }

    private void add(int x, int y, int blockType, int turnState) {
    for( int a=0; a<4; a++){
    for(int b=0; b<4; b++){
    if( shapes[blockType][turnState][a*4+b] ==1 ){
    map[x+b+1][y+a] = 1;
    }
    }
    }
    tryDelLine();
    }

    //消行
    private void tryDelLine(){
    for(int b=0;b<21;b++){
    int c=1;
    for(int a=0;a<12;a++){
    c &=map[a][b];
    }
    if(c==1){//有一行需要消
    //依次往下移动一行
    for(int d=b; d>0; d--){
    for(int e=0;e<11;e++){
    map[e][d] = map[e][d-1];
    }
    }
    //加分
    score +=10;
    delay /=2;
    timer.setDelay(delay);
    }
    }

    }

    //参数例子: 4,3,2,3
    private int crash(int x, int y, int blockType, int turnState){
    for( int a=0; a<4; a++){
    for(int b=0; b<4; b++){
    // if( (shapes[blockType][turnState][a*4+b]==1 && map[x+b+1][y+a] ==1) ||
    // (shapes[blockType][turnState][a*4+b]==1 && map[x+b+1][y+a] ==3 ) ){
    // }
    if( (shapes[blockType][turnState][a*4+b] & map[x+b+1][y+a]) ==1 ){
    return 0;//碰撞
    }
    }
    }
    return 1;//没有碰撞
    }

    @Override
    public void paint(Graphics g) {
    // blockType =6;
    // turnState = 3;
    // x=4;
    // y=6;
    super.paint(g);//消除残影

    g.setColor(new Color(153,51,205));
    //画当前方块
    for(int j=0;j<16;j++){
    if(shapes[blockType][turnState][j]==1){
    g.fillRect((j%4+x+1)*10, (j/4+y)*10, 10, 10);
    }
    }

    //画界面框架 以及 堆积块---整个地图
    g.setColor(Color.red);
    for( int i=0;i<12;i++){//走列
    for(int j=0;j<22;j++){//走行
    if(map[i][j]==3){
    g.drawRect(i*10, j*10, 10, 10);
    }else if(map[i][j]==1){
    g.fillRect(i*10, j*10, 10, 10);
    g.setColor(Color.GREEN);
    g.drawRect(i*10, j*10, 10, 10);
    g.setColor(Color.red);
    }
    }
    }

    //显示分数,同时为版面美观,在界面上再加点东西
    // 画方块区右侧部分
    g.setColor(Color.blue);
    g.setFont(new Font("aa", Font.BOLD, 18));
    g.drawString("score=" + score, 130, 20);
    g.setFont(new Font("aa", Font.PLAIN, 13));

    g.drawString("拒绝盗版游戏", 130, 70);
    g.drawString("注意自我保护", 130, 90);
    g.drawString("谨防受骗上当。", 125, 110);
    g.drawString("适度游戏益脑,", 125, 130);
    g.drawString("沉迷游戏伤身。", 125, 150);
    g.drawString("合理安排时间,", 125, 170);
    g.drawString("享受健康生活。", 125, 190);

    }

    class TimerKeyLister extends KeyAdapter implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
    down();
    }

    @Override
    public void keyPressed(KeyEvent e) {
    switch(e.getKeyCode()){
    case KeyEvent.VK_DOWN:
    down(); break;
    case KeyEvent.VK_LEFT:
    left();break;
    case KeyEvent.VK_RIGHT:
    right();break;

    case KeyEvent.VK_UP:
    turn();
    }
    }

    }

    }

  • 相关阅读:
    DC中为什么要用Uniquify?
    hdu 1596 find the safest road
    hdu2112 HDU Today
    hdu 2066 一个人的旅行
    poj 3026 Borg Maze
    poj 1979 Red and Black
    poj 1321 棋盘问题
    hdu 1010 Tempter of the Bone
    hdu 4861 Couple doubi
    codeforces584B Kolya and Tanya
  • 原文地址:https://www.cnblogs.com/1314wamm/p/5600025.html
Copyright © 2011-2022 走看看