标签:mapr click print xtend wstring i++ tor finish tool
逻辑判断当前地图的状态(注意数组越界问题), 根据这个状态, 对数组的值进行修改, 然后调用 repaint() -> paint() 来将图形绘制出来.
实际上, 步骤1,2 完全可以用在 连连看中. 而且连连看不需要撤销功能, 所以不需要保存之前的图形的样子.
而连连看的主程序在实现逻辑上会有区别, 另外, 连连看在鼠标事件中会有应用, 点了哪个图片等等.
1. 创建初始化界面(地图) {可共用} MapFactory.java
package com.leon.movebox; public class MapFactory { /** * */ static byte map[][][] = { /* * 0 表示空白, 什么都不用画, 不参与到游戏中 * WALL = 1, BOX = 2, BOXONEND = 3, END = 4, * MANDOWN = 5, MANLEFT = 6, MANRIGHT = 7, MANUP = 8, * GRASS = 9, MANDOWNONEND = 10, MANLEFTONEND = 11, MANRIGHTONEND = 12, * MANUPONEND = 13; * */ { // map[0] {0, 0, 1, 1, 1, 0, 0, 0}, {0, 0, 1, 4, 1, 0, 0, 0}, {0, 0, 1, 9, 1, 1, 1, 1}, {1, 1, 1, 2, 9, 2, 4, 1}, {1, 4, 9, 2, 5, 1, 1, 1}, {1, 1, 1, 1, 2, 1, 0, 0}, {0, 0, 0, 1, 4, 1, 0, 0}, {0, 0, 0, 1, 1, 1, 0, 0}, }, { // map[1] {1, 1, 1, 1, 1, 0, 0, 0, 0}, {1, 9, 9, 5, 1, 0, 0, 0, 0}, {1, 9, 2, 2, 1, 0, 1, 1, 1}, {1, 9, 2, 9, 1, 0, 1, 4, 1}, {1, 1, 1, 9, 1, 1, 1, 4, 1}, {0, 1, 1, 9, 9, 9, 9, 4, 1}, {0, 1, 9, 9, 9, 1, 9, 9, 1}, {0, 1, 9, 9, 9, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 0, 0, 0}, }, }; // count 当前有多少关 static int count = map.length; public static byte[][] getMap(int grade) { byte temp[][]; if (grade >= 0 && grade < count) // 指针, 并非真正 copy temp = map[grade]; else temp = map[0]; int row = temp.length; int column = temp[0].length; byte[][] result = new byte[row][column]; // 真正 copy for (int i = 0; i < row; i++) for (int j = 0; j < column; j++) result[i][j] = temp[i][j]; return result; } public static int getCount() { return count; } }
2. 初始化声音 {可共用} Sound.java
package com.leon.movebox; import java.io.File; import java.io.IOException; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; public class Sound { private String path = new String("musics/"); private String file = new String("nor.mid"); private Sequence seq; private Sequencer midi; private boolean sign; public void loadSound() { try { // 打开 MIDI 文件 seq = MidiSystem.getSequence(new File(path+file)); // 建立音频序列 midi = MidiSystem.getSequencer(); // 打开音频序列 midi.open(); // 读取即将播放的音频序列 midi.setSequence(seq); // 播放音乐 midi.start(); midi.setLoopCount(Sequencer.LOOP_CONTINUOUSLY); } catch (Exception e) { e.printStackTrace(); } sign = true; } public void mystop() { midi.stop(); midi.close(); sign = false; } public boolean isPlay() { return sign; } public void setMusic(String e) { file = e; } }
3. 记录当前的地图的状态
package com.leon.movebox; /** * save the currently map status * @author Leon * */ public class Map { int manX = 0; int manY = 0; byte map[][]; int grade; public Map(int manX, int manY, byte[][] map) { this.manX = manX; this.manY = manY; int row = map.length; int column = map[0].length; byte temp[][] = new byte[row][column]; for (int i = 0; i < row; i++) for (int j = 0; j < column; j++) temp[i][j] = map[i][j]; this.map = temp; } public Map(int manX, int manY, byte[][] map, int grade) { this(manX, manY, map); this.grade = grade; } public int getManX() { return manX; } public int getManY() { return manY; } public byte[][] getMap() { return this.map; } public int getGrade() { return grade; } }
4. 主程序(还需要再调整, 当前有 Bug) (设计到 上, 下, 左, 右 移动, 即根据当前的状态更改数组的状态, 进而更改图片)
package com.leon.movebox; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; import javax.swing.JFrame; import javax.swing.JOptionPane; public class GameFrame extends JFrame implements ActionListener, MouseListener, KeyListener{ // 游戏关卡 // row, column 记载人的行号和列号 // leftX, leftY 记载图片左上角的位置 private int grade = 0; private int row = 7; private int column = 7; private int leftX = 0; private int leftY = 0; private int mapRow = 0; private int mapColumn = 0; // 记载屏幕的宽 和 高 private int width = 0; private int height = 0; private boolean acceptKey = true; private Image pic[] = null; private byte[][] map = null; // 为了悔棋, 回退步骤 private ArrayList list = new ArrayList(); Sound sound; final byte WALL = 1, BOX = 2, BOXONEND = 3, END = 4, MANDOWN = 5, MANLEFT = 6, MANRIGHT = 7, MANUP = 8, GRASS = 9, MANDOWNONEND = 10, MANLEFTONEND = 11, MANRIGHTONEND = 12, MANUPONEND = 13; public GameFrame() { super("推箱子游戏音乐版"); setSize(600, 600); setVisible(true); setResizable(false); setLocation(300, 20); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container cont = getContentPane(); cont.setLayout(null); cont.setBackground(Color.black); getPic(); width = this.getWidth(); height = this.getHeight(); this.setFocusable(true); initMap(); this.addKeyListener(this); this.addMouseListener(this); sound = new Sound(); sound.loadSound(); } public void initMap() { map = getMap(grade); list.clear(); getMapSizeAndPosition(); getManPosition(); } public void getMapSizeAndPosition() { mapRow = map.length; mapColumn = map[0].length; // 找到起始图片位置, 相当于留出边界 leftX = (width - map[0].length * 30) / 2; leftY = (height - map.length * 30) / 2; System.out.println(leftX); System.out.println(leftY); System.out.println(mapRow); System.out.println(mapColumn); } public void getManPosition() { for (int i = 0; i < map.length; i++) for (int j = 0; j < map[0].length; j++) if (map[i][j] == MANDOWN || map[i][j] == MANDOWNONEND || map[i][j] == MANUP || map[i][j] == MANUPONEND || map[i][j] == MANLEFT || map[i][j] == MANLEFTONEND || map[i][j] == MANRIGHT || map[i][j] == MANRIGHTONEND) { row = i; column = j; break; } } // 初始化地图 public byte[][] getMap(int grade) { return MapFactory.getMap(grade); } // 加载图片 public void getPic() { pic = new Image[14]; for (int i = 0; i < 13; i++) { pic[i] = Toolkit.getDefaultToolkit().getImage("images/pic" + i + ".JPG"); } } // 判断人所在的位置, 是grass 还是 end public byte grassOrEnd(byte man) { byte result = GRASS; if (man == MANDOWNONEND || man == MANLEFTONEND || man == MANRIGHTONEND || man == MANUPONEND) result = END; return result; } // 这个函数命名成 paint, 就会自动调用 public void paint(Graphics g) { for (int i = 0; i < mapRow; i++) for (int j = 0; j < mapColumn; j++) { // 画出地图, i 代表行数, j 代表列数 if (map[i][j] != 0) g.drawImage(pic[map[i][j]], leftX + j*30, leftY + i*30, this); } // g.setColor(Color.RED); // g.setFont(new Font("楷体_2312", Font.BOLD, 30)); // g.drawString("现在是第", 150, 140); // g.drawString(String.valueOf(grade+1), 310, 140); // g.drawString("关", 360, 140); } public int getManX() { return row; } public int getManY() { return column; } public boolean isFinished() { for (int i = 0; i < mapRow; i++) for (int j = 0; j < mapColumn; j++) if (map[i][j] == END || map[i][j] == MANDOWNONEND || map[i][j] == MANUPONEND || map[i][j] == MANLEFTONEND || map[i][j] == MANRIGHTONEND) return false; return true; } private void moveUp() { // 上一步 p1 为 wall if (map[row-1][column] == WALL) return; // 如果 p1 是 BOX, BOXONEND, 须考虑 p2 if (map[row-1][column] == BOX || map[row-1][column] == BOXONEND) { if (map[row-2][column] == END || map[row-2][column] == GRASS) { Map currMap = new Map(row, column, map); list.add(currMap); byte boxTemp = map[row-2][column] == END? BOXONEND: BOX; byte manTemp = map[row-1][column] == BOX? MANUP: MANUPONEND; // 箱子变成 temp, 箱子往前一步 map[row-2][column] = boxTemp; // 人变成MANUP, 往上走一步 map[row-1][column] = manTemp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后, 修改人的坐标 row--; } } else { // 上一位是 GRASS, END 无需考虑 p2, 其他情况不用处理 if (map[row-1][column] == GRASS || map[row-1][column] == END) { Map currMap = new Map(row, column, map); list.add(currMap); byte temp = map[row-1][column] == END?MANUPONEND: MANUP; // 人变成 temp, 人往上走一步 map[row-1][column] = temp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后修改人的坐标 row--; } } } private void moveDown() { // 下一步 p1 为 wall if (map[row+1][column] == WALL) return; // 如果 p1 是 BOX, BOXONEND, 须考虑 p2 if (map[row+1][column] == BOX || map[row+1][column] == BOXONEND) { if (map[row+2][column] == END || map[row+2][column] == GRASS) { Map currMap = new Map(row, column, map); list.add(currMap); byte boxTemp = map[row+2][column] == END? BOXONEND: BOX; byte manTemp = map[row+1][column] == BOX? MANUP: MANUPONEND; // 箱子变成 temp, 箱子往前一步 map[row+2][column] = boxTemp; // 人变成MANUP, 往下走一步 map[row+1][column] = manTemp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后, 修改人的坐标 row--; } } else { // 下一位是 GRASS, END 无需考虑 p2, 其他情况不用处理 if (map[row+1][column] == GRASS || map[row+1][column] == END) { Map currMap = new Map(row, column, map); list.add(currMap); byte temp = map[row+1][column] == END?MANUPONEND: MANUP; // 人变成 temp, 人往下走一步 map[row+1][column] = temp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后修改人的坐标 row--; } } } private void moveLeft() { // 左一步 p1 为 wall if (map[row][column-1] == WALL) return; // 如果 p1 是 BOX, BOXONEND, 须考虑 p2 if (map[row][column-1] == BOX || map[row][column-1] == BOXONEND) { if (map[row][column-2] == END || map[row][column-2] == GRASS) { Map currMap = new Map(row, column, map); list.add(currMap); byte boxTemp = map[row][column-2] == END? BOXONEND: BOX; byte manTemp = map[row][column-1] == BOX? MANUP: MANUPONEND; // 箱子变成 temp, 箱子往前一步 map[row][column-2] = boxTemp; // 人变成MANUP, 往下走一步 map[row][column-1] = manTemp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后, 修改人的坐标 row--; } } else { // 下一位是 GRASS, END 无需考虑 p2, 其他情况不用处理 if (map[row][column-1] == GRASS || map[row][column-1] == END) { Map currMap = new Map(row, column, map); list.add(currMap); byte temp = map[row][column-1] == END?MANUPONEND: MANUP; // 人变成 temp, 人往下走一步 map[row][column-1] = temp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后修改人的坐标 row--; } } } private void moveRight() { // 左一步 p1 为 wall if (map[row][column+1] == WALL) return; // 如果 p1 是 BOX, BOXONEND, 须考虑 p2 if (map[row][column+1] == BOX || map[row][column+1] == BOXONEND) { if (map[row][column+2] == END || map[row][column+2] == GRASS) { Map currMap = new Map(row, column, map); list.add(currMap); byte boxTemp = map[row][column+2] == END? BOXONEND: BOX; byte manTemp = map[row][column+1] == BOX? MANUP: MANUPONEND; // 箱子变成 temp, 箱子往前一步 map[row][column+2] = boxTemp; // 人变成MANUP, 往下走一步 map[row][column+1] = manTemp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后, 修改人的坐标 row--; } } else { // 下一位是 GRASS, END 无需考虑 p2, 其他情况不用处理 if (map[row][column+1] == GRASS || map[row][column+1] == END) { Map currMap = new Map(row, column, map); list.add(currMap); byte temp = map[row][column+1] == END?MANUPONEND: MANUP; // 人变成 temp, 人往下走一步 map[row][column+1] = temp; // 人刚才站的地方编程 GRASS 或者 END map[row][column] = grassOrEnd(map[row][column]); // 人离开后修改人的坐标 row--; } } } public int getGrade() { return grade; } public void displayToast(String str) { JOptionPane.showMessageDialog(null, str, "提示", JOptionPane.ERROR_MESSAGE); } public void undo() { if (acceptKey) { // 撤销 if (list.size() > 0) { // 若要撤销, 必须走过 Map priorMap = (Map) list.get(list.size() - 1); map = priorMap.getMap(); row = priorMap.getManX(); column = priorMap.getManY(); repaint(); list.remove(list.size() - 1); } else displayToast("不能再撤销!"); } else { displayToast("此关已经完成, 不能撤销!"); } } public void nextGrade() { if (grade >= MapFactory.getCount() - 1) { displayToast("恭喜你完成所有关卡"); acceptKey = false; } else { grade++; initMap(); repaint(); acceptKey = true; } } public void priorGrade() { grade--; acceptKey = true; if (grade < 0) grade = 0; initMap(); repaint(); } @Override public void mouseClicked(MouseEvent e) { // 右键撤销移动 if (e.getButton() == MouseEvent.BUTTON3) { undo(); } } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP ) { moveUp(); } if (e.getKeyCode() == KeyEvent.VK_DOWN ) { moveDown(); } if (e.getKeyCode() == KeyEvent.VK_LEFT ) { moveLeft(); } if (e.getKeyCode() == KeyEvent.VK_RIGHT ) { moveRight(); } repaint(); if (isFinished()) { acceptKey = false; if (grade == 2) { JOptionPane.showMessageDialog(this, "恭喜通过最后一关"); } else { // 提示进入下一关 String msg = "恭喜您通过第" + grade + "关!!!\n 是否进入下一关?"; int type = JOptionPane.YES_NO_OPTION; String title = "过关"; int choice = 0; choice = JOptionPane.showConfirmDialog(null, msg, title, type); if (choice == 1) System.exit(0); else if (choice == 0) { acceptKey = true; nextGrade(); } } } } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub } public static void main(String[] args) { new GameFrame(); } }
标签:mapr click print xtend wstring i++ tor finish tool
原文地址:https://www.cnblogs.com/moveofgod/p/12636644.html