How to do smooth-scrolling by Java robot? - java

I got used to my touch pad, that allows to scroll smoothly and very exactly, but I can not to simulate it by Java robot - mousewheel is getting only integer parameters and a scrolling carried by steps. Can I simulate smoothly scrolling in Java?
robot.mouseWheel(a); // int a

The unit of scrolls will always be by "notches of the wheel" (before you ask: that's how the measurement is named in the docs). This is simply how it's implemented by the hardware (to be more specific: the mouse). How many pixels are scrolled per "notch" is nothing but OS-configuration. You can't mess with that with pure java and I wouldn't recommend it, even if it was possible.
What you can do nevertheless is to slow down the speed at which the robot scrolls:
import java.awt.Robot;
public class Test{
public static void main(String[] args)
throws Exception
{
//time to switch to a specific window where the robot ought to be tested
try{ Thread.sleep(2000); }catch(InterruptedException e){}
Robot r = new Robot();
for(int i = 0; i < 20; i++){
//scroll and wait a bit to give the impression of smooth scrolling
r.mouseWheel(1);
try{ Thread.sleep(50); }catch(InterruptedException e){}
}
}
}

Related

Problem Making A T-Rex Game Bot Using Selenium and Robot Class

I have a problem making T-Rex game bot. The code works fine for a few seconds but then the game gets over.
I have used Selenium and The Robot class for this project.
MyCode>>
public static void main(String[] args) throws InterruptedException, AWTException {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\BHEL\\Downloads\\chromedriver_win32\\chromedriver.exe");
WebDriver driver= new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://trex-runner.com/");
Robot robo = new Robot();
robo.mouseMove(460, 520);
while(true) {
//now i have used for loops to sense the cactus in a square area
for(int i = 0; i<=10;i++) {
for(int j=0;j<=10;j++) {
if(robo.getPixelColor(460-i, 520-j).equals(new Color(83,83,83))) {
robo.keyPress(KeyEvent.VK_UP);
robo.keyRelease(KeyEvent.VK_UP);
Thread.sleep(200-j-i);//Stay in the air for a while
robo.keyPress(KeyEvent.VK_DOWN);
robo.keyRelease(KeyEvent.VK_DOWN);
}
}
}
}
}
The WebSite url for T-Rex game that i used https://trex-runner.com .
I have seen some other tutorials that did the same thing that i did.
Thanks for your help :)
Could be that the coordinates aren't too precise. You could use System.out.println(MouseInfo.getPointerInfo().getLocation()); to get the coordinates of your mouse on your monitor and then change your x and y value to those. That method would get me to 400 points. To get further you have to add more conditions so the robot responds better to the obstacles.
Simple code:
while (true) {
//Got the coordinates from the mouse location ^^^
if (robo.getPixelColor(580 ,530).equals(new Color(83,83,83))) {
robo.keyPress(KeyEvent.VK_SPACE);
robo.keyRelease(KeyEvent.VK_SPACE);
Thread.sleep(150);//Stay in the air for a while
robo.keyPress(KeyEvent.VK_DOWN);
robo.keyRelease(KeyEvent.VK_DOWN);
}
}

Simulate Mouse Click in Java in DirectX Game

I am currently using Java's Robot Class within a DirectX game programmed in C++. I can successfully use the Robot class's mouseMove method, but when I try to use the mouse left click input event, nothing happens. I have tried different time spacings between the release and press to no avail. Note: I am currently running eclipse in administrator mode. Here is the code:
public class test {
public static void main(String [] args) throws AWTException, I nterruptedException{
Robot r = new Robot();
Thread.sleep(3000);
for(int i = 0; i<20; i++){
r.mouseMove(100+i*50, 550);
Thread.sleep(1);
}
Thread.sleep(1000);
r.mousePress(InputEvent.BUTTON1_MASK);
Thread.sleep(50);
r.mouseRelease(InputEvent.BUTTON1_MASK);
Thread.sleep(50);
r.mousePress(InputEvent.BUTTON1_MASK);
Thread.sleep(50);
r.mouseRelease(InputEvent.BUTTON1_MASK);
Thread.sleep(50);
}
}
Any idea on how to get the mouse click to register?
In some games you just cant do this.Depends on the engine and implementation , for instance in source engine games your events will be registered(probably,based on my experience example :CS:GO) , bud unreal engine games might not register anything.
Its really common for game developers to actually block some calls of WIN32 mouse_event , which is what Robot API uses.So there is not much you can do to go around it(with Robot api).

How to wait for a specified time between parts of code in Java?

I have fairly simple question I didn't see properly answered anywhere.
I'm designing a Java applet using java.awt. What I'm trying to do is to have Java wait a few seconds between executing different parts of code in a method for a simple graphical animation.
So it goes like this:
runAnimation() {
// draw red shapes
// wait 2 seconds so the shapes remain visible
// set color of shapes to green and repaint
}
As suggested elsewhere, if I use something like
try {
// do first task
Thread.sleep(2000);
// do second task
} catch (InterruptedException e) {
}
the program only shows the results of the second task after waiting 2 seconds ie I never see the red shapes. I want to see the red shapes for two seconds and then have them set to blue and so on.
You don't say what GUI / graphics library you're using which is key information. If Swing or AWT, then use a Swing Timer to do your pausing. You should not use Thread.sleep(...) for this as you would put the GUI's event thread to sleep, causing the whole application to freeze.
e.g.,
someColor = Color.RED;
int delay = 2000;
repaint()
Timer swingTimer = new Timer(delay, new ActionListener() {
public void actionPerformed(ActionEvent e) {
someColor = Color.GREEN;
repaint();
}
});
swingTimer.setRepeats(false);
swingTimer.start();

Java Swing Frame crashes upon opening?

I am programming a chess game in java, and at the moment I am building a basic interface. It is simply an 8x8 array of buttons that will display in a window. I have coded for these buttons, and have gotten the board to display properly. However, when I connect this with the rest of the game, the game window crashes upon running and I have to force quit the java application. This is my code:
package Chess_Game;
import javax.swing.SwingUtilities;
import Chess_Interface.Iboard;
public class Game_Tester
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Game G = new Game();
Iboard I = new Iboard(G.getBoard().getArray(), G.getSides());
I.setVisible(true);
while(!(G.isGameOver()))
{
boolean redo = true;
while(redo)
{
int row = 0;
int col = 0;
int nRow = 0;
int nCol = 0;
System.out.println("Click the piece you want to move.");
while(!(I.getBool())){}
if(I.getBool())
{
row = I.getRow();
col = I.getCol();
I.setBool(false);
}
System.out.println("Click the place you want to move to.");
while(!(I.getBool())){}
if(I.getBool())
{
nRow = I.getRow();
nCol = I.getCol();
I.setBool(false);
}
if(G.canMove(row, col, nRow, nCol))
{
G.move(row, col, nRow, nCol, I);
redo = false;
}
else
{
System.out.println("You cant move there! Try again!");
}
}
I.updateBoard(G.getBoard().getArray(), G.getSides());
}
}
});
}
}
The board displays properly when I comment out the main while loop (and everything inside of it), and I assume the problem lies somewhere inside there, but I have been unable to find it. I have also looked online for similar game loop problems, but all of those have been for games involving frame rates and movement across a java swing frame, something that is not present in my code.
Any help would be greatly appreciated.
You have several loops such as
while(!(I.getBool())){}
which could potentially run forever if I does not respond as expected. You could start by printing something out within these loops, and within the following blocks if(I.getBool()){...} to see at what point your application gets stuck.
Checking the user interface in a loop like this is not good practice. It is better to use Listeners to respond to the user interface.
Nor is running the main application on the Swing thread using SwingUtilities.invokeLater(new Runnable(), even though it avoids potential problems of updating the GUI from another thread.
In fact, this may be your root problem, as running the main application loop on the Swing thread (the thread used to run the GUI) like this probably prevents the GUI from ever responding properly. You are putting a task (the entire game) onto the GUI's queue, but that task never completes while(!(G.isGameOver())).

Java: Checking if PC is idle

This is a rather tricky question as I have found no information online. Basically, I wish to know how to check if a computer is idle in Java. I wish a program to only work if the computer is in active use but if it is idle then to not.
The only way i can think of doing this is hooking into the mouse/keyboard and having a timer.
MSN Messenger has that "away" feature, I wish for something similar to this.
Java has no way of interacting with the Keyboard, or Mouse at the system level outside of your application.
That being said here are several ways to do it in Windows. The easiest is probably to set up JNI and poll
GetLastInputInfo
for keyboard and mouse activity.
Im not a professional, but i have an idea:
you can use the java's mouse info class to check mouse position at certian intervals say like:
import java.awt.MouseInfo;
public class Mouse {
public static void main(String[] args) throws InterruptedException{
while(true){
Thread.sleep(100);
System.out.println("("+MouseInfo.getPointerInfo().getLocation().x+", "+MouseInfo.getPointerInfo().getLocation().y+")");
}
}
}
replace the print statement with your logic, like if for some interval say 1 min the past position of mouse is the same as new position (you can simply compare only the x-coordinates), that means the system is idle, and you can proceed with your action as you want (Hopefully it is a legal activity that you want to implement :-)
Besure to implement this in a new thread, otherwise your main program will hang in order to check the idle state.
You can solve this with the help of Java's robot class.
Use the robot class to take a screenshot, then wait for lets say 60 seconds and take another screenshot. Compare the screenshots with each other to see if any changes
has happened, but don't just compare the screenshots pixel by pixel. Check for the percentage of the pixels that has changed. The reason is that you don't want small differences like Windows clock to interfere with the result. If the percentage is less that 0.005% (or whatever), then the computer is probably idling.
import java.awt.AWTException;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
public class CheckIdle extends Thread {
private Robot robot;
private double threshHold = 0.05;
private int activeTime;
private int idleTime;
private boolean idle;
private Rectangle screenDimenstions;
public CheckIdle(int activeTime, int idleTime) {
this.activeTime = activeTime;
this.idleTime = idleTime;
// Get the screen dimensions
// MultiMonitor support.
int screenWidth = 0;
int screenHeight = 0;
GraphicsEnvironment graphicsEnv = GraphicsEnvironment
.getLocalGraphicsEnvironment();
GraphicsDevice[] graphicsDevices = graphicsEnv.getScreenDevices();
for (GraphicsDevice screens : graphicsDevices) {
DisplayMode mode = screens.getDisplayMode();
screenWidth += mode.getWidth();
if (mode.getHeight() > screenHeight) {
screenHeight = mode.getHeight();
}
}
screenDimenstions = new Rectangle(0, 0, screenWidth, screenHeight);
// setup the robot.
robot = null;
try {
robot = new Robot();
} catch (AWTException e1) {
e1.printStackTrace();
}
idle = false;
}
public void run() {
while (true) {
BufferedImage screenShot = robot
.createScreenCapture(screenDimenstions);
try {
Thread.sleep(idle ? idleTime : activeTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
BufferedImage screenShot2 = robot
.createScreenCapture(screenDimenstions);
if (compareScreens(screenShot, screenShot2) < threshHold) {
idle = true;
System.out.println("idle");
} else {
idle = false;
System.out.println("active");
}
}
}
private double compareScreens(BufferedImage screen1, BufferedImage screen2) {
int counter = 0;
boolean changed = false;
// Count the amount of change.
for (int i = 0; i < screen1.getWidth() && !changed; i++) {
for (int j = 0; j < screen1.getHeight(); j++) {
if (screen1.getRGB(i, j) != screen2.getRGB(i, j)) {
counter++;
}
}
}
return (double) counter
/ (double) (screen1.getHeight() * screen1.getWidth()) * 100;
}
public static void main(String[] args) {
CheckIdle idleChecker = new CheckIdle(20000, 1000);
idleChecker.run();
}
}
Nothing in the platform-independent JRE will answer this question. You might be able to guess by measuring clock time for a calculation, but it wouldn't be reliable. On specific platforms, there might be vendor APIs that might help you.
1) Make a new thread.
2) Give it a super super low priority (the lowest you can)
3) Every second or two, have the thread do some simple task. If super fast, at least 1 CPU is prolly idle. If it does it slow, then at least 1 core is prolly not idle.
Or
Just run your program at a low priority. That will let the OS deal with letting other programs run over your program.

Categories