Image rectangles and screen sizes - android

i am having a problem with canvas, rectangles and screen sizes:
I do not know whats wrong, because i am using the exact same code in both emulators, here is the code:
clouds is a plain object that contains the image and some methods to move them, this is how i create the clouds:
The clouds are all in one file, the coordinates are the rectangles where the single clouds are.
for (byte i = 0; i < 4; i++) {
Cloud c;
if (i == 1) c = new Cloud(5, 5, 245, 145);
else if (i == 2) c = new Cloud(340, 30, 480, 130);
else if (i == 3) c = new Cloud(565, 30, 725, 130);
else c = new Cloud(830, 20, 980, 130);
c.SetX(0);c.SetY(i * 150);
//c.ReubicarNube();
Clouds.Add(c);
}
The constructor of Cloud class call this to handle the images (Plain is the super class of cloud):
public Plain(int ResourceImg, int left, int top, int right, int bottom){
this.img = BitmapFactory.decodeResource(Init.GetContext().getResources(), ResourceImg);
this.Width = right - left;
this.Height = bottom - top;
this.frameImg = new Rect(left, top, right, bottom);
this.rect = new Rect(0, 0, this.Width, this.Height);
Log.v("Plains", this.frameImg.toString() + " " + this.rect.toString());
}
and this is how I draw:
public void draw(Canvas canvas) {
canvas.drawBitmap(img, frameImg, rect, Init.PaintFilter);
//canvas.drawbi
}
Thanks in advance for the help!

I did it!,
I fogot to put the image in the drawable-hdpi folder!, thats why i wasn't working!!
Thanks!

Related

Transformation of a bitmap- Android

I'm having a bit of a problem with a (very basic and crude) implementation of Parallax. Basically I have an image which is supposed to move across the screen at a slightly different rate to the background. It does this- until it reaches the end of the image. It seems to loop back to the start of the image-- but when it reaches the end of the image, it seems to stretch the bitmap out across the length of the screen until it's stretched out completely- then it resets itself.
I can't attach a screenshot (not enough rep) but here's the code.
Init method:
private void init(Context context) {
screenSize = new Point();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getSize(screenSize);
backGroundViewPort = new Rect();
cityscapeRect = new Rect();
backGroundViewPort.set(0, 0, 400, 300);
GGRAssetManager ggrAssetManager = new GGRAssetManager(context);
background = ggrAssetManager.loadImage("background.jpg");
cityscape = ggrAssetManager.loadImage("cityscape3.png");
clouds = ggrAssetManager.loadImage("clouds.png");
backGroundViewPort.set(0, 0, 400, 300);
}
DoUpdate method:
public void doUpdate() {
Game.getInstance().viewport.set(Math.max(0, (int) (game.getPlayer().getxPos() - screenSize.x / 2)),
0,
(int) (game.getPlayer().getxPos() + (screenSize.x / 2)),
screenSize.y);
if (backGroundViewPort.right + 1 >= background.getWidth()) {
backGroundViewPort.left = 0;
backGroundViewPort.right = 400;
} else {
backGroundViewPort.right += 1;
backGroundViewPort.left += 1;
}
if (cityscapeRect.right + 1 >= cityscape.getWidth()) {
cityscapeRect.left = cityscape.getWidth() - screenSize.x;
cityscapeRect.right = 0;
} else {
cityscapeRect.right += 1;
cityscapeRect.left += 1;
}
}
DoDraw method:
public void doDraw(Canvas canvas) {
//PARALLAX
backGroundRect.set(0, 0, screenSize.x, screenSize.y);
canvas.drawBitmap(background, backGroundViewPort, backGroundRect, null);
cityscapeRect.set(0, screenSize.y/2, (screenSize.x), screenSize.y);
Paint paint = new Paint();
paint.setAlpha(150);
canvas.drawBitmap(cityscape, backGroundViewPort, cityscapeRect, paint);
}
I'm sure it's to do with the rectangles, but I don't know how to fix it. Help is greatly appreciated.

Collision ImageViews not working

I'm trying to generate random ImageViews on a Layout without the ImageViews intersecting each other. I'm generating a random point within the screen dimensions like this:
private Point generateRandomLocation(Point dimensions) {
Random random = new Random();
// generate random x
int x = random.nextInt((dimensions.x - 0) + 1);
// generate random y
int y = random.nextInt((dimensions.y - 0) + 1);
Point location = new Point(x, y);
if(!collision(location)) {
return new Point(x, y);
} else {
return generateRandomLocation(dimensions);
}
}
The collision method contains the following method to determine wether the ImageViews collide or not. BubbleImage is a simple extension of ImageView.
private boolean collision(Point location) {
// takes 100 as inital width & height
int x_1 = location.x;
int y_1 = location.y;
int x_2;
int y_2;
boolean collided = false;
// get all bubbleimages
for (int i = 0; i < mainLayout.getChildCount(); i++) {
View childView = mainLayout.getChildAt(i);
if (childView instanceof BubbleImage) {
x_2 = (int) childView.getX();
y_2 = (int) childView.getY();
// create rectangles
Rect rect1 = new Rect(x_1, y_1, x_1 + 100, y_1 - 100);
Rect rect2 = new Rect(x_2, y_2, x_2 + 100, y_2 - 100);
collided = Rect.intersects(rect1, rect2);
}
}
return collided;
}
Anyone spotting the faulty logic here?
Edit: Rect.intersects() seems to be returning false, even when the imageviews are intersecting.
When creating new Rects rect1 & rect2, the constructor is Rect(left, top, right, bottom). E.g. Rect(10, 10, 20, 20), because android screen origin is in the top left corner.
You have created the Rects in a wrong way, as Rect(left, bottom, right, top). Try switching the 2nd and 4th parameters in the constructor calls, or increase the 4th parameter to be bigger than 2nd.
Like this:
Rect rect1 = new Rect(x_1, y_1, x_1 + 100, y_1 + 100);

Animate (Zoom and Translate) a part of image on android canvas view

I have an image e.g. the image shown below:
This image has two parts part 1 of size width W and height L and part 2 (smaller part) of width w and height h (call part one as source and part 2 as destination). Let the coordinates of the 1st rectangle be (measured from top left corner): top:100 left: 10 right: 200 bottom: 300 and the coordinates of the 2nd rectangle be (as measured from top left corner): top 50 left: 500 bottom: 100 right: 700
I want to animate from source to destination such that the image translates and zooms in from source to destination.
So my first screen would look like:
and my second image would look like:
How do I tween between these two ?
My code (without animation) looks like as follows:
public class SuperGame extends View implements OnGestureListener
{
int sreenHeight, screenWidth;
int drawCount = 0;
Bitmap bg;
public SuperGame(Context context, Bitmap bmp)
{
this.screenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
this.screenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
bg = BitmapFactory.decodeResource(getResources(),R.drawable.bg_img);
}
#Override
/* this function triggers the image change
*/
public boolean onDown(MotionEvent e) {
invalidate(0,0,screenWidth, screenHeight);
return true;
}
#Override
public void onDraw(Canvas canvas)
{
Rect dest = new Rect(0,0,screenWidth, screenHeight);
if (count==0) //draw the first image part
{
count=1;
Rect src = new Rect(100,10,200,300);//coordinates of rectangle 1
canvas.drawBitmap(bg, src, dest, new Paint());
}
else //draw the second image part - (I'd like to show movement/ transition between these)
{
Rect src = new Rect(50,500,100,700);//coordinates of rectangle 2
count=0;
canvas.drawBitmap(bg, src, dest, new Paint());
}
}
}
How to I animate the transition (which involves zoomin as well as translation)?
You might need to create a custom valueAnimator of type Rect/RectF.
Code example given below:
public class RectFEvaluator
implements TypeEvaluator<RectF>
{
#Override
public RectF evaluate(float fraction, RectF srcRect, RectF destRect) {
RectF betweenRect = new RectF();
betweenRect.bottom = srcRect.bottom + fraction*(destRect.bottom-srcRect.bottom);
betweenRect.top = srcRect.top + fraction*(destRect.top-srcRect.top);
betweenRect.left = srcRect.left + fraction*(destRect.left-srcRect.left);
betweenRect.right = srcRect.right + fraction*(destRect.right-srcRect.right);
return betweenRect;
}
}
The value animator will give you the intermediate values between src Rect and dest Rect.
Once you have these values, updated them using an animation

When I try to create animated objects from sprite on Android, they start to be slow

I use followed example (described here) to animate my sprite sheet.
from example I wrote my Object:
public class Sprite {
private int x, y;
private int width, height;
private Bitmap b;
MainGamePanel ov;
int currentFrame = 0;
public Sprite(MainGamePanel mainGamePanel, Bitmap blob) {
this.ov = mainGamePanel;
this.b = blob;
// 1x12
height = b.getHeight();
width = b.getWidth()/12;
x = y = 50;
}
private void update(int dist) {
currentFrame = ++currentFrame % 12;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//return _b;
}
public void draw(int shift, Canvas canvas, int dist) {
update(dist);
int srcX = currentFrame * width;
Rect src = new Rect(srcX, 0, srcX+width, height);
Rect dst = new Rect(x, y+shift, x+width, y+height+shift);
canvas.drawBitmap(b, src, dst, null);
}
Here every 100 msec I take different part from image (Bitmap) and show it.
1 -> 2 -> 3 -> 4 -> ... -> 12
So my creature flies and moves with wings.
If I show only 1 object, it seems good but when I try to run 20 creatures in loop:
Bitmap blob = BitmapFactory.decodeResource(getResources(), R.drawable.sprite3);
for(int i=0; i<20; i++){
spriteList.add(new Sprite(this, blob));
}
....
for(int i=0; i<spriteList.size(); i++){
sprite = spriteList.get(0);
sprite.draw(canvas, dist);
}
My objects start to be slow according to drawn object count.
It happens I think because of Thread.sleep(100);.
I don't see any performance problem.
Sounds like each object sleep pauses all objects.
For 20 objects this sleep grows to 2 sec.
For sure I use workaround like:
int sleep = 100/spriteList.size();
Thread.sleep(sleep);
But code looks messy.
Can anyone help me how to fix it?
Here is sprite3 image:
[EDIT]
Maybe I need create each object in separate Thread?
You should definitely not sleep while rendering; it greatly reduces the performance, especially, as you add new Animation Clips, etc. Also, don't create objects within your onDraw method and do try to reuse the Rect objects. Creating objects during rendering is very expensive.

How shift graph in Android's Canvas

I draw a graph with canvas in android, but I want to shift it to left or right side. I don't want to scroll it, I just want to shift it in one page by which you can see the graph is shifting lively.
I would be appreciated if any body help me.
I am looking for a an answer to this question as well. I have a solution but it is to slow and uses a lot of CPU time. I am drawing two graphs with a width of 200 pixels and have the values stored in an array. I just shift the values in the array and moves them into a path.
I would be nice to have a solution where the canvas gets shifted by 1 pixel to the left and the 200th column gets drawn with the new value. With both paths are empty it takes about 2ms (Droid Incredible) to draw the paths. When the 2 paths are filled up it can take more than 40ms. This would give still 25fps but I would like to run other threads at the same time and don't want to waste CPU time.
Here is the source.
public class OSCI extends View
{
Integer[] codebuffer = new Integer[200];
Integer[] codebuffer1 = new Integer[200];
private static final String TAG = "MyActivity";
long start;
int code=0;
// private static final String TAG = "MyActivity";
public OSCI(Context context)
{
super(context);
Arrays.fill(codebuffer, 1);
Arrays.fill(codebuffer1, 1);
}
public OSCI(Context context, AttributeSet attrs)
{
super(context, attrs);;
Arrays.fill(codebuffer, 1);
Arrays.fill(codebuffer1, 1);
}
#Override
protected void onDraw(Canvas canvas)
{
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.YELLOW);
Path path = new Path();
path.moveTo(0, 70);
Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeWidth(2);
paint1.setColor(Color.GREEN);
Path path1 = new Path();
path1.moveTo(0, 70);
int max = Collections.max(Arrays.asList(codebuffer));
if(max==0)max=1;
for (int a = 0; a < codebuffer.length; a++)
{
if (codebuffer[a] < 0)code=0;
code = 70 * codebuffer[a] / max;
path.lineTo(a * 2 + 2, 70 - code);
path1.lineTo(a * 2+ 2, 70 - (codebuffer1[a]));
}
start=(SystemClock.elapsedRealtime());
canvas.drawPath(path1, paint);
canvas.drawPath(path, paint1);
Log.v(TAG, " "+(SystemClock.elapsedRealtime()-start));
}
public void newValue(int value, int valuew)
{
System.arraycopy(codebuffer, 1, codebuffer, 0, 199);
codebuffer[199] = value;
System.arraycopy(codebuffer1, 1, codebuffer1, 0, 199);
codebuffer1[199] = valuew;
invalidate();
}
}

Categories

Resources