I'm new in LibGdx, actually I'm creating a simple Libgdx game for Android devices.
I'm facing to a problem with my play/pause music in LibGdx here is the simplified code.
//...
#Override
public void render(float delta) {
//...
if(inputHelper.isTouched()){
input.x = inputHelper.getScreenX();
input.y = inputHelper.getScreenY();
camera.unproject(input);
if(soundRect.contains(input.x, input.y)){
if(parent.getSound()) parent.pauseBackMusic();
if(!parent.getSound()) parent.playBacMusic();
}
}
}
//...
public void pauseBackMusic(){
if(backMusic.isPlaying()){
backMusic.pause();
isSound = false;
}
}
public void playBackMusic(){
if(!backMusic.isPlaying()){
backMusic.play();
isSound = true;
}
}
public Boolean getSound() {
return isSound;
}
As you can see in the code when I touch the soundRect it's looping between pauseBackMusic() and playBackMusic().
Thank you.
Your Problem is that you use two if statements:
if(parent.getSound()) parent.pauseBackMusic();
if(!parent.getSound()) parent.playBacMusic();
So the first statement is true because isSound = true
Then you call method pauseBackMusic() in this method you set isSound = false
Then your next if statement tests: !parent.getSound() this is also true because: isSound = false and the method playBacMusic() set isSound = true
And it starts at the beginning by the next click.
Use else if statement instead:
if(parent.getSound()) parent.pauseBackMusic();
else if(!parent.getSound()) parent.playBacMusic();
So if parent.getSound() is true the else if statement will be skipped and isSound is still false. And by the next click only the else if statement will be true and the music will turn back on.
Or in this example you can simplify by only use else:
if(parent.getSound()) parent.pauseBackMusic();
else parent.playBacMusic();
You can use an InputProcesser in order to listen to touch events. Using this, you can listen to a touch event that is only called once when a user presses your button unlike running in a constant loop like in your example.
You can do this by using the touchDown Method
Related
i am creating an android game and have an onTouchEvent like this:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (!action) {
action = true;
}
} else {
action=false;
}
return true;
}
My problen is now, that action is false as soon as i swipe my finger a little bit.
thanks for helping,
Florian
If you want to return true even when a swipe input occurs, you could store the last action to compare if the last action was ACTION_DOWN and if the current 'event.getAction()' is also ACTION_DOWN, then you can assume that the swipe action occurs (also if the previous 'x' and 'y' positions differ to the current 'x' and 'y' positions), therefore still return true. Any other scenario, you can return false.
You could also try looking in the android API documentation about a swipe input action/gesture.
Hope that is helpful.
I am doing a beginner project and I have had a little issue with a radio button. This button's job is to change the theme of the window from light to dark and vice versa.
I'm not too sure on how to ask for Java to detect the value for the Color.decode() method. I want it to check if the current color is either "#21252B" or "#FFFFFF"
I expect it to look kind of like:
if(*however you are supposed to do it*.equals("#21252B")) {
frame.getContentPane().setBackground(Color.decode("#FFFFFF"));
darkMode.setBackground(Color.decode("#FFFFFF"));
} else {
frame.getContentPane().setBackground(Color.decode("#21252B"));
darkMode.setBackground(Color.decode("#21252B"));
}
What can I do?
I figured out what I had to do. Thanks to #AndrewThompson for the suggestion. If anyone needs an answer to a similar problem, here it is. Make
private boolean isDark = true //or false if you want from the get go.
Then, whenever you do your button do the following code
public void actionPerformed(ActionEvent arg0) {
if(isDark == true) {
lightTheme();
isDark = false;
} else {
darkTheme();
isDark = true;
}
after this you should be good to go.
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
}
My method some reason doesnt work I want it so when I click tab it grabs the mouse and moves the player but when clicked again I want it to release the mouse and stop the players rotation I tried putting a print statement into the movePlayerWithMouse method but it just returns true the only thing that does change is the mouse each time I click tab it releases and grabs any help?
Heres the method I use:
boolean movePlayerWithMouse = false;
while(Keyboard.next()) {
if(!Keyboard.getEventKeyState()) {
if(Keyboard.getEventKey() == Keyboard.KEY_TAB) {
movePlayerWithMouse = !movePlayerWithMouse;
Mouse.setGrabbed(!Mouse.isGrabbed());
}
}
}
if(movePlayerWithMouse = !movePlayerWithMouse) {
rotY -= Mouse.getDX() / SENSITIVITY;
}
when I run my app it will continuously be stuck in a while loop. It should leave the while loop when a button is pressed, however even after pressing a button it continues to loop.
View.OnClickListener listener11 = new View.OnClickListener() {
#Override
public void onClick(View view) {
temp1 = button[0];
temp3 = button[0].getBackground();
state++;
}
};
while(state == 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
button[0].setOnClickListener(listener11);
}
variable:
state is an int temp1 is a button temp3 is a Drawable
the delay is there because I actually have 20 buttons and I have the setOnClickListeners for all the buttons inside that while loop so I think it causes it to crash without the delay. Another question would be is it possible to have the setOnClickListeners outside the while loop but still be able to check for button clicks inside the loop?
The problem is you are pressing the button while the thread is in a sleeping state causing the event to not be triggered and therefor the state to never change.
You should remove the while loop and just set all the listeners in a for loop:
for(int i = 0; i< button.length; i++) {
button[0].setTag(i);
button[0].setOnClickListener(listener11);
}
And then change your listener to be something like:
private boolean firstClick = true;
View.OnClickListener listener11 = new View.OnClickListener() {
#Override
public void onClick(View view) {
if(firstClick) {
firstClick = false;
temp1 = button[(int)view.getTag()];
} else {
temp2 = button[(int)view.getTag()];
}
}
};
I'm not sure exactly what the code is supposed to be doing because I have no idea of the context, but I think think you could remove the while loop altogether:
// initialize the listener
View.OnClickListener listener11 = new View.OnClickListener() {
#Override
public void onClick(View view) {
// add code that runs when button is clicked here
}
};
// now that we have the listener all set up we add it to the button, at which point it just keeps listening for you, no need to put the thread to sleep
button[0].setOnClickListener(listener11);
UPDATE:
So because you want to see if the second value matches the first value you could use a helper method:
private String firstValue = "";
public boolean isMatch(String mostRecentValue) {
boolean match = false;
if (firstValue.isEmpty()) {
firstValue = mostRecentValue;
} else {
match = firstValue.equals(mostRecentValue);
firstValue = "";
}
return match;
}
This method takes a value and if it is the first click the value is saved, if it is the second click it compares it with the first click and then resets the method. A boolean is returned false for no match, and true for a match. Call this method from within the onClick() method and pass in the buttons value. I've used String as an example value but you could use any object type.
I think you might be misunderstanding what setOnClickListener is doing. It's not handling the click, it is setting up the click handler. The line button[0].setOnClickListener(listener11); would be part of your activity initialisation and then not called again.
The reason you get stuck is because the main thread is busy in the while loop and isn't given an opportunity to process click events. Click events are handled on the main thread but only when it's not already busy doing something. In this case, it's forever busy in the while loop. For example, if the main thread was processing a method that would take 10 seconds to complete and you tap on a button 3 seconds into it, the button press wouldn't be handled for another 7 seconds. At which point, the previously set listener11 would be executed.
What you seem to be trying to achieve is already handled by the Looper. You need to be thinking in terms of event handling. So in other words, all your logic needs to go in listener11 or something similar.