Show and Hide Bitmap In Surfaceview android - android

I am trying to make a simple game where, i want to have 5 bitmaps in surface view and they are shown and hidden randomly .As i have placed all bitmaps, now how to hide and show bitmaps In surface view randomly.
I do not want to have a layer above those bitmap as my background is moving

generate 5 random numbers from 0 - 1
int randomOne = (int) ((Math.random()); //repeat this 4 more times
within your canvas, choose to draw or not draw those bitmaps because of the random number selected
if (randomOne == 1)
{
canvas.drawBitmap((Bitmap)bitmapName,x,y,null);
}
//repeat this 4 more times
if you wish to constantly change whether or not these bitmaps are shown, use a timer

Related

How to render alternating sprites to achieve infinite background in Libgdx?

I am trying to write a program in Libgdx that has a scrolling background.
The way am trying to scroll the background is as follows:
//creating two sprites whose size is the 2*viewportwidth
//this shows half of the sprite on my phone screen
//which I assume that it takes two viewport widths to show the entire sprite
sprite1;
sprite2;
//setting the positions which shows the sprites next to each other
sprite1.setPosition(0f,0f);
sprite2.setPosition(2f*viewportwidth,0);
//on to my render method, I have the following besides the usual:
#Override
public void render(){
//usual stuff here
camera.update
camera.setProjectionMatrix(camera.combined);
batch.begin();
sprite1.draw(batch);
sprite2.draw(batch);
batch.end();
moveCammy();
}
private void moveCammy(){
if(System.currentTimeMillis()-time>1000){
moviX=moviX+0.1*camera.viewportWidth;//moviX is a float
camera.translate(moviX,0f);
time= System.currentTimeMillis();
if(System.currentTimeMillis()-time2>22000){
sprite1.setX(4f*camera.viewportWidth)//since each phone screen width
//represents half of each sprite. It takes two phone screens to show
//one sprite. Since, originally there were two sprites it takes 4 phone
//screens to show them side by side.However, third sprite doesn't appear
//right after the second sprite. I think it should since it's 4 phone
// screens away. I assume the translation of the camera is around the second
//sprite after about 220000 milliseconds.
time2= System.currentTimeMillis();}
}
Everything works in the program, except that the third sprite doesn't appear
at all. My goal is to keep alternating sprite1 and sprite2 infinitely to achieve
an infinite background.
Please advise as to what might be wrong.

Fast tap on TextView clearing random portion of my Custom View

I am using one 40 miliseconds timer and am plotting graph with this speed. (In each 40 milisecsnds of onDraw() call , it is plotting 5 points).
but on the layout same time when I am taping on one TextView, it is clearing random portion of Custom View.
So my question Is
Is it related with cache Drawing. ?
I tried with setDrawingcacheEnabled(true); but this also is not working.
Any idea ?
This is my onDraw()
#Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
//setDrawingCacheEnabled(true);
//canvas.drawBitmap(bBitMap,0,0,null);
drawStuff(canvas);
}
My cache memory Size is 256k and my screen resulotion is 800x480

Dynamically create / draw images to put in android view

I'm not sure I'm doing this the "right" way, so I'm open to other options as well. Here's what I'm trying to accomplish:
I want a view which contains a graph. The graph should be dynamically created by the app itself. The graph should be zoom-able, and will probably start out larger than the screen (800x600 or so)
I'm planning on starting out simple, just a scatter plot. Eventually, I want a scatter plot with a fit line and error bars with axis that stay on the screen while the graph is zoomed ... so that probably means three images overlaid with zoom functions tied together.
I've already built a view that can take a drawable, can use focused pinch-zoom and drag, can auto-scale images, can switch images dynamically, and takes images larger than the screen. Tying the images together shouldn't be an issue.
I can't, however, figure out how to dynamically draw simple images.
For instance: Do I get a BitMap object and draw on it pixel by pixel? I wanted to work with some of the ShapeDrawables, but it seems they can only draw a shape onto a canvas ... how then do I get a bitmap of all those shapes into my view? Or alternately, do I have to dynamically redraw /all/ of the image I want to portray in the "onDraw" routine of my view every time it moves or zooms?
I think the "perfect" solution would be to use the ShapeDrawable (or something like it to draw lines and label them) to draw the axis with the onDraw method of the view ... keep them current and at the right level ... then overlay a pre-produced image of the data points / fit curve / etc that can be zoomed and moved. That should be possible with white set to an alpha on the graph image.
PS: The graph image shouldn't actually /change/ while on the view. It's just zooming and being dragged. The axis will probably actually change with movement. So pre-producing the graph before (or immediately upon) entering the view would be optimal. But I've also noticed that scaling works really well with vector images ... which also sounds appropriate (rather than a bitmap?).
So I'm looking for some general guidance. Tried reading up on the BitMap, ShapeDrawable, Drawable, etc classes and just can't seem to find the right fit. That makes me think I'm barking up the wrong tree and someone with some more experience can point me in the right direction. Hopefully I didn't waste my time building the zoom-able view I put together yesterday :).
First off, it is never a waste of time writing code if you learned something from it. :-)
There is unfortunately still no support for drawing vector images in Android. So bitmap is what you get.
I think the bit you are missing is that you can create a Canvas any time you want to draw on a bitmap. You don't have to wait for onDraw to give you one.
So at some point (from onCreate, when data changes etc), create your own Bitmap of whatever size you want.
Here is some psuedo code (not tested)
Bitmap mGraph;
void init() {
// look at Bitmap.Config to determine config type
mGraph = new Bitmap(width, height, config);
Canvas c = new Canvas(mybits);
// use Canvas draw routines to draw your graph
}
// Then in onDraw you can draw to the on screen Canvas from your bitmap.
protected void onDraw(Canvas canvas) {
Rect dstRect = new Rect(0,0,viewWidth, viewHeight);
Rect sourceRect = new Rect();
// do something creative here to pick the source rect from your graph bitmap
// based on zoom and pan
sourceRect.set(10,10,100,100);
// draw to the screen
canvas.drawBitmap(mGraph, sourceRect, dstRect, graphPaint);
}
Hope that helps a bit.

Live wallpaper canvas flickers when it includes a bitmap

For my live wallpaper I use the following code (called by a Runnable) to draw each frame. Each time it is called, I fill the current canvas with a solid color and draw a background bitmap (bg_image has been resized to perfectly fit the screen). I then call drawParticles(c), which simply uses c.drawCircle(...) a bunch of times drawing particles all over the canvas.
In the live wallpaper preview mode, this code works great. However, when I actually set this as my live wallpaper it flickers and seems to not clear the canvas before drawing. Let me 'splain:
Frame 1: The bitmap is drawn and circles are overlaid.
Frame 2: The bitmap is drawn and circles are overlaid (based on my rough understanding, there are two canvases that are drawn on and posted alternately for efficiency).
Frame 3: The canvas is not being cleared! This frame includes the new positions of each drawn circle as well as the circles from Frame 1!.
Frame 4: Includes the new positions of each drawn circle as well as the circles from Frame 2!
The end effect is that the circles leave "trails" all over the screen that flicker between (I believe) the two alternating canvases. Why, based on my code below, isn't my canvas being cleared each frame? Again, this works fine during preview mode but not when it is actually set as my live wallpaper. It's also worth noting that this flickering problem only occurs if I am drawing a bitmap; if the background is just a solid color, this problem never arises.
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
c.drawColor(Color.BLACK);
c.drawBitmap(bg_image, 0, 0, null);
fluid.drawParticles(c);
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mDrawRunnable);
mHandler.postDelayed(mDrawRunnable, 1000/targetFramerate -(System.currentTimeMillis() - mLastTime));
}
My guess is that your animation is too complex to keep up with your frame rate. If you slow the frame rate way down, do you still have the problem? Also, if you are drawing an opaque background bitmap at each frame, you do not need to paint the screen black first--that just wastes time, and limits your maximum frame rate.
I'm guessing that the problem does not happen in preview mode because more of the phone's resources are focused on you, whereas once the wallpaper is set, more stuff is going on in the background.

Animating and rotating an image in a Surface View

I would like to animate movement on a SurfaceView . Ideally I would like to also be notified once the animation had finished.
For example:
I might have a car facing North. If I wanted to animate it so that it faces South for a duration of 500ms, how could I do that?
I am using a SurfaceView so all animation must be handled manually, I don't think I can use XML or the android Animator classes.
Also, I would like to know the best way to animate something continuously inside a SurfaceView (ie. a walk cycle)
Rotating images manually can be a bit of a pain, but here's how I've done it.
private void animateRotation(int degrees, float durationOfAnimation){
long startTime = SystemClock.elapsedRealtime();
long currentTime;
float elapsedRatio = 0;
Bitmap bufferBitmap = carBitmap;
Matrix matrix = new Matrix();
while (elapsedRatio < 1){
matrix.setRotate(elapsedRatio * degrees);
carBitmap = Bitmap.createBitmap(bufferBitmap, 0, 0, width, height, matrix, true);
//draw your canvas here using whatever method you've defined
currentTime = SystemClock.elapsedRealtime();
elapsedRatio = (currentTime - startTime) / durationOfAnimation;
}
// As elapsed ratio will never exactly equal 1, you have to manually draw the last frame
matrix = new Matrix();
matrix.setRotate(degrees);
carBitmap = Bitmap.createBitmap(bufferBitmap, 0, 0, width, height, matrix, true);
// draw the canvas again here as before
// And you can now set whatever other notification or action you wanted to do at the end of your animation
}
This will rotate your carBitmap to whatever angle you specify in the time specified + the time to draw the last frame. However, there is a catch. This rotates your carBitmap without adjusting its position on screen properly. Depending on how you're drawing your bitmaps, you could end up with your carBitmap rotating while the top-left corner of the bitmap stays in place. As the car rotates, the bitmap will stretch and adjust to fit the new car size, filling the gaps around it with transparent pixels. It's hard to describe how this would look, so here's an example rotating a square:
The grey area represents the full size of the bitmap, and is filled with transparent pixels. To solve this problem, you need to use trigonometry. It's a bit complicated... if this ends up being a problem for you (I don't know how you're drawing your bitmaps to the canvas so it might not be), and you can't work out the solution, let me know and I'll post up how I did it.
(I don't know if this is the most efficient way of doing it, but it works smoothly for me as long as the bitmap is less than 300x300 or so. Perhaps if someone knows of a better way, they could tell us!)
Do you want multiple independent animated object? If so, then you should use a game loop. (One master while loop that incrementally updates all game objects.) Here's a good discussion on various loop implementations. (I'm currently using "FPS dependent on Constant Game Speed" for my Android game project.)
So then your Car will look something like this (lots of code missing):
class Car {
final Matrix transform = new Matrix();
final Bitmap image;
Car(Bitmap sprite) {
image = sprite; // Created by BitmapFactory.decodeResource in SurfaceView
}
void update() {
this.transform.preRotate(turnDegrees, width, height);
}
void display(Canvas canvas) {
canvas.drawBitmap(this.image, this.transform, null);
}
}
You only need to load your bitmap once. So if you have multiple Cars, you may want to give them each the same Bitmap object (cache the Bitmap in your SurfaceView).
I haven't got into walk animations yet, but the simplest solution is to have multiple Bitmaps and just draw a different bitmap each time display is called.
Have a look at lunarlander.LunarView in the Android docs if you haven't already.
If you want to be notified when the animation is complete, you should make a callback.
interface CompletedTurnCallback {
void turnCompleted(Car turningCar);
}
Have your logic class implement the callback and have your Car call it when the turn's complete (in update()). Note that you'll get a ConcurrentModificationException if you are iterating over a list of Cars in update_game() and you try to remove a Car from that list in your callback. (You can solve this with a command queue.)

Categories

Resources