I'm making an escape room through the console.
I'm trying to run an if statement, and I want to have the if statement code run once, and then run the else code forever afterward. My program is looped to go back to the same menu after it's finished with a choice the user chooses.
Here is my current code:
if (checkBedDraw = false) {
clear();
typePrint("You found a \u001b[34mpicklock\u001b[0m! you can only use this on a specific lock, because of its shape. This item has been added to your \u001b[31minventory\u001b[0m.", 50);
invArray[0] = "picklock";
checkBedDraw = true;
} else if (checkBedDraw = true) {
typePrint("You have already checked the drawers, and aqcuired a picklock.", 50);
}
typePrint() and clear() are methods I made.
= and ==
Be careful, in if statements you have to use == as = is used to assign a value to a variable.
Also, you are dealing with Boolean so you can just do something like this:
if (checkBedDraw) {
typePrint("You have already checked the drawers, and aqcuired a picklock.", 50);
} else {
clear();
typePrint("You found a \u001b[34mpicklock\u001b[0m! you can only use this on a specific lock, because of its shape. This item has been added to your \u001b[31minventory\u001b[0m.", 50);
invArray[0] = "picklock";
checkBedDraw = true;
}
Related
I'm trying to write a logic in memory game that when I click on cards and they are not a pair (different ID), program should swap them back after 1s. If they are same, then leave them as they are.
The problem is that when I first click and the card appears, after second clicking on another (different) card it doesn't appear and swap the first card after 1s. someone knows why the second card does not appear after clicking?
Btw when the pair is correct, everything works fine, here is my fragment of the code responsible for that logic in listener:
final int copy = i;
card2.addActionListener((e) -> {
card2.setIcon(new ImageIcon(icons[copy].getAbsolutePath()));
if(firstClick == null)
{
firstClick = (Card)e.getSource();
}
else
{
Card secondClick = (Card)e.getSource();
if(firstClick.getID() != secondClick.getID())
{
try
{
Thread.sleep(1000);
} catch (InterruptedException e1)
{
//e1.printStackTrace();
}
firstClick.setIcon(new ImageIcon(background.getAbsolutePath()));
secondClick.setIcon(new ImageIcon(background.getAbsolutePath()));
firstClick = null;
}
else
firstClick = null;
}
});
While method actionPerformed is executing, the GUI cannot react to mouse and keyboard events, so basically your code is "freezing" your GUI for one second. I believe that the class javax.swing.Timer is what you need and at first glance it looks like the duplicate question that MadProgrammer referred to may help you.
i'm sure I can figure this out on my own but I feel like the way i'm writing it is already too expensive and coupled.
I am writing a simulator with a security robot and a intruder, I have a collision function, where in the 3rd if statement it checks if an intruder (rectangle of width 11) collides with an surveillance camera (arc) and if that happens then I want to activate my function for the security robot to chase the intruder.
<-- Important note: the checkShapeIntersection function is inside a timeLine event so its running constantly -->
private boolean checkShapeIntersection(Shape block) {
//Name to check for intruder and surveillance collision
String Surveillance = "Arc";
boolean collisionDetected = false;
for (Shape static_bloc : nodes) {
if (static_bloc != block) {
Shape intersect = Shape.intersect(block, static_bloc);
if (intersect.getBoundsInLocal().getWidth() != -1) {
collisionDetected = true;
//Checks of intruder collides with an arc (surveillance), the 11th width is only for intruder rectangles
if ( Surveillance.equals(block.getClass().getSimpleName()) && static_bloc.getBoundsInLocal().getWidth() == 11) {
//Activate Chase function
testRobot.chaseIntruder(static_bloc);
detected = true;
}
}
}
}
if (collisionDetected) {
block.setFill(Color.BLUE);
} else {
block.setFill(Color.RED);
}
return detected;
}
And inside my Security Robot Class
public void chaseIntruder(Shape intruder) {
destinationsList.add(new Vector2D(intruder.getLayoutBounds().getMinX(),intruder.getLayoutBounds().getMinY()));
this.updatePosition();
}
You probably want to use multi-threading here, in Java you can implement Runnable or Thread to achieve wanted functionality.
Here are some links with more info:
In a simple to understand explanation, what is Runnable in Java?
https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html
Hope it helps.
I am making an app and i have an annoying bug/error: when i want my image to move gradually upwards, it doesn't do anything. Here is some of my code:
public void checkButtons(){
MoveToAction moveUp = new MoveToAction();
moveUp.setDuration(actionDuration);
moveUp.setPosition(0, Gdx.graphics.getHeight());
MoveToAction moveDown = new MoveToAction();
moveDown.setDuration(actionDuration);
moveDown.setPosition(0, Gdx.graphics.getHeight() - Gdx.graphics.getHeight() * 2);
MoveToAction moveLeft = new MoveToAction();
moveLeft.setDuration(actionDuration);
moveLeft.setPosition(Gdx.graphics.getWidth() - Gdx.graphics.getWidth() * 2, 0);
MoveToAction moveRight = new MoveToAction();
moveRight.setDuration(actionDuration);
moveRight.setPosition(Gdx.graphics.getWidth(), 0);
if (goingUp == true){
red_dot.addAction(moveUp);
if (goingUp == false){
red_dot.removeAction(moveUp);
}
}
if (goingDown == true){
red_dot.addAction(moveDown);
if (goingDown == false){
red_dot.removeAction(moveDown);
}
}
if (goingLeft == true){
red_dot.addAction(moveLeft);
if (goingLeft == false){
red_dot.removeAction(moveLeft);
}
}
if (goingRight == true){
red_dot.addAction(moveRight);
if (goingRight == false){
red_dot.removeAction(moveRight);
}
}
red_dot is an image and the rest of the variables are pretty straightforward.
Thanks in advance.
A few things to check:
Are you calling stage.act()?
Is your actionDuration non-zero?
Are you sure about those coordinates? Most of them look like they would be off-screen if you're using a ScreenViewport. And if you're not, why would the size of the screen have anything to do with where you want to move your object?
It also seems you have some kind of misunderstanding about logic flow. The code structure that you repeat four times doesn't make sense:
if (someCriterion == true) {;
doSomething();
if (someCriterion == false) {
//Code in here will never be called unless `doSomething()` immediately causes
//someCriterion to become false as a side effect (which addAction() will not do).
}
}
I'm guessing you are thinking either that the code under addAction will get called after the action is complete, or that it will be called repeatedly. But neither is the case. If you want to stop the actions early, you must remove them at the spot in your code where you are changing variables such as goingUp to false.
But if you are just trying to remove actions that are complete, that is unnecessary, because that happens automatically.
Also, you shouldn't be creating all those extra actions that you may not be using. You're generating lots of garbage that could cause stuttering. Only create actions that you are definitely going to use. And instead of using new MoveToAction(), use Actions.moveTo() to get the action you need from the pool. Then it will not trigger garbage collection when it is complete, because Stage knows to send pooled actions back to the pool for recycling.
I am trying to perform white box testing on the method below. It's a method for blinking an array list (lightUpSequence) of JButtons in Swing using a timer.
My question is as follows:
since this is a void method, how would one check the expected output? I plan to create different sizes of array lists as the inputs. For white box testing, is one allowed to add any codes such as print/counter statements inside the method being tested? I feel hesitant to add any modifications to the method and think that the method should be tested as is.
Thank you very much.
private void blinkSequence() {
final Timer timer = new Timer(BLINKING_TIMER_DELAY, null);
timer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (lightUpSequence.size() == 0) {
timer.stop();
}
// Turn button ON
if (!isON && lightUpSequence.size() > 0) {
int elementIndex = lightUpSequence.get(0);
buttonArrayList.get(elementIndex).setBackground(
Color.yellow);
isON = true;
// Turn button OFF if it's ON already. Then remove the
// element.
} else if (isON && lightUpSequence.size() > 0) {
int elementIndex = lightUpSequence.get(0);
buttonArrayList.get(elementIndex).setBackground(null);
lightUpSequence.remove(0);
isON = false;
}
}
});
timer.start();
timer.setRepeats(true);
}
Well, there is nothing stopping you from making it return a boolean, but if you want to keep it the way it is you can use assert statements.
have a look at assert
For testing void method I use the following startegy:
Granulize the variables of the method through globalizing them.
So if you have an array, check the size before and after calling it.
If the size is the same, check the state of the objects in the array and compare them as before and after calling the method, like if they are lit or not.
In this way you can effectively comply to the white box testing rules.
Okay so I am pretty much doing a crash course through creating a java application and am having an issue with executing an action. The program is the 15 puzzle, the game where you slide one piece at a time and try to get all numbers in order, so I allow for an 'Auto' mode option that will solve the board for the user once clicked. So my code reads the solution from a text file which is working fine just none of the 'squares' (JButtons) move when I click the auto button. So i am not sure if I just don't understand the action even process completely or not. heres my code, I can supply more of it if necessary.
if (e.getSource() == ctrButtons[0]) {
System.out.println("Auto Mode started\n");
Scanner s = null;
try {
s = new Scanner(new BufferedReader(new FileReader("move_list.txt")));
int count = 0;
while (s.hasNext()) {
//Cycle through to move in move_list
if (count != 18) {
s.next();
count+=1;
}
else {
int cur_move = Integer.parseInt(s.next());
count = 0;
/*Use cur_move to move blank space accordingly
*UP------------3
*LEFT----------2
*RIGHT---------1
*DOWN----------0
*/
int zero_index = -1;
for (int j=0; j<jbnButtons.length; j++) {
if (Integer.parseInt(jbnButtons[j].getText()) == 0) {
zero_index = j;
break;
}
}
Point zero = jbnButtons[zero_index].getLocation();
//Check if move is up
if (cur_move == 3) {
Point next = jbnButtons[zero_index-4].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index-4].setLocation(zero);
}
//Check if move is left
else if (cur_move == 2) {
Point next = jbnButtons[zero_index-1].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index-1].setLocation(zero);
}
//Check if move is right
else if (cur_move == 1) {
Point next = jbnButtons[zero_index+1].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index+1].setLocation(zero);
}
//Check if move is down
else {
System.out.println("Current move = 0");
Point next = jbnButtons[zero_index+4].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index+4].setLocation(zero);
}
}
}
}
So my code executes when I click the 'Auto' button and I was printing output to the screen to see if it was looping through the code which it was, just none of the buttons move each time through the loop. Any ideas??
You code is executing on the Event Dispatch Thread. The GUI can't repaint itself until the code finishes executing, so you won't see the intermediate steps only the final location of each component.
Read tje section from the Swing tutorial on Concurrency for a more complete explanation.
Maybe you should use a Swing Timer (the tutorial also has a section on this). Each time the Timer fire you do the next move.