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();
    }
    }

    }

    }

  • 相关阅读:
    CentOS 7 SSH远程证书登陆
    Keepalived安装配置入门
    Docker-Compose 一键部署Ningx+.Net Core+Redis集群
    .Net Core Cookie跨站点共享 会话保持
    .Net Core EF Core之Sqlite使用及部署
    CentOS 7 Fail2ban防暴力破解
    CentOS 7 Nginx安装配置
    CentOS 7 Firewalld 常用操作
    Linux 修改SSH端口及禁用ROOT远程SSH登陆
    Mysql MariaDB安装
  • 原文地址:https://www.cnblogs.com/1314wamm/p/5600025.html
Copyright © 2011-2022 走看看