So I was making a simple game in Java + Processing where there were buttons and loops in draw(). Apparently the PApplet function mousePressed() doesn't work constantly if there is a loop, so I tried putting my own checkmouse() function to be checked during the loop. However, it still doesn't work. How do I make it so that I can run a game with while-loops and constantly check for mousePressed at the same time?
//draw() func
public void draw() {
for (int i = 0; i < 10000; i++) { //to simulate a while loop
//do something, like run some other functions that create the buttons
checkmouse();
}
}
//checkmouse function
public void checkmouse() {
if (mousePressed) {
System.out.println("x");
}
}
When I click the mouse in the processing window, it never shows "x" even though checkmouse() runs every time it loops, so theoretically it should be checking it pretty constantly while the loop runs.
Also could someone explain why this doesn't work?
boolean esc = false;
while (!esc) {
if (mousePressed) {
System.out.println("x");
esc = true;
}
}
The event variables (mousePressed, keyPressed, etc.) are updated between calls to the draw() function.
In other words: the mousePressed function will never change within a call to the draw() function. You need to let the draw() function complete and then be called again if you want the event variables to be updated.
Behind the scenes, this is because Processing is single-threaded. (This is by design, because multi-threaded UI programs are a nightmare.)
Taking a step back, you probably don't want to include a long loop inside your draw() function. Take advantage of the 60 FPS loop that's implemented by Processing instead.
Related
I've been writing a method to switch two images. This method is called in a mouse drag-and-drop event and is followed by another method that lets images drop down a few positions (I'm talking about a sort of candy crush mechanism).
In my case, the transition in the second method starts before the switch is done, which is why you can barely see the switch.
What I'm looking for is a way to make the program wait until the first transition is finished before it steps into the next method. Thread.sleep() isn't working for me since it stops the switch animation as well, and I don't know how to use the transition.setOnFinished() properly within my switch method without causing an infinite loop.
This is part of my switch method:
public void animateSwitch(int xFirst, int yFirst, int xLast, int yLast) {
/.../
ParallelTransition allMovements = new ParallelTransition();
TranslateTransition tt = new TranslateTransition(Duration.millis(FALL_TIME_PER_ROW), getNodeFromGridPane(grdPane, xFirst, yFirst));
TranslateTransition tt2 = new TranslateTransition(Duration.millis(FALL_TIME_PER_ROW), getNodeFromGridPane(grdPane, xLast, yLast));
Image old = iv1.getImage();
iv1.setImage(iv2.getImage());
iv1.setTranslateX(iv2.getX());
iv1.setTranslateY(iv2.getY());
iv2.setImage(old);
iv2.setTranslateX(iv1.getX());
iv2.setTranslateY(iv1.getY());
if (xFirst == xLast) {
tt.toYProperty().set(0);
tt.toXProperty().set(tt.getFromX());
if (yFirst < yLast) {
tt.fromYProperty().set(rowHeight);
tt2.fromYProperty().set(-rowHeight);
}
else {
tt.fromYProperty().set(-rowHeight);
tt2.fromYProperty().set(rowHeight);
}
tt2.toYProperty().set(0);
tt2.toXProperty().set(tt2.getFromX());
}
else if (yFirst == yLast) {
tt.toXProperty().set(0);
tt.toYProperty().set(tt.getFromY());
if (xFirst < xLast) {
tt.fromXProperty().set(rowWidth);
tt2.fromXProperty().set(-rowWidth);
}
else {
tt.fromXProperty().set(-rowWidth);
tt2.fromXProperty().set(rowWidth);
}
tt2.toXProperty().set(0);
tt2.toYProperty().set(tt2.getFromY());
}
allMovements.getChildren().add(tt);
allMovements.getChildren().add(tt2);
allMovements.play();
}
Thanks in advance!
You will have to set the onFinished event handler using allMovements.setOnFinished(eventHandler); Here eventHandler is an object that implements the EventHandler interface.
EDIT:
I skipped past the part where you don't know how to prevent an infinite loop using this solution. You can use two different eventHandlers to do the different parts. The first calls the second when it finishes. The second doesn't need to call the first, so you will not get into a loop.
I´ve been dealing with this for some days now I´ve serach over the internet and tried everything that came up to my mind but nothing works. My problem is that I am making a pexeso game, we have some additionaly library directly from school or something like that which allows us to draw some pictures instead of comad line only... (We didn´t have graphics yet) So my problem is that my game is running in cycle and waiting for my click som I am checking the condition if click was made. And if I want to click I have to have just a method public void vyberSuradnice(int, int) declared in my code.
So the problem is that my game is runinng in cycle and checking if click was made. But when the click was made the method vyberSuradnice is executed and there I am setting the value off atrrbiute - cakatNaKlik on false, so click was made and one step of game can be made.. But since the function is running in cycle, then even If I clicked and in the method vyberSuradnice the value of attribute is changed, my function which is running in cycle isn´t respond to that change, so the game isn´t going on.
this is the method for clicking
public void vyberSuradnice(int paSuradnicaX, int paSuradnicaY) {
this.riadokOdkry = (paSuradnicaY ) / 25;
this.stlpecOdkry = (paSuradnicaX - 10) / 25;
if (this.riadokOdkry > this.aPocetRiadkov || this.stlpecOdkry > this.aPocetStlpcov) {
System.out.println("Klikli ste mimo hracieho pola ");
} else {
this.cakatNaKlik = false;
}
}
This the part of code where I am waiting for cakatNaklik - false value
while (uhadol) {
if (!this.cakatNaKlik) {
if (this.pocetUhadnutych >= (this.aPocetRiadkov * this.aPocetStlpcov) / 2) {
uhadol = false;
}
this.hraciaPlocha[this.riadokOdkry][this.stlpecOdkry].setUhadnute(true);
But even if the value is changed in method vyberSuradnice this condition is not triggered. But when I make something like this :
while (uhadol) {
System.out.print(this.cakatNaKlik);
if (!this.cakatNaKlik) {
if (this.pocetUhadnutych >= (this.aPocetRiadkov * this.aPocetStlpcov) / 2) {
uhadol = false;
}
this.hraciaPlocha[this.riadokOdkry][this.stlpecOdkry].setUhadnute(true);
the game is working like by writing the variable refresh it or something... but I am getting neverending print of true true or false on command line and this is something I can´t afford to have...
I know this may can be dan by threads but it´s something I can´t allowed to make and I am basically trying to do two things at once.
Is there any other to do this that the variable will be refreshed even without that println and the code will work ?
Thanks very much for every help
Thanks everybody for help, I finally solved it. I just tried tu put a sleep before the if condition. It only need to sleep for even a one miliseconds and it´s seems that the condition is refreshed so it works.
Try this:
Implement an ActionListener interface or extend a class that implements an ActionListener interface. For example:
public class MyClass implements ActionListener {
}
Register an instance of the event handler class as a listener on one or more components. For example:
someComponent.addActionListener(instanceOfMyClass);
instanceOfClass = this; //(if it is handled in the same Class)
Include code that implements the methods in listener interface. For example:
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
Reference:
https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html
I have this loop
while (true) {
game.update();
view.repaint();
Thread.sleep(DELAY);
}
In the game.update various components of the game have their position changed and those updates are reflected when the repaint() method is called on the view. The view extends JComponent and loops through the game objects and calls their print methods.
What I want to do is have a boolean called nextLevel in the game and if it's true Flash text on the screen for the player to notify them that they're going onto the next level. Maybe flash 4-5 times. Then continue the game.
Is this possible? I have been playing around with Thead.Sleep() but this only seems to pause the displaying and in the background the game is still going on.
Any ideas on how to do this?
Maybe you want to avoid threading by using a Timer object.
an example like that could be
int flashTimer = 0;
if(nextLevel) {
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
//flash something method here
flashTimer++;
}
});
timer.start();
}
and then check your flashTimer if it reaches the number you want then just stop the timer by timer.stop();
Just an idea which seems to me a bit simpler. the 1000 value is milliseconds which is passed and executes the code inside the actionPerformed method every 1 sec.
Hope it helped
So I've been trying to write a simple game where a character is moving using the statement
character1.x+=0.1f*delta
where delta is the time (in milliseconds) between frames. This works well when I want to move it every frame, but I want to be able to move it a set distance (50 pixels, or a single tile in my game) at that speed. Using for() loops makes it move the sprite at maximum speed, so I can't do that. It has to work on a single keypress, so they don't have to hold the key down.
Of course, I've barely done anything ever in Java, so there's probably a really stupidly simple solution that I'm missing. For now, I can just change it to instantaneous movement, but it looks really jerky. Can someone help?
In this case, you might want to add a keyListener yo your component.
yourComponent.addKeyListener(new KeyAdapter () { // Possibly your Frame
#Override // Overrides the keyPressed event
public void keyPressed(KeyEvent e) {
if ( e == YOUR_KEY_CODE ) {
for( int var = 0; var < yourDistance; var ++ ){
yourSpriteComponent.x += 1;
try{
Thread.sleep(yourTimeInMilliSec);
} catch( Exception e ){
// Your catch block here
}
}
}
}
});
Where YOUR_KEY_CODE is the key that the user needs to be pressed in order to execute the for() loop. Key Codes can be found in javadoc
I know J2ME is pretty outdated, but I have to do this for an assignment. Currently, I am using the GameCanvas class, and my game is a thread, so my code looks something like this..
class Game extends GameCanvas implements Runnable {
public GameCanvas() {
super(false);
}
public void run() {
while (true) {
draw();
flushGraphics();
}
}
protected void keyPressed(int keyCode) {
System.out.println("Hey, it actually worked.");
// other code to handle key press...
}
}
The sad thing is that the keyPressed method never gets called no matter how hard I spam hits on the emulator's numpad. I know of the getKeyStates() method that GameCanvas has, but I don't want to use it because I want to capture not just the game keys, but also the number keys 1~9.
Does anyone have any idea why my code doesn't go into my keyPressed() method, and what I can do about it? Many thanks.
Don't know where I went wrong... but after tweaking a little here and there, it started working perfectly fine. Thanks a lot guys! :)
You have a busy wait within Game#run method which most likely causes device ignore all your hits, making your UI loose responsiveness.
For simple test if above assumption is correct, just insert sleep within the loop, about like below:
while (true) {
draw();
flushGraphics();
try { Thread.sleep(100); } // sleep for 1/10 sec
catch (InterruptedException ie) { System.out.println(ie); }
}
If above helps to recover UI responsiveness, redesign your application to avoid busy waits - MIDP API provides a couple of ways to achieve that.
The MIDP documentation excerpt for GameCanvas(...)
If the developer only needs to query key status using the getKeyStates method, the regular key event mechanism can be suppressed for game keys while this GameCanvas is shown. If not needed by the application, the suppression of key events may improve performance by eliminating unnecessary system calls to keyPressed, keyRepeated and keyReleased methods.
Note that key events can be suppressed only for the defined game keys (UP, DOWN, FIRE, etc.); key events are always generated for all other keys.
So super(false) will suppress the Canvas key event listener methods in GameCanvas. In which case if you still want to register the key events use getKeyEvents(...) in your run(), the example is as under
// Get the Graphics object for the off-screen buffer
Graphics g = getGraphics();
while (true) {
// Check user input and update positions if necessary
int keyState = getKeyStates();
if ((keyState & LEFT_PRESSED) != 0) {
sprite.move(-1, 0);
}
else if ((keyState & RIGHT_PRESSED) != 0) {
sprite.move(1, 0);
}
// Clear the background to white
g.setColor(0xFFFFFF);
g.fillRect(0,0,getWidth(), getHeight());
// Draw the Sprite
sprite.paint(g);
// Flush the off-screen buffer
flushGraphics();
}