Android app memory and lag problems - java

I am making an app for android, in which at some point i need to add a lot of levels. To be efficient, after the player leaves a level, i delete it and add a new level, depending on some factors. The problem is, as I advance through the levels, the game gets a lot of lag. I looked on memory with device monitor and I saw that the memory used keeps going up, even if I use .clear to delete previous levels. I will put the code in and I tested it only with the player, without any other entities:
void manageLevels(){
while(inc < sf && inc < minLevel){
blocks.get(0).clear();
inc++;
}
while(sf < numberLevels && sf < maxLevel + 2){
blocks.add(new ArrayList<blockClass>());
sf++;
nrLv[sf] = blocks.size() - 1;
float BlockX = -1500 * scaleX, BlockY = 250 * scaleY - (sf - 1) * levelSize;
platforms[sf] = BlockY + 100 * scaleY;
setTexture();
for(int i = 0 ; i < numberOfBlocks ; i++){
blocks.get(nrLv[sf]).add(new blockClass(BlockX, BlockY, typeT, scaleX, scaleY));
BlockX += 100 * scaleX;
}
}
}

Related

Code works only on one object at a time

Im trying to build a simple game, built on the bases of RealTutsGML wave game(I assume some here knows it so it might help). Anyway, Im trying to make a "bot player" that will avoid the enemies and I believe that everything should be right, but for some reason it works only on one enemy at a time(Im adding enemies to the game every few seconds and the new enemy is the only enemy that works). The weird thing is, I created a circle around my enemy, and with that circle I detect nearby enemies, I have the following code: if (circle.intersects(rectangle)), the circle recieves the player position and updates all the time, and the rectangle gets the enemies position through a for loop:
for (int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ID.basicEnemy) {
rectangle = new Rectangle((int) tempObject.getX(), (int) tempObject.getY(), 16, 16); }
I set a print line if a collision occures, just to test and see, and whenever enemies hit the circle around the player, it prints "collision", it works with all enemies. but the following code that causes the player to move, only occures when the last created enemy object hits.
Thats how the whole method looks like:
public void AImove() {
for (int i = 0; i < handler.object.size(); i++) {
circle = new Ellipse2D.Double((int) player.getX() - 48, (int) player.getY() - 48, 130, 130);
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ID.basicEnemy) {
rectangle = new Rectangle((int) tempObject.getX(), (int) tempObject.getY(), 16, 16);
}
if (rectangle != null && circle != null) {
if (circle.intersects(rectangle)) {
float diffX = rectangle.x - player.getX() - 8;
float diffY = rectangle.y - player.getY() - 8;
float distance = (float) Math.sqrt((rectangle.x - player.getX()) * (rectangle.x - player.getX())
+ ((rectangle.y - player.getY()) * (rectangle.y - player.getY())));
float newX = ((-1 / distance) * diffX * 10);
float newY = ((-1 / distance) * diffY * 10);
player.setVelX(newX);
player.setVelY(newY);
} else if (player.getX() != WIDTH / 2 - 32 && player.getY() != HEIGHT / 2 - 32) {
float diffX = player.getX() - 368 + 10;
float diffY = player.getY() - 268 + 10;
float distance = (float) Math.sqrt((player.getX() - 368) * (player.getX() - 368)
+ ((player.getY() - 268) * (player.getY() - 268)));
player.setVelX((-1 / distance) * diffX * 5);
player.setVelY((-1 / distance) * diffY * 5);
}
}
}
}
(Just a short exlanation, newX/Y algorithm is not setting the player in a new position, it just sets the velocityX/Y, which moves the player to the oopsite direction of the collided enemy, if there is no collision, the player will try to go back to the center of the screen using the same algorithm).
I've also tested with a prints of the "supposed to be" new velX and velY, like so:
System.out.println((-1 / distance) * diffX * 10);
System.out.println((-1 / distance) * diffY * 10);
And again, it gives the right value no matter which enemy collides with the player's circle, but for some reason it just doesn't move, and works ONLY when the last created enemy object hits the circle.
Im kinda lost, as I really don't see a reason it wouldn't work, the condition occures, the code that needs to be executed works, but it just doesn't.
Sorry for the long post, I tried to be as specific and short as I can, if more code is needed please let me know, I just don't want to add too much code. Thanks for the help!
edit - https://github.com/pardovot/MyProjects/tree/master/AImove/Pong - link to the project in github, so you'll have all the needed information about it.
I assume that what Dezigo said about the last iteration replating the values is corret, does anyone has any ideas what I can do to fix that? Because overall I don't see a real reason for that to happen, as the actual code should run in each iteration, and actually work(which doesn't obviously....)

Enemy's speed when following player

So I have this code before which is obviously very familiar. It currently moves all the zombies that I add to an arraylist towards my player, but if the zombie is positive of the player (to the right) then the zombie moves faster than it does on the left. Any ideas how this is fixed?
for (Zombie zombie : zombies) {
zombie.distX = Game.player.x - zombie.x;
zombie.distY = Game.player.y - zombie.y;
zombie.angle = Math.atan2(zombie.distY, zombie.distX);
zombie.x += Math.cos(zombie.angle) * zombie.speed;
zombie.y += Math.sin(zombie.angle) * zombie.speed;
}
EDIT: I made these changes which normalized it and now it works! Thanks!
zombie.angle = Math.sqrt(Math.pow(zombie.distX, 2) + Math.pow(zombie.distY, 2));
zombie.distX /= zombie.angle;
zombie.distY /= zombie.angle;
zombie.x += zombie.distX * 2;
zombie.y += zombie.distY * 2;

Collision Detection in Box2D

So I'm using Box2D for collision detection in a game. I have a tilemap that contains information on the terrain: for now it's just a char[][] that has either road or grass. Now, at the start of each level I wanted to create rectangles to describe the different terrains, but I wanted these rectangles to be optimized and apparently that takes quite an algorithm.
My first approach was to create an individual terrain for EVERY tile in the map at the start of the level. The FPS was reduced to 5.
My second idea was to simply create the different rectangles for terrains as the player moved along the map, deleting the rectangles that were out of view. Although it would still be a lot of rectangles, it would be considerably less.
I haven't attempted the second method yet, but I want to know: is there any easy way for me to efficiently perform collision detection against terrain with a large tilemap?
Thanks.
Try combining tiles. For example, if you have 16 rectangular collision volumes for 16 tiles like so...
* * * *
* * * *
* * * *
* * * *
You can obviously combine these tiles into one large rectangle.
Now, things get more difficult if you have tiles in a weird arrangement, maybe like this...
**---
****-
*--**
-*-*-
I just recently solved this problem in my game using a quad tree and sweep and prune. (Sweep and prune isn't strictly necessary, its an optimization.)
Quad tree partitions your square tiles into bigger rectangles, then you iterate over the rectangles the quad tree produces, and combine them if they have the same width, then iterate over them again and combine them by similar heights. Repeat until you can't combine them anymore, then generate your collision volumes.
Here's a link to a question I asked about a more optimal reduction. I probably won't implement this as it sounds difficult, and my current approach is working well.
Some code:
do {
lastCompressSize = currentOutput;
this.runHorizontalCompression(this.output1, this.output2);
this.output1.clear();
this.runVerticalCompression(this.output2, this.output1);
this.output2.clear();
currentOutput = this.output1.size;
iterations += 1;
}while (lastCompressSize > currentOutput);
public void runHorizontalCompression(Array<SimpleRect> input,
Array<SimpleRect> output) {
input.sort(this.xAxisSort);
int x2 = -1;
final SimpleRect newRect = this.rectCache.retreive();
for (int i = 0; i < input.size; i++) {
SimpleRect r1 = input.get(i);
newRect.set(r1);
x2 = newRect.x + newRect.width;
for (int j = i + 1; j < input.size; j++) {
SimpleRect r2 = input.get(j);
if (x2 == r2.x && r2.y == newRect.y
&& r2.height == newRect.height) {
newRect.width += r2.width;
x2 = newRect.x + newRect.width;
input.removeIndex(j);
j -= 1;
} else if (x2 < r2.x)
break;
}
SimpleRect temp = this.rectCache.retreive().set(newRect);
output.add(temp);
}
}
public void runVerticalCompression(Array<SimpleRect> input,
Array<SimpleRect> output) {
input.sort(this.yAxisSort);
int y2 = -1;
final SimpleRect newRect = this.rectCache.retreive();
for (int i = 0; i < input.size; i++) {
SimpleRect r1 = input.get(i);
newRect.set(r1);
y2 = newRect.y + newRect.height;
for (int j = i + 1; j < input.size; j++) {
SimpleRect r2 = input.get(j);
if (y2 == r2.y && r2.x == newRect.x
&& r2.width == newRect.width) {
newRect.height += r2.height;
y2 = newRect.y + newRect.height;
input.removeIndex(j);
j -= 1;
} else if (y2 < r2.y)
break;
}
SimpleRect temp = this.rectCache.retreive().set(newRect);
output.add(temp);
}
}

Java smooth scrolling (Game)

Ok, so I have a game I just started and I am kind of stuck on the smooth scrolling. I have the basic scrolling part done but my background (Grid) only moves by intervals of 50.
for (int x = (getPlayerX() / getTileSize()) - 6; x < (getPlayerX() / getTileSize()) + 9; x++)
{
for (int y = (getPlayerY() / getTileSize()) - 5; y < (getPlayerY() / getTileSize()) + 8; y++)
{
int xPos = ((x - (getPlayerX() / tileSize)) + (getScreenX() / tileSize) - 1) * tileSize;
int yPos = ((y - (getPlayerY() / tileSize)) + (getScreenY() / tileSize) - 1) * tileSize;
if (x > 0 && x < mapX && y > 0 && y < mapY)
{
if (getTiles()[x][y].tileID == 0)
{
g.drawRect(xPos, yPos, tileSize, tileSize);
}
if (getTiles()[x][y].tileID == 1)
{
g.fillRect(xPos, yPos, tileSize + 1, tileSize + 1);
}
}
}
}
Sorry about the subtraction and addition in the for loops, I have them set up so it will display from 1 to whatever instead of 0 to whatever - 1.
So basically I want to redraw the grid every pixel I move, instead of every 50. Put I dont want to iterate over every pixel on the screen
Ok, at first you are confusing with the background and the grid. A grid is a way to check collisions and a spatial partitioning algorithm that never moves. A background is an image which is drawn behind every entity in your game in every level.
What you are trying to do is make the level scroll, as per what I understand. To do so, we create a class called View also called as a Camera which draws the background and the visible entities by centering the entity which is controlled by the player.
And to center an entity and draw the map, I use these classes. Hope you understand that I wrote them in C#.
Map
MapInfo
MapLayer
MapLoader
MapManager
MapView
And here is my implementation of Grid. I have the java versions of the same classes here but I haven't implemented the Grid class in java.
You can read my tutorial Using Grids For Collisions for more info on how it works. Hope it helps.

Blocking light on a tiled level

I'm making a tiled(tiles size is 16px) level scrolling game in Java.
Right now I'm dealing with the lighting system.
I calculated the light gradient(as shown on the picture) with this code for each light(yellow blocks and tiles):
visMap = new int[level.getWidth() * level.getHeight()];
int lighted = 0;
for (int x = 0; x < level.getWidth(); x++) {
for (int y = 0; y < level.getHeight(); y++) {
double xd = (this.x >> 4) - x;
double yd = (this.y >> 4) - y;
double distance = Math.sqrt(xd * xd + yd * yd);
double p = power * 1.0;
double bright = p - distance;
visMap[x + y * level.getWidth()] = (int) (bright * power);
}
}
And now I'm trying to make the block somehow block the light(like in real life).
Is there a good method for this?
Thank's in advance,
Zaplik
The Picture: click
Spread light recursively. Decrease with each level of recursion the light intensity with the appropriated amount. Keep also track of the direction light is moving. Once you hit an obstacle, stop that branch of the recursion.

Categories