I'm making my own level editor and I want to change the cursor to a hand when the spacebar is pressed:
#Override
public boolean keyDown(InputEvent event, int keycode) {
switch (keycode) {
case Input.Keys.SPACE:
System.out.println("Spacebar is pressed");
Gdx.graphics.setSystemCursor(Cursor.SystemCursor.Hand);
break;
}
return true;
}
#Override
public boolean keyUp(InputEvent event, int keycode) {
switch (keycode) {
case Input.Keys.SPACE:
Gdx.graphics.setSystemCursor(Cursor.SystemCursor.Arrow);
break;
}
return true;
}
But it doesn't work and I don't know why... What I am doing wrong?
According to Libgdx wiki page it requires LWJGL3 backend:
You can also change the cursor to a system cursor, this only works in the
LWJGL3 backend and in the GWT backend. It can be done as follows:
Gdx.graphics.setSystemCursor(SystemCursor.Crosshair);
Following is taken from the original issue:
You can easily switch out the LWJGL 2 backend for the LWJGL 3 backend
in Gradle. In your core projects dependencies, change:
compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
to
compile "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
Make sure gdxVersion is set to the latest snapshot version 1.7.3-SNAPSHOT.
In your desktop launcher, simply replace LwjglApplicationConfiguration
and LwjglApplication with Lwjgl3ApplicationConfiguration and
Lwjgl3Application
Related
Here is my Desktop Launcher code:
public class DesktopLauncher {
public static void main (String[] arg) {
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setForegroundFPS(60);
config.setTitle("Game10");
config.setWindowedMode(1240, 760);
config.forceExit = false; // ERROR!!!
new Lwjgl3Application(new GdxGame10(), config);
}
}
In new LWJGL3 config.forceExit not working. I can't find any solution so far. Any help is appreciated.
There is no forceExit in config. So presumably you have a master application that runs a child libGDX component and when you end that child component you find that the entire application shuts down, when you want the master application to continue. I guess you are on desktop because Android would be OK. So you must want to avoid a full System.exit
i.e.
Gdx.app.exit()
shuts down everything.
So when you instantiate a libGDX application you instantiate based on the application type, so for me, I use the same as you
final Lwjgl3Application application = new Lwjgl3Application(Services.GAME_CONTROLLER,config);
and the implementation for exit is
#Override
public void exit () {
running = false;
}
This finished the while loop that drives the application i.e. kills the main thread. If you have -other threads- running in the background they keep going.
If on the other hand you were instantiating LwglAWTCanvas then your shutdown would be this.
#Override
public void exit () {
postRunnable(new Runnable() {
#Override
public void run () {
stop();
System.exit(-1);
}
});
}
which would shut down the entire application. Anyway so forceExit being -false- was to stop a full system exit killing all your threads. The forceExit was to "force" the other threads to finish. It doesn't do that anymore so the fact it is now missing should not matter, your background threads should keep going.
In other words, config.forceExit = false; is now the default behaviour for your application type so you don't need it.
Because of I had problems with Bluetooth on Android Lollipop, I have tried to change the scanner method.
So I have tried to use the new package.
In the previous version, I called startScan(mLeScanCallback) and everything works but now, when I call startScan(mScanCallback) I have the error: "D/BluetoothLeScanner: could not find callback wrapper".
No devices are found and the ListAdapter, I use to show the devices, is empty.
The comment lines are the previous code (and it worked!).
This my code:
public class Selection extends ListActivity implements ServiceConnection {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
// Initializes a Bluetooth adapter through BluetoothManager.
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
getApplicationContext().bindService(new Intent(this, MetaWearBleService.class), this, Context.BIND_AUTO_CREATE);
}
private void scanLeDevice(final boolean enable) {
final BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if (enable) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
//mBluetoothAdapter.stopLeScan(mLeScanCallback);
bluetoothLeScanner.stopScan(mScanCallback);
setListAdapter(listAdapter);
}
}, SCAN_PERIOD);
//mBluetoothAdapter.startLeScan(mLeScanCallback);
bluetoothLeScanner.startScan(mScanCallback);
} else {
//mBluetoothAdapter.stopLeScan(mLeScanCallback);
bluetoothLeScanner.stopScan(mScanCallback);
setListAdapter(listAdapter);
}
}
private ScanCallback mScanCallback =
new ScanCallback() {
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
listAdapter.addDevice(device);
}
});
}
};
Instead the ListAdapter extends BaseAdapter and use a ViewHolder. If it necessary, I post it.
So what does it mean "D/BluetoothLeScanner: could not find callback wrapper"? What is it wrong?
Otherwise how I can't resolve the problem of scanning with the Android Lollipop?
In Lollipop I have often errors about BluetoothGatt. I don't know to minized it (or solve it).
Thanks
The log message D/BluetoothLeScanner: could not find callback wrapper appears whenever Android's bluetooth scanning APIs are told top stop scanning for an app when they think scanning has not started. You can see this by looking at the source code of Android's BluetoothLeScanner here.
This is usually safe to ignore as there are lot of reasons that scanning my not have actually started (it was already stopped, bluetooth is off, permissions have not been granted, etc.) Client software that does scanning often stops scanning on a timer regardless of whether it has been successfully started, or whether it was manually stopped before the timer goes off. Android's example code (and the code shown above) does exactly this, often causing these log messages to show up.
If you really want to minimize these messages, you need to keep track of whether scanning actually started and only stop scanning if it actually did. Unfortunately, you don't get a return code if scanning starts successfully, and you only get an asynchronous callback to onScanFailed(errorCode) if you cannot start successfully. So one approach would be to set scanStartCount++; when you call start scan, and set scanStartCount--; when you get a callback to onScanFailed(errorCode). Then when your timer goes off to stop the scan, only actually stop it if the scanStartCount > 0.
Keep in mind that you can only minimize these messages coming from your application. Other applications on the phone doing bluetooth scanning may be causing these messages to be emitted as well.
for the same problem
I had just add permissions :
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.
Manifest.permission.
Manifest.permission.BLUETOOTH_PRIVILEGED,
in your activity call this methods :
checkPermissions(MainActivity.this, this);
public static void checkPermissions(Activity activity, Context context){
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_PRIVILEGED,
};
if(!hasPermissions(context, PERMISSIONS)){
ActivityCompat.requestPermissions( activity, PERMISSIONS, PERMISSION_ALL);
}
}
public static boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
hope it's help
I had the same problem with android m.It was due to lack of permissions.Make sure you go to settings and grant location permission to your app
for location permission, only ACCESS_FINE_LOCATION worked. ACCESS_COARSE_LOCATION had the same problem.
Short question...
How do I correctly use UniversalTweenEngine with the Music class in LibGDX?
Long question...
I've encountered a problem with using UniversalTweenEngine and the Music class in LibGDX. I have a MusicAccessor that implements TweenAccessor like so:
public static final int VOLUME = 0;
#Override
public int getValues(Music target, int tweenType, float[] returnValues) {
switch(tweenType) {
case VOLUME:
returnValues[0] = target.getVolume();
return 1;
default:
assert false;
return -1;
}
}
#Override
public void setValues(Music target, int tweenType, float[] newValues) {
switch(tweenType) {
case VOLUME:
target.setVolume(newValues[0]);
break;
default:
assert false;
}
}
first I used it like this:
Tween.registerAccessor(Music.class, new MusicAccessor());
myMusicInstance.setVolume(0);
Tween.to(myMusicInstance, MusicAccessor.VOLUME, 1f).target(1).start();
Which gave me an error saying that
No TweenAccessor was found for the target
I read some on the problem and saw people having the same issue, and the answer to this question told me that I had to use .cast(Music.class) as well, so i changed it to this:
Tween.to(myMusicInstance, MusicAccessor.VOLUME, 1f).cast(Music.class).target(1).start();
which no longer gives me the error. The snag with this is that it doesn't actually tween any value! I've added TweenCallbacks and done System.out.println("text") in the TweenAccessor's methods, and found out that they aren't being called. So how am I supposed to do for it to work?
I reproduced your problem and managed to fix it, so here is a solution.
First of all you need an instance of TweenManager. Then don't forget to start your music (it won't start by itself). Your MusicAccessor class is ok, so no need to change anything there. The final code snippet:
an instance field
private TweenManager tweenManager = new TweenManager();
constructor (or wherever you used it)
Tween.registerAccessor(Music.class, new MusicAccessor());
myMusicInstance.setVolume(0);
myMusicInstance.play();
and then in render:
tweenManager.update(delta);
Tween.to(music, MusicAccessor.VOLUME, 1f).cast(Music.class).target(1).start(tweenManager);
If anything is unclear, please let me know.
My problem is I want an actor to do an action (in this case a fade) and just after the end of the action, switch to the game screen. But the action is finished not complete, but quickly changed the game screen.
I want to wait to complete this action before changing the screen .. And in general, I wonder how I can make waiting instructions in the game, because it is sometimes good to want to allow some time before anything happens.
myActor.addAction(Actions.fadeIn(2));
setScreen(AnotherScreen);
Use the static imports for actions, way easier.
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.*;
Actor.addAction(sequence(fadeOut(2f), run(new Runnable() {
public void run () {
System.out.println("Action complete!");
}
});
Put the code you want to run in the runnable.
For more info,
https://github.com/libgdx/libgdx/wiki/Scene2d#actions
What you have to do is create an Action subclass and override Action#act where you will call setScreen(AnotherScreen);.
Then, use Actions#sequence to wrap both actions into a single SequenceAction object.
Action switchScreenAction = new Action(){
#Override
public boolean act(float delta){
setScreen(AnotherScreen);
return true;
}
};
myActor.addAction(Actions.sequence(
Actions.fadeIn(2)
, switchScreenAction
));
For more info, check out: https://github.com/libgdx/libgdx/wiki/Scene2d#complex-actions
Windows phone 8.1 new to world. Basic function is back button click. Is that function not working properly is this windows phone 8.1. Is that behavior or i'm made mistake.
Below code using in Homepage but this code calling from all other class too while clicking back. I need to access below method only on Home page .
Please check below code and refer me good solution.
Please look my code:
public HomePage()
{
this.InitializeComponent();
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
}
Thanks
It is working properly. The BackPressed event is working app-wide. Two options that come to my mind:
write eventhandler that would recognize the Page in which you currently invoke it - simple example can look like this:
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
Frame frame = Window.Current.Content as Frame;
if (frame == null) return;
if (frame.Content is HomePage)
{
e.Handled = true;
Debug.WriteLine("I'm in HomePage");
}
else if (frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
second option - subscribe to Windows.Phone.UI.Input.HardwareButtons.BackPressed when you enter the Page and unsubscribe when you leave the Page. Note that in this way there are some pitfalls - you have to handle properly OnNavigatedTo, OnNavigatedFrom, Suspending and Resuming (more about Lifecycle here). Note also that the subscription should be done before others - for example NavigationHelper.
Some remarks - the above code should work, but it also depends on other circumstances:
if there is something other subscribed to BackPressed before (in App.xaml.cs) - remember that usually events are fired in order they were subscribed
check if you are using NavigationHelper - it also subscribes to BackPressed
remember not to subscribe multiple times
remember to allow the User to leave your HomePage