How to play a sound on android with a delay? - android

I'm doing a small school project of object detection by color. When the object arrives in the center of the screen, it must have a sound. So the sound does not stay uninterrupted, I tried to put a delay on it. But every time the application arrives at the point of playing the sound, it closes. I already researched here and in other forums and the solutions presented did not work.
public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2{
static {
if(!OpenCVLoader.initDebug()){
Log.d("TAG", "OpenCV not loaded");
} else {
Log.d("TAG", "OpenCV loaded");
}
}
public void voltatela(View v) {
setContentView(R.layout.activity_main);
}
Mat imgHVS, imgThresholded;
Scalar sc1, sc2;
JavaCameraView cameraView;
int largura, altura;
public void Verde(View v) {
sc1 = new Scalar(45, 20, 10);
sc2 = new Scalar(75, 255, 255);
irTelaCamera();
}
public void Azul(View v) {
sc1 = new Scalar(80, 50, 50);
sc2 = new Scalar(100, 255, 255);
irTelaCamera();
}
public void Vermelho(View v) {
sc1 = new Scalar(110, 100, 50);
sc2 = new Scalar(130, 255, 255);
irTelaCamera();
}
public void irTelaCamera(){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.telacamera);
cameraView = (JavaCameraView)findViewById(R.id.cameraview);
cameraView.setCameraIndex(0); //0 para traseira e 1 para dianteira
cameraView.setCvCameraViewListener(this);
cameraView.enableView();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowmanager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
windowmanager.getDefaultDisplay().getMetrics(displayMetrics);
}
#Override
protected void onPause() {
super.onPause();
cameraView.disableView();
}
#Override
public void onCameraViewStarted(int width, int height) {
imgHVS = new Mat(width,height, CvType.CV_16UC4);
imgThresholded = new Mat(width,height, CvType.CV_16UC4);
largura = width;
altura = height;
}
#Override
public void onCameraViewStopped() {
}
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Point centrotela = new Point((largura*0.5),(altura*0.5));
final MediaPlayer som = MediaPlayer.create(this, R.raw.bip);
Imgproc.medianBlur(imgHVS,imgHVS,1);
Imgproc.cvtColor(inputFrame.rgba(), imgHVS,Imgproc.COLOR_BGR2HSV);
Core.inRange(imgHVS, sc1, sc2, imgThresholded);
Imgproc.GaussianBlur(imgThresholded, imgThresholded, new Size(3, 3), 1, 1);
Mat circles = new Mat();
double dp = 1.2d;
int minRadius = 20;
int maxRadius = 0;
double param1 = 100, param2 = 20;
int desvio = (int) (minRadius*0.5);
Imgproc.HoughCircles(imgThresholded, circles, Imgproc.HOUGH_GRADIENT, dp, imgThresholded.rows()/4, 100, 20, minRadius, maxRadius);
int numCircles = (circles.rows() == 0) ? 0 : circles.cols();
for (int i = 0; i < numCircles; i++) {
double[] circleCoordinates = circles.get(0, i);
int x = (int) circleCoordinates[0], y = (int) circleCoordinates[1];
Point center = new Point(x, y);
int radius = (int) circleCoordinates[2];
if((((center.x-desvio) <= centrotela.x) && ((center.x+desvio) >= centrotela.x))) {
if ((((center.y-desvio) <= centrotela.y) && ((center.y+desvio) >= centrotela.y))) {
som.start();
Imgproc.circle(imgThresholded, center, radius, new Scalar(100, 255, 255), 4);
// Play sound after 2 sec delay
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
som.stop();
}
}, 2000);
}}
}
Imgproc.circle(imgThresholded,centrotela,50, new Scalar(100,255,255),7);
Imgproc.circle(imgThresholded,centrotela,25, new Scalar(100,255,255),4);
Imgproc.circle(imgThresholded,centrotela,5, new Scalar(100,255,255),-1);
return imgThresholded;
}
}

You have to write sop.start(); instead of sop.stop() inside the handler;

Have you tried playing the sound in a different thread (AsyncTask? See example here). You would have to keep track if you have already spawned a task though, otherwise, you will end up creating too many threads playing the same sound.

Related

solve game problems in Android Studio

For the university project, we have to solve the problems of a game. In the game that was given to me, there are many problems, for example, the spikes do not come down, the background is not displayed completely, the points and lives are not visible. Can someone help me? How can I use an activity instead of using Android view? Note: In this game, the first character must be saved and spikes will be thrown on him from the top of the screen, when the spikes hit the ground, an explosion will occur.
public class GameView extends View {
Bitmap background, ground, rabbit;
Rect recetBacground, rectGround;
Context context;
Handler handler;
final long UPDATE_MILLS = 30;
Runnable runnable;
Paint textPaint = new Paint();
Paint healthpaint = new Paint();
float TEXT_SIZE = 120;
int points = 0;
int life = 3;
static int dWidth, dHeight;
Random random;
float rabbitX, rabbitY;
float oldX;
float oldRabbitX;
ArrayList<Spike> spikes;
ArrayList<Explosion> explosions;
public GameView(Context context) {
super(context);
this.context = context;
background = BitmapFactory.decodeResource(getResources(), R.drawable.background);
ground = BitmapFactory.decodeResource(getResources(), R.drawable.ground);
rabbit = BitmapFactory.decodeResource(getResources(), R.drawable.rabbit);
Display display = ((Activity) getContext()).getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
dWidth = size.x;
dHeight = size.y;
recetBacground = new Rect(0, 0, dWidth, dHeight);
rectGround = new Rect(0, dHeight - ground.getHeight(), dWidth ,dHeight);
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
invalidate();
}
};
textPaint.setColor(Color.rgb(255, 165, 0));
textPaint.setTextSize(TEXT_SIZE);
textPaint.setTextAlign(Paint.Align.LEFT);
textPaint.setTypeface(ResourcesCompat.getFont(context, R.font.pingiefont));
healthpaint.setColor(Color.GREEN);
random = new Random();
rabbitX = dWidth / 2 - rabbit.getWidth() / 2;
rabbitY = dHeight - ground.getHeight() - rabbit.getHeight();
spikes = new ArrayList<>();
explosions = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Spike spike = new Spike(context);
spikes.add(spike);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(background, null, recetBacground, null);
canvas.drawBitmap(ground, null, rectGround, null);
canvas.drawBitmap(rabbit, rabbitX, rabbitY, null);
for (int i = 0; i < spikes.size(); i++) {
canvas.drawBitmap(spikes.get(i).getSpike(spikes.get(i).spikeFarm), spikes.get(i).spikeX, spikes.get(i).spikeY, null);
spikes.get(i).spikeFarm++;
if (spikes.get(i).spikeFarm > 2) {
spikes.get(i).spikeFarm = 0;
}
spikes.get(i).spikeY += spikes.get(i).spikeVelocity;
if (spikes.get(i).spikeY + spikes.get(i).getSpikeHeight() >= dHeight - ground.getHeight()) {
points += 10;
Explosion explosion = new Explosion(context);
explosion.explosionX = spikes.get(i).spikeX;
explosion.explosionY = spikes.get(i).spikeY;
explosions.add(explosion);
spikes.get(i).resetPosition();
}
}
for (int i = 0; i < spikes.size(); i++) {
if(spikes.get(i).spikeX+spikes.get(i).getSikeWidth()>=rabbitX
&& spikes.get(i).spikeX <= rabbitX+rabbit.getWidth()
&& spikes.get(i).spikeY+spikes.get(i).getSikeWidth() >= rabbitY
&& spikes.get(i).spikeY+spikes.get(i).getSikeWidth()<= rabbitY +rabbit.getHeight()){
life--;
spikes.get(i).resetPosition();
if (life==0){
Intent intent=new Intent(context,GameOver.class);
intent.putExtra("points:",points);
context.startActivity(intent);
((Activity) context).finish();
}
}
}
for (int i=0;i<explosions.size();i++){
canvas.drawBitmap(explosions.get(i).getExplosion(explosions.get(i).explosionFarm),explosions.get(i).explosionX,
explosions.get(i).explosionY,null );
explosions.get(i).explosionFarm++;
if (explosions.get(i).explosionFarm>3){
explosions.remove(i);
}
}
if (life==2) {
healthpaint.setColor(Color.YELLOW);
}
else{
healthpaint.setColor(Color.RED);
}
canvas.drawRect(dWidth-200,30,dWidth-200+60*life,80,healthpaint);
canvas.drawText(""+points,20,TEXT_SIZE,textPaint);
handler.postDelayed(runnable,UPDATE_MILLS);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX=event.getX();
float touchY=event.getY();
if (touchY>= rabbitY){
int action = event.getAction();
if(action== MotionEvent.ACTION_DOWN){
oldX=event.getX();
oldRabbitX=rabbitX;
}
if(action==MotionEvent.ACTION_MOVE){
float shift = oldX- touchX;
float newRabbitX =oldRabbitX-shift;
if(newRabbitX<=0)
rabbitX=0;
else if (newRabbitX>=dWidth-rabbit.getWidth())
rabbitX = dWidth - rabbit.getWidth();
else
rabbitX=newRabbitX;
}
}
return true;
}
}
public class Spike {
Bitmap spike[] = new Bitmap[3];
int spikeFarm =0;
int spikeX,spikeY,spikeVelocity;
Random random;
public Spike(Context context){
spike[0]= BitmapFactory.decodeResource(context.getResources(),R.drawable.spike0);
spike[1]= BitmapFactory.decodeResource(context.getResources(),R.drawable.spike1);
spike[2]= BitmapFactory.decodeResource(context.getResources(),R.drawable.spike2);
random=new Random();
}
public Bitmap getSpike(int spikeFarm){
return spike[spikeFarm];
}
public int getSikeWidth(){
return spike[0].getWidth();
}
public int getSpikeHeight(){
return spike[0].getHeight();
}
public void resetPosition(){
spikeX=random.nextInt(GameView.dWidth-getSikeWidth());
spikeY=-200+random.nextInt(600)* -1;
spikeVelocity= 35+random.nextInt(16);
}
}

Screen resolution handling

So the fact that my textboxes are ending up in different places depending on which device I run it on is tearing my soul apart. I really cant fix this.
This is the code:
I know it is a mess right now, since I was playing around with the viewport API that Libgdx provides. But it didn´t help anything.
To describe what the last thing i tried was that I set the X & Y coordinates for the textboxes to be final and have no unit assign to it. Although, when running on my tablet the textboxes as always ends up totally away from where they were set on my phone.
public class StoneScreen implements Screen, purchaseInterface {
OrthographicCamera camera;
Viewport view;
final TombStone game;
purchaseInterface pInt;
//Textures and art.
public Texture background, sdStone, arrowBack, stone_3, flowerTex, flowerTex_2, flowerTemp;
public Sprite backgrounds;
//TextField´s stuff
private Stage stage;
private Skin skin;
ImageButton btnArrow, btnFB;
Image stoneImage, flowerImage, flowerImage_2, flowerImageTemp;
private static int counter= 1;
private static final float screenWidth = 1000;
private static final float screenHeight = 1500;
private final float textX = 200;
private final float textY = 700;
private final float textAreaX = 200;
private final float textAreaY = 400;
private final int textWidth = 350;
private final int textHeight = 100;
private final float stoneWidth = 600;
private final float stoneHeight = 800;
public StoneScreen(TombStone gam) {
this.game = gam;
this.pInt = game.pi;
//Set´s the current device´s height and width into a float for easier usage
//Set´s the tombstones height and width
//viewport = new FitViewport(camera, screenWidth, screenHeight)
float aspectRatio = (float) Gdx.graphics.getHeight() / (float)Gdx.graphics.getWidth();
camera = new OrthographicCamera();
camera.setToOrtho(false, screenWidth, screenHeight);
game.assets.load();
loadStandard();
stoneImage = new Image(sdStone);
flowerImage = new Image(flowerTemp);
//flowerImageTemp = new Image(flowerTemp);
//flowerImage_2 = new Image(flowerTex_2);
}
public void loadStandard(){
background = game.assets.background;
sdStone = game.assets.sdStone;
stone_3 = game.assets.stone3;
flowerTex = game.assets.flowerTexture;
flowerTemp = game.assets.flowerTemp;
//backgrounds = Assets.backgrounds;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
Gdx.app.log("X", "FPS:" + Gdx.graphics.getFramesPerSecond());
game.batch.draw(background,0,0);
//game.batch.draw(sdStone, 160, 190, screenWidth * 0.60f, screenHeight * 0.60f);
stoneImage.setBounds(180, 190, stoneWidth, stoneHeight);
stoneImage.draw(game.batch, 2);
flowerImage.setBounds(300, 50, screenWidth * 0.65f, screenHeight * 0.30f);
flowerImage.draw(game.batch, 2);
//SpriteBatch batcher = (SpriteBatch)stage.getBatch();
game.batch.end();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void resize(int width, int height) {
//float aspectRatio = (float) height / (float) width;
//camera = new OrthographicCamera(screenWidth, screenHeight * aspectRatio);
//view.update(width, height);
camera.update();
}
#Override
public void show() {
//Generates the new font
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("AcademyEngraved.ttf"));
FreeTypeFontParameter parameter = new FreeTypeFontParameter();
parameter.size = 40;
BitmapFont textFont = generator.generateFont(parameter);
generator.dispose(); //Avoiding memory leaks.
Preferences prefs = Gdx.app.getPreferences("preferences");
Skin skin = new Skin();
Skin textSkin = new Skin();
stage = new Stage();
Gdx.input.setInputProcessor(stage);
//Sets skin
skin = new Skin(Gdx.files.internal("uiskin.json"));
//Sets a color to the new font
Color fontcolor = Color.BLACK;
//Sets a new font to the textare n the textfield
TextFieldStyle textstyle = new TextFieldStyle();
textstyle.font = textFont;
textstyle.fontColor = fontcolor;
final TextArea textArea = new TextArea(prefs.getString("textArea", "Enter text:"), textstyle);
textArea.setX(textAreaX);
textArea.setY(textAreaY);
textArea.setWidth(textWidth);
textArea.setHeight(textHeight);
textArea.setMaxLength(30);
textArea.setZIndex(5);
final TextField textField = new TextField(prefs.getString("textField", "Enter name:"), textstyle);
textField.setX(textX);
textField.setY(textY);
textField.setMaxLength(20);
textField.setWidth(textWidth);
textField.setHeight(textHeight);
//String text = Gdx.app.getPreferences("prefs").getString("text", "Default text if missimg");
//TextField textField = new TextField(text, skin);
//Backbutton
ImageButtonStyle styleTwo = new ImageButtonStyle();
//ImageButtonStyle styleFB = new ImageButtonStyle();
TextureRegionDrawable arrowImage = new TextureRegionDrawable(new TextureRegion(new Texture("pil.png")));
TextureRegionDrawable arrowImageDown = new TextureRegionDrawable(new TextureRegion(new Texture("pilD.png")));
//TextureRegionDrawable fbImage = new TextureRegionDrawable(new TextureRegion(new Texture("fb.png")));
//TextureRegionDrawable fbImageDown = new TextureRegionDrawable(new TextureRegion(new Texture("fbDown.png")));
styleTwo.up = skin.newDrawable(skin.newDrawable(arrowImage));
styleTwo.down = skin.newDrawable(skin.newDrawable(arrowImageDown));
styleTwo.pressedOffsetX = -1;
styleTwo.pressedOffsetY = -1;
//styleFB.up = skin.newDrawable(skin.newDrawable(fbImage));
//styleFB.down = skin.newDrawable(skin.newDrawable(fbImageDown));
//styleFB.pressedOffsetX = -1;
//styleFB.pressedOffsetY = -1;
/*Object[] dropMenu = new Object[2];
dropMenu[0] = new Label("this iaios", skin);
final SelectBox<Object> sb = new SelectBox<Object>(skin);
sb.setItems(dropMenu);
Table table = new Table();
table.setFillParent(true);
table.setPosition(0, 800);
table.add(sb);*/
//Back button
btnArrow = new ImageButton(styleTwo);
//btnFB = new ImageButton(styleFB);
btnArrow.setSize(150, 150);
btnArrow.setPosition(50, 10);
//btnFB.setSize(100, 100);
//btnFB.setPosition(800, 10);
stage.addActor(textArea);
stage.addActor(textField);
stage.addActor(btnArrow);
//stage.addActor(table);
//Backbutton takes us back to mainmenu
btnArrow.addListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
game.setScreen(new MainScreen(game));
//Saves the entered text.
Preferences prefs = Gdx.app.getPreferences("preferences");
prefs.putString("textField", textField.getText());
prefs.putString("textArea", textArea.getText());
prefs.flush();
}
});
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
public void changeStone1() {
//sdStone.dispose();
stoneImage.setDrawable(new SpriteDrawable(new Sprite(stone_3)));
camera.update();
}
private static void saveScreenshot() {
try{
FileHandle fh;
do{
fh = new FileHandle("screenshot" + counter++ + ".png");
}while(fh.exists());
Pixmap pixmap = getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
PixmapIO.writePNG(fh, pixmap);
pixmap.dispose();
}catch(Exception e) {
}
}
private static Pixmap getScreenshot(int x, int y, int w, int h, boolean yDown){
final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, w, h);
if(yDown) {
ByteBuffer pixels = pixmap.getPixels();
int numBytes = w * h * 4;
byte[] lines = new byte[numBytes];
int numBytesPerLine = w * 4;
for (int i = 0; i < h; i++) {
pixels.position((h - i - 1) * numBytesPerLine);
pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
}
pixels.clear();
pixels.put(lines);
}
return pixmap;
}
#Override
public void applyTombstone() {
// TODO Auto-generated method stub
}
#Override
public void applyTombstone1() {
// TODO Auto-generated method stub
}
#Override
public void applyTombstone2() {
// TODO Auto-generated method stub
}
#Override
public void applyFlower() {
// TODO Auto-generated method stub
flowerImage.setDrawable(new SpriteDrawable(new Sprite(flowerTex)));
camera.update();
}
#Override
public void applyFlower1() {
// TODO Auto-generated method stub
}
#Override
public void applyLight() {
// TODO Auto-generated method stub
}
#Override
public void processPurchases() {
// TODO Auto-generated method stub
}
#Override
public void changeStone() {
// TODO Auto-generated method stub
stoneImage.setDrawable(new SpriteDrawable(new Sprite(stone_3)));
camera.update();
}
}
So here´s the solution:
#Override
public void resize(int width, int height) {
stageText.getViewport().update(width, height, true);
}
I simply made the textField I wanted to be positioned to a seperate Stage so that the other elements in my app wouldn´t be affected.

When using the button, my program closes, libgdx

I have encountered the problem with my buttons. My code is as follows.
public class rarsterinco implements ApplicationListener {
Texture background;
Texture background2;
Texture background3;
Vector2 backgroundmove;
Vector2 backgroundmove2;
SpriteBatch batch;
Rectangle bounds;
CharSequence line = "got touched."; // = myScore;
Rectangle bounds2;
boolean check;
boolean collision;
int beginning;
CharSequence headup = "got touched";
Vector2 pos;
Vector2 position;
Vector2 size;
Vector2 size2;
BitmapFont font;
Texture mysteryCloud;
Texture mario;
Texture water;
Vector2 watermove;
Vector2 watersize;
Stage stage;
TextureAtlas buttonAtlas;
TextButtonStyle buttonStyle;
TextButton button;
Skin skin;
#Override
public void create() {
BitmapFont font = new BitmapFont();
skin = new Skin();
buttonAtlas = new TextureAtlas("buttons/pause.pack");
skin.addRegions(buttonAtlas);
buttonStyle = new TextButtonStyle();
buttonStyle.up = skin.getDrawable("imgres");
buttonStyle.over = skin.getDrawable("imgres");
buttonStyle.down = skin.getDrawable("imgres");
button = new TextButton("", buttonStyle);
stage.addActor(button);
mysteryCloud = new Texture(Gdx.files.internal("data/mysteryCloud.jpg"));
batch = new SpriteBatch();
mario = new Texture(Gdx.files.internal("data/mario.jpg"));
background = new Texture(Gdx.files.internal("data/background1.jpg"));
background2 = new Texture(Gdx.files.internal("data/background2.jpg"));
background3 = new Texture(Gdx.files.internal("data/background3.jpg"));
position = new Vector2();
pos = new Vector2();
backgroundmove = new Vector2();
backgroundmove2 = new Vector2();
size2 = new Vector2(mario.getWidth() ,mario.getHeight() );
//size2.y = trash.getHeight();
//size2.x = trash.getWidth();
size = new Vector2(mysteryCloud.getWidth() ,mysteryCloud.getHeight());
bounds= new Rectangle(pos.x, pos.y, size.x, size.y);
bounds2= new Rectangle(position.x, position.y, 32, 32);
}
#Override
public void dispose() {
//font.dispose();
}
public void update(){
bounds.set(pos.x, pos.y, 32, 32);
bounds2.set(position.x, position.y, size2.x, size2.y);
position.x = position.x + 5* Gdx.input.getAccelerometerY();
//float pos1=Gdx.input.getAccelerometerY();
//position.x = position.x - 5*pos1;
//float pos2=Gdx.input.getAccelerometerY();
//position.y = position.y - 5*pos2;
}
#Override
public void render() {
beginning = beginning+ 1;
if(beginning == 1){
backgroundmove.x = Gdx.graphics.getWidth();
}
position.y = position.y -10;
if(position.x<0){
Gdx.input.vibrate(250);
}
if(position.x>Gdx.graphics.getWidth()){
Gdx.input.vibrate(250);
}
//if(position.y<0){
//Gdx.input.vibrate(250);
//}
if(position.y>Gdx.graphics.getHeight()){
Gdx.input.vibrate(250);
}
if(bounds.overlaps(bounds2)){
collision=true;
}else{
collision= false;
}
if(position.x<0){
position.x= position.x+80;
}
if(position.x>Gdx.graphics.getWidth() - mario.getWidth()){
position.x= position.x-80;
}
if(Gdx.input.isTouched()){
position.y = position.y + 30;
}
if(position.y<0){
position.y= position.y+80;
}
if(position.y>Gdx.graphics.getWidth() +mario.getHeight()){
position.y= position.y-80;
}
pos.x = pos.x - 10;
if(pos.x <0 && collision == false){
pos.x = Gdx.graphics.getWidth();
Random randomGenerator = new Random();
pos.y = randomGenerator.nextInt(Gdx.graphics.getHeight()-30);
}
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(Gdx.input.getAccelerometerX() == 10){
}
if(collision){
pos.x = Gdx.graphics.getWidth();
Random randomGenerator = new Random();
pos.y = randomGenerator.nextInt(Gdx.graphics.getHeight()-30);
}
backgroundmove.x = backgroundmove.x - 10;
backgroundmove2.x = backgroundmove2.x - 10;
if(backgroundmove.x <-Gdx.graphics.getWidth()){
backgroundmove.x = Gdx.graphics.getWidth();
}
if(backgroundmove2.x <-Gdx.graphics.getWidth()){
backgroundmove2.x = Gdx.graphics.getWidth();
}
update();
batch.begin();
// if(!collision){
// batch.draw(mysteryCloud, pos.x, pos.y, 64, 64);
// }
// batch.draw(mysteryCloud, pos.x, pos.y, 64, 64);
// if(collision){
// mysteryCloud.dispose();
// }
// if(pos.x<0 && collision == true){
// batch.draw(mysteryCloud, pos.x, pos.y, 64, 64);
// }
//
//batch.draw(background3, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
//batch.draw(background, backgroundmove.x, backgroundmove.y, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
//batch.draw(background2, backgroundmove2.x, backgroundmove2.y, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.draw(mario, position.x,position.y);
batch.draw(mysteryCloud, pos.x, pos.y, 64, 64);
font.setScale(4);
font.setColor(0.0f, 1.0f, 1.0f,1.0f);
stage.draw();
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
What I realized was that when I commented the stage.draw() and the other button code my app worked, but when I uncommented the code it said mylibgdxgame has stopped working.
The button code is as follows:
TextureAtlas buttonAtlas;
TextButtonStyle buttonStyle;
TextButton button;
Skin skin;
#Override
public void create() {
BitmapFont font = new BitmapFont();
skin = new Skin();
buttonAtlas = new TextureAtlas("buttons/pause.pack");
skin.addRegions(buttonAtlas);
buttonStyle = new TextButtonStyle();
buttonStyle.up = skin.getDrawable("imgres");
buttonStyle.over = skin.getDrawable("imgres");
buttonStyle.down = skin.getDrawable("imgres");
button = new TextButton("", buttonStyle);
stage.addActor(button);
,
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: No Drawable, NinePatch, TextureRegion, Texture, or Sprite registered with name: imgres at com.badlogic.gdx.scenes.scene2d.ui.Skin.getDrawable(Skin.java:291) at com.me.rarsterinco.rarsterinco.create(rarsterinco.java:64) at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:‌​136) at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114‌​)
Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: Missing LabelStyle font. at com.badlogic.gdx.scenes.scene2d.ui.Label.setStyle(Label.java:77) at com.badlogic.gdx.scenes.scene2d.ui.Label.<init>(Label.java:71) at com.badlogic.gdx.scenes.scene2d.ui.TextButton.<init>(TextButton.java:48) at com.me.rarsterinco.rarsterinco.create(rarsterinco.java:69) at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:‌​136) at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114‌​)

Android App Tracking Points: Video.calcOpticalFlow(...) method not working properly?

I am currently trying to create an Android App using OpenCV that allows the user to track points of moving objects using the smartphone camera. An analogous code in C++ that does exactly what I am looking for can be found in the following link: OpticalFlow C++ Sample Code
I have been Googling and looking around in StackOverflow, but I still can't figure out why my code is not working. I am able to place points on the screen every time I press on a certain spot, but the points seem motionless even as I move objects in front of the camera. The method used to calculate the opitcal flow is the following:
void org.opencv.video.Video.calcOpticalFlowPyrLK(Mat prevImg, Mat nextImg, MatOfPoint2f prevPts, MatOfPoint2f nextPts, MatOfByte status, MatOfFloat err)
I believe I am passing the exact parameters needed to calculate the optical flow of consecutive images, but for some reason it's not working. Below is my code:
package org.opencv.UActivity;
//INCLUDE FILES
...
public class U2Activity extends Activity implements OnTouchListener,CvCameraViewListener2{
private static final String TAG = "OCVSample::Activity";
private Mat nextGray,Rscale;
private Mat prevGray;
private MatOfPoint2f prev2D,next2D;
private MatOfByte status;
private MatOfFloat err;
private Scalar color;
private CameraBridgeViewBase mOpenCvCameraView;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
mOpenCvCameraView.setOnTouchListener(U2Activity.this);
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public U2Activity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.u2_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.u2_activity_surface_view);
mOpenCvCameraView.setCvCameraViewListener(this);
color = new Scalar(0, 255, 0);
}
#Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
#Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
nextGray = new Mat(height, width, CvType.CV_8UC1); //unsigned char
Rscale = new Mat(height, width, CvType.CV_8UC1);
prevGray = new Mat(height, width, CvType.CV_8UC1);
prev2D = new MatOfPoint2f(new Point());
next2D = new MatOfPoint2f(new Point());
status = new MatOfByte();
err = new MatOfFloat();
}
public void onCameraViewStopped() {
nextGray.release();
Rscale.release();
}
public boolean onTouch(View v, MotionEvent event) {
int cols = nextGray.cols();
int rows = nextGray.rows();
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
int x = (int)event.getX() - xOffset;
int y = (int)event.getY() - yOffset;
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
prev2D.push_back(new MatOfPoint2f(new Point((double)x,(double)y)));
next2D.push_back(new MatOfPoint2f(new Point()));
return false; // don't need subsequent touch events
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
nextGray = inputFrame.gray(); //get current image
Rscale = nextGray; //make a copy of current image
if(prevGray.empty()) prevGray = nextGray; //on start there is no prevGray. Copy current.
Video.calcOpticalFlowPyrLK(prevGray,nextGray,prev2D,next2D,status,err); //Calc the Optical Flow
prevGray = nextGray; //Overwrite old Image (prevGray)
prev2D = next2D; //Overwrite old point coordinates
for(int i=0;i<next2D.toArray().length;i++){ //Draw the points in the image
Core.circle(Rscale, next2D.toArray()[i], 3, color);
}
return Rscale;
}
}
SOLVED:
I changed:
prevGray = nextGray;
prev2D = next2D;
to:
nextGray.copyTo(prevGray);
next2D.copyTo(prev2D);
I hope it helps anyone encountering similar problems.

Android game in surfaceview lagg spikes

guys. I'm playing around with making my very first Android game, but stumbled into a problem. The framerate seems to have random lag spikes. If I comment the background(s) out the framerate gets much smoother. I've looked around SO and can't find anything to solve my problems. I have a feeling it has something to do with allocating a specific amount of time every time I draw, but I don't know how to properly implement such a feature. Any suggestions? Btw, tryed hardware ac, anti etc.
This is the class that starts the surfaceview :
package com.example.glassrunner;
Imports Here
public class Game extends Activity
{
MySurfaceView mySurfaceView;
public SoundPool spool;
private int soundID;
int length=0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
}
#Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
mySurfaceView.onResumeMySurfaceView();
}
#Override
protected void onPause()
{
// TODO Auto-generated method stub
super.onPause();
mySurfaceView.onPauseMySurfaceView();
}
#Override
protected void onDestroy()
{
super.onDestroy();
mySurfaceView = null;
}
}
This is the surfaceview class :
package com.example.glassrunner;
Imports here
public class MySurfaceView extends SurfaceView implements Runnable
{
public static boolean gameOver = false;
SurfaceHolder surfaceHolder;
Thread thread = null;
public Integer score=0;
public SoundPool spool;
private int soundID;
int length=0;
public static MediaPlayer mp;
volatile boolean running = false;
int Yposition = 450;
int Xposition = 50;
Paint textPaint;
long mLastTime;
Bitmap background;
Bitmap background2;
Bitmap lines;
Bitmap runSprite;
Bitmap box;
Paint bitmapPaint ;
Paint textPaint2;
Bitmap scaledBackground ;
Bitmap scaledBackground2 ;
Bitmap scaledLines ;
Bitmap scaledBox;
Canvas canvas;
Paint paint;
int SpX=0;
int SpY=0;
Bitmap[][] sprite;
/** Variables for the counter */
int frameSamplesCollected = 0;
int frameSampleTime = 0;
int fps = 0;
int speed = 5;
Toast GameOverToast;
Context context;
MediaPlayer mMediaPlayer;
public MySurfaceView(Context context)
{
super(context);
this.context = context;
// TODO Auto-generated constructor stub
surfaceHolder = getHolder();
surfaceHolder.setFormat(PixelFormat.RGB_565);
CharSequence text = "Game Over!";
int duration = Toast.LENGTH_SHORT;
GameOverToast = Toast.makeText(context, text, duration);
spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundID = spool.load(context, R.raw.jump, 1);
mp = MediaPlayer.create(context, R.raw.saturdaymorningfunk);
initialization();
}
public void initialization()
{
mp.setLooping(true);
mp.start();
Options options = new Options();
options.inSampleSize = 1/4;
options.inPreferredConfig = Bitmap.Config.RGB_565;
background=BitmapFactory.decodeResource(getResources(),R.drawable.background,options);
lines=BitmapFactory.decodeResource(getResources(),R.drawable.lines);// getting the png from drawable folder
background2=BitmapFactory.decodeResource(getResources(),R.drawable.background2,options);
runSprite=BitmapFactory.decodeResource(getResources(),R.drawable.runsprite);
box=BitmapFactory.decodeResource(getResources(),R.drawable.box);
bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // tool for painting on the canvas
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);
textPaint = new Paint();
textPaint.setColor(Color.RED);
textPaint.setTextSize(32);
textPaint2 = new Paint();
textPaint2.setColor(Color.BLUE);
textPaint2.setTextSize(50);
scaledBackground = Bitmap.createScaledBitmap(background, 2560, 500, true);
scaledBackground2 = Bitmap.createScaledBitmap(background2, 2560, 400, true);
scaledLines = Bitmap.createScaledBitmap(lines, 2560, 30, true);
runSprite = Bitmap.createScaledBitmap(runSprite, 1400, 1000, true);
scaledBox = Bitmap.createScaledBitmap(box, 100, 100, true);
sprite = new Bitmap[4][7];
for(int row=0;row<=3;row++)
{
for(int col=0;col<=6;col++)
{
sprite[row][col] = Bitmap.createBitmap(runSprite, SpX, SpY, 200, 250);
SpX+=200;
}
SpX=0;
SpY+=250;
}
}
public void onResumeMySurfaceView()
{
mp.seekTo(length);
mp.start();
running = true;
thread = new Thread(this);
thread.start();
}
public void onPauseMySurfaceView()
{
mp.pause();
length=mp.getCurrentPosition();
boolean retry = true;
running = false;
while(retry){
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void onDestroyMySurfaceView()
{
mp.stop();
running = false;
thread = null;
thread.stop();
}
private void fps()
{
long now = System.currentTimeMillis();
if (mLastTime != 0)
{
//Time difference between now and last time we were here
int time = (int) (now - mLastTime);
frameSampleTime += time;
frameSamplesCollected++;
//After 10 frames
if (frameSamplesCollected == 10)
{
//Update the fps variable
fps = (int) (10000 / frameSampleTime);
//Reset the sampletime + frames collected
frameSampleTime = 0;
frameSamplesCollected = 0;
}
}
mLastTime = now;
}
public boolean pressDown = false;
public long pressTime;
public boolean onTouchEvent(MotionEvent event)
{
if (event != null)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{ if(Yposition == orgPos)
{
spool.play(soundID, 15, 15, 1, 0, 1f);
pressDown = true;
pressTime = System.currentTimeMillis();
}
}else if (event.getAction() == MotionEvent.ACTION_UP)
{
pressDown = false;
}
}
return true;
}
int x=0;
int y=100;
int x2=0;
int y2=20;
int row=0;
int col=0;
int limit = 100;
int orgPos = 450;
int Xbox = 1280;
int Ybox = 580;
Random r = new Random();
int RBox;
public static String Fscore;
boolean onTop = false;
long now;
long start;
long stop;
long time ;
int spritePosition = 0 ;
int spriteSize;
#Override
public void run()
{
while(running)
{
canvas = null;
if(surfaceHolder.getSurface().isValid())
{
canvas = surfaceHolder.lockCanvas();
fps(); // fps
// Update screen parameters
update();
draw();
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
public void update()
{
if(score<500)
{
speed = 7;
}
else if(score%500 == 0)
{
speed = 7 + (score / 500);
}
if(col==6)
{
row++;
col=0;
}
if(row==4)
{
row=0;
}
score++;
Fscore = score.toString();
if(x>-1280)
{
x-=speed;
}else if(x<=-1280)
{
x=0;
}
if(x2>-1280)
{
x2-=5;
}else if(x2<=-1280)
{
x2=-0;
}
RBox = r.nextInt(999)+1280;
if(Xbox > -100)
{
Xbox-=speed;
}else if(Xbox<=-100)
{
Xbox=RBox;
}
if( (Xposition + 200 == Xbox +40 )&&(Yposition + 250 > Ybox+20)||( Xposition+200<=Xbox+70)&&( Xposition+200>=Xbox+20)&&(Yposition + 250 > Ybox+30) ) // collision
{
GameOverToast.show();
running = false;
spool.release();
mp.release();
Looper.prepare();
Intent database = new Intent(context, MainHighscore.class);
database.putExtra("score", Fscore);
context.startActivity(database);
onDestroyMySurfaceView();
}
now = System.currentTimeMillis();
if(( now - pressTime) <= 600)
{
if(Yposition > limit)
{
Yposition -= 10;
}
}
onTop = false;
if((now - pressTime) >= 600 && (now - pressTime) <= 1200)
{
if(!(Yposition == orgPos))
{
if(Yposition+250 >= Ybox && Xposition+200>=Xbox+70 && Xposition <= Xbox+40)
{
onTop=true;
Yposition = 340;
}else
{
Yposition += 10;
}
}
}
if((now - pressTime) >= 1200)
{
if(Yposition < 450) Yposition +=10;
else Yposition = 450;
}
}
public void draw()
{
canvas.drawColor(Color.WHITE);
//canvas.drawBitmap(scaledBackground, x2,y2, bitmapPaint);
canvas.drawBitmap(scaledBackground2, x,y, bitmapPaint);
canvas.drawBitmap(scaledLines, x,650, bitmapPaint);
canvas.drawText(Fscore, 1050, 50, textPaint2);
canvas.drawText(fps + " fps", getWidth() / 2, getHeight() / 2, textPaint);
canvas.drawBitmap(sprite[row][col],Xposition,Yposition,bitmapPaint );
canvas.drawBitmap(scaledBox,Xbox,Ybox,bitmapPaint);
col++;
}
}
I think your problem might be actually the moving part. Your just drawing too much stuff, and the surfaceView is not meant for that.

Categories

Resources