I have a Problem to detect collisions. I'm using TiledMap and created a virtual joystick, so that its possible to move in every direction not just left, right, top, bottom. The Point of View is directly 90 degrees from the top.
I don't know if that's the purpose of a TiledMap, but I thought the maps are easy to create. But now I 've got Problems with the collision detection. Since the map is not arranged like a chessboard, for example, I need to check the whole Sprite for collision. Can you please explain me to how that works?
Thank You
First of all I recommend you to checkout this question to clear up some things, and to get a basic Idea how collision detection works with TiledMaps.
Summarized: Using a TileEditor you can add different layers to your TiledMap. One of theese layers can be a object layer which can be used for collision. For how to create and access the layer please checkout the linked question.
For your example there are some central questions which needs to be cleared out first:
Which shape and size do the colliding objects have?
Can the objects move in between two tiles?
What should happen on collision?
Pokemon is a super easy example. The Player has the size of exactly one tile and can not move in between them. If there is a collision the player just can't move.
If that is what you want you can just add a check before moving any object: If the next tile isn't valid just don't move the object. For the collision check you can just adapt the example code from the first answer.
On the other end of the specturm you could have different shaped objects with differnt scales which have a dynamic velocity and should bounce of the objects on the TileMap. In that case it could be clever to use box2d for collision detection like in this answer.
So depending on your needs just try to adapt any of the answers I linked. Maybe just start with a super simple box collision try to extend your code.
use this method
void isCollition(Object x, Object y) {
Boolean collide = false;
if (x.getX() + x.getwidth() < y.getX() + y.getWidth() ||
x.getY() + x.getHeight() < y.getY() + y.getHeight() {
collide = true;
}
return collide;
}
Related
I am very new to this ARCore and I have been looking at the HelloAR Java Android Studio project provided in the SDK.
Everthing works OK and is pretty cool, however, I want to place/drop an object when I touch the screen even when no planes have been detected. Let me explain a little better...
As I understand ARCore, it will detect horizontal planes and ONLY on those horizontal planes I can place 3D objects to be motion tracked.
Is there any way (perhaps using PointCloud information) to be able to place an object in the scene even if there are no horizontal planes detected? Sort of like these examples?
https://experiments.withgoogle.com/ar/flight-paths
https://experiments.withgoogle.com/ar/arcore-drawing
I know they are using Unity and openFrameworks, but could that be done in Java?
Also, I have looked at
How to put an object in the air?
and
how to check ray intersection with object in ARCore
but I don't think I'm understanding the concept of Ancor (I managed to drop the object on the scene, but it either disappears immediately or it is just a regular OpenGL object with no knowledge about the real world.
What I want to understand is:
- How and is it possible to create a custom/user defined plane, that is, a plane that is NOT automatically detected by ARCore?
- How can I create an Ancor (the sample does it in the PlaneAttachment class, I think) that is NOT linked to any plane OR that is linked to some PointCloud point?
- How do I draw the object and place it at the Ancor previously created?
I think this is too much to ask but looking at the API documentation has not helped me at all
Thank you!
Edit:
Here is the code that I added to HelloArActivity.java (Everything is the same as the original file except for the lines after // ***** and before ...
#Override
public void onDrawFrame(GL10 gl) {
...
MotionEvent tap = mQueuedSingleTaps.poll();
// I added this to use screenPointToWorldRay function in the second link I posted... I am probably using this wrong
float[] worldXY = new float[6];
...
if (tap != null && frame.getTrackingState() == TrackingState.TRACKING) {
// ***** I added this to use screenPointToWorldRay function
worldXY = screenPointToWorldRay(tap.getX(), tap.getY(), frame);
...
}
...
// Visualize anchors created by touch.
float scaleFactor = 1.0f;
for (PlaneAttachment planeAttachment : mTouches) {
...
}
// ***** This places the object momentarily in the scene (it disappears immediately)
frame.getPose().compose(Pose.makeTranslation(worldXY[3], worldXY[4], worldXY[5])).toMatrix(mAnchorMatrix, 0);
// ***** This places the object in the middle of the scene but since it is not attached to anything, there is no tracking, it is always in the middle of the screen (pretty much expected behaviour)
// frame.getPose().compose(Pose.makeTranslation(0, 0, -1.0f)).toMatrix(mAnchorMatrix, 0);
// *****I duplicated this code which gets executed ONLY when touching a detected plane/surface.
mVirtualObject.updateModelMatrix(mAnchorMatrix, scaleFactor);
mVirtualObjectShadow.updateModelMatrix(mAnchorMatrix, scaleFactor);
mVirtualObject.draw(viewmtx, projmtx, lightIntensity);
mVirtualObjectShadow.draw(viewmtx, projmtx, lightIntensity);
...
}
You would first have to perform a hit test via Frame.hitTest and iterate over the HitResult objects until you hit a Point type Trackable. You could then retrieve a pose for that hit result via HitResult.getHitPose, or attach an anchor to that point and get the pose from that via ArAnchor.getPose (best approach).
However, if you want to do this yourself from an arbitraty point retrieved with ArPointCloud.getPoints, it will take a little more work. In this approach, the question effectively reduces down to "How can I derive a pose / coordinate basis from a point?".
When working from a plane it is relatively easy to derive a pose as you can use the plane normal as the up (y) vector for your model and can pick x and y vectors to configure where you want the model to "face" about that plane. (Where each vector is perpendicular to the other vectors)
When trying to derive a basis from a point, you have to pick all three vectors (x, y and z) relative to the origin point you have. You can derive the up vector by transforming the vector (0,1,0) through the camera view matrix (assuming you want the top of the model to face the top of your screen) using ArCamera.getViewMatrix. Then you can pick the x and z vectors as any two mutually perpendicular vectors that orient the model in your desired direction.
I'm making a program that needs to detect the collision between 2 non-axis aligned boxes. My program only needs an indication if 2 non-axis aligned boxes are colliding. I would like to have the most simple and efficient algorithm possible.
Here I visualized the problem.
So as you can see squares 1,2 and 3 would return true because they collided with the green squares.
4 would return false because it isn't colliding.
I do have all the boxes of both colors in separate array lists.
Does anybody know a library or algorithm for this problem? Thanks in advance.
Check out the Area class in the java.awt.geom package.
http://docs.oracle.com/javase/6/docs/api/java/awt/geom/Area.html
I don't know how "easy" your game really is, how many shapes you'd have to check for (I'm thinking efficiency here), but if you have your different color shapes in different lists, a kind of brute force iteration may work for you. Not a clue if it would be efficient enough for you. I use box2D to tell me the collisions, but sounds like that may be overkill for you.
The brute force method I'm thinking of would be to utilize libgdx's Intersector class (check out the API, it has lots of methods). Iterate through your rectangles comparing to the others. Something like IntersectRectangles() gives you a boolean if two rectangles overlap (ie: collide).
This may be too inefficient/hacky, and a physics library may be too much. So one of the other answers provided may be the sweet spot.
A commonly-used approach involves quadtrees. There's a good write-up and tutorial here, which explains how to use quadtrees to perform collision detection in 2D space.
The general idea is that your game area will keep being partitioned by four as your add objects. Each partition is called a node and each node will maintain a reference to objects that exist in the corresponding partition. Objects are placed into nodes based on where they are in the 2D space. If a node does not fit cleanly into a partition, it is inserted into the parent node. Using this method, you don't have to perform an expensive check against every other object in your 2D space, because you can be sure that objects in different nodes (at the same level; i.e., sibling nodes) will not collide. So you only have to perform your collision detection on a small subset of objects.
Note that this just tells you which objects are occupying a certain area; it's a more efficient way to hone in on objects that are likely to be colliding. After that you have to check if the objects are actually colliding. There is another write-up here that goes over various techniques to accomplish this.
There are two algorithms/data-structures you need to consider for this problem:
A spatial data-structure to store your rotated quads, to efficiently determine which pairs of quads need to be tested against each other. Other answers have already addressed this. If the number of quads is small enough then you can just test all the red quads against all the green quads, which is O(m * n).
An algorithm to perform the actual test of one rotated quad against another. One of the simplest is the Separating Axis Theorem.
The basic idea behind the SAT is that if you can find at least one line where all the points of one convex object are on one side of it, and all the points of the other are on the other side, then the two are not colliding. The potential lines that you need to test are just the edges of both of the objects.
To implement it you need to implement a point-line test to tell you which side of an edge a point is on. This is done by calculating the normal to the edge, and then calculating the dot product of the edge normal and a vector from a point on the edge to the point you are testing. The sign of the dot product tells you which side the point is on (positive means the outside the edge, for an outward pointing normal). Whether you count zero (on the line) as outside or inside depends on whether you want objects that are just touching but not penetrating to count as a collision, if you do then the dot product must be greater than zero to count as outside.
For example if the points on objects are in clockwise order, and edgeA and edgeB are the two points of an edge on one object, and pointC is a point on the other object, the test is done like this (not using function calls, to show the math):
boolean isOutsideEdge(PointF edgeA, PointF edgeB, PointF pointC)
{
float normalX = edgeA.Y - edgeB.y;
float normalY = edgeB.X - edgeA.x;
float vectorX = pointC.x - edgeA.x;
float vectorY = pointC.y - edgeA.y;
return (normalX * vectorX) + (normalY * vectorY) > 0.0f;
}
Then the algorithm is:
For each edge on quad A, if all the corner points on quad B are on the outward facing side of the edge, then A and B are not colliding, stop processing and return false.
For each edge on quad B, if all the corner points on quad A are on the outward facing side of the edge, then A and B are not colliding, stop processing and return false.
If all those tests have been performed and none have returned false, then A and B are colliding, so return true.
The SAT can be generalized to arbitrary convex polygons.
So I decided to go with box2d in the end. This was the best solution because of the diffrent mask-qualifiers, the objects didn't collide but it could be easily checked wether they should be colliding.
I had to make my own contactlistener that overrides the default contactlistener. Here I could do anything if any 2 objects collided.
Thanks everyone for the help.
I want to add springs in my game that work like the ones in sonic - i.e. if you can't get over an obstacle you have to hit a spring which sends the main character flying towards another spring that gets him over that obstacle. I drew a little diagram below to demonstrate what I mean (yellow arrows represent the direction the player will go towards and the red - are the springs).
In my Spring class I have created a method:
//The detection area (blue rectangle in the diagram)
public Rectangle broadPhaseDetection() {
broadPhaseRectangle = new Rectangle(getxPos() - broadPhaseLength, getyPos(),
broadPhaseLength, broadPhaseLength);
return broadPhaseRectangle;
}
If the Player collides with a Spring, I check to see if there's ANOTHER Spring within the blue area and if there is - calculate the vector that takes you towards that spring and send the player in that direction.
This seems like a very simple concept which has probably been done loads of times before, but I couldn't find any good examples online for some reason. Does anybody know how I can get the vector I need?
Any insight is highly appreciated, thanks.
If the position vector of the spring you hit is Vector2 v1, and the position of the second spring is Vector2 v2, then you just need v2.sub(v1).
If you are only interested in the direction rather than the length of the vector, you might want to normalize by doing v2.sub(v1).nor() (this gives you a vector pointing the right way, but with length 1)
Just subtract the destination from the source to get the vector between them. The vector from PointA to PointB is: PointB - PointA. (And to subtract two vectors, just subtract their components.)
In Libgdx a Vector2 can be used to track these, and it supports overloaded sub methods.
I am making a game in java which involves characters moving around a map and having some solid collision objects (i.e. buildings) placed around the map by reading certain data from a text file. There will be multiple maps where these objects' locations will change. My question is would painting a rectangle in a certain color that indicates collision behind such structures or would reading mouse coordinates and searching an array of these structures to see if that point lies on a building, thus denying the move or altering, be more resourceful and/or quicker. If painting a rectangle is the best, would leaving it behind the structure or deleting it after detecting for collision be better. Thanks for your time!
In my junior year in college I worked on a Collision detection system algorithm for the windows phone. It is hardly perfect but it was EXTREMELY efficient and can be adapted to a majority of games.
The way that it worked was pretty simple. There were two types of objects; Collidable objects (such as enemies or buildings) and Objects that you wish to check for collisions with these collidable objects.
I had this idea when I was going through a data structures class and we spoke about Linked Lists. I thought what if each link was a collidable object that you could stick your game objects that were already created in it. Then as the game objects moved around you would have a lightweight way of checking their locations for collisions. Thus my system was born.
All it really is, is a class that fires off either every game cycle or when ever you choose to check for collisions. You give it your players location, or bullet location or what ever object you want to see if it is colliding with something and it searches all of the collidable object locations and conducts test to see if they are overlapping.
The real efficiency of it comes into play when you add in a second element (Locations AND quadrant)
For Example if I break the phone screen up into for parts and I know which quadrant my player or bullet is in I can choose to only scan a list of collidable objects that are within that quadrant. Thus cutting your search algorithm to a fourth of its origonal size.
There are many different ways of detecting collisions. This was a simple example I used in my class to show how you could detect two circles colliding that were actually squares. As you can see simply by taking the center point coords of the circles and the radius's you can calculate the hypotenuse and determine where or if they are touching.
Good luck! if you have any questions feel free to ask!
The last reply in this posting may help you out. It is a simple maze. The structure of the maze is controlled by a data file which simply contains 0, 1 to indicate a path or a wall. You navigate through the maze using the arrow keys. When an arrow key is pressed the code checks to make sure the next square is not a wall.
I have made threads in the past about similar questions but because of my lack of detail the answers have not really been related to what I needed so I am going to try explain my question in as much detail as I can and hopefully it will be easier for you to understand what I require.
I watched Bucky's slick game tutorials on youtube and made a 2D Java game, the game is basically a 2D player viewed from above (birds eye view) can move around a 2D map with user key input (up, down, left, right). The map the player moves around is very small so that meant boundaries had to be set so that the player could not walk off of the map, to give you a better idea of how this was done, here is the tutorial for setting up the voundries:
http://www.youtube.com/watch?v=FgGRHId8Fn8
The video will also show you exactly what the game is like.
The problem is, these boundaries only require one axis meaning that if the player is walking down you say something like "if player gets to the coordinate (number) on the X axis change the player movement to the opposite direction so that he can not go any further."
Now this creates a problem for me because this only requires one axis so it easy to set up and understand but if you look on the video, on the map there is a house and I want my player not to be able to walk over that also but this deals with 2 dimensions, I have looked at things like rectangle collisions and have seen things relating to them in the other posts but I get confused because I am new to Java and havent really done much with it at the moment apart from watching Bucky's tutorials.
My code at the moment for my game class has got the following methods: init, render and update. So to sum it up I really just want to set up a way of not letting my player walk through the house, I will mention also (I should have mentioned it in my other threads) as I am very new to Java, could you please take a step by step method of showing me how to set up the collisions, I mean even the basics of things like making the rectangle if required.
If my code is required please tell me and I will post it as soon as possible.
Thank you in advance.
You can set up the board as a 2x2 grid of a class that has has property such as 'isBlocked'. By default the edges of the board would have this property set to true to prevent the character from walking off the edge. When you add other obstacles such as a house or a wall the grid position(s) the object occupies would also have the property set to true. Then when moving a character you just check if the grid position the character moves to has the property set to false to see if it's an allowable move. This also makes it quite trivial to save the level data so you can just load them from disk later on.
Two possible options:
Extend Shape or Rectangle or the relevant Slick objects (they should exist IMO) and just check for intersect()
Look for (x1,y1) and (x2,y2) values such that it starts outside and ends up inside.
Assuming you have intersect() methods:
//Grab the previous position
prevPosX = movingobject.X;
prevPosY = movingobject.Y;
//Update the position
movingobject.update();
//Test for collision
if(movingobject.intersects(targetobj)) {
//If it collided, move it back
movingobject.X = prevPosX;
movingobject.Y = prevPosY;
//And reverse the direction
//(might want to do other stuff - e.g. just stop the object)
movingobject.speed *= -1; //Reverse the speed
}
in this case your update class should also add one more condition to look for the house. let say the cooridnates of house(assuming rectanglular house here for other shape just change x and y values) are (x1,y1)(x1,y2)(x2,y2)(x3,y1) you have to add a condition to make sure
x value is not between x1 and x2 and at the same time y value cannot between y1 and y2.