Screen resolution handling - android

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.

Related

How to play a sound on android with a delay?

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.

How to get the screen size?

I am trying to set a sprite image as a background
and I didn't success to set the image size to screen size.
I'm trying this:
public class Game extends SurfaceView implements Runnable {
private SurfaceHolder holder;
private boolean isRunning = false;
private Thread gameThread;
private Sprite s;
private int screenWidth;
private int screenHeight;
Canvas canvas;
// private Sprite[] sprites;
private final static int MAX_FPS = 40; //desired fps
private final static int FRAME_PERIOD = 1000 / MAX_FPS; // the frame period
public Game(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
screenWidth = width;
screenHeight = height;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
//====== not working
// Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
// int sWidth = display.getWidth();
// int sHeight = display.getHeight();
//====== not working
// DisplayMetrics dm = new DisplayMetrics();
// ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(dm);
// int sWidth = dm.widthPixels;
// int sHeight = dm.heightPixels;
//====== not working
// screenHeight=canvas.getHeight();
// screenWidth=canvas.getWidth();
s=new Sprite(0, 0, BitmapFactory.decodeResource(this.getResources(), R.mipmap.back));
}
/**
* Start or resume the game.
*/
public void resume() {
isRunning = true;
gameThread = new Thread(this);
gameThread.start();
}
/**
* Pause the game loop
*/
public void pause() {
isRunning = false;
boolean retry = true;
while (retry) {
try {
gameThread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
}
class Sprite {
int x;
int y;
int directionX = 1;
int directionY = 1;
int speed = 10;
int color = 0;
Bitmap image;
public Sprite(int x, int y) {
this.x = x;
this.y = y;
}
public Sprite(int x, int y, Bitmap image) {
this(x, y);
this.image = image;
}
public Sprite(int x, int y, Bitmap image, int color) {
this(x, y, image);
this.color = color;
}
}
protected void step()
{
//blablabla
}
protected void render(Canvas canvas) {
canvas.drawColor(Color.BLACK);
Paint p = new Paint();
canvas.drawBitmap(s.image,s.x,s.y,p);
}
#Override
public void run() {
while(isRunning) {
// We need to make sure that the surface is ready
if (! holder.getSurface().isValid()) {
continue;
}
long started = System.currentTimeMillis();
// update
step();
// draw
canvas = holder.lockCanvas();
if (canvas != null) {
render(canvas);
holder.unlockCanvasAndPost(canvas);
}
float deltaTime = (System.currentTimeMillis() - started);
int sleepTime = (int) (FRAME_PERIOD - deltaTime);
if (sleepTime > 0) {
try {
gameThread.sleep(sleepTime);
}
catch (InterruptedException e) {
}
}
while (sleepTime < 0) {
step();
sleepTime += FRAME_PERIOD;
}
}
}
}
This options doesn't work:
//====== not working
// Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
// int sWidth = display.getWidth();
// int sHeight = display.getHeight();
//====== not working
// DisplayMetrics dm = new DisplayMetrics();
// ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(dm);
// int sWidth = dm.widthPixels;
// int sHeight = dm.heightPixels;
//====== not working
// screenHeight=canvas.getHeight();
// screenWidth=canvas.getWidth();
So how I can get the canvas or current screen size?
And set the Sprite.image to full screen ?
Try this for size in pixels,
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Try this when you decode your bitmap.
final int width = context.getResources().getDisplayMetrics().widthPixels;
final int height = context.getResources().getDisplayMetrics().heightPixels;
BitmapFactory.Options options = new BitmapFactory.Options();
options.outHeight = height;
options.outWidth = width;
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher, options)

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.

Custom, refreshing view not responding to OnClick

I made a view that contains a bar graph, which for now is fueled by random numbers generator and refreshes once a second. The idea is that after clicking one of the bars, it would change to a line graph.
This is code of the view:
public class BarGraph extends View implements OnClickListener{
private Paint paint;
private String[] horlabels;
private String[] verlabels;
private String title;
private int[] values;
Context co;
private RectF[] rects;
public BarGraph(Context context, String title, String[] hor, String[] var) {
super(context);
// TODO Auto-generated constructor stub
if (title == null)
title = "";
else
this.title = title;
if (hor == null)
this.horlabels = new String[0];
else
this.horlabels = hor;
if (var == null)
this.verlabels = new String[0];
else
this.verlabels = var;
paint = new Paint();
co = context;
}
public void updateVals(int[] vals){
values = vals;
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
float border = 20;
float horstart = border;
float height = getHeight();
float width = getWidth() - 1;
int max = 100;
int min = 0;
float diff = max - min;
float graphheight = height - (2 * border);
float graphwidth = width - (2 * border);
rects = new RectF[horlabels.length];
this.setClickable(true);
paint.setTextAlign(Align.LEFT);
int vers = verlabels.length - 1;
for (int i = 0; i < verlabels.length; i++) {
paint.setColor(Color.DKGRAY);
float y = ((graphheight / vers) * i) + border;
canvas.drawLine(horstart, y, width - border, y, paint);
paint.setColor(Color.WHITE);
canvas.drawText(verlabels[verlabels.length - 1 - i], 0, y, paint);
}
int hors = horlabels.length;
for (int i = 0; i < horlabels.length + 1; i++) {
paint.setColor(Color.DKGRAY);
float x = ((graphwidth / hors) * i) + horstart;
canvas.drawLine(x, height - border, x, border, paint);
paint.setTextAlign(Align.CENTER);
if (i==horlabels.length-1)
paint.setTextAlign(Align.RIGHT);
if (i==0)
paint.setTextAlign(Align.LEFT);
paint.setColor(Color.WHITE);
}
for (int i = 0; i < horlabels.length; i++)
{
float x = ((graphwidth / hors) * i) + horstart;
canvas.drawText(horlabels[i], x + (graphwidth / (2*hors)), height - 4, paint);
}
paint.setTextAlign(Align.CENTER);
canvas.drawText(title , (graphwidth / 2) + horstart, border - 4, paint);
if (max != min) {
paint.setColor(Color.LTGRAY);
float datalength = values.length;
float colwidth = (width - (2 * border)) / datalength;
for (int i = 0; i < values.length; i++) {
float val = values[i] - min;
float rat = val / diff;
float h = graphheight * rat;
RectF r = new RectF((i * colwidth) + horstart, (border - h) + graphheight, ((i * colwidth) + horstart) + (colwidth - 1), height - (border - 1));
rects[i] = r;
canvas.drawRect(r, paint);
}
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int[] coords = new int[2];
v.getLocationInWindow(coords);
Toast t = Toast.makeText(co, "KLIKNIETO", Toast.LENGTH_LONG);
t.show();
for(RectF r : rects){
if(r.contains(coords[1], coords[2]))
{
try {
this.finalize();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return;
}
It's started in this activity:
public class GraphTestActivity extends Activity{
/** Called when the activity is first created. */
public List<DataSet> sets;
String[] verlabels;
int[] vals;
BarGraph graph;
Thread t1;
String[] hortable;
// private Updater task;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sets = new LinkedList<DataSet>();
verlabels = new String[] {"0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"};
DataSet set1 = new DataSet("set1");
DataSet set2 = new DataSet("set2");
DataSet set3 = new DataSet("set3");
DataSet set4 = new DataSet("set4");
DataSet set5 = new DataSet("set5");
sets.add(set1);
sets.add(set2);
sets.add(set3);
sets.add(set4);
sets.add(set5);
hortable = new String[sets.size()];
vals = new int[sets.size()];
for(int i = 0; i < sets.size(); i++)
{
hortable[i] = sets.get(i).getName();
}
graph = new BarGraph(this, "Diagram slupkowy", hortable, verlabels);
for(DataSet d : sets)
{
d.nextGen();
}
graph.updateVals(vals);
setContentView(graph);
new Updater().execute();
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
new BarRefresh().execute();
}
class Updater extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// doSomething();
while(true){
for(DataSet d : sets)
{
d.nextGen();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(isCancelled()){
break;
}
}
return null;
}
}
class BarRefresh extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// doSomething();
while(true){
for(int i = 0; i < sets.size(); i++)
{
vals[i] = sets.get(i).getLast();
}
graph.updateVals(vals);
graph.postInvalidate();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(isCancelled()){
break;
}
}
return null;
}
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
try {
this.finish();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The problem is, it does not react to touch. Could it have something to do with the way I set up refreshing in BarRefresh task?
If your BarGraph View Class is the one that you want to be clicking, you should make it HAVE an OnClickListener, instead of BEING an OnClickListener.
Here's what you do
1 remove the implements OnClickListener()
2 do something in your Activity like
bargraph.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//do whatever
}});
or you can put that code chunk inside the constructor (this.setOnClickListener()) so that all your BarGraph classes get it etc.

Android live wallpaper scaling

I'm learning android and java and am trying to learn how to make a live wallpaper
I am using the aquarium tutorial, I put it all in one file instead of spreading it but what I am trying to do is get one scale number for everything, I want to get the height of the screen divide that by the background image height (which will always be bigger), this should give me a ratio to use for scaling everything, I tried this in a surfaceView code and it worked perfect, I tried it in livewallpaper and nada.
In the surfaceView test I use onSizeChange and got the height that way and it worked no problems.
This is what I did for the livewallpaper one
This is what I put for the onSurfaceChange
public int screenWidth;
public float rescaler;
public float totalHeight = theTemplate._backgroundImage.getHeight();
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//add rescale and width
screenWidth = width;
rescaler = (float) (height / totalHeight);
super.onSurfaceChanged(holder, format, width, height);
}
The background image comes from an inner class named TheTemplate
This is what I did there
The variables
private SpriteAnimationActivityEngine theTest;
private Bitmap theBackgroundImage;
private float theScaler = theTest.rescaler;
then I try and rescale it using theScaler
public void initialize(Context context, SurfaceHolder surfaceHolder) {
this.spriteThread = new SpriteThread(this);
this._surfaceHolder = surfaceHolder;
this._sprites = new ArrayList<Renderable>();
this._context = context;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
this._backgroundImage = BitmapFactory.decodeResource(context.getResources(),ca.samsstuff.testonepagewallpaper.R.drawable.sky, options);
this.theBackgroundImage = Bitmap.createScaledBitmap(_backgroundImage, (int) (theScaler * _backgroundImage.getWidth()), (int) (theScaler * _backgroundImage.getHeight()), true);
this.addSprites();
}
Then it passes it to draw the background
private void renderBackGround(Canvas canvas) {
canvas.drawBitmap(this.theBackgroundImage, 0, 0, null);
}
Which sends it to draw
protected void onDraw(Canvas canvas) {
this.renderBackGround(canvas);
for (Renderable renderable : this._sprites) {
renderable.render(canvas);
}
}
I keep getting errors and don't know what I am doing wrong. Like I said I am learning both android and java but this method worked in another test I did but I got the screen height from onSizeChange can I get the height by using onSurfaceChange?
Any help would be appreciated
Thanks in advance
sam
EDIT
I also tried to rescale within the theTemplate class just to see if it would work having everything within its own class and still having issues, I used the DisplayMetrics to get the screen height this time.
This might work if I can get it going properly.
Here is this attempt
public class TheTemplate {
private SpriteThread spriteThread;
private SurfaceHolder _surfaceHolder;
private ArrayList<Renderable> _sprites;
public Bitmap _backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.sky);;
private Context _context;
// add rescale stuff
private Bitmap theBackgroundImage;
private float theScaler = initFrameParams() / _backgroundImage.getHeight();
private Bitmap oneBackImage = Bitmap.createScaledBitmap(_backgroundImage, (int) (theScaler * _backgroundImage.getWidth()), (int) (theScaler * _backgroundImage.getHeight()), true);
int initFrameParams()
{
//get the screen height to use to rescale everything
DisplayMetrics metrics = new DisplayMetrics();
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
display.getMetrics(metrics);
int screenHeight = display.getHeight();
return screenHeight;
}
public void render(){
Canvas canvas = null;
try{
canvas = this._surfaceHolder.lockCanvas(null);
synchronized (this._surfaceHolder) {
this.onDraw(canvas);
}
}finally{
if(canvas != null){
this._surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
protected void onDraw(Canvas canvas) {
this.renderBackGround(canvas);
for (Renderable renderable : this._sprites) {
renderable.render(canvas);
}
};
public void start(){
this.spriteThread.switchOn();
}
public void stop(){
boolean retry = true;
this.spriteThread.switchOff();
while (retry) {
try {
this.spriteThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
public int getLeft() {
return 0;
}
public int getRight() {
return this.theBackgroundImage.getWidth();
}
public void initialize(Context context, SurfaceHolder surfaceHolder) {
this.spriteThread = new SpriteThread(this);
this._surfaceHolder = surfaceHolder;
this._sprites = new ArrayList<Renderable>();
this._context = context;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
this.theBackgroundImage = oneBackImage;
this.addSprites();
}
private void addSprites() {
Point startPoint = new Point(100, 100);
this._sprites.add(new SpriteOne(this._context, this, startPoint, 90));
Point startPoint1 = new Point(100, 300);
this._sprites.add(new SpriteOne(this._context, this, startPoint1, 50));
Point startPoint2 = new Point(200, 200);
this._sprites.add(new SpriteOne(this._context, this, startPoint2, 15));
}
private void renderBackGround(Canvas canvas)
{
canvas.drawBitmap(this.theBackgroundImage, 0, 0, null);
}
}
As I stated before any help would be appreciated.
Thanks again in advance
Sam
Edit SOLVED Here is an answer I came up with, The rescale code is where the comments are
Hope this helps someone out.
public class TheTemplate {
private SpriteThread spriteThread;
private SurfaceHolder _surfaceHolder;
private ArrayList<Renderable> _sprites;
public Bitmap _backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.sky);;
private Context _context;
// add rescale stuff
//private SpriteAnimationActivityEngine theTest;
private Bitmap theBackgroundImage;
private float totalHeight = _backgroundImage.getHeight();
private int screenSized = initFrameParams();
private float theScaler = (float) (screenSized / totalHeight);
private Bitmap oneBackImage = Bitmap.createScaledBitmap(_backgroundImage, (int) (theScaler * _backgroundImage.getWidth()), (int) (theScaler * _backgroundImage.getHeight()), true);
int initFrameParams()
{
DisplayMetrics metrics = new DisplayMetrics();
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
display.getMetrics(metrics);
int screenHeight = display.getHeight();
return screenHeight;
}
public void render(){
Canvas canvas = null;
try{
canvas = this._surfaceHolder.lockCanvas(null);
synchronized (this._surfaceHolder) {
this.onDraw(canvas);
}
}finally{
if(canvas != null){
this._surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
protected void onDraw(Canvas canvas) {
this.renderBackGround(canvas);
for (Renderable renderable : this._sprites) {
renderable.render(canvas);
}
};
public void start(){
this.spriteThread.switchOn();
}
public void stop(){
boolean retry = true;
this.spriteThread.switchOff();
while (retry) {
try {
this.spriteThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
public int getLeft() {
return 0;
}
public int getRight() {
return this.theBackgroundImage.getWidth();
}
public void initialize(Context context, SurfaceHolder surfaceHolder) {
this.spriteThread = new SpriteThread(this);
this._surfaceHolder = surfaceHolder;
this._sprites = new ArrayList<Renderable>();
this._context = context;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
this.theBackgroundImage = oneBackImage;
this.addSprites();
}
private void addSprites() {
Point startPoint = new Point(100, 100);
this._sprites.add(new SpriteOne(this._context, this, startPoint, 90));
Point startPoint1 = new Point(100, 300);
this._sprites.add(new SpriteOne(this._context, this, startPoint1, 50));
Point startPoint2 = new Point(200, 200);
this._sprites.add(new SpriteOne(this._context, this, startPoint2, 15));
}
private void renderBackGround(Canvas canvas)
{
canvas.drawBitmap(this.theBackgroundImage, 0, 0, null);
}
}
I added the answer to the original post, hope this helps someone.
Sam
Sorry about that folks, new to this method of using a forum
Here is the answer, I added comments in the code where I made the changes for scaling images.
This method can also be used for positioning also.
Here is the answer.
public class TheTemplate {
private SpriteThread spriteThread;
private SurfaceHolder _surfaceHolder;
private ArrayList<Renderable> _sprites;
public Bitmap _backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.sky);;
private Context _context;
// add rescale stuff
//private SpriteAnimationActivityEngine theTest;
private Bitmap theBackgroundImage;
private float totalHeight = _backgroundImage.getHeight();
private int screenSized = initFrameParams();
private float theScaler = (float) (screenSized / totalHeight);
private Bitmap oneBackImage = Bitmap.createScaledBitmap(_backgroundImage, (int) (theScaler * _backgroundImage.getWidth()), (int) (theScaler * _backgroundImage.getHeight()), true);
int initFrameParams()
{
DisplayMetrics metrics = new DisplayMetrics();
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
display.getMetrics(metrics);
int screenHeight = display.getHeight();
return screenHeight;
}
public void render(){
Canvas canvas = null;
try{
canvas = this._surfaceHolder.lockCanvas(null);
synchronized (this._surfaceHolder) {
this.onDraw(canvas);
}
}finally{
if(canvas != null){
this._surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
protected void onDraw(Canvas canvas) {
this.renderBackGround(canvas);
for (Renderable renderable : this._sprites) {
renderable.render(canvas);
}
};
public void start(){
this.spriteThread.switchOn();
}
public void stop(){
boolean retry = true;
this.spriteThread.switchOff();
while (retry) {
try {
this.spriteThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
public int getLeft() {
return 0;
}
public int getRight() {
return this.theBackgroundImage.getWidth();
}
public void initialize(Context context, SurfaceHolder surfaceHolder) {
this.spriteThread = new SpriteThread(this);
this._surfaceHolder = surfaceHolder;
this._sprites = new ArrayList<Renderable>();
this._context = context;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
this.theBackgroundImage = oneBackImage;
this.addSprites();
}
private void addSprites() {
Point startPoint = new Point(100, 100);
this._sprites.add(new SpriteOne(this._context, this, startPoint, 90));
Point startPoint1 = new Point(100, 300);
this._sprites.add(new SpriteOne(this._context, this, startPoint1, 50));
Point startPoint2 = new Point(200, 200);
this._sprites.add(new SpriteOne(this._context, this, startPoint2, 15));
}
private void renderBackGround(Canvas canvas)
{
canvas.drawBitmap(this.theBackgroundImage, 0, 0, null);
}
}

Categories

Resources