How to handle event in a program running in a cycle (loop)? - java

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

Related

Java/Processing mousePressed in loop not working

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.

java: make program wait until transition is finished

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.

Why is it adding more than 1 to my speed control?

import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
public class Turtle extends Actor
{
/**
* Act - do whatever the Turtle wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
int laufmenge;
public void act()
{
if(Greenfoot.isKeyDown("left")){
move(-speed);
}
if(Greenfoot.isKeyDown("right")){
move(speed);
}
if(Greenfoot.isKeyDown("up")){
setLocation(getX() ,getY() -speed);
}
if(Greenfoot.isKeyDown("down")){
setLocation(getX() ,getY() +speed);
}
if(Greenfoot.isKeyDown("x")){
if(speed<10) speed++;
}
if(Greenfoot.isKeyDown("y")){
if(speed>0) speed--;
}
System.out.println(speed);
}
private int speed=1;
}
This is code from Greenfoot because i am currently trying to learn coding. I cant understand why when i execute the programm and control the speed he is changing the value by more than one. I guess it will be an easy question.
And is it possible to put the increase and decrease of the speed on one button with two letters like the >< key? i didnt work in my case.
This happens because act() is called in rapid succession. Even if you just press and release x, act() will have run several times while the key is down, and therefore updated the speed several times.
To avoid that, you can track whether or not you've adjusted the speed since the first time you noticed that the button was pressed.
For example, you can have a private bool adjustedSpeed = false; in your class, and then do:
if(Greenfoot.isKeyDown("x")){
if(speed<10 && !adjustedSpeed) speed++;
adjustedSpeed = true;
} else if(Greenfoot.isKeyDown("y")){
if(speed>0 && !adjustedSpeed) speed--;
adjustedSpeed = true;
} else {
adjustedSpeed = false
}

I'm trying to create a display which shows a number of components changing colors in a loop

My issue with the above is that graphic functions in java seems to only act at the end of a method, meaning that they will never produce an output during a loop, and that there's no way to delay the visual changes to keep them from happening all at once. If you try to delay the visual changes with sleep the code will just take longer to compile and then make all the visual changes at the very end all at once.
Here is a snipit of the code I am working with:
public class simulation{ //this class is inside of my main class so it inherits all the objects
public void update(){
//drawProgression is supposed to be called from here in a loop, and update is called from the main class
//I hanven't found a way to make this work though
}
//This method is meant to turn a grid of 12 panels green one by one
//pnM# are the panels
//This method works, but I can't find a way to loop it, or delay the actions so the user can see the changes as they happen
private void drawProgression(){
if(progressionCounter>11){
progressionCounter=0;
}
if(progressionCounter==0){
pnM1.setBackground(GREEN);
pnM12.setBackground(GRAY);
}
if(progressionCounter==1){
pnM2.setBackground(GREEN);
pnM1.setBackground(GRAY);
}
if(progressionCounter==2){
pnM3.setBackground(GREEN);
pnM2.setBackground(GRAY);
}
if(progressionCounter==3){
pnM4.setBackground(GREEN);
pnM3.setBackground(GRAY);
}
if(progressionCounter==4){
pnM5.setBackground(GREEN);
pnM4.setBackground(GRAY);
}
if(progressionCounter==5){
pnM6.setBackground(GREEN);
pnM5.setBackground(GRAY);
}
if(progressionCounter==6){
pnM7.setBackground(GREEN);
pnM6.setBackground(GRAY);
}
if(progressionCounter==7){
pnM8.setBackground(GREEN);
pnM7.setBackground(GRAY);
}
if(progressionCounter==8){
pnM9.setBackground(GREEN);
pnM8.setBackground(GRAY);
}
if(progressionCounter==9){
pnM10.setBackground(GREEN);
pnM9.setBackground(GRAY);
}
if(progressionCounter==10){
pnM11.setBackground(GREEN);
pnM10.setBackground(GRAY);
}
if(progressionCounter==11){
pnM12.setBackground(GREEN);
pnM11.setBackground(GRAY);
}
progressionCounter++;
}
}
Is what I'm trying to do possible in Java, or Java JFrame From? How would I go about it because I've been stumped for hours. Thanks.

Should I implement actions inside the methods of an InputListener object?

I am making a button using MouseOverArea. After some trial and error, I realized I can override the methods in InputListener to do particular actions when an input event is notified.
For example, do things when mouse left button is pressed while cursor is over the component.
#Override
public void mousePressed(int button, int mx, int my) {
if (isMouseOver() && button == Input.MOUSE_LEFT_BUTTON) {
// Some magic happens
}
}
However, I will not able to do things like changing current game state because no Game object around. I know there are many ways to solve this problem, but I would like to know what is the Slick way to do this.
Are these methods suitable for such behavior ?
One way to modify game states is to use boolean states; Which are boolean variables that hold the state of the game or player. For example:
boolean isMovingUp, isMovingLeft, isMovingRight, isMovingDown;
You can then set these to true/false depending on what mouse or keyboard event takes place and your game class then read these variables, like so:
if (isMovingUp) {
// do something
isMovingUp = !isMovingUp;
}
Hope that helps!

Categories

Resources