1

Hi I've got an issue with an app I'm making for a "virtual drum-kit" I'm not to fantastic with libgdx I will be honest, I was taught "what I needed to know" by somebody who I am no longer in contact with.

The app is all up and running great however when I use it on an android device I can not hit two drums/cymbals at the same time it just repeats the sound of the drum I was already pressing, I think I am probably not using the best method to track presses but as said I am fairly unfamiliar with libgdx, if I paste my code it would be great to get some help or advice off you guys!

Here is the class that runs my virtual drum:

package gamebulk.drumkit;

import java.util.Random;

import gamebulk.drumkit.DrumKit.DialogListener;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.GLCommon;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;

public class DrumScreen implements Screen, ApplicationListener {

Game game;

OrthographicCamera guiCam;
SpriteBatch batcher;
Rectangle snareBounds;
Rectangle hihatBounds;
Rectangle crashBounds;
Rectangle rideBounds;
Rectangle bassBounds;
Rectangle hitBounds;
Rectangle lowtBounds;
Rectangle floortBounds;
Rectangle exitBounds;
Vector3 touchPoint;
DialogListener callback;

float time = 0;

public final Random rand;

public DrumScreen (Game game, DialogListener callback) {
    this.game = game;

    guiCam = new OrthographicCamera(800, 480);
    guiCam.position.set(800 / 2, 480 / 2, 0);
    batcher = new SpriteBatch();
    snareBounds = new Rectangle (180, 150, 147, 80);
    hihatBounds = new Rectangle (28, 184, 160, 90);
    crashBounds = new Rectangle(36, 310, 246, 160);     
    rideBounds = new Rectangle (550, 250, 222, 140);
    bassBounds = new Rectangle (278, 38, 250, 211);
    hitBounds = new Rectangle (256, 242, 132, 96);
    lowtBounds = new Rectangle (410, 240, 130, 92);
    floortBounds = new Rectangle (494, 128, 178, 118);
    exitBounds = new Rectangle (704, 384, 64, 64);
    touchPoint = new Vector3();
    this.callback = callback;
    Gdx.input.setCatchBackKey(true);
    rand = new Random ();

}

public void update (float deltaTime) {

    handleInput(deltaTime);

    if (Gdx.input.justTouched()) {
        guiCam.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));


        if (OverlapTester.pointInRectangle(snareBounds, touchPoint.x, touchPoint.y)) {
            if (rand.nextFloat() < 0.5){
                Assets.playSound(Assets.snare1sound);}
            else{
                Assets.playSound(Assets.snare2sound);
            }
        }
        if (OverlapTester.pointInRectangle(hihatBounds, touchPoint.x, touchPoint.y)) {
            if (rand.nextFloat() < 0.5){
                Assets.playSound(Assets.hihat1sound);}
            else{
                Assets.playSound(Assets.hihat2sound);
            }
        }               
        if (OverlapTester.pointInRectangle(crashBounds, touchPoint.x, touchPoint.y)) {
            if (rand.nextFloat() < 0.5){
                Assets.playSound(Assets.crash1sound);}
            else{
                Assets.playSound(Assets.crash1sound);
            }
        }   
        if (OverlapTester.pointInRectangle(rideBounds, touchPoint.x, touchPoint.y)) {
            if (rand.nextFloat() < 0.5){
                Assets.playSound(Assets.ride1sound);}
            else{
                Assets.playSound(Assets.ride2sound);
            }
        }   
        if (OverlapTester.pointInRectangle(bassBounds, touchPoint.x, touchPoint.y)) {
            if (rand.nextFloat() < 0.5){
                Assets.playSound(Assets.bass1sound);}
            else{
                Assets.playSound(Assets.bass2sound);
            }
        }   
        if (OverlapTester.pointInRectangle(hitBounds, touchPoint.x, touchPoint.y)) {
            Assets.playSound(Assets.hitom1sound);
        }   
        if (OverlapTester.pointInRectangle(lowtBounds, touchPoint.x, touchPoint.y)) {
            Assets.playSound(Assets.lowtom1sound);
        }   
        if (OverlapTester.pointInRectangle(floortBounds, touchPoint.x, touchPoint.y)) {
            Assets.playSound(Assets.floortom1sound);
        }   

        if (OverlapTester.pointInRectangle(exitBounds, touchPoint.x, touchPoint.y)) {
            if (callback != null){
                callback.showOfferwall2();} 
                Gdx.app.exit();
        }
    }
}

private void handleInput(float delta) {  

time += delta;
if (time > 0.5) {
if(Gdx.input.isKeyPressed(Input.Keys.BACK)) {                  
callback.showOfferwall2();
Gdx.app.exit();}
}       
}

public void draw (float delta) {
GLCommon gl = Gdx.gl;
time += delta;
gl.glClearColor(1, 1, 1, 1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
guiCam.update();
batcher.setProjectionMatrix(guiCam.combined);

batcher.enableBlending();
batcher.begin();
batcher.draw(Assets.drumbackground, 0, 0);

batcher.draw(Assets.exitbutton, 704, 384);

batcher.end();      

}

@Override
public void render (float delta) {
update(delta);
draw(delta);
}

@Override
public void resize (int width, int height) {
}

@Override
public void show () {
}

@Override
public void hide () {
}

@Override
public void resume () {
}

@Override
public void dispose () {
}

@Override
public void pause() {
// TODO Auto-generated method stub

}

@Override
public void create() {
// TODO Auto-generated method stub

}

@Override
public void render() {
// TODO Auto-generated method stub

}
}

Any help relating to this would be fantastic thanks in advance.

  • First result on Google: http://stackoverflow.com/questions/16876877/how-to-track-multiple-touch-events-in-libgdx – lxknvlk Sep 09 '14 at 18:49

1 Answers1

0

The Libgdx Input getX() method returns the x coordinate for the first touch point (aka the first finger). The justTouched() method returns true for each new touch event (for any finger).

So your current code is running every time any touch-down event triggers on the screen. But then it only looks at the coordinates of the first finger's touch point.

Libgdx does not have a justTouched() method for any other pointer (it does have getX(int) and getY(int) method for checking the coordinates of other pointers). So, you'll probably want to do your own just-touched check (assuming you don't want to switch from input polling to event-based inputs).

First, decide how many fingers you want to support on the screen. Its cheap to support lots, so try 40. Add a new class variable:

private static final int maxFingers = 40;

Add a new instance variable for the just-touched check:

boolean sawTouch[maxFingers];

and initialize it in your constructor:

sawTouch = new boolean[40];

Now, you just check every pointer to see if been touched, and if so where, and then run your sounds:

for (int i = 0; i < maxFingers; i++) {
   if (Gdx.input.isTouched(i)) {
      if (!sawTouch[i]) {
         sawTouch[i] = true;  // Mark this finger as "seen" for future checks

         // Figure out where the i'th touch was
         guiCam.unproject(touchPoint.set(Gdx.input.getX(i), Gdx.input.getY(i), 0));

         // XXX put all the code that does OverlapTester.calls here (or put that in a separate function and call it here) 
      }
      // else already saw the touch ..
   } else {
      sawTouch[i] = false; // Finger is gone, any future touch is "new"
   }
}

Or something approaching that. I haven't tried compiling this code, so it might have typos, but hopefully it gets the idea across.

P.T.
  • 24,557
  • 7
  • 64
  • 95
  • Hey thanks for the response, I'm having some trouble trying to get this implemented, wherever I place the boolean I'm getting an error: Syntax error on token "maxFingers", delete this token I've tried it in a few different places and can't figure it out I've also tried looking at the libgdx tutorial for handling input but still not really getting it! – user3618087 Sep 12 '14 at 15:48
  • The `maxFingers` declaration should go at "class scope" in your code (i.e., next to the line `public final Random rand;` that declares `rand`). (Same with the declaration of `sawTouch`.) – P.T. Sep 13 '14 at 06:59