LibGdx moveTo action not executed - java

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.

Related

How to run if once, then run else forever

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;
}

How to activate a function within an loop to continue after exiting loop

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.

How to force something to happen before something else JAVA

In my app I'm trying to create a "loading screen" so the user knows what's happening and doesn't think the app is lagging when loading a new view upon releasing a button. I'm trying to have my "setViewVisibility" method run before the rest of the code but I can't seem to make it work. The way I have it set up right now is that there's an instance boolean that gets changed when one action is completed but for some reason it's not working. Any ideas on how I could fix this?
if(isLoadScreen == true){
setViewVisibility(visibility.END);
buttoni.setAlpha((float) 1);
isLoadScreen = false;
}
if (isLoadScreen == false){
setKeysList(list);
startQuestion(keysList.get(0));
currentQuestion = 0;
isLoadScreen = true;
}
Your second block is always executed because isLoadScreen is always false at that point. You need to use else instead of if to get the behavior you want.
if (isLoadScreen == false){ //isLoadScreen is always false here - just use else instead
setKeysList(list);
startQuestion(keysList.get(0));
currentQuestion = 0;
isLoadScreen = true;
}
That said, there are better ways to create splash/loading screens - this question How do I make a splash screen? might provide some hints.

How to perform white box testing on void methods?

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.

small lags when starting the next moveTo action

[UPDATE] i changed the order a bit so i call the super.act(delta) at the end of the method and it seems to help a bit! But not that sure about it yet.
I got a square system for my map. So its an 2D array and i i make one move the figure does move from one square to the next. While that it's not possible to "stop" the figure between 2 squares. When my characters made one move i check if the Touchpad is touched and if yes i start the next move. While that it seems to lag sometimes and i dont know why!? I really hope you may find the "lag". Here is how i calculate the next move inside the act()of my Actor Character:
#Override
public void act(float delta) {
super.act(delta); // so the actions work
if (moveDone) {
if (screen.gameHud.pad.isTouched()) {
// check in which direction is the touchcontroller
if (screen.gameHud.pad.getKnobPercentX() < 0
&& Math.abs(screen.gameHud.pad.getKnobPercentY()) < Math
.abs(screen.gameHud.pad.getKnobPercentX())) {
// checkt if the |x|>|y|
if (checkNextMove(Status.LEFT)) {
this.status = Status.LEFT;
move(Status.LEFT);
this.screen.map.mapArray[(int) (this.mapPos.x)][(int) this.mapPos.y] = Config.EMPTYPOSITION;
this.screen.map.mapArray[(int) (this.mapPos.x - 1)][(int) this.mapPos.y] = Config.CHARSTATE;
this.mapPos.x--;
moveDone = false;
}
} else if //.... rest is the same just with other directions
else{ //if touchpad isnt touched!
setIdle();
}
updateSprite(delta); //just change the textureRegion if its time for that
} //methode end
Okay so you need some more informations i am sure. Checkmoves like this:
case LEFT:
if (this.mapPos.x - 1 >= 0)
if (this.screen.map.mapArray[(int) (this.mapPos.x - 1)][(int) this.mapPos.y] == Config.EMPTYPOSITION)
return true;
break; //same for all other just direction changin
And the last you need to know is the move(_) i guess. It does add an moveTo Action to my figures.
public void move(Status direction) {
switch (direction) {
case LEFT:
this.addAction(Actions.sequence(
Actions.moveTo((getX() - Config.BLOCK_SIZE), getY(), speed),
moveDoneAction));
break;
moveDoneAction is a simple RunnableAction that set the boolean moveDone to true if its done moving.
i really hope you can help. If you need some more informations please let me know as comment!
There are better tools than StackOverflow for optimizing Android code. Use a profiler and see what is actually happening. Specifically, the traceview profiler: how to use traceview in eclipse for android development? (If you're not using Eclipse, you can use traceview directly via the ADT.)

Categories

Resources