⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pintu.java

📁 java游戏编程导学系列二 使用说明 所有范例
💻 JAVA
字号:
package pintu;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.net.URL;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */

public class Pintu
    extends Applet
    implements MouseListener, KeyListener, Runnable {
  final int IMAGE_WIDTH = 120;
//每张拼图的宽
  final int IMAGE_HEIGHT = 120;
//每张拼图的高
  Image[] m_Image = new Image[9];
//总的大图片
  Image m_ImgAll;
//9个用来装入每个拼图的图片对象
  final int DELTAX = 80;
//标志提示信息区的宽度
  int m_nImageNo[][] = new int[3][3];
//标志现在各个拼图的排列情况
  final int NO_IMAGE = -1;
//此位置没有拼图
  int nStep = 0;
  //已经走的步数
  int nTime = 0;
  //已经玩过的时间,以秒为单

  final int DIRECTION_UP = 1;
//代表移动方向为向上
  final int DIRECTION_DOWN = 2;
//代表移动方向为向下
  final int DIRECTION_LEFT = 3;
//代表移动方向为向左
  final int DIRECTION_RIGHT = 4;
//代表移动方向为向右
  final int DIRECTION_NONE = -1;
//代表不能移动

  boolean bWantStartNewGame = false;

  boolean bOnShowAll = false;
//预览的开关
  AudioClip m_audioClip1, m_audioClip2;

  int m_nNumOfImg = 0;
//拼图底图所使用的图片的个数

  String m_sImgName[] = new String[9];
//记录拼图底图的名字

  int nScore;
  //int nTime=0;
//已经玩过的时间,以秒为单位
  Thread thTimer;
//计时器线程

  public void initData() {
    for (int j = 0; j < 3; j++) {
      for (int i = 0; i < 3; i++) {
        m_nImageNo[i][j] = j * 3 + i;
      }
    }
    m_nImageNo[1][2] = NO_IMAGE;
    m_nImageNo[1][1] = 7;
  }

  //Construct the applet
  public Pintu() {
  }

  //Initialize the applet
  public void init() {
    try {
      jbInit();

      m_audioClip1 = getAudioClip(getCodeBase(), "au/move.au");
      m_audioClip2 = getAudioClip(getCodeBase(), "au/notmove.au");

      MediaTracker mediaTracker = new MediaTracker(this);
      //建立一个监视器
      m_ImgAll = getImage(getDocumentBase(), "img/pintu.jpg");
      //装载总的大图片
      mediaTracker.addImage(m_ImgAll, 1);
      try {
        mediaTracker.waitForAll();
      }
      catch (Exception e) {
        System.out.println("图片装载出错");
      }
      for (int i = 0; i < 9; i++) {
        //遍历9个小拼图对象,用来装载其中的每个。
        m_Image[i] = getImage(getDocumentBase(), "img/" + i + ".jpg");
        /*m_Image[i] = createImage(IMAGE_WIDTH, IMAGE_HEIGHT);
                 //创建实例,也就是为每个图片对象分配内存空间
                 Graphics g = m_Image[i].getGraphics();
                 //获得Graphics对象
                 int nRow = i % 3;
                 int nCol = i / 3;
                 //算出这个小图片对象应对应总图的那一块区域
                 g.drawImage(m_ImgAll, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT,
                    nRow * IMAGE_WIDTH, nCol * IMAGE_HEIGHT,
                    (nRow + 1) * IMAGE_WIDTH, (nCol + 1) * IMAGE_HEIGHT,
                    this);
                 //往小拼图上画*/
        mediaTracker.addImage(m_Image[i], 1);
        try {
          mediaTracker.waitForAll();
        }
        catch (Exception e) {
          System.out.println("图片装载出错");
        }
        //m_Image[0]

      }
      thTimer = new Thread(this);
//为线程分配内存空间
      thTimer.start();
//开始线程

      initData();

    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  //Component initialization
  private void jbInit() throws Exception {
    addMouseListener(this);
    addKeyListener(this);
  }

  public void paint(Graphics g) {
    //g.drawImage(m_Image[0],0,0,this);
    //g.drawImage(m_ImgAll,0,0,this);
    g.setColor(Color.white);
    //将当前颜色置为白色
    g.fillRect(0, 0, DELTAX, IMAGE_HEIGHT * 3);
    //填充左边的提示信息区域
    g.setFont(new Font("宋体", Font.PLAIN, 12));
    //设置字体
    g.setColor(Color.blue);
    //设置颜色
    g.drawString("步数:" + nStep, 10, 20);
    //在坐标(10,20)画出字符串,来显示现在走了多少步
    //g.setColor(Color.white);

    //所加的代码如下
    g.drawString("现有图片"+m_nNumOfImg+"张",5,60);
        g.drawString("请按1-"+m_nNumOfImg+"键改变图片",5,100);
        g.setColor(Color.white);


    //加入代码
    if (bOnShowAll) {
      int x = DELTAX;
      int y = 0;
      g.drawImage(m_ImgAll, x, y, this);
      //在拼图区画出整幅图片
      return;
    }

    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        int x = i * IMAGE_WIDTH + DELTAX;
        int y = j * IMAGE_HEIGHT;
        //计算要画得拼图的区域
        if (m_nImageNo[i][j] == NO_IMAGE) {
          //用空白来填充
          g.fill3DRect(x, y, IMAGE_WIDTH, IMAGE_HEIGHT, true);
        }
        else {
          g.drawImage(m_Image[m_nImageNo[i][j]], x, y, this);
          g.drawRect(x, y, IMAGE_WIDTH, IMAGE_HEIGHT);
        }
      }
    }
    checkStatus();
    //检查当前状态

    if (bWantStartNewGame) {
      nScore = 1000 - nTime - nStep;
      g.setColor(Color.blue);
      g.drawString("请按任意键重新开始", 0, 150);
      g.setColor(Color.red);
      g.setFont(new Font("宋体", Font.PLAIN, 40));
      g.drawString("你赢了," + nScore + "分", 50 + DELTAX, 180);
      //在界面上显示出玩家赢了的信息
      g.drawString("祝贺你!", 110 + DELTAX, 220);

      //增加的代码
      transferScore(nScore);
      //增加的代码结束
    }

  }

  public void run() {
//这个线程里我们要做的事情
//我们将当前用户玩得时间显示出来
    while (true) {
      try {
        thTimer.sleep(990);
        String sTemp = "你玩了" + nTime + "秒的时间,";
        if (nTime > 200)
          sTemp = sTemp + "时间用的很长了,你可要加油啦!";
        else
          sTemp = sTemp + "别紧张,慢慢来。";
        showStatus(sTemp);

        if (!bWantStartNewGame)
          nTime++;
          //如果游戏已经结束,则不将时间累加

      }
      catch (Exception e) {
      }
    }
  }

  public int directionCanMove(int nCol, int nRow) {
    if ( (nCol - 1) >= 0) {
      if (m_nImageNo[nRow][nCol - 1] == NO_IMAGE) {
        return DIRECTION_UP;
      }
    }
    if ( (nCol + 1) <= 2) {
      if (m_nImageNo[nRow][nCol + 1] == NO_IMAGE) {
        return DIRECTION_DOWN;
      }
    }
    if ( (nRow - 1) >= 0) {
      if (m_nImageNo[nRow - 1][nCol] == NO_IMAGE) {
        return DIRECTION_LEFT;
      }
    }
    if ( (nRow + 1) <= 2) {
      if (m_nImageNo[nRow + 1][nCol] == NO_IMAGE) {
        return DIRECTION_RIGHT;
      }
    }
    return DIRECTION_NONE;
  }

  public void move(int nCol, int nRow, int nDirection) {
//nCol和nRow为要移动的拼图的位置
    switch (nDirection) {
      case DIRECTION_UP:
        m_nImageNo[nRow][nCol - 1] = m_nImageNo[nRow][nCol];
        m_nImageNo[nRow][nCol] = NO_IMAGE;
        break;
      case DIRECTION_DOWN:
        m_nImageNo[nRow][nCol + 1] = m_nImageNo[nRow][nCol];
        m_nImageNo[nRow][nCol] = NO_IMAGE;
        break;
      case DIRECTION_LEFT:
        m_nImageNo[nRow - 1][nCol] = m_nImageNo[nRow][nCol];
        m_nImageNo[nRow][nCol] = NO_IMAGE;
        break;
      case DIRECTION_RIGHT:
        m_nImageNo[nRow + 1][nCol] = m_nImageNo[nRow][nCol];
        m_nImageNo[nRow][nCol] = NO_IMAGE;
        break;
    }
  }

  public boolean move(int nDirection) {
//往某个方向移动拼图
    int nNoImageCol = -1;
    int nNoImageRow = -1;
    int i = 0;
    int j = 0;
    while (i < 3 && nNoImageRow == -1) {
      while (j < 3 && nNoImageCol == -1) {
        if (m_nImageNo[i][j] == NO_IMAGE) {
          nNoImageRow = i;
          nNoImageCol = j;
        }
        j++;
      }
      j = 0;
      i++;
    }
    //以上判断哪个拼图可以往方向nDirection移动
    //可以移动的拼图的位置为第nNoImageCol列,第nNoImageRow行

    switch (nDirection) {
      case DIRECTION_UP:
        if (nNoImageCol == 3) {
          return true;
        }
        m_nImageNo[nNoImageRow][nNoImageCol] =
            m_nImageNo[nNoImageRow][nNoImageCol + 1];
        m_nImageNo[nNoImageRow][nNoImageCol + 1] = NO_IMAGE;
        break;
      case DIRECTION_DOWN:
        if (nNoImageCol == 0) {
          return true;
        }
        m_nImageNo[nNoImageRow][nNoImageCol] =
            m_nImageNo[nNoImageRow][nNoImageCol - 1];
        m_nImageNo[nNoImageRow][nNoImageCol - 1] = NO_IMAGE;
        break;
      case DIRECTION_LEFT:
        if (nNoImageRow == 3) {
          return true;
        }
        m_nImageNo[nNoImageRow][nNoImageCol] =
            m_nImageNo[nNoImageRow + 1][nNoImageCol];
        m_nImageNo[nNoImageRow + 1][nNoImageCol] = NO_IMAGE;
        break;
      case DIRECTION_RIGHT:
        if (nNoImageRow == 0) {
          return true;
        }
        m_nImageNo[nNoImageRow][nNoImageCol] =
            m_nImageNo[nNoImageRow - 1][nNoImageCol];
        m_nImageNo[nNoImageRow - 1][nNoImageCol] = NO_IMAGE;
        break;
    }
    return false;
    //以上往某个方向移动拼图
  }

  public void checkStatus() {
    boolean bWin = true;
    //定义成员,默认值为真
    int nCorrectNum = 0;
    for (int j = 0; j < 3; j++) {
      for (int i = 0; i < 3; i++) {
        if (m_nImageNo[i][j] != nCorrectNum &&
            m_nImageNo[i][j] != NO_IMAGE)
          bWin = false;
        nCorrectNum++;
      }
    }
    //比较拼图是否都放到了正确的位置上
//如果有一个没有放到正确位置上,则游戏就不能结束
    if (bWin)
      bWantStartNewGame = true;
  }

  public void mouseClicked(MouseEvent e) {

    //加入的代码
    if (bOnShowAll)
      return;

    int nX = e.getX() - DELTAX;
    int nY = e.getY();
    int nCol = nY / IMAGE_HEIGHT;
    int nRow = nX / IMAGE_WIDTH;
    int nDirection = directionCanMove(nCol, nRow);
    if (nDirection != DIRECTION_NONE) {
      move(nCol, nRow, nDirection);
      if (!bWantStartNewGame)
        nStep++;
      m_audioClip1.play();
      repaint();
    }
    else {
      m_audioClip2.play();
    }

    repaint();

  }

  public void mousePressed(MouseEvent e) {
  }

  public void mouseReleased(MouseEvent e) {
  }

  public void mouseEntered(MouseEvent e) {
  }

  public void mouseExited(MouseEvent e) {
  }

  public void keyPressed(KeyEvent e) {

    //加入的代码
    if (bOnShowAll) {
      if (e.getKeyCode() == KeyEvent.VK_Y) {
        //在预览状态下如果Y键按下,则取消预览状态
        bOnShowAll = false;
        repaint();
      }
      return;
    }
    //添加结束

    int nDirection;

    switch (e.getKeyCode()) {
      case KeyEvent.VK_DOWN:
        nDirection = DIRECTION_DOWN;
        break;
      case KeyEvent.VK_UP:
        nDirection = DIRECTION_UP;
        break;
      case KeyEvent.VK_LEFT:
        nDirection = DIRECTION_LEFT;
        break;
      case KeyEvent.VK_RIGHT:
        nDirection = DIRECTION_RIGHT;
        break;
        //the Code Added here
      case KeyEvent.VK_F1:

        //F1键按下,重新开始游戏
        initData();

        repaint();
        return;
        //加入代码
      case KeyEvent.VK_Y:
        if (bOnShowAll)
          bOnShowAll = false;
        else
          bOnShowAll = true;

        repaint();
        return;

      default:
        nDirection = 0;
        return;
    }
    boolean bCanMove = move(nDirection);
    if (bCanMove) {
      if (!bWantStartNewGame)
        nStep++;
      m_audioClip1.play();
      repaint();
    }
    else {
      m_audioClip2.play();
    }

  }

  public void keyTyped(KeyEvent e) {
  }

  public void keyReleased(KeyEvent e) {
  }

  public void transferScore(int nScore) {
    String sLocation = "http://202.112.107.1/saveScore.php3?score=";
    nScore = (nScore / 2) * 10 + nScore % 4;
    //加密分数
    sLocation = sLocation + nScore;
    URL url = null;
    try {
      url = new URL(sLocation);
    }
    catch (Exception e) {}
    getAppletContext().showDocument(url);
  }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -