I made a flappy bird clone and the pipes are going forward to the bird, but the text comes with the pipes. I want to lock the text in the middle of the screen.
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(bg, cam.position.x - (cam.viewportWidth / 2), 0);
sb.draw(bird.getTexture(), bird.getPosition().x, bird.getPosition().y);
for (Tube tube : tubes) {
sb.draw(tube.getTopTube(), tube.getPosTopTube().x, tube.getPosTopTube().y);
sb.draw(tube.getBottomTube(), tube.getPosBotTube().x, tube.getPosBotTube().y);
}
sb.draw(ground, groundPos1.x, groundPos1.y);
sb.draw(ground, groundPos2.x, groundPos2.y);
sb.end();
}
I usually use a Scene2D Stage with a static Viewport to display a hud or gui as a overlay on top of the actual game.
In most cases a HUD or GUI should be fixed to the actual screen and should not move therefor to have a movable camera in your game world you have to separate these elements entirely. What is happening in your case is that your current camera is drawing all elements and when it moves position the elements of your GUI will be drawn at a different position on your screen, like your "pipes" do.
If you are just drawing your text using the same batch an easy fix would be to just setup a new camera for this and when you are done drawing your game just input it's combined matrix to the projection matrix of the SpriteBatch, after you end it.
spriteBatch.setProjectionMatrix(movingCam.combined);
spriteBatch.begin();
//... draw stuff that belongs to your game world
spriteBatch.end();
spriteBatch.setProjectionMatrix(staticCam.combined);
spriteBatch.begin();
//... draw stuff that belongs to your GUI
spriteBatch.end();
Anyway, I would still recommend using Scene2D for the purpose of a GUI since it has everything you would need like buttons, tables, labels, etc.
Are you moving the camera to follow the bird? Just use an extra camera for your UI and/or static texts like score counters. And draw them after drawing game objects (on top of them).
See this question and submitted answer.
Related
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.
I am making a learning game for teaching numbers to kindergarten kids. It requires some animation like this but I am failing in achieving this animation smoothly in canvas.
I want exactly the same animation appearing using this dotted line.
Please guide me to perform exactly this type of animation.
What you need is:
a loop
path definition
The loop should update current image position and rotation. Then draw the updated animation on a screen. You can just override dispatchDraw method and call invalidate at the very end of it. You can update position right before drawing. Your case is similar to game programming, so you can look for articles about game loops.
Path definition should allow you to calculate position depending on time. Fo example you can use Bezier curves. Bezier curve equation is parametric and the parameter is 'time'. Using the animation time gives you smooth movement along the path.
Example of a generic game loop: http://www.gameprogblog.com/generic-game-loop/
Bezier curve: http://en.wikipedia.org/wiki/B%C3%A9zier_curve
long time = System.currentTimeMillis();
protected void dispatchDraw(Canvas canvas) {
PointF pos = getBezierPos(System.currentTimeMillis() - time);
drawImage(pos);
invalidate();
}
i am working on isometric tiled map game.here in introduction i want to show complete game field .so i used
this.mCamera = new ZoomCamera(CAMERA_WIDTH, CAMERA_HEIGHT, CAMERA_WIDTH, CAMERA_HEIGHT) {
#Override
public void onApplySceneBackgroundMatrix(final GLState pGLState) {
final float widthRaw = this.getWidthRaw();
final float heightRaw = this.getHeightRaw();
pGLState.orthoProjectionGLMatrixf(0, widthRaw, heightRaw, 0, getZNear(), getZFar());
}
#Override
public void onUpdate(float pSecondsElapsed) {
if (timeCounter >= 1) {
mCamera.setRotation(i);
timeCounter = 0;
i=i+1;
}
timeCounter += pSecondsElapsed;
super.onUpdate(pSecondsElapsed);
}
};
but its rotating 2d view .i want to rotate in 3d perspective .how can i rotate camera in 3d perspective in andenigne GLES2.0.
please suggest me
You cannot rotate your camera in 3D. The appearance of 3D is caused by the fact that the artwork is drawn in perspective. Rotating the artwork does not cause the artwork to change the way its drawn any more than rotating a piece of paper with a drawing on it would cause a 3D transformation. To rotate in 3D you need to be using a 3D engine.
Several times I stumbled upon this tutorial in the AndEngine Forum, where it states that it is possible to rotate the Camera in a way to show distant objects further away (smaller). It is made for the AndEngine GLES1 but it should be possible to adapt it to GLES2.
AndEngine knows a z-axis. The position on that axis is set automatically based on the order in which you attach the Sprites to the Scene. However, you should set it manually. In most cases it will be sufficient to set the z-axis according to the y-position (z-axis = y-axis) every time a Sprite changes its position.
public class YourSprite extends Sprite{
...
#Override
setPosition(float x, float y){
super.setPosition(x,y);
this.setZIndex(y);
}
}
If you then manage to implement the camera rotation as described in the tutorial, together with the z-axis you should have a pretty realistic 3D effect.
However, I never tried that tutorial, because most games that use the Bird's-eye view (as the game from the youtube link you provided) don't need a real vanishing point, since the display is most likely so small, so the player wouldn't notice anyway. So I stick to changing the position on the z-axis. But I would certainly like to know more if anyone manages to rotate the camera!
I'm developing a Android board game and have a question regarding creating a board that is zoomable and scrollable. The board contains a static background, characters (players) and the actual "level" which is drawn using tiles.
My solutions is to have a collection of elements (tiles, figures, all game elements - all have x,y coordinates and width + height), a camera and a renderer that draws the collection according to cameraX,cameraY, cameraWidth and cameraHeight. So if a user would scroll to the right, the camera would just set the cameraX appropriately - and the surface is scrollable. And if a user would zoom in/out the renderer would just scale every element image appropriately.
Example code for the renderer with scrollable surface and zoom in/out
protected function draw(Canvas c){
Collection elements = collection.getElements(cameraX,cameraY,cameraWidth,cameraHeight);
if(elements.size() > 0) {
for(int i = 0; i < elements.size(); i++) {
elements.get(i).drawElement(c);
}
}
}
.
.
.
// element class drawElement function
protected drawElement function(Canvas c) {
if(this.image != null) {
int w = this.width;
int h = this.height;
if(this.zoomFactor < 1) {
w*=this.zoomFactor;
h*=this.zoomFactor;
}
c.drawBitmap(this.image,this.x,this.y,w,h);
}
}
Is this the best solutions?
Could it be achived somehow else?
Could scrolling be achived using a ScrollView?
I dont wanna use any engine, because this is for a school project.
Actually you can simplify this situation somewhat. If you are indeed seeking a flat texture plane that is simply distorted by perspective, the Android Camera class can help you. Do not confuse this with the hardware camera for taking photos. This camera is a helper class wrapped around a matrix to perform transformations on 2D objects. You can read more about this very complex rendering topic by googling "fast fourier transforms". Basically you will want to create a canvas and do your drawing in a completely 2D way. Then right before you draw to the screen, you should transform this canvas using the Camera class. Let me know if you need some clarification. There is a lot of cool mathematics going on behind the scenes!
Take a look at this sample from the Android API Demos
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.html
Android graphics.Camera documentation
http://developer.android.com/reference/android/graphics/Camera.html
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.