Stopping an Animation in render method LibGDX - java

I have an animation of a flipping coin made of five Textures. I would like to delete the animation when the player's Rectangle overlaps the coin's Rectangle but since I haven't found how to do this, I want to just stop it.
With this code, I can draw a Texture above the Animation, but just if the player is overlapping. How can I make it definite? Thanks for the help.
public boolean catchcoin(Rectangle player, Rectangle coin){
if (Intersector.overlaps(player, coin)) {
return true;
}
return false;
}
public boolean changecoin(Rectangle play, Coin coin ) {
boolean b = m.pegamoeda(play, coin.getRectangle());
if(b){
return true;
}
return false;
}
Part of the render method:
public void render(float delta){
currentframe = (Texture) coin.returnsanimatio().getKeyFrame(stateTime, true);
currentframe2 =(Texture)coin2.returnsanimation().getKeyFrame(stateTime, true);
currentframe3 =(Texture)coin3.returnsanimation().getKeyFrame(stateTime, true);
sp.draw(currentframe, coin.getx(),coin.gety(), 30,30);
sp.draw(currentframe2, coin2.getx(),coin2.gety(), 30,30);
sp.draw(currentframe3,coin3.getx(),coin3.gety(), 30,30);
boolean b = changecoin(player, coin);
if(b){
sp.draw(bluecoin, coin.getx(), coin.gety(), 30,30);
}
sp.end();
}

Related

Simple animation of a rectangle sprite

I'm a beginner with java and libgdx, and i'm trying to make a simple sprite of a rectangle slowly going out/in of the screen when I swipe (with GestureDetector).
Is there any tool with libgdx to do a simple task like that?
Here the code I have without any animation :
private Sprite rect;
private void drawRect(){
//some code to draw the rectangle as a sprite on a SpriteBatch
// (the rectangle's position is a the top right of the screen)
}
#Override
public boolean fling(float velocityX, float velocityY, int button) {
//swipe right to close
if (velocityX >= 150 && !rectClosed) {
rect.setPosition(rect.getX() + rectWidth, rect.getY());
rectClosed = true;
}
//swipe left to open
if (velocityX <= -150 && rectClosed) {
rect.setPosition(xRectOrigine, rect.getY());
rectClosed = false;
}
return false;
}
Thank you !

inputprocessor touch down gives late response?

So I am currently busy with a kind of pong game for android. All i have currently is the paddle and the ball. The controls for the player (the paddle) is as followed:
If player touches on left side of screen, paddle goes left
If player touches on right side of screen, paddle goes right
Actually the above 2 points work fine, but what bothers me, is that when im holding right with my right finger, and after that release it and really fast holding left with my left finger, the paddle only executes one time "going left", and then stops, while I am still holding left. (and vice versa)
I discovered this only happens if I use two fingers. If im holding down right with my finger, and try to go really fast to press the other side, it doesnt stop and actually keeps going left.
But it is important to use two fingers, since that is the way how the game should be played.
This all may be explained unclear, so you can ask in the comments more specific questions.
Player.java: http://pastebin.com/pdFZJTRB
MyInputProcessor.java: http://pastebin.com/XPzi8JPB
I think your problem resides in the fact that you have the touchDown boolean being shared between the left and right sides. If you press the left side fast enough, the touchDown for the left finger gets set to true before the touchDown for the right finger is set to false, thus making them all false. Try something like this instead:
package com.nahrot.teleportball;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.math.Vector2;
public class MyInputProcessor implements InputProcessor
{
public Vector2 leftTouchPos = new Vector2();
public Vector2 rightTouchPos = new Vector2();
public boolean touchLeft = false;
public boolean touchRight = false;
#Override
public boolean keyDown(int keycode)
{
return false;
}
#Override
public boolean keyUp(int keycode)
{
return false;
}
#Override
public boolean keyTyped(char character)
{
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button)
{
if(sideTouched(screenX, true))
{
touchLeft = true;
leftTouchPos.set(screenX, screenY);
}
if(sideTouched(screenX, false))
{
touchRight = true;
rightTouchPos.set(screenX, screenY);
}
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button)
{
if(sideTouched(screenX, true))
{
touchLeft = false;
}
if(sideTouched(screenX, false))
{
touchRight = false;
}
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer)
{
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY)
{
return false;
}
#Override
public boolean scrolled(int amount)
{
return false;
}
private boolean sideTouched(int x, boolean checkLeft)
{
if(checkLeft)
{
if(x <= Gdx.graphics.getWidth() / 2)
return true;
}
else
{
if(x > Gdx.graphics.getWidth() /2)
return true;
}
return false;
}
}
Here, I separated the booleans and vectors into left side and right side, and made a convenience function for checking whether a touchDown or touchUp is on the right or left side of the screen, and adjusted the corresponding booleans and vectors accordingly. I assume the vector was needed to check which side was pressed anyway, so I suspect you could work it so that all you need is the two booleans for the sides touched. This code is untested, by the way, but you should get the idea if it doesn't work.

LibGDX Bouncing ball

I want to create an infinite bouncing ball. For now I'm just trying to make the bouncing on Y (up & down).
This is my GameWorld class, you can see there is a method collides to detect the collision but How to make that "circle" go up?
public class GameWorld {
private Circle rond;
private Rectangle rect;
public GameWorld(int midPointY) {
rond = new Circle(100, midPointY - 5, 5);
rect = new Rectangle(0, 200, Gdx.graphics.getWidth(), 5);
}
public void update(float delta) {
if(collides(rond)){
}else
rond.y++;
}
public boolean collides(Circle rond) {
if (rect.y < rond.y + (rond.radius)*2) {
return (Intersector.overlaps(rond, rect));
}
return false;
}
public Circle getRond() {
return rond;
}
public Rectangle getRect() {
return rect;
}
}
Of course, I have another class GameRenderer that rendere these two objects
Typically with any kind of physics you want to store the speed of an object as well as its position. That way, each time though your update loop you just have to change the y position by the y speed. When the collision occurs, all you need to do is calculate the new yspeed and update rond.
public void update(float delta) {
if(collides(rond)){
rond.yspeed = -rond.yspeed;
}else{
rond.y+=rond.yspeed*delta;
}
}

LibGDX - IllegalArgumentException causes my game to crash whenever my main character touches a Coin

Trying to figure out why my Android game crashes whenever the player touches an animated coin. I have attached an image of the LogCat and my code is below (NOTE: all game objects in ![Renderer] are in an arraylist called toRender. the 2 coins in the game are currently held in the 3rd and 4th position in the list). Renderer and Coin classes respectively:
public class Renderer extends ApplicationAdapter {
private SpriteBatch batch;
private Texture background;
private ArrayList<GameObject> toRender;
private Timer timer;
private float delta;
private Game game;
public Renderer(ArrayList<GameObject> toRender) {
batch = new SpriteBatch();
background = new Texture(Gdx.files.internal("background2.png"));
this.toRender = toRender;
timer = Timer.getInstance();
}
public void collect() {
// for every object in toRender (an arraylist of objects)
for (GameObject o : toRender) {
// if player collides with/collects an object
if (Player.getInstance(null).hasCollected(o)) {
// if its the first coin that he collides with, dispose it
if (o.equals((Coin) toRender.get(3))) {
((Coin) toRender.get(3)).dispose();
}
// if its the second coin that he collides with, dispose it
if (o.equals((Coin) toRender.get(4))) {
((Coin) toRender.get(4)).dispose();
}
}
}
}
public void beginRendering() {
delta = Timer.getInstance().getTime();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(background, 0, 0, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
timer.drawTime(batch);
for (GameObject object : toRender) {
object.update();
boolean objectIsntCoin = !(object.equals(toRender.get(3)) ||
object.equals(toRender.get(4))); //the 2 coins are in the 3rd and 4th position in the array list
// draw every object's sprite apart from coin, since coin should render the animation rather than the sprite
if (objectIsntCoin) {
object.draw(batch);
}
}
collect();
((Flag) toRender.get(toRender.size() - 1)).drawLevelComplete(batch);
// if the coin exists (i.e. hasn't been disposed), render the animation
if (((Coin) toRender.get(3)).checkExists()) {
((Coin) toRender.get(3)).render(delta);
}
// if the coin exists (i.e. hasn't been disposed), render the animation
if (((Coin) toRender.get(4)).checkExists()) {
((Coin) toRender.get(4)).render(delta);
}
batch.end();
}
}
public class Coin extends GameObject implements Screen {
private SpriteBatch batch;
private Animation animation;
private float time;
private float xPos;
private float yPos;
private Rectangle objectRect;
private boolean exists;
public Coin(Sprite spr, float xPos, float yPos, float radius) {
super(spr, xPos, yPos, radius);
this.xPos = xPos;
this.yPos = yPos;
batch = new SpriteBatch();
objectRect = new Rectangle(getxPos(), getyPos(), getSprite().getWidth(), getSprite().getHeight());
exists = true;
time = 0;
show();
}
public Rectangle getRect() {
return objectRect;
}
public void render(float delta) {
// TODO Auto-generated method stub
batch.begin();
batch.draw(animation.getKeyFrame(time += delta), xPos, yPos);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
animation = new Animation(1 / 8f,
new TextureRegion(new Texture(Gdx.files.internal("coin1.png"))),
new TextureRegion(new Texture(Gdx.files.internal("coin2.png"))),
new TextureRegion(new Texture(Gdx.files.internal("coin3.png"))),
new TextureRegion(new Texture(Gdx.files.internal("coin4.png"))),
new TextureRegion(new Texture(Gdx.files.internal("coin5.png"))),
new TextureRegion(new Texture(Gdx.files.internal("coin6.png"))),
new TextureRegion(new Texture(Gdx.files.internal("coin7.png"))),
new TextureRegion(new Texture(Gdx.files.internal("coin8.png"))));
animation.setPlayMode(Animation.PlayMode.LOOP);
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
batch.dispose();
exists = false;
}
public boolean checkExists() {
return exists;
}
}
LogCat:1
So the errors that the LogCat point to:
1)dispose() method in Coin:
batch.dispose();
2)collect() method in Renderer:
if(o.equals((Coin) toRender.get(3))) {
3)beginRendering() method in Renderer:
for (GameObject object : toRender) {
Does anyone know why my program is crashing? I just want the animated coin to disappear when the Player touches it. Currently the coin DOES disappear, the application just shuts down immediately after though. Have been stuck on this for a while so any insight is highly appreciated.
Thank you in advance.
First, I want to mention that downcasting the objects in toRender like you are is both dangerous and indicates there is a flaw in your design. Additionally, you'll notice that equals(Object) accepts an Object as an argument; you don't need to cast it to Coin.
Anyway, the reason your program is crashing is explained in the IllegalArgumentException message,
buffer not allocated with newUnsafeByteBuffer or already disposed.
You're trying to dispose your Coin's batch when it has already been disposed.
In your collect() method, you loop through the objects, and you dispose of their batches, but the Coin objects themselves are never removed from your toRender list. So, the next time collect() is called, it will loop through those same Coin objects and try to dispose of them again, and an exception is thrown.
The solution is to remove the Coin objects from your toRender list when they no longer belong in your game's scene. However, you can't remove an element from a list while you're iterating over it, as this would disrupt the loop. Instead, remove them like so:
public void collect() {
// Holds the Coins we want to remove from toRender
final Collection<GameObject> toRemove = new LinkedList<>();
for (GameObject o : toRender) {
if (Player.getInstance(null).hasCollected(o)) {
if (o.equals(toRender.get(3))) {
final Coin coin = (Coin) toRender.get(3);
coin.dispose();
toRemove.add(coin);
}
if (o.equals(toRender.get(4))) {
final Coin coin = (Coin) toRender.get(4);
coin.dispose();
toRemove.add(coin);
}
}
}
// Remove the collected Coins
toRender.removeAll(toRemove);
}

perform single touch on isActionMove()

how to perform single touch on isActionMove() because when i move finger on sprites it takes multipal touch events and update scores twice thrice
mHardware[active] = new Sprite(pX, pY, java, this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y) {
if (pSceneTouchEvent.isActionMove()) {
score++;
}
}
};
i cant use isActionDown because its a game like fruit ninja in which i need to move finger across screen
now problem is score is sometimes increasse by 2 sometimes by 3 because when i move finger on sprite application notices several short movements in place of one
you should use
private static boolean isFirstMove;
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y) {
if (pSceneTouchEvent.isActionDown()) {
isFirstMove = true;
}
if (pSceneTouchEvent.isActionMove()) {
if(isFirstMove) {
score++;
isFirstMove = false;
}
}
if (pSceneTouchEvent.isActionUp()) {
isFirstMove = false;
}
});
If you found some what above answer correct for you then I have some suggestion in this.
You have to implement both scene and area touch event for your game scene.
SceneTouch event method contains two events isActionDown() and isActionUp() like in the following code.
public void onSceneTouchEvent(...){
if(pSceneTouchEvent.isActionDown()){
isFirstTouch=true;
return true;
} else if(pSceneTouchEvent.isActionUp()){
isFirstTouch=false;
return true;
}
return false;
}
Area Touch method contains only single event isActionMove() like in the following code.
public void onAreaTouch(...){
if(pSceneTouchEvent.isActionMove()){
if(isFirstMove) {
score++;
isFirstMove = false;
}
return true;
}
return false;
}
You have to follow above strategy because some time desire event not occur for your sprite so you don't get your desire result.
solution given by julien dumortier is working perfectly
static boolean isFirstMove=true;
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y) {
if (pSceneTouchEvent.isActionMove()) {
if(isFirstMove) {
score++;
isFirstMove = false;
}
}
});

Categories