How to add knockback? :S

Hi again! So Im currently trying to figure out how to add knockback to my game, but I’m stuck :frowning: I searched around a bit, but the only thing I could find was this:

  public void knockback(float r, float force){
      r = r - 180;
      
      force *= knockbackResistance; // how heavy the entity is (so lesser knock back)
      
      knockbackTimer = force * 8;
      knockbackTo = new Vector2((force * (float) MathUtils.sin(r * MathUtils.degreesToRadians)),
                         (-force * (float) MathUtils.cos(r * MathUtils.degreesToRadians)))
                                       .add(position);
               
   }


//Then I have this on the update loop for the entity

   public void update(){
      if(knockbackTimer > 0){
         position = Tools.lerp(position, knockbackTo, 0.2f);
         knockbackTimer -= Gdx.graphics.getDeltaTime() * 1000;
      }
        }

To be honest, I really don’t understand it :frowning: Help, please? :slight_smile:

Ok first off, format your code, I don’t feel like trying to read that mess. Second, just think about the problem and how you can solve it. Is your game a side scroller? If so, you’ll need to know a little trig to add a parabola shaped knock back flight path. You need to then just move the entity along the path. It really isn’t that hard and I think if you can’t figure this out by yourself, then you need to think a little harder on it. Programming is all about problem solving. Not re-using old code from other people.

Hey m8, well if you are using 2D, maybe you need some Newton laws?

http://answers.unity3d.com/questions/242648/force-on-character-controller-knockback.html

As far as i know, all you really need to know is this :

º REACH THE QUANTITY OF PIXELS YOU NEED TO MOVE BACK ( FORCE )

So you need reach something like this :

int force = (??? + ??? - ?? * ?? / ???)

Just a little example.

Anyway, to reach that, you will need physics, which im not good at it. I got a good physics teacher in college, if you are in college maybe you should ask him ?

Well, maybe this post can help a little.

xD

Ok, so I have been able to make the knockback work for when the player hits a enemy, but how do I make the collision for when a enemy hit another enemy work? :frowning: I tried doing this:

public void checkCollisionBetweenEnemies(Rectangle rectEnemy){
		if (rectEnemy.intersects(rectEnemy)){
			System.out.println("Collision between enemies!");
			}
		}

But that makes it think that it is always a collision :frowning: It always displays the message since its always hitting it self :confused: Note: Im using a superclass called Enemy and I currently have one subclass which is called Zombie :stuck_out_tongue:

You’re checking if it intersects itself, so obviously it always will be true…try something like


public void checkCollisionBetweenEnemies(Enemy a, Enemy b){
     if(a.getRectangle().intersects(b.getRectangle()){
     System.out.println("Collision");
   }
}

in your collision manager, and then modify/use as needed.

Ahh, thanks! Got it working now! ^^

Since I’m still a newbie at this, I feel it’s important to learn what I actually did, so here’s another question for you Java experts out there! :wink:

Here is the code for my entity controller class:

public void tick(){
		for(int i = 0; i < entityList.size(); i++){
			tempEntity = entityList.get(i);
			
			tempEntity.tick();
			
			if(entityList.size() >= 2){
				for(int j = 0; j < entityList.size(); j++){
					
					tempEntity2 = entityList.get(j);
					
					if(tempEntity != tempEntity2){
						
						if (tempEntity.getRectEnemy().intersects(tempEntity2.getRectEnemy())){
							
							System.out.println("Collision between enemies!");
						}
					}
				}
			}
		}
	}

My question is that to get this working I had to go the Enemy superclass and remove the “static” modifier that was on my rectangle around my enemy (don’t know what it was doing there in the first place :S ), but what did I really do? :stuck_out_tongue: If I remember correctly, static is used when you have to use something in a class you haven’t initialised yet, but I’m sure you use it for different stuff :stuck_out_tongue:

static means that the method or variable applies to the whole class and not to an individual instances - all instances of the class share the same value. So in your example, when the rect was static entity 1 and entity 2 had the same rect value, because it was static.

It might be helpful for you to work through the first parts of the Java tutorial (which covers the fundamentals of the language):

http://docs.oracle.com/javase/tutorial/

Okay, so I have almost got everything working, except that I have one small problem left :frowning: I want the enemies to not go through eachother, but I just can’t find a solution :frowning: I tried this code:
Note: I’m using it on the player for testing purposes!

if(player.isMovingRight() == true){
				player.setX(x - 22 + speedX);
			}else if(player.isMovingLeft() == true){
				player.setX(x + 22 - speedX);
			}
			
			if(player.isMovingDown() == true){
				player.setY(y - 22 + speedY);
			}else if(player.isMovingUp() == true){
				player.setY(y + 22 - speedY);
			}
			
			if(player.getSpeedX() == 0 && player.getSpeedY() == 0){

				if(speedX > 0 && speedX < 3) player.setX(x + 22 - speedX);
				if(speedX < 0 && speedX > -3) player.setX(x - 22 + speedX);
				if(speedY > 0 && speedY < 3) player.setY(y + 22 - speedY);
				if(speedY < 0 && speedY > -3) player.setY(y - 22 + speedY);
			}

Hey that’s my weird knockback code!

When there are a lot of enemies, this solution makes them all shake and do funky stuff, but here it is anyway to get you going somewhere.

Add to update loop:


if(entityRect.intersects(otherEntityRect)){
	
	Vector2f translatedDifference = Tools.calcMinTranslationDistance(entityRect, otherEntityRect);
	entity.addPosition(translatedDifference.x, translatedDifference.y);
}

I didn’t write all this myself and I don’t remember who exactly did (sorry). It basically just gives you the distance to stop two rectangles from overlapping:

public static Vector2f calcMinTranslationDistance(Rectangle rect1, Rectangle rect2){
	
	float difference;
	float minTranslateDistance;
	short axis;
	short side;
	Vector2f translatedDifference = new Vector2f(0,0);
	
	// Left
	difference = (rect1.getX() + rect1.getWidth()) - (rect2.getX());
	minTranslateDistance = difference;
	axis = 0;
	side = -1;
	
	// Right
	difference = (rect2.getX() + rect2.getWidth()) - rect1.getX();
	if(difference < minTranslateDistance){
		minTranslateDistance = difference;
		axis = 0;
		side = 1;
	}
	
	// Down
	difference = (rect1.getY() + rect1.getHeight()) - rect2.getY();
	if(difference < minTranslateDistance){
		minTranslateDistance = difference;
		axis = 1;
		side = -1;
	}
	
	// Up
	difference = (rect2.getY() + rect2.getHeight()) - rect1.getY();
	if(difference < minTranslateDistance){
		minTranslateDistance = difference;
		axis = 1;
		side = 1;
	}
	
	// Y
	if(axis == 1)	
		translatedDifference.y = side * minTranslateDistance;
	// X
	else
		translatedDifference.x = side * minTranslateDistance;
	
	return translatedDifference;
}