My game has an end of level screen, on which I wish to display an animated player score. If you have seen the one in Angry birds and many other games, the score text starts at "000000" and increments rapidly until it reachs the actual score the player achieved. I have tried to write this with a while loop, and a for loop but it just doesn't work properly - I am obvioulsy still misunderstanding how the update method works. Here is my render() method of my End of Level screen:
#Override
public void render (float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
timeElapsed = delta;
while(this.iCounter < this.score) {
font.draw(batch, "Score: " + this.iCounter, screenWidth / 2, screenHeight / 2);
if(timeElapsed > 1.0f) {
iCounter = iCounter + 10;
}
timeElapsed = 0.0f;
}
batch.end();
}
The above just seems to crash the screen.
I just want the score to start at zero and then every half a second for example increase the score until it reaches the actual score.
Has anyone got any ideas on how to do this properly as I just can't seem to get this working.
You are calling font.draw() multiple times inside the render. The result would be multiple scores, drawn over ach other.
Note, that render is called once per frame and you want to animate the score over n Frames.
So your variable iCounter should be a class variable, and you increment and draw it once inside the render method. Yoou may also want to store a constant scorePerSecond, which defines how much the iCounter increments per second.
So the result should look like this:
public static final int SCORE_PER_SECOND = 100;
private int iCounter;
public void render (float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
iCounter = Math.min((int)(iCounter+SCORE_PER_SECOND*delta), score)
font.draw(batch, "Score: " + this.iCounter, screenWidth / 2, screenHeight / 2);
batch.end();
}
The render method is called every frame and all the drawing you put in there should just be for a single frame. What it's doing is trying to run your entire look in a single frame, and hence looking like it's crashed.
What you need to do is get rid of the loop and just add an amount to iCounter each frame (i.e. each time render() is called).
Here's your coded edited into a very simple implementation to show what I mean...
#Override
public void render (float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
font.draw(batch, "Score: " + this.iCounter, screenWidth / 2, screenHeight / 2);
if (this.iCounter < this.score) {
this.iCounter++;
}
batch.end();
}
This will increment the score every single frame, which I think is probably what you want. Eitehr way it should provide a good starting point.
Thanks to everyone above who helped me. This is how I got it working in the end.
time += delta;
if (time >= this.SCORE_DELAY) {
if (iCounter < this.score) {
iCounter = iCounter + 10;
}
time -= this.SCORE_DELAY;
}
SCORE_DELAY is declared as a float and I have got the setting at 0.15f which seems to be a good rate.
private static float SCORE_DELAY = 0.15f;
Related
I am making a game in which i am making arcs using ShapeRenderer, As i needed to rotate those arcs around the center so i wrote that code only begin and end in render method, I am initializing them in create method,
But as the number of arcs increases the game gets slower and slower. I have maximum of 13 arcs and minimum 2 arcs.
It running fine till few say 8 arcs and after that it gets slower.
Please any one out there if he/she can help, please help...
thanks in advance.
Render Method is having 5 loops, I don't have any choice to get rid of them.
this is in create:
for (int i = 0; i < 13; i++) {
random = randomGenerator.nextInt(5);
a[i] = new Arc(arcColors[random]);
arcs_visible[i] = 1;
pointercolor[i] = a[i].getArcColor();
a[i].begin(ShapeRenderer.ShapeType.Line);
}
this is in render:
private void draw_one_arc(int i, double radius, float startangle, float sweep) {
if (arcs_visible[i] == 1 && collides[i] == false) {
a[i].arc(pointerorigin.x + pointer.getWidth() / 2, pointerorigin.y + pointer.getWidth() / 2, (float) radius, startangle, sweep, 100);
}
}
`
What I want to do is to create a new planet in my system for example every 10 seconds and that it starts to move and also prints a "hello" . At the end I want that the 8 planets (ellipses) will be moving together.
I try to use delay(); but I failed .
Can someone help me please?
Planet [] planetCollection = new Planet [8];
float [] wid2 = {100,200,300,400,500,600,700,800};
float [] hig2 = {50,75,100,125,150,175,200,225};
int [] colorR = {100,800,300,400,500,600,700,800};
int [] colorG = {50,225,100,125,150,175,200,225};
int [] colorB = {50,225,100,125,150,175,200,225};
int [] size = {10,12,14,16,18,20,22,24};
int lastTime =0;
int contador =0;
void setup (){
size (1600,1600);
smooth();
//INITIALIZE
for (int i=0 ; i<planetCollection.length; i++){
planetCollection [i] = new Planet(wid2[i], hig2[i], colorR[i],
colorG[i], colorB[i], size[i]);
}
}
void draw (){
background (0);
//CALL FUNCIONALITY
for (int i=0 ; i<planetCollection.length; i++){
planetCollection [i].run();
}
}
class Planet {
//GLOBAL VARIABLES
float val;
float x = 0;
float y = 0;
float wid2;
float hig2;
float speed;
int colorR;
int colorG;
int colorB;
int size;
int centerx = width/2;
int centery = height/4;
//CONTRUCTOR
Planet(float _w, float _h,int _colorR,int _colorG,int _colorB, int _size){
wid2=_w;
hig2=_h;
colorR= _colorR;
colorG= _colorG;
colorB= _colorB;
size = _size;
speed=10/(2*PI * sqrt ((pow(wid2,2)+pow (hig2,2)/2))); ;
}
//FUNCTIONS
void run (){
move();
display();
}
void move (){
x= sin (val);
y= cos(val);
x *=wid2;
y *=hig2;
//SUN/CENTER
noStroke();
fill (255,238,41);
ellipse (centerx,centery,40,40);
if (dist (mouseX,mouseY,centerx,centery)<20){
if(mousePressed){
speed =0;
}
}
//
x+= centerx;
y+= centery;
val += speed;
}
void display (){
//PLanets
fill(colorR, colorG, colorB);
ellipse(x, y, size, size);
///Orbits
noFill();
stroke(255);
ellipse(centerx, centery, wid2*2, hig2*2);
println ("posicionx "+x);
println ("posiciony "+y);
println ("width "+wid2);
println ("high "+hig2);
println ("val "+val);
println ("speed "+speed);
}
}
You can use the modulo % operator along with the frameCount variable inside the draw() function to do something every X frames.
Here is an example program that draws little circles most frames, but draws a big circle every 60 frames:
void setup() {
size(500, 500);
background(0);
}
void draw() {
ellipse(mouseX, mouseY, 10, 10);
if (frameCount % 60 == 0) {
ellipse(mouseX, mouseY, 50, 50);
}
}
You can build a timer for counting seconds using a helper variable and the in-built variable frameRate. (Note that this solution ensures that you truly count seconds independent on your machine's current workload.)
frameRate tells you how many cycles Processing is currently performing per second (one cycle = one execution of draw, also called one frame). This is usually 60 (frames per second) but can also be lower depending on other processes on your machine (e.g. when running video processing, 3D games etc. the frame rate goes down).
Here's a snippet to see what your current frameRate is:
void draw() {
println(frameRate);
}
And here's the timer using a helper variable counter which is reset every second. You should see a new dot appear on the console output every second.
int counter = 0;
void draw() {
if (counter > frameRate) {
print(".");
counter = 0;
} else {
counter++;
}
}
To make it count every 10 seconds you can just change the if condition to "counter > 10 * frameRate".
I have 2 problems with PolygonSpriteBatch on libGDX.
1) I try to render a simple polygon (in this case a rectangle) and I only see a triangle when drawn.
Picture:
http://i.snag.gy/kHV3N.jpg
texture=new TextureRegion(new Texture("texture.png"));
texture.getTexture().setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
polygonRegion=new PolygonRegion(texture,createVertices(),createIndices(createVertices()));
The polygon that i want to draw is this one
private float[] createVertices() {
float[] verts = new float[5 * 2];
int i = 0;
verts[i++] = 2;
verts[i++] = 2;
verts[i++] = 2;
verts[i++] = 3;
verts[i++] = 3;
verts[i++] = 3;
verts[i++] = 3;
verts[i++] = 2;
verts[i++] = verts[0];
verts[i++] = verts[1];
return verts;
}
private short[] createIndices(float[] vertices){
short[] indices=new short[vertices.length/2];
for(short i=0; i<vertices.length/2; i++){
indices[i]=i;
}
return indices;
}
And when I draw it
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.polygon(createVertices());
shapeRenderer.end();
polygonSpriteBatch.setProjectionMatrix(camera.combined);
polygonSpriteBatch.begin();
polygonSpriteBatch.draw(polygonRegion, 0, 0);
polygonSpriteBatch.end();
I also draw the plain texture to see how it looks like
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(texture, 4f, 2.4f, 1f, 1f);
batch.end();
As you can see, the polygon is drawn with the shaperenderer correctly, but not well textured with the polygonspritebatch.
The second problem:
Instead of the problem above, polygonspritebatch works perfectly when using a normal camera size, like 800x480.
When I use a camera that is 8 x 4.8 (for box2d world) the texture is zoomed a lot ..like in the picture out there.
Any solutions?
For the first issue, the problem is the createIndices() function. The third argument to PolygonRegion needs to contain a number of indices that is a multiple of three (the first three vertices form a triangle, etc).
So you should return { 0, 1, 2, 1, 2, 3 }. Also, why do you have 5 vertices? It seems four are enough.
For the second issue, you should clarify your question. From the screenshot, everything seems fine.
Hi i am new to libgdx and try to build a ludo game.right know i could draw the board but when i try to show dice or any peaces nothing happens I attach game code .
please read and help.
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
batch = new SpriteBatch();
camera = new OrthographicCamera(1, h / w);
boardtexture = new Texture(Gdx.files.internal("data/ludo-boardx2.png"));
boardtexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
boardsprite = new Sprite(boardtexture);
boardsprite.setSize(1f,
1f * boardsprite.getHeight() / boardsprite.getWidth());
boardsprite.setOrigin(boardsprite.getWidth() / 2,
boardsprite.getHeight() / 2);
boardsprite.setPosition(-boardsprite.getWidth() / 2,
-boardsprite.getHeight() / 2);
Texture dice = new Texture(Gdx.files.internal("data/dices.png"));
dice.setFilter(TextureFilter.Linear, TextureFilter.Linear);
dtemp = new Sprite(dice);
dtemp.setSize(1f, 1f * dtemp.getHeight() / dtemp.getWidth());
dtemp.setPosition(0f, 0f);
// System.out.println(w/2+" " +h/2);
// System.out.println(dtemp.getWidth()+":"+dtemp.getHeight());
// animatedDice.setPosition(new Vector2(0, 0));
System.out.println(animatedDice.getX() + ":" + animatedDice.getY()
+ "\n" + w + ":" + h);
}
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
// camera.update();
handleInput();
batch.begin();
boardsprite.draw(batch);
dtemp.draw(batch);
//animatedDice.draw(batch);
batch.end();
// animatedDice.update();
}
You are drawing your die at a position of (w/2, h/2), which is way out of range of your viewport. You set your viewport so the X coordinate of the right side of your screen is 0.5, but your sprite's left side is at x=w/2, where w is the number of pixels wide your window is.
Even if you had set your camera size to match the window ((w, h)), you would have an issue here because you'd be drawing your sprite so its left edge matched the right edge of the screen. By default, the origin of your die sprite will be its lower left corner.
If you aren't planning to zoom your scene in and out, it might be simpler to set your camera viewport to the size of the window by using camera = new OrthographicCamera(w, h); Then you'll know that your units are equivalent to pixels.
I am making game in libgdx. I want to show tutorials on game start and disappear after few seconds.My code is given below
public class HeroCar{
static final int TUTE_STATE_SHOW = 0;
static final int TUTE_STATE_HIDE = 1;
int tuteState;
float tuteStateTime = 0;
public HeroCar()
{
tuteState = TUTE_STATE_SHOW;
}
public void update(float deltaTime){
if(tuteStateTime >= 0.56f){
tuteStateTime = 0;
tuteState = TUTE_STATE_HIDE;
}
else{
tuteState = TUTE_STATE_SHOW;
}
tuteStateTime += deltaTime;
}
and in game play screen class render method my code is
if(world.heroCar.tuteState == HeroCar.TUTE_STATE_SHOW){
spriteBatch.draw(Assets.speedingup_region, 480 / 2 - 172 / 2, 400, 172, 30);
}
}
Or can can just use Car distance
if(herocar.position.x<50&&canShowTute)
{
fon.draw(batcher,string,posx,posy);
}
else if(herocar.position.x>50&&canShowTute)
{
canShowTute=false;
}
This way u dont have to manage a variable for statetime
Also if car crosses a ceratain distance than manage that no further need to show tute next time.
if(tuteStateTime >= 0.56f){
tuteStateTime = 0; //--------------wrong
tuteState = TUTE_STATE_HIDE;
}
donot set
tuteStateTime = 0
because if you set it 0 then in the next cycle it will check time > 0.56f , then it goes to else block and set state = show...... Hence your tutorial will never dissappear. it will always remain in show state.
If you are saying about alpha of texture then may be this could help.
make
Sprite sprite = new Sprite(Assets.speeding_upregion);
in constuctor. and in render cyle
float step = 0;
float speed = 5;
float alpha = 0;
step = alpha > .9f ? -speed : alpha < .1f ? speed : step; alpha += step * deltaTime;
sprite.draw(spritebatch, alpha);
add your condition before draw if you want to draw or not.