LibGDX - given an arraylist of moving circles, how can i check for collision between them? - libgdx

So I have 3 classes, MyGdxGame, Ball and DetectCollision. MyGdxGame initialises 4 instances of Ball (different colours and speed/direction, all bounce off the sides of the screen) and stores them as an arraylist.
This arraylist is passed through the constructor of DetectCollision:
public class DetectCollisions {
ArrayList<Ball> ball;
public DetectCollisions(ArrayList<Ball> ball) {
this.ball = ball;
start();
}
public void start() {
for(int i=0; i<ball.size();i++) {
...
}
}
Can anyone give me a hint as to where I should go with this? I just want to detect every time a ball collides with another (and eventually I'll have it print the number of collisions).
Any help highly appreciated :)

If you are going to add a lot of objects to the arraylist, use a 2D physics engine to do all the work for you. If you want to continue implementing your own functions, the very basic method to do is to implement a nested loop over the list to check every possible pair in the arraylist. The complexity is O(n^2)
for(int i=0; i<ball.size();i++) {
for(int j=i+1; j<ball.size();j++) {
check(ball.get(i), ball.get(j));
}
}
The method named check checks if given two circles collide or not. Checking two circles' collision is very easy. If the distance between the central points of the circles is smaller than the sum of the radiuses of the circles, then they collide. Check this page for further info about this.

This is very easy to accomplish if you let each Ball have bounds of type Circle.
You can make a circle as follows: Circle ballBounds = new Circle(float x, float y, float radius) This circle can act as the bounds of each ball ultimately allowing you to check if they collide using the Intersector class.
Having each Ball's boundary we can easily loop through the ArrayList<Ball> and check how many collide. For example:
ArrayList<Ball> ball = new ArrayList<Ball>(); // You need to add Balls to this ArrayList
Intersector intersector = new Intersector();
int counter = 0;
for(int i = 0; i < ball.size()-2; i++){
if(intersecor.overlaps(ball.get(i), ball.get(i+1)){
counter++;
}
i++;
}

Related

Pattern creation of collectibles - LibGdx

I am working on a LibGdx running game.I have collectibles/coins in the game.
I have created a coin array,and spawned it throughout the game.
To improve the play,I want to make patterns of coins.Like 2 coins or 3 coins together , coins in vertical or diagonal arrangements etc.
I tried to implement this,but found it a difficult task as a fresher.
Please suggest me some code to implement patterns like triangle with an array of objects.
Like this:triangle with 3 coins in equal distance:
My coin array and method are included here:
I am adding new coins on the basis of last coin passes a particular distance on the screen.
Array<Coin> coins = new Array<Coin>();
private void createCoin() {
coinObj = objectFactory.createCoin(CoinEnum.random());
coinObj.isCollided = false;
coins.add(coinObj);
}
private void spawnCoin() {
if (coins.size == 0) {
createCoin();
} else {
Coin c = coins.peek();
if (c.getY() > (Constants.WORLD_HEIGHT / 8))
createCoin();
}
// remove out of screen coins
if (coins.size > 0) {
Coin cc = coins.first();
if (cc.getY() > Constants.WORLD_HEIGHT) {
coins.removeValue(cc, true);
}
}
}
Also hope someone can tell me the mistakes in my approach if any!
Thanks in advance!
First of all, try to model the CoinPattern:
- What is a CoinPattern?
It is just a pattern, describing an arrangement of multiple coins.
- What do I need to describe it?
As it is just a pattern, you don't need no Coins yet.
In my opinion, a list of Points (or Vector2) should be enough.
Each of these Points could describe the relative Position of the Object (in your case Coin) inside the Pattern.
Now you could create constants for your Patterns. The triangle could look something like this:
public static final PATTERN_TRIANGLE = new Vector2[] {
new Vector2(0,0),
new Vector2(1,0),
new Vector2(0,1),
};
Then you could create a method spawnPattern(Vector2[] pattern, int x, int y). This method should then create a Coin for every Vector2 in the pattern.
The position of each Coin could be calculated like this:
int posX = x + pattern[i].x;
int posY = y + pattern[i].y;
Note, that using this methode, the positions of the Coins are relative to the lower, left corner of the Pattern position.

AS3 Change position of object in TileList

I am using a tileList in ActionScript 3 to display movieclips. However I have the problem that not all reference points of the movieclips are in the correct place. This leads to that these movieclips are shown partly outside of their cell in the tileList.
I have tried to adjust the x and y position of the movieClip before adding it to the tileList, but this did not change anything. Now I have tried to find if it is possible to change the x and y position of an object already in the tileList, but without finding any answers.
I hope that I have made my problem clear.
Thanks in advance!
EDIT:
This is the code I tried:
private function initTileList():void {
for(var i:int = 0; i < _movieClips.length; i++) {
changePos(_movieClips[i]);
tileList.addItem({label: _movieClips[i].name, source: _movieClips[i]});
}
}
private function changePos(mc:MovieClip):void {
if(MovieClip(mc).getRect(mc).x != 0) {
mc.x -= MovieClip(mc).getRect(stateMachineRef).x;
}
if(MovieClip(mc).getRect(mc).y != 0) {
mc.y -= MovieClip(mc).getRect(stateMachineRef).y;
}
}
I do not have any errors, it just doesn't affect the position of the object in the tileList.
Example of how the problem looks.
Hard to say where's the problem without knowing these things:
1. What tileList.AddItem() does exactly;
2. What is stateMachineRef
3. How MovieClips are loaded. If they are loaded from a network, that'll be a whole different story.
By the way, you don't have to cast MovieClip(mc) as mc is already a MovieClip. Also, there is no difference as to when you will correct the coordinates: before or after adding to the tileList. Should work either way.
So, given that information on your problem is not complete, I would just suggest you insure the following steps:
-We assume all tiles are displayed inside a tile container. It can be Stage or a MovieClip or any suitable DisplayObjectContainer, so let's call it just tileContainer from now on.
-We assume all tiles are of the same width and height. If you are not sure, you should check it again.
-We assume that each tile in the tileContainer is displayed at some regular grid coordinates. I.e. it conforms the following code:
for (var pos_y:int = 0; pos_y < GRID_SIZE_Y; pos_y++) {
for (var pos_x:int = 0; pos_x < GRID_SIZE_X; pos_x++) {
var tile:Tile = getNextTile(); // just get a tile from somewhere
tile.source.x = pos_x * TILE_WIDTH; // using your tile structure
tile.source.y = pos_y * TILE_HEIGHT;
tileContainer.addChild(tile.source);
}
}
Now I see your problem that some tiles are created in a way that they have their source movieclip coordinates shifted from (0,0). So they will not align with the grid.
What are you doing seems to be a proper way of aligning them but I don't know exactly what happens in your code so I'll just rewrite it:
function changePos(mc:MovieClip) {
var r:Rectangle = mc.getRect(mc);
mc.x -= r.x; // note you don't need any if's
mc.y -= r.y;
}
And in the above loop just add the changePos() AFTER setting the grid coordinates:
tile.source.x = pos_x * TILE_WIDTH;
tile.source.y = pos_y * TILE_HEIGHT;
changePos(tile.source);
tileContainer.addChild(tile.source);
If you're following all these steps, that's basically all you need and it will work for sure.

How to create sprite from RenderTexture cocos2d-x v3.2?

I'm trying to make a game that will take what users draw on their screens and create a sprite with a physics body. I looked around and I saw a tutorial that demonstrated this. Unfortunately the tutorial was made in Cocos2d-x v2.
http://build-failed.blogspot.com/2012/08/freehand-drawing-with-cocos2d-x-and.html
That is the tutorial that I am referring to.
http://www.cocos2d-x.org/wiki/Render_To_Texture
I tried to use that cocos2d-x tutorial to help me, but it has been labeled outdated (I tried it anyway and it didn't work). Is it still possible to allow the user to draw through this method? Or do I need to find another method to allow the user to draw the sprites? Any suggestions would be helpful. Thanks.
void GameScene::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event)
{
Point start = touch->getLocation();
start = Director::getInstance()->convertToGL(start);
Point end = touch->getPreviousLocation();
end = Director::getInstance()->convertToGL(end);
target->begin();
float distance = start.getDistance(end);
for (int i = 0; i < distance; i++)
{
float difx = end.x - start.x;
float dify = end.y - start.y;
float delta = (float) i / distance;
brush->setPosition(Point(start.x + (difx * delta), start.y + (dify * delta)));
brush->visit();
}
target->end();
}
void GameScene::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event)
{
myObjectSprite = Sprite::createWithTexture(target->getSprite()->getTexture());
myObjectSprite->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));
this->addChild(myObjectSprite);
}
This is what I gathered from those links. I can draw but there are a few problems.
The first attempt to draw always reflects horizontally over the center of the screen.
After a few drawings the fps begins to drop, and the app begins to take up a lot of memory and CPU usage.
The for loop in the onTouchMoved method is used because the onTouchEnded method isn't called fast enough, so there is often a large gap between each point that the onTouchMethod obtains. The loop is used to draw the brush sprites in a line between each point to prevent the gaps. However, for some reason it is not drawing in between the gaps.
Additionally, in the first link the person uses b2PolygonShape and b2FixtureDef from box2d. What are the new names of the classes in cocos2d-x v3?

issue with addChild's X and Y value

I have an Enemy class that deals with my monster moving and attacking. Within that class, I have another class called enemyMagic, which is a blank movieclip that serves as a masterclass to different movieclips that I will make.
So in the enemyMagic class, I add a movieclip called attack1
public var attack1:Attack1 = new Attack1;
public function EnemyMagic() {
////////////CREATE THE TIMER//////////
masterEnemyAttackTimer.addEventListener(TimerEvent.TIMER, mastertimer);
////////////ATTACKS/////////
//TIER 1//
addChild(attack1);
}
And in the enemy class, I add the enemyMagic when the enemy is attacking a certain position.
for (var k:int = 0; k < Main.tileset.length; k++)
{
if (! Main.tileset[k].tileMiddle.hitTestObject(this.enemyVisionPoint))
{
if (Main.tileset[k].tileHP !== 0)
{
attackoptions.push(Main.tileset[k]);
}
if (Main.tileset[k].tileMiddle.hitTestObject(Main.player.visionPoint))
{
addChild(enemymagic);
Main.tileset[k].outline.gotoAndStop("attack");
this.enemymagic.x = (Main.tileset[k].x);
this.enemymagic.y = (Main.tileset[k].y);
trace(enemymagic.x, enemymagic.y, Main.tileset[k].x, Main.tileset[k].y);
For some reason, the enemymagic is tracing the exact same number as the tile's x and y, but it isn't adding it on the tile. It adds it way off the screen. I think it might be because it starts on the enemy's x and y and then calculates?
So my question is how can I get the enemymagic movie clip to get exactly on the position of the tile?
You can do two things. First, when you do a plain addChild() the base coordinate system of the child is the one of its parent, which is your Enemy instance, which is of course at somewhere nonzero. And then you assign it the coordinates of Main.tileset[k] which has a different parent (most likely instance of Main). This creates the distance you speak of. So, in order to locate your magic over the exact tile, either use this.globalToLocal(Main.tileset[k].localToGlobal(PZERO)) where PZERO is a new Point() constant (or write new Point() instead of PZERO, but this will create another empty Point object and will quickly escalate), or do an addChild() directly to the tile you are attacking with unaltered coordinates.

AS3: Sprite following a Path in high speed

First of all sorry for some english mistakes. Portuguese is my first language(I am from Brazil)
Im trying to make a space game from scratch in AS3 and the way to move the ship is like in the game Air Traffic Chief.
I succeed at some point. But when the ship is very fast it start to shake and its not very smooth and clean as I want.
Here is what i have done: http://megaswf.com/s/2437744
As the code is very big so I pasted in pastebin: pastebin.com/1YVZ23WX
I also wrote some english documentation.
This is my first game and my first post here. I really hope you guys can help me.
Thanks in advance.
Edit:
As the code is very big i will try to clarify here.
When the user MouseDown and MouseMove the ship every coordinate is passed to an array.
When the user MouseUP this array is passed to a function that fix the array.
For example: If the distance between two coordinates is greater than 5px, the function creates a coordinate in the middle of the two coordinates.
if I take this function off the problem seen to be solved. But if the user move the mouse very slow it still happens. It also creates a problem that i was trying to solve with that function. as the distance of the two coordinates are very big when the ship arrive in one coordinate most of the line path disappear.
I uploaded a version without the function that fixes the array. http://megaswf.com/s/2437775
I think there is 2 ways for solving this problem
1- Try to fix the noise in the array of coordinates 2- Take off the function that create an coordinate between two points and try to fix the problem of the line path disappear.
Here is the 2 important functions:
this function moves the ship
private function mover():void
{
if (caminhoCoords[0]!=null) // caminhoCoords is the array that contain the path
{
var angulo:Number = Math.atan2(this.y - caminhoCoords[0][1], this.x - caminhoCoords[0][0]);
this.rotation = angulo / (Math.PI / 180);
this.x = this.x - velocidade * (Math.cos(angulo));
this.y = this.y - velocidade * (Math.sin(angulo));
var testex:Number = Math.abs(this.x - caminhoCoords[0][0]); //test to see the distance between the ship and the position in the array
var testey:Number = Math.abs(this.y - caminhoCoords[0][1]);
if (testey<=velocidade+2 && testex<=velocidade+2) // if is velocidade+2 close then go to the next coordnate
{
caminhoCoords.shift();
}
}
}
This function draw the line:
private function desenhaCaminho():void //draw the black Path
{
if(caminhoCoords.length>=1)
{
caminho.graphics.clear();
caminho.graphics.lineStyle(1, 0x000000, 1,true);
caminho.graphics.moveTo(caminhoCoords[0][0],caminhoCoords[0][1]);
for (var i:int = 1; i < caminhoCoords.length; i++)
{
caminho.graphics.lineTo(caminhoCoords[i][0], caminhoCoords[i][1]);
}
}else
{
caminho.graphics.clear();
}
}
Every time the ship arrive in one coordinate is take that coordinate off the array and redraw the array.
Is there a better way of doing that?
I believe if you set your registration point of the plane to the centre and use .snapto(path), it will improve the action.
Judging from just the look of the stuttering, I would guess you need to smooth out the "line" a fair bit. It's probably picking up a lot of noise in the line, which is then translated into the rotation of the plane. Either smooth out the rotation/position of the plane, or the line itself.