2012-07-04 20:56:44Morris
[JAVA][Eclipse] Diamond Dash 外掛
Demo 影片 http://www.youtube.com/watch?v=5Tjwk8dfXMU
Learn from http://annimon119.blogspot.tw/2011/09/blog-post.html
此次學習重點 :
1. Robot 的操作
2. 由於要判定圖形是否相同, 加入容錯處理, 為解決速度上的問題, 並不使用多次 robot.getPixelColor(), 速度過於緩慢, 用截取圖片替代, 速度明題明顯
操作要點:
按下 A 進行開始
並且在執行前, 確認 startx, starty 的值, 採用絕對位置方便操作, 如果電腦不同, 請自行找出左上角的操作點,
最左上角黑色區塊的角落
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.AWTException;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import java.awt.Font;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.MouseInfo;
import java.awt.Robot;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
public class Game2 extends JFrame implements KeyListener {
public final int BRICK_SIZE = 40;
public final int COLOR_TOLERANCE = 130;
public final int startx = 521, starty = 405;
public static Robot robot;
public int[][] brickID = new int[9][10];
private static final int[][][] good = {
{ {0, 1}, {2, 1} },
{ {1, 0}, {1, 2} },
{ {0, 0}, {0, 1} },
{ {1, 0}, {2, 0} },
{ {2, 1}, {2, 2} },
{ {1, 2}, {0, 2} },
{ {0, 1}, {0, 2} },
{ {1, 2}, {2, 2} },
{ {2, 0}, {2, 1} },
{ {0, 0}, {1, 0} }
};
private JLabel text = new JLabel("Diamond Dash");
private JLabel state = new JLabel("Ready");
public Game2() throws AWTException {
setTitle("Diamond Dash");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
setSize(200, 200);
setResizable(false);
setAlwaysOnTop(true);
text.setFont(new Font("Arial", Font.ITALIC, 18));
text.setBounds(35, 15, 150, 30);
add(text);
state.setFont(new Font("Arial", Font.ITALIC, 18));
state.setBounds(70, 50, 150, 30);
add(state);
addKeyListener(this);
robot = new Robot();
}
private void clickBlock(int xClick, int yClick) {
xClick = startx + xClick * BRICK_SIZE + BRICK_SIZE / 2;
yClick = starty + yClick * BRICK_SIZE + BRICK_SIZE / 2;
robot.mouseMove(xClick, yClick);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(15);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
public BufferedImage getImage(int x, int y, int width, int height) {
return robot.createScreenCapture(new Rectangle(x, y, width, height));
}
public int[][] getBricksID(BufferedImage image) {
int[] brickColors = new int[] { 0xFF0000, // RED
0x00FF00, // GREEN
0x0000FF, // BLUE
0xFFFF00, // YELLOW
0xFF00FF, // MAGENTA
};
for (int y = 0; y < brickID.length; y++) {
for (int x = 0; x < brickID[0].length; x++) {
int color = image.getRGB(x * BRICK_SIZE + BRICK_SIZE / 2
+ BRICK_SIZE / 4, y * BRICK_SIZE + BRICK_SIZE / 4);
brickID[y][x] = 0;
for(int id = 0; id < brickColors.length; id++) {
if(isEquals(color, brickColors[id], COLOR_TOLERANCE)) {
brickID[y][x] = id+1;
break;
}
}
}
}
return brickID;
}
private boolean isEquals(int color1, int color2, int tolerance) {
int r1, r2, g1, g2, b1, b2;
r1 = (color1>>16) & 0xff;
g1 = (color1>>8) & 0xff;
b1 = color1 & 0xff;
r2 = (color2>>16) & 0xff;
g2 = (color2>>8) & 0xff;
b2 = color2 & 0xff;
return (Math.abs(r1 - r2) <= tolerance) &&
(Math.abs(g1 - g2) <= tolerance) &&
(Math.abs(b1 - b2) <= tolerance);
}
public int getId(int x, int y) {
if(x < 0 || x >= 10 || y < 0 || y >= 9)
return 0;
return brickID[y][x];
}
private boolean searchArea(int x, int y) {
int curID = getId(x, y);
if (curID == 0) return false;
boolean[][] indexEquals = {
{ getId(x-1, y-1) == curID, getId(x, y-1) == curID, getId(x+1, y-1) == curID },
{ getId(x-1, y) == curID, true, getId(x+1, y) == curID },
{ getId(x-1, y+1) == curID, getId(x, y+1) == curID, getId(x+1, y+1) == curID }
};
for (int i = 0; i < good.length; i++) {
if ( (indexEquals[ good[i][0][0] ][ good[i][0][1] ]) &&
(indexEquals[ good[i][1][0] ][ good[i][1][1] ])) {
return true;
}
}
return false;
}
public void click() {
for(int y = 0; y < brickID.length; y++) {
BufferedImage screen = getImage(startx, starty, 10 * BRICK_SIZE, 9 * BRICK_SIZE);
brickID = getBricksID(screen);
for (int x = brickID[0].length-1 ; x >= 0; x--) {
//System.out.print(getId(x, y));
if( ((getId(x, y) != 0) && searchArea(x, y))) {
clickBlock(x, y);
}
}
//System.out.println("");
}
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_A:
state.setText("Running !!");
int cnt = 160;
while(cnt-- != 0)
click();
state.setText("Ready");
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
Learn from http://
此次學習重點 :
1. Robot 的操作
2. 由於要判定圖形是否相同, 加入容錯處理, 為解決速度上的問題, 並不使用多次 robot.getPixelColor(), 速度過於緩慢, 用截取圖片替代, 速度明題明顯
操作要點:
按下 A 進行開始
並且在執行前, 確認 startx, starty 的值, 採用絕對位置方便操作, 如果電腦不同, 請自行找出左上角的操作點,
最左上角黑色區塊的角落
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.AWTException;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import java.awt.Font;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.MouseInfo;
import java.awt.Robot;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
public class Game2 extends JFrame implements KeyListener {
public final int BRICK_SIZE = 40;
public final int COLOR_TOLERANCE = 130;
public final int startx = 521, starty = 405;
public static Robot robot;
public int[][] brickID = new int[9][10];
private static final int[][][] good = {
{ {0, 1}, {2, 1} },
{ {1, 0}, {1, 2} },
{ {0, 0}, {0, 1} },
{ {1, 0}, {2, 0} },
{ {2, 1}, {2, 2} },
{ {1, 2}, {0, 2} },
{ {0, 1}, {0, 2} },
{ {1, 2}, {2, 2} },
{ {2, 0}, {2, 1} },
{ {0, 0}, {1, 0} }
};
private JLabel text = new JLabel("Diamond Dash");
private JLabel state = new JLabel("Ready");
public Game2() throws AWTException {
setTitle("Diamond Dash");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
setSize(200, 200);
setResizable(false);
setAlwaysOnTop(true);
text.setFont(new Font("Arial", Font.ITALIC, 18));
text.setBounds(35, 15, 150, 30);
add(text);
state.setFont(new Font("Arial", Font.ITALIC, 18));
state.setBounds(70, 50, 150, 30);
add(state);
addKeyListener(this);
robot = new Robot();
}
private void clickBlock(int xClick, int yClick) {
xClick = startx + xClick * BRICK_SIZE + BRICK_SIZE / 2;
yClick = starty + yClick * BRICK_SIZE + BRICK_SIZE / 2;
robot.mouseMove(xClick, yClick);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(15);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
public BufferedImage getImage(int x, int y, int width, int height) {
return robot.createScreenCapture(new Rectangle(x, y, width, height));
}
public int[][] getBricksID(BufferedImage image) {
int[] brickColors = new int[] { 0xFF0000, // RED
0x00FF00, // GREEN
0x0000FF, // BLUE
0xFFFF00, // YELLOW
0xFF00FF, // MAGENTA
};
for (int y = 0; y < brickID.length; y++) {
for (int x = 0; x < brickID[0].length; x++) {
int color = image.getRGB(x * BRICK_SIZE + BRICK_SIZE / 2
+ BRICK_SIZE / 4, y * BRICK_SIZE + BRICK_SIZE / 4);
brickID[y][x] = 0;
for(int id = 0; id < brickColors.length; id++) {
if(isEquals(color, brickColors[id], COLOR_TOLERANCE)) {
brickID[y][x] = id+1;
break;
}
}
}
}
return brickID;
}
private boolean isEquals(int color1, int color2, int tolerance) {
int r1, r2, g1, g2, b1, b2;
r1 = (color1>>16) & 0xff;
g1 = (color1>>8) & 0xff;
b1 = color1 & 0xff;
r2 = (color2>>16) & 0xff;
g2 = (color2>>8) & 0xff;
b2 = color2 & 0xff;
return (Math.abs(r1 - r2) <= tolerance) &&
(Math.abs(g1 - g2) <= tolerance) &&
(Math.abs(b1 - b2) <= tolerance);
}
public int getId(int x, int y) {
if(x < 0 || x >= 10 || y < 0 || y >= 9)
return 0;
return brickID[y][x];
}
private boolean searchArea(int x, int y) {
int curID = getId(x, y);
if (curID == 0) return false;
boolean[][] indexEquals = {
{ getId(x-1, y-1) == curID, getId(x, y-1) == curID, getId(x+1, y-1) == curID },
{ getId(x-1, y) == curID, true, getId(x+1, y) == curID },
{ getId(x-1, y+1) == curID, getId(x, y+1) == curID, getId(x+1, y+1) == curID }
};
for (int i = 0; i < good.length; i++) {
if ( (indexEquals[ good[i][0][0] ][ good[i][0][1] ]) &&
(indexEquals[ good[i][1][0] ][ good[i][1][1] ])) {
return true;
}
}
return false;
}
public void click() {
for(int y = 0; y < brickID.length; y++) {
BufferedImage screen = getImage(startx, starty, 10 * BRICK_SIZE, 9 * BRICK_SIZE);
brickID = getBricksID(screen);
for (int x = brickID[0].length-1 ; x >= 0; x--) {
//System.out.print(getId(x, y));
if( ((getId(x, y) != 0) && searchArea(x, y))) {
clickBlock(x, y);
}
}
//System.out.println("");
}
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_A:
state.setText("Running !!");
int cnt = 160;
while(cnt-- != 0)
click();
state.setText("Ready");
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}