In my game I implement fling gesture detection. Everything work fine , but I want to modify fling detection
From documentation for fling: https://github.com/libgdx/libgdx/wiki/Gesture-detection
fling: A user dragged the finger across the screen, then lifted it. Useful to implement swipe gestures.
I want to modify this and fling to work without lifting touch, only when user drag some distance not lifting it.
Here is my code:
public class SimpleDirectionGestureDetector extends GestureDetector {
public interface DirectionListener {
void onLeft();
void onRight();
void onUp();
void onDown();
}
public SimpleDirectionGestureDetector(DirectionListener directionListener) {
super(new DirectionGestureListener(directionListener));
}
private static class DirectionGestureListener extends GestureAdapter{
DirectionListener directionListener;
public DirectionGestureListener(DirectionListener directionListener){
this.directionListener = directionListener;
}
#Override
public boolean fling(float velocityX, float velocityY, int button) {
if(Math.abs(velocityX)>Math.abs(velocityY)){
if(velocityX>0){
directionListener.onRight();
}else{
directionListener.onLeft();
}
}else{
if(velocityY>0){
directionListener.onDown();
}else{
directionListener.onUp();
}
}
return super.fling(velocityX, velocityY, button);
}
}
}
public SimpleDirectionGestureDetector gestureDetector = new SimpleDirectionGestureDetector(
new SimpleDirectionGestureDetector.DirectionListener() {
#Override
public void onUp() {
onUpSwipe();
}
#Override
public void onRight() {
onRightSwipe();
}
#Override
public void onLeft() {
onLeftSwipe();
}
#Override
public void onDown() {
onDownSwipe();
}
});
Any help would be appreciated
Thanks
Related
How to check if compass is calibrated well in LibGDX (on Android). I've found how to do it on native Android:
In Android can I programmatically detect that the compass is not yet calibrated?
But couldn't find if that's implemented in LibGDX.
What you want is described in the wiki article Interfacing with platform specific code. LibGDX doesn't have any functionality for it because it isn't common and it doesn't make any sense for other backends.
In the core module you'll have something like this:
public interface GameListener {
void calibrateCompassIfNeeded()
}
public class Application extends ApplicationAdapter {
private GameListener listener;
public Application(GameListener listener) {
this.listener = listener;
}
#Override
public void create() {
// Call listener.calibrateCompassIfNeeded() whenever needed.
}
public void onCompassChanged(float[] values) {
// Do something...
}
}
And in the android module:
public class AndroidLauncher extends AndroidApplication implements GameListener, SensorEventListener {
private static final int COMPASS_ACCURACY_UNKNOWN = -1;
private Application app;
private int compassAccuracy = COMPASS_ACCURACY_UNKNOWN;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor compassSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(this, compassSensor, SensorManager.SENSOR_DELAY_GAME)
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
app = new Application(this);
initialize(app, config);
}
#Override
public void calibrateCompassIfNeeded() {
if (compassAccuracy != COMPASS_ACCURACY_UNKNOWN && compassAccuracy < SENSOR_STATUS_ACCURACY_MEDIUM) {
// Calibrate only if accuracy is below medium.
// Show whatever is needed so user calibrates the compass.
}
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
app.onCompassChanged(event.values);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
compassAccuracy = accuracy;
}
}
I haven't tried it and I have never used the compass before but I'm pretty sure this will work fine.
I want for all the Buttons in my game to scale down when user touch down the button and goes back to normal scale as soon as on touch up.What should be be the best possible way.Just like functionality of button in COCOS-2d.
I don't want to use extra small image for button down,if there is other alternative without using extra image.?
Second one is to produce some sound on click,I don't want to this in input listener of every button since sound is same for all buttons.How should i implement this in best possible way.
Thanks in advance.
// i just implement my custom class ,is there is other good way to implement.
public class ImprovedButton extends Button {
boolean isTouchDown=false;// is touch begin
float originalWidth,originalHeight; //actual size
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
if( isPressed()) {
if (!isTouchDown) {
//play sound if any
isTouchDown=true;
originalHeight=getHeight();
originalWidth=getWidth();
setWidth(originalWidth*.95f);
setHeight(originalHeight*.95f);
}
}
else { //pressing is stopper if any
if (isTouchDown) {
isTouchDown=false;
setWidth(originalWidth);
setHeight(originalHeight);
}
}
}
}
one problem with this code is,pivot of scaling bottom left corner.How to set it as center.
I do the same thing on my games.
Make like your custom class for the button.
If you want you can increase the scale in the update method, so the button will scale smooth.
Look here, I wrote for you a example
public class CoolButton {
private Sprite sprite; // the sprite that we are going to use to draw our button
private float scale; // the scale of the button, 1 = full scale, 0.5 half, 2 = twice bigger, etc
public CoolButton(Texture texture, float x, float y, float width, float height) {
sprite = new Sprite(texture);
sprite.setPosition(x, y);
sprite.setSize(width, height);
sprite.setOriginCenter();
scale = 1;
}
public void draw(SpriteBatch batch) {
sprite.setScale(scale); // setting the scale and drawing the button
sprite.draw(batch);
}
// this method should be called when the user touches the screen (don't forget to unproject the coords)
public boolean touchDown(float x, float y) {
if (sprite.getBoundingRectangle().contains(x, y)) { // if the button is touched
scale = 0.7f;
return true;
}
return false;
}
// when you release the touch from the screen make the button back to its normal size
public void touchUp() {
scale = 1f;
}
}
If you have any question please comment here.
Here is a custom class ImprovedButton extends from Button class has additional functionality of Change in SCALE of button and plays SOUND on click .
There is also a class of ImprovedButtonStyle has paramter of scale and sound.
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
public class ImprovedButton extends Button {
boolean isPressedOnce=false;//is press started or touchDown
float originalWidth,originalHeight;
private ImprovedButtonStyle istyle;
public ImprovedButton() {
super();
this.istyle=new ImprovedButtonStyle();
}
public ImprovedButton(Actor child, ImprovedButtonStyle style) {
super(child, style);
this.istyle=style;
}
public ImprovedButton(Actor child, Skin skin, String styleName) {
this(child,skin.get(styleName, ImprovedButtonStyle.class));
}
public ImprovedButton(Actor child, Skin skin) {
this(child,skin.get(ImprovedButtonStyle.class));
}
public ImprovedButton(ImprovedButtonStyle style) {
super(style);
this.istyle=style;
}
public ImprovedButton(Drawable up, Drawable down, Drawable checked) {
super(up, down, checked);
istyle=new ImprovedButtonStyle();
}
public ImprovedButton(Drawable up, Drawable down) {
this(up, down,null);
}
public ImprovedButton(Drawable up) {
this(up,null,null);
}
public ImprovedButton(Skin skin, String styleName) {
super(skin, styleName);
this.istyle=skin.get(ImprovedButtonStyle.class);
}
public ImprovedButton(Skin skin) {
super(skin);
setStyle(skin.get(ButtonStyle.class));
}
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
if( isPressed()) {
if (!isPressedOnce) {
if (istyle.sound!=null) {
istyle.sound.play();
}
isPressedOnce=true;
originalHeight=getHeight();
originalWidth=getWidth();
setWidth(originalWidth-istyle.changeInWidth);
setHeight(originalHeight-istyle.changeInHeight);
}
}
else {
if (isPressedOnce) {
isPressedOnce=false;
setWidth(originalWidth);
setHeight(originalHeight);
}
}
}
#Override
protected void drawBackground(Batch batch, float parentAlpha, float x,float y) {
int offsetX=0;
int offsetY=0;
if(isPressed()){
offsetX=istyle.changeInWidth/2;
offsetY=istyle.changeInHeight/2;
}
super.drawBackground(batch, parentAlpha, x+offsetX, y+offsetY);
}
public static class ImprovedButtonStyle extends ButtonStyle{
public int changeInWidth=2,changeInHeight=2;
public Sound sound=null;
public ImprovedButtonStyle() {
super();
}
public ImprovedButtonStyle(ButtonStyle style,int changeInWidth,int changeInHeight,Sound sound) {
super(style);
this.changeInHeight=changeInHeight;
this.changeInWidth=changeInWidth;
this.sound=sound;
}
public ImprovedButtonStyle(Drawable up, Drawable down, Drawable checked) {
super(up, down, checked);
}
public ImprovedButtonStyle(ImprovedButtonStyle style) {
super(style);
this.changeInHeight=style.changeInHeight;
this.changeInWidth=style.changeInWidth;
this.sound=style.sound;
}
}
}
I've made a simple Media Player for an application I'm working on, the problem is that I thought that you could simply integrate JavaFX into Swing. Which is not the case. I have been searching for a solution to this problem and tried to use this website: http://docs.oracle.com/javafx/2/swing/jfxpub-swing.htm
The problem is that even though I have the website that explains how to put the code together, I still don't understand how. Here is the mediaplayer and I plan to integrate it into my Swing code, so that I can call the media player when a button is clicked. Here is all my code for the media player and if anyone can share some light on how to integrate it into my Swing code i.e my GUI, I would probably have to kiss you through the computer.
public class Player extends Application{
private boolean atEndOfMedia = false;
private final boolean repeat = false;
private boolean stopRequested = false;
private Duration duration;
private Label playTime;
private Slider volumeSlider;
#Override
public void start(final Stage stage) throws Exception {
stage.setTitle("Movie Player");//set title
Group root = new Group();//Group for buttons etc
final Media media = new Media("file:///Users/Paul/Downloads/InBruges.mp4");
final MediaPlayer playa = new MediaPlayer(media);
MediaView view = new MediaView(playa);
//Slide in and out and what causes that.
final Timeline slideIn = new Timeline();
final Timeline slideOut = new Timeline();
root.setOnMouseEntered(new javafx.event.EventHandler<javafx.scene.input.MouseEvent>() {
#Override
public void handle(MouseEvent t) {
slideIn.play();
}
});
root.setOnMouseExited(new javafx.event.EventHandler<javafx.scene.input.MouseEvent>() {
#Override
public void handle(MouseEvent t) {
slideOut.play();
}
});
final VBox vbox = new VBox();
final Slider slider = new Slider();
final Button playButton = new Button("|>");
root.getChildren().add(view);
root.getChildren().add(vbox);
vbox.getChildren().add(slider);
vbox.getChildren().add(playButton);
vbox.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 400, 400, Color.BLACK);
stage.setScene(scene);
stage.show();
// Play/Pause Button
playButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
Status status = playa.getStatus();
if (status == Status.UNKNOWN || status == Status.HALTED)
{
// don't do anything in these states
return;
}
if ( status == Status.PAUSED
|| status == Status.READY
|| status == Status.STOPPED)
{
// rewind the movie if we're sitting at the end
if (atEndOfMedia) {
playa.seek(playa.getStartTime());
atEndOfMedia = false;
}
playa.play();
} else {
playa.pause();
}
}
});
//Listeners and Shit for Play Button
playa.setOnPlaying(new Runnable() {
#Override
public void run() {
if (stopRequested) {
playa.pause();
stopRequested = false;
} else {
playButton.setText("||");
}
}
});
playa.setOnPaused(new Runnable() {
#Override
public void run() {
playButton.setText(">");
}
});
playa.play();
playa.setOnReady(new Runnable() {
#Override
public void run(){
int v = playa.getMedia().getWidth();
int h = playa.getMedia().getHeight();
stage.setMinWidth(v);
stage.setMinHeight(h);
vbox.setMinSize(v, 100);
vbox.setTranslateY(h-50);
//slider and graphical slide in/out
slider.setMin(0.0);
slider.setValue(0.0);
slider.setMax(playa.getTotalDuration().toSeconds());
slideOut.getKeyFrames().addAll(
new KeyFrame(new Duration(0),
new KeyValue(vbox.translateYProperty(), h-100),
new KeyValue(vbox.opacityProperty(), 0.9)
),
new KeyFrame(new Duration(300),
new KeyValue(vbox.translateYProperty(), h),
new KeyValue(vbox.opacityProperty(), 0.0)
)
);
slideIn.getKeyFrames().addAll(
new KeyFrame(new Duration(0),
new KeyValue(vbox.translateYProperty(), h),
new KeyValue(vbox.opacityProperty(), 0.0)
),
new KeyFrame(new Duration(300),
new KeyValue(vbox.translateYProperty(), h-100),
new KeyValue(vbox.opacityProperty(), 0.9)
)
);
}
});
//Slider being current and ability to click on slider.
playa.currentTimeProperty().addListener(new ChangeListener<Duration>(){
#Override
public void changed(ObservableValue<? extends Duration> observableValue, Duration duration, Duration current){
slider.setValue(current.toSeconds());
}
});
slider.setOnMouseClicked(new javafx.event.EventHandler<javafx.scene.input.MouseEvent>() {
#Override
public void handle(javafx.scene.input.MouseEvent t) {
playa.seek(Duration.seconds(slider.getValue()));
}
});
}
Use JFXPanel:
public class Test {
private static void initAndShowGUI() {
// This method is invoked on Swing thread
JFrame frame = new JFrame("FX");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setVisible(true);
Platform.runLater(new Runnable() {
#Override
public void run() {
initFX(fxPanel);
}
});
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initAndShowGUI();
}
});
}
}
where method createScene() is start(final Stage stage) from your code.
Just instead of putting scene to stage you return it.
I am making an mp3 player, with several JLists in my JFrame. When I right click on a JList item, a popup with some options for that song appears. But when this popup is visible, and I minimise my JFrame, this popup stays visible! Also, when the popup is visible, and I drag my JFrame to somewhere else on the screen, the popup stays on it's original position (so it does not stay on the same position relative to the JFrame)... Can someone please help me out with this? I tried to strip down this class as much as possible :)
I would be really grateful if someone could help me out !!
Joe
public class playListPanel extends JPanel implements MouseListener {
private DefaultListModel model;
private Interface interFace;
private JList list;
private boolean emptyPlaylist;
private ArrayList<Song> currentPlayList;
private Song rightClickedSong;
private JPopupMenu popup;
private Point panelLocation;
public playListPanel(Interface interFace) // Interface extends JFrame,
// playListPanel is a part of
// this JFrame.
{
this.interFace = interFace;
this.panelLocation = new Point(559, 146);
setBackground(SystemColor.controlHighlight);
setBorder(new TitledBorder(null, "", TitledBorder.LEADING,
TitledBorder.TOP, null, null));
setBounds((int) panelLocation.getX(), (int) panelLocation.getY(), 698,
368);
setLayout(null);
currentPlayList = new ArrayList<Song>();
model = new DefaultListModel();
list = new JList(model);
list.setVisible(true);
list.addMouseListener(this);
JScrollPane scrollPane = new JScrollPane(list);
scrollPane.setBounds(5, 5, 688, 357);
add(scrollPane);
emptyPlaylist = true;
}
private void openMenuPopup(Point point)
{
removePopup();
popup = new JPopupMenu();
int x = (int) point.getX();
int y = (int) point.getY();
popup.setLocation((int) (x+panelLocation.getX()),(int) (y+panelLocation.getY()));
//popup.setLabel("popup voor playlist");
JMenuItem removeSong;
popup.add(removeSong = new JMenuItem("Remove Song from Playlist", new ImageIcon("image.jpg")));
ActionListener menuListener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if(event.getActionCommand().equals("Remove Song from Playlist"))
{
System.out.println("Remove Song from Playlist");
interFace.getPlaylistManager().removeOneSong(rightClickedSong);
removePopup();
}
};
//ADD THE LISTENERS TO THE MENU ITEMS
removeSong.addActionListener(menuListener);
popup.setVisible(true);
}
public void removePopup()
{
if(popup!==null)
{
popup.setVisible(false);
System.out.println("popup removed");
}
}
private int getRow(Point point) {
return list.locationToIndex(point);
}
public void refreshPlayList(ArrayList<Song> playlist) {
this.currentPlayList = playlist;
model.clear();
for (Song song : playlist) {
model.add(model.getSize(), song.getPlaylistString());
}
list.setVisible(true);
}
public void highlightSong(int index) {
list.setSelectedIndex(index);
}
public int getRowOfList(Point point) {
return list.locationToIndex(point);
}
#Override
public void mouseClicked(MouseEvent e) {
interFace.getPlaylistManager().doubleClickOnPlaylist(e);
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
rightClickedSong = currentPlayList.get(getRow(e.getPoint()));
openMenuPopup(e.getPoint());
System.out.println("should open popup at "
+ e.getPoint().toString());
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
There are some basic flaws in the way you are handling click for showing popup.
It is not advisable to call popup.setVisible in simple scenarios like this. Instead, you may rely on its default behavior. Also, better to use e.isPopupTrigger() than to check SwingUtilities.isRightMouseButton(e) to show popup.
You may do something like the following :
//at classlevel,
private JPopupMenu popup = new JPopupMenu();
//create a Popuplistener
PopupListener pl = new PopupListener();
list.addMouseListener(pl);
//Implementation of your popuplistener
class PopupListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger())
//e.getSource - and construct your popup as required.
//and then.
popup.show(((JApplet) e.getComponent()).getContentPane(), e
.getX(), e.getY());
}
}
I'm trying to set a documentFilter for my JTextArea. Having overriden the insert(...) method I admitted that it is never called. What's wrong? A piece of code:
package jaba;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class Main extends JFrame {
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(640, 480);
setLayout(new FlowLayout());
add(txt);
Document doc = txt.getDocument();
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).setDocumentFilter(new DocumentFilter() {
#Override
public void insertString(DocumentFilter.FilterBypass fb,
int offset, String string, AttributeSet att)
throws BadLocationException {
if (string.toLowerCase().contains("ass")) {
super.insertString(fb, offset, "###", att);
} else {
super.insertString(fb, offset, string, att);
}
}
});
} else {
txt.setText("error setting filter");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Main().setVisible(true);
}
});
}
private JTextArea txt = new JTextArea(40, 40);
}
Having overriden the insert(...) method I admitted that it is never called.
Changes to the text in Swing components ultimately invoke the replace(...) method of the DocumentFilter.
The insertString(...) method is only invoked when you update the Document directly by using code like:
textField.getDocument().insertString(...);
So you need to make sure that you also override the replace() method in the DocumentFilter.