I am new to 'Collision Detection'; I have found resources on collisions, such as:
Rect rc_img1 = new Rect();
image.getDrawingRect(rc_img1);
Rect rc_img2 = new Rect();
bottomLayout.getDrawingRect(rc_img2);
if (Rect.intersects(rc_img1, rc_img2)){
Toast.makeText(MainActivity.this, "Detected", Toast.LENGTH_LONG).show();
}
The image coming from the top of the screen should collide with the layout at the bottom of the screen. When the image hits the bottom layout I want to perform my actions.
For rectangles colliding with other rectangles, you can check all 8 points of the 2 rectangles with .contains() of the other rectangle. More generally, you can use Area, and Area.intersect(otherArea) != null
Related
I have an ArrayList called rectangles that are at specific x,y,width,height values and another Rect called bar that moves up the screen and is supposed to intersect those rectangles. This is my code:
for (Rect rect : rectangles) {
if(Rect.intersects(bar, rect)) {
Log.d("GameScreen", "intersected");
intersected = rect;
checkButtons();
}
}
However, when I look at my logcat, it isn't logging "GameScreen, intersected" and the counter I have set up from checkButtons() doesn't change the score on the screen when they intersect and bar just seems to pass through the rectangles.
How can I make it so that I am sure that the Rects are intersecting?
Here is the code that I use for the moving ImageView:
int x=brickimg.getRight()-brickimg.getLeft();
int y=brickimg.getBottom()-brickimg.getTop();
final TranslateAnimation translate = new TranslateAnimation(
Animation.ABSOLUTE,x1, Animation.ABSOLUTE,
-2000, Animation.ABSOLUTE,0,
Animation.ABSOLUTE,y);
translate.setDuration(1200);//speed of the animation
translate.setFillEnabled(true);
translate.setFillAfter(true);
//brickimg.startAnimation(translate);
//2nd brick animation
int x1=brickimg2.getRight()-brickimg2.getLeft();
int y1=brickimg2.getBottom()-brickimg2.getTop();
final TranslateAnimation secondone = new TranslateAnimation(
Animation.ABSOLUTE,x1, Animation.ABSOLUTE,
-2000, Animation.ABSOLUTE,0,
Animation.ABSOLUTE,y1);
secondone.setDuration(1200);//speed of the animation
secondone.setFillEnabled(true);
secondone.setFillAfter(true);
This is for two images. Here is the code that I tried to use for collision detection:
Rect rc1 = new Rect();
brickimg.getDrawingRect(rc1);
Rect rc2 = new Rect();
playerimage.getDrawingRect(rc2);
if (rc1.intersect( rc2)) {
playerimage.setVisibility(View.GONE);
}
However, the only thing that happens is that playerimage turns invisible when the app starts. It doesn't turn invisible again. One of the images doesn't move, and the other moves across the screen towards the one that doesn't move (using the code I put above). The image that doesn't move turns invisible immediately, and not when the second image touches it. I'm trying to make it so it does something when it touches the moving image. Besides this, I've also tried .getHitRect and I've also tried .intersects instead of .intersect, but none of it works. The moving image is an ImageView, not a sprite. Is there another option?
I use libGDX for a 3D game. In this game an 3D arrow should indicate a certain direction in 3D space. As the player is moving, the direction of the 3D arrow is updated for every frame.
I want to place the arrow in the direction, the camera is looking 3 units before the camera, so that the arrow is always visible. Therefore I added the camera direction to the current camera position and used this as translation part for the arrow. The direction is calculated by substracting the arrow position from the target.
All this works fine, the arrow is displayed at the right position and it moves. The problem is, it sometimes points to the target, and sometimes not.
Here my code:
Vector3 targetPosition = new Vector3(1, 1, 10);
Vector3 cameraPosition = gameController.getCamera().position.cpy();
Vector3 cameraDirection = gameController.getCamera().direction.cpy();
Vector3 up = gameController.getCamera().up.cpy();
Vector3 arrowPosition = cameraDirection.scl(3).add(cameraPosition);
Vector3 arrowDirection = targetPosition.cpy();
arrowDirection = arrowDirection.sub(arrowPosition).nor();
Matrix4 transformationMatrix = new Matrix4();
// calculate orthogonal up vector
up.crs(arrowDirection).crs(arrowDirection);
arrowModel.transform = transformationMatrix.setToLookAt(arrowDirection,
up).trn(arrowPosition);
To avoid that the vectors are calculated wrong, some debug lines were added:
modelBuilder.begin();
MeshPartBuilder partBuilder = modelBuilder.part("lines", GL20.GL_LINES,
Usage.Position,
new Material(ColorAttribute.createDiffuse(Color.GREEN)));
Vector3 linePos = arrowPosition.cpy();
partBuilder.line(linePos.cpy().add(arrowDirection), linePos);
partBuilder.line(linePos.cpy().add(up), linePos);
debugModel = new ModelInstance(modelBuilder.end());
As a result, I see a correct green line for the up vector (current up vector of the camera), and a green line pointing correctly to my target, the green cube. The arrow does something other:
http://www.directupload.net/file/d/3638/2ka7kvvj_jpg.htm
In the picture the arrow is quite near the right direction (green line), there are other situations, where it points in the completely wrong direction.
I used quite a lot combinations of .translate, .trn, .setToLookAt, and .rotate but all of them showed similar, wrong results.
Do you have an idea what went wrong here?
I am currently developing a game for android using libgdx library .
Lets say we have a lizard, now the user creates paths by sliding fingers on the screen, on which the lizard can walk on.
The question is , how do restrict the lizard to walk on only where the finger touched the screen( on the path - between the bounds).
public class Block {
static final float SIZE = 1f;
Vector2 position = new Vector2();
Rectangle bounds = new Rectangle();
public Block(Vector2 pos) {
this.position = pos;
this.bounds.width = SIZE;
this.bounds.height = SIZE;
}
}
In this example we can see a block, the bounds of the block is a rectangle on which the lizard can walk on.
how do I make some similar bounds only using a circle?
Here is what i got so far:
I have created a doubled layer bitmap that overlap each other. When the user touches the screen , he erases the first bitmap reveling the second bitmap underneath the first one ( only the part where the user touched get removed).
here is the function that erases the first bitmap.
public void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(bgr, 0, 0, null);
c2.drawCircle(X, Y, 40, pTouch);
Paint new_paint = new Paint(/*Paint.ANTI_ALIAS_FLAG*/);
new_paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));
//new_paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawBitmap(overlay, 0, 0, new_paint);
}
Notice#
the bitmap is removed using a circle shape.
It would be great if i could add to the circle that's removing the bitmap, a property of bound, on which the lizard can walk on.
Any ideas?
u should update the cordinates of bounds as per the lizard position
bounds.x=position.x;
bounds.y=position.y;
So that your bounds follow the lizard
Also instead of using recatangle for bounds try to use
sprite.getBoundingRectangle()
this method gives u the exact rectangular bounds of the image so no need to maintain bounds.
Provided you use AtlasSprite or Sprite for your image.
I shared my game Bomberman early. You can find code you needed in GameScreen class
p.s. also you can find different interesting samples of LibGDX usage here
I am making a finger painting app. Using Paths I have created a canvas for users to draw lines on as if finger painting. I have saved the paths and reload them when the device is rotated to landscape mode. However with the new screen dimensions part of the drawing is now off screen.
What is the best way of adjusting the points in my path to stretch the image across the new screen dimensions so the user doesn't loose any of their drawing off screen?
I solved my issue like this:
if(getWidth() > getHeight())
{
Matrix scaleMatrix = new Matrix();
RectF rectF = new RectF();
p.computeBounds(rectF, true);
scaleMatrix.setScale(1.6f, .6f,0,0);
p.transform(scaleMatrix);
}
canvas.drawPath(p, paint);
Where p is the path.