Android AndEngine score += 1 error increases a lot - java

I am creating sprites that get saved into a list called listSprites each sprite that touches a line (line3) that I made gets detached from the screen. What I want is when It gets detached (collides with line3) the score increases only 1, but now it increases a lot like it reacher 10,218 in 1 minute, once a sprite collides with the line it detaches and the score starts increasing without stopping even though no sprite is coliiding with it.
/* The actual collision-checking. */
mScene.registerUpdateHandler(new IUpdateHandler() {
#Override
public void reset() { }
#Override
public void onUpdate(final float pSecondsElapsed) {
} for(Sprite s: listSprites){
if (s.collidesWith(line3)){
mScore += 1;
mScene.detachChild(s);
mText.setText(" "+mScore+"");
}
}
}
});
}

It looks like collidesWith() doesn't care whether the child is attached or not. If that's the case, and you don't want to remove the sprite from listSprites, you need to check each sprite in the list to see if it's attached in addition to the collision check.
I haven't used andengine much, but from looking at the source and examples, it looks like you could just do something as simple as changing:
if (s.collidesWith(line3)){
to:
if (s.hasParent() && s.collidesWith(line3)){
hasParent() should return false if the sprite is not attached to anything, so check for that.
This assumes that you're not attaching the sprites to a different scene in the meantime.

Related

How to make a similar animation to Flappy Bird in Libgdx?

I'm creating a game like flappy bird where the bird flaps his wings only when the screen is touched, but I'm having a problem activating the animation when the screen is touched.
batch.draw(animation.getKeyFrame(myTimeState, false), x, y); //the myTimeState is 0 to render the 1st frame only.
Then when the screen is touched I do this:
//myTimeStep is just basically a controllable timeState for the animation only
if(Gdx.input.justTouched){
myTimeState = timeState;
}else if(Gdx.input.justTouched == false && animation.isAnimationFinished(timeState)){
myTimeState = 0;
}
I don't think the animation is able to play all the frames because myTimeStep become 0 immediately after finishing to touch the screen. Also I don't think this is the right way of doing it, if you guys have better ideas or solution please help. Thanks in advance.
There are probably several ways to achieve this. You'll need to increment your timeState, of course, and also it depends how long your animation is and if you want it to loop.
If you've created your animation to play only once, and then stop (until the screen is touched again), you could simply set your myTimeState to 0 when the screen is touched, and then increment it every frame. The animation will run through and then "stop" on its own when it reaches the end (as you said no loop). The next time someone touches the screen, your myTimeState is set back to 0 and the animation starts again.
Firstly, you have to ensure your animation's playmode is set to Animation.PlayMode.NORMAL. It's a default setting, but if you set it somewhere to LOOPED, nothing would work as expected.
Secondly, I wouldn't use Input.justTouched() in this case. Instead, a listener in your input processor would be a great fit. Here's an example with Stage. If you have no idea what input processor is, here's tutorial on event handling and class documentation.
stage.addListener(new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if(button == Input.Buttons.LEFT) {
timeState = 0;
}
return super.touchDown(event, x, y, pointer, button);
}
});
You can pick what's going to be displayed (animation's keyframe or sprite) based on result of animation.isAnimationFinished()
if(animation.isAnimationFinished(timeState)) {
//draw some sprite
} else {
//draw animation keyframe
}
I haven't checked it but there's a possibility, that this could lead to the last frame being cut out, because as soon as it gets displayed, animation.isAnimationFinished() will return true. I may be wrong, so you'll have to check it. If it becomes an issue, you can add your sprite as the last frame of your animation. When animation ends, it frezzes on the last frame, which would be your static sprite.
In both cases you'll get your animation played at the beginning of game because timeStep equal to 0. I see 2 solutions, I advise you to take the second:
Set timeStep to a large number, that is for sure larger than your animation's duration. Animation.isAnimationFinished() will then return true.
Introduce boolean variable isAnimationPlayed that:
is initialized with false,
gets set to true in your click listener,
gets set to false during isAnimationFinished(), which is called each frame only when isAnimationPlayed is true,
is used in draw() method to determine what to display.
You could just set your timeState to the duration of the animation.

what is stopping my screen from rendering as planned?

#Override
public void render(float delta) {
Gdx.gl.glClearColor(0,0,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
combattext.setText(combatstring);
stage.act();
stage.draw();
}
combatstring is a string that displays what happened in my game. when enemies attacks, it says what happened. when I attack, it says what happens. As of now my game has a loop when in combat that runs a turncounting instance. When it's time for a turn, it runs that participants turn, and when their turn is over it updates combatstring.
I have 2 combatstrings. One is for my characters, and one is for enemies. Here is an example of what happens when it's an enemies turn.
if(thisencounter.monster1turn){ //monster1's turn goes in here
thiscombat.getTarget(1); //get enemy's target
thiscombat.calculateVars(1); //calculate all combat variables for
// this turn
thiscombat.theyAttack();
combatstring = thisencounter.thisenemy.species+
" "+thiscombat.action+
" "+thiscombat.theirtarget.species+
" for "+thiscombat.effect;
thisencounter.monster1turn=false;
}
This works fine, my combattext label updates instantly when a monster goes.
For my characters, their turns make buttons visible on my screen. The buttons have listeners that determine actions, here is an example:
monster1.addListener(new ClickListener(){ //makes the first enemy's
//image clickable, but only
//when the attack button
//has been clicked
#Override
public void clicked(InputEvent event, float x, float y) {
thiscombat.ChooseTarget(1); //various methods that calculate damage,
//output what happened, and put us back in
thiscombat.calculateVars(4); //the loop to wait for next
//participant's turn
thiscombat.youAttack();
combatstring = thisencounter.thisspirit.species+
" "+thiscombat.action+
" "+thiscombat.yourtarget.species+
" for "+thiscombat.effect;
monster1.clear();
monster2.clear();
monster3.clear();
try {
combatloop();
} catch (InterruptedException ex) {
Logger.getLogger(map1field.class.getName()).
log(Level.SEVERE, null, ex);
}
}});
This also works fine, EXCEPT on the turn just before a monster goes. Since there is no wait between my turn and the monster's turn, the combattext just instantly displays what the monster does.
I assumed 'oh hey this is because there is no delay between the two turns'. So, I threw a thread.sleep(2000) just before where it updates the monsters combatstring.
But that does not fix it. It still does not show the text for my character that goes just before a monster. Also, since fighting starts right when you go to this screen in the game, it waits about 2 seconds before it displays anything on the screen.
For the life of me I don't understand why it behaves like this. Can someone explain what is happening to me? Is it because it isn't rendering before it gets to thread.sleep ?
If that's the case, how do I force it to render before it does thread.sleep, or what should I be using instead of thread.sleep ?

Slick2d, How can i draw a string on screen for a few seconds?

I've been trying to figure this out, all I want to do is be able to draw a string for longer than just a frame, but when I call it in the method I want it to flash up then disappear immediately, any advice would be appreciated :) I'm using something like this:
g.drawString("You got a Key!", 100, 100);
I'm doing this in a method which is called after an Item is picked up
public void addItemFound(Graphics g){
ip.mainInventory[ip.getFirstEmptyStack()] = getItemStackFound();
System.out.println(this.getItemFound() + " added");
g.drawString("You Got a Key!", 100, 100);
}
That's the full method if you were interested :) Thanks!Also apologies for the dumb question, i'm a newbie to this :P
I believe that the best way to do this project would be to draw the scene at regular intervals e.g. 10 milliseconds using a Thread.sleep(). This way, you can simply add a variable to show the message for, say, 100 loops (1 second) like this:
private LinkedList<String> drawStringList= new LinkedList<>();
private LinkedList<Integer> drawStringTimeout= new LinkedList<>();
private LinkedList<Integer[]> drawStringPos= new LinkedList<>();
public void addText(String stringToWrite, int posX, int posY, int timeOut) {
drawStringList.add(stringToWrite);
int[] pos = new int[2];
pos[0] = posX;
pos[1] = posY;
drawStringPos.add(pos);
drawStringTimeout.add(timeOut);
}
private void mainLoop() {
...items to be drawn here...
for(int i=0;i<drawStringList.size();i++){
g.drawString(drawStringList.get(i),drawStringPos.get(i)[0],drawStringPos.get(i)[1]);
drawStringTimeout.set(i,drawStringTimeout.get(i)-1);
if(drawStringTimeout.get(i)<=0) {
drawStringList.remove(i);
drawStringTimeout.remove(i);
drawStringPos.remove(i);
}
}
try { Thread.sleep(10); } catch (Exception e) {}
}
In this code, you must add the string you want to draw to drawStringList, add the number of loops you want it to stay for to drawStringTimeout and add the position you would like to draw it in to drawStringPos as an array (you could use a point if you wanted to). I have made a method to do this.
I don't know what Dan300 is trying to tell you to do but that's way, way, way over complicated. Slick2D works on gamestates:
http://slick.ninjacave.com/javadoc/org/newdawn/slick/state/GameState.html
The gamestate has a method called render(). The render() is called every single cycle of the loop to update your screen with drawing information. If you want to draw the text on the screen for a longer time you should be drawing the text somewhere within the stack space of this render() function.
What is happening now is you have a function with one specific purpose that only exists every so briefly: add an item to the player. The game comes across this statement and when adding an item within that 1 cycle the text will be drawn. But the next cycle when the player isn't picking up an item it won't come by that drawString statement and you won't have your string on your screen longer than 1 game cycle.

Android Missile sprite

I am trying to make a onTouchEvent to create a missile that will launch from my character sprite and forward.
I have this working using
if (missdraw = true){
canvas.drawBitmap(missile,missilex,missileY,null);
missilex = missilex + 14;
missdraw = false;
}
in my onDraw method, but the problem is it will only create one at a time.
I tried to create a class to deal with this, but this just causes an error and crashes when i try to fire.
here is what i use for the class: (this is in the ondraw in my gameview)
for (Batcher missile : missiles ){
missile.onDraw(canvas);
}
this is in the class
public Batcher(List<Batcher> temps, ScreenActivity newView, float x,
float y, Bitmap missile){
this.x = 1;
this.y = 2;
this.missile = missile;
}
public void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawBitmap(missile, x,y, null);
}
I would appreciate any help, but also if you could explain how it would work, instead of just code, as im quite new to programming, and really need to understand what im doing and why im doing it, rather than just copying peoples code because it works.
Cheers Phil.
Your concepts are pretty good, actually. There are a few things I don't quite understand about the code samples you posted up, I'll try to translate into what I'd do and you can tell me if I'm doing it wrong :)
in your game class you need (and it looks like you have) a list of Missiles:
LinkedList<Batcher> missiles;
In your onTouch(), however a missile is created -
missiles.add(new Batcher(missilex, missiley, missile));
you now have a collection of missiles. Note that I didn't include the list in the constructor of your batcher, because an object should never need to know that it's a part of a collection. All it needs to know is how to draw itself and where. Since I assume that all of your missiles will be added to or removed from the screen frequently, while only having a few on screen at a time, I've used a LinkedList, which is fast for adding and removing, but slow for accessing a specific missile. If you needed to access specific items in the collection and the collection didn't change very much, you would use an ArrayList instead. on to onDraw - as you have it the missile draws itself, which is fine, but I prefer to let the View do the drawing, with the missile telling it where it should be drawn -
for (Batcher missile : missiles ){
missile.setX(missile.getX() + 14); // to make it move
if (missile.getX() > canvas.gedWidth()) { //check if it's left the screen
missiles.remove(missile); // Remove it
}
else { //perform drawing
canvas.drawBitmap(missile.getBitmap(), missile.getX(), missile.getY(), null);
}
}
Hopefully that'll do it for you, but feel free to let me know if there's anything you'd like me to explain more!

Within my for loop it appears that it is ignoring if statements

I'm pretty new at java and I've been trying to write a method that draws a gradient from one configurable color to another. However, it appears that if statements inside of the for loop are being ignored.
How can I fix this? or is there something else I'm missing?
and usage of the method is:
Gradient.dVertical(Graphics,Top left corner X,Top left corner Y,Size X,Size Y,tarting Red Value,Starting Green Value,Starting Blue Value,Ending Red Value,Ending Green Value,Ending Blue Value);
EDIT: I figured out what the real problem was and I fixed it. When it should have been incremental down it was going up. So I added a couple more if statements and that cleared it up. Using random integers when calling the method did reveal another problem though. With certain values it will not finish drawing and it will just cut off in the middle. FIXED
Here's the fixed part of the code if anyone is interested
if (rrepeat == true)
{
//prevents division by zero
if(rrate!=0)
{
//for a rate that must repeat checks
//whether or not it is time to increment
check = k%rrate;
if (check==0)
{
if(ered<sred)
{
rr--;
}
if(sred<ered)
{
rr++;
}
}
else
{
rr = rr;
}
}
}
You need to be overriding the paint method.
Here's an example: Introduction to applets

Categories