Hello :) I'm currently working on something that hinges on checking the overlap of two rectangles in Java on BlueJ, and I've been checking the internet stuck for hours for anything to help but I've not managed to find anything which helps which is specific enough to what I'm dealing with.
Currently, I'm writing a method called "checkOverLap" and it looks a little like this:
private Boolean checkOverlap() {
if (word2.getXPosition() >= word1.getXPosition() && word2.getXPosition() <= word1.getXPosition() + word1.getTextWidth() && (word2.getYPosition() >= word1.getYPosition() && word2.getYPosition() <= word1.getYPosition() + word1.getTextHeight())){
return true;
}
else{
return false;
}
}
Erm, I'm relatively new to Java, so please forgive how horrendously this is formatted >.>
The general gist of what it needs to do, is to return true when the rectangles overlap :) Else, it will return false. The reason this is required, is because I want the rectangles to randomize their position on the screen until they overlap.
I have already included accessor methods which return the X and Y coordinates and the Width and Height of the rectangles, and these are what I am using in the if statement to compare and see if they over lap.
As to whats wrong with it, I'm currently unsure but I'm thinking it's to do with the logic of the statement, like I haven't compared the right variables etc or I've added the wrong operators :/
Any advice or such would be appreciated :)
You don't have to do it yourself. Use the intersects method of java.awt.Rectangle instead:
final Rectangle r1 = new Rectangle(50, 50, 10, 10);
final Rectangle r2 = new Rectangle(40, 40, 10, 10);
final Rectangle r3 = new Rectangle(40, 40, 15, 15);
System.out.println(r2.intersects(r1)); // false
System.out.println(r3.intersects(r1)); // true
Related
I've finally completed the collision detection, however the collision response is very glitchy (if you try you can go through walls) and that's mainly because I have no information about the collision angle!
I have camPos(x,y,z) coordinates of my camera aswell as the min and max values of model(minX,minY,minZ,maxX,maxY,maxZ).. with a simple test I check if the camPos is interecting the model boundaries:
if(cameraX > xMax || cameraX < xMin) {
collisionX = false;
collisionY = false;
collisionZ = false;
} else {
collisionX = true;
System.out.println("collisionX: "+ collisionX); // collision on x is true!
}
I have acess to all vertice positions and calculated the min max values of the object to create a BoundingBox.
In order to get the right direction in which I want to push the object I need to know in which direction the nearest face is pointing (left,right,forward,back?)
To find out the angle I thought I could use the normal coordinates which I also have acess to, since they indicate a 90 degree angle to the face, right?
console print: //all 'vn' values of cube.obj
xNormals:0.0
yNormals:0.0
zNormals:0.0
xNormals:0.0
yNormals:0.0
zNormals:0.0
xNormals:1.0
yNormals:1.0
zNormals:1.0
xNormals:0.0
yNormals:0.0
zNormals:0.0
xNormals:-1.0
yNormals:-1.0
zNormals:-1.0
xNormals:0.0
yNormals:0.0
zNormals:0.0
Basically I want to know how these normal coordinates have to be applied to the min and max values of the object so that I can define all faces of the BoundingBox for example: face A is defined by xMin_a and xMax_a and faces left, face B is defined by xMin_b and xMax_b and faces right and so on..
I hope it's a bit more understandable, it's quite hard to explain..
Okay I've figured out a way to do it, hope it will help someone else too: I found out how to calculate the faces of a bounding box, it was actually not even that hard and it had absolutely nothing to do with normals.. sorry for the confusion.
As shown in my answer you can calculate the boundingBox of objects with their min/max values.. but you can also define all six faces of the box by extending the check and use a boolean to find out if the respective face collides somewhere:
if(collisionX == true && collisionY == true) {
if(cameraZ+0.2 > zMin_list.get(posIndex)-0.2 && cameraZ+0.2 < zMin_list.get(posIndex)) {
faceA = true;
System.out.println("faceA = " +faceA + " face a is true!");
} else {
faceA = false;
}
}
You can do this for all six faces where A(Forward), B(Back), C(Left), D(Right), E(Up) and F(Down) will define where the collision direction should be:
If the collision is on Face A, the response will be moving backwards (on z axis minus).. That way you will never be able to glitch through a wall because it will always push you away from the collision area.
I am currently making a 2D Platformer in Java. I am a beginner so take it easy.
I have a problem with the gravity in the game. I am using different variables for falling and jumping. I am using a tiled map. So lets get to the point.
My fall method works like this -
if(collisionDown == false) {
characterY += fall;
fall ++;
{
fall is equal to 4. and If collisionDown is true it resets back to 4.
My jump method is almost the same:
if(key.E == true && collisionDown == true) {
characterY -= jump;
jump --;
}
jump is equal to 16. and If collisonDown is true it resets back to 16.
Now problem is: imagine the character is jumping. its in the air and while going down characterY += fall; lets say characterY = 250 and fall is equal - 15 at that exact moment. The next solid tile below the character starts at Y position 255. character is at 250 and does NOT detect collision so next frame it adds 15 to characterY which is 250 + 15 = 265. At that point the character has "entered" the solid tile which was at positionY 255.
I have "fixed" that so the character gets back ON TOP of the solid tile (and that is visible and annoying.) That is not the perfect solution because it slows the character 1 frame each time it enters a solid tile(which is because it detects left and right collision and the character can't move). The character visibly stutters if I can say it like that.
I need a solution for that problem but can't think of any.
So if you make a suggestion I would be happy. Thank you.
I would probably use something like the following.
if(collisionDown == false) {
characterYnext = characterY + fall; //Get Next Position
if(NextMovementCollides()){ //Basically if next position is too far.
characterYnext += difference_between(CharacterY,Ground); //This should move the character to the ground state.
fall = 0; //No longer falling so reset the value.
}
else{characterY += fall; fall++;} //Otherwise continue falling like normal.
}
DISCLAIMER: I'm not a java programmer so my syntax might be a bit off.
This should work, just plug in your game logic where it would make sense.
The way I usually handle this, is to pre-check movement:
private int moveDown(int fall){
if (isSolidBlock(characterX, characterY + fall)){
//Knowing the height of your block, calculate some kind of reduction. If your block height is 40, it's probably something like (characterY + fall)%40
fall = 4;
collisionDown = true;
return maxFallUntilSolidBlockReached();
}
fall++;
return fall;
}
private boolean isSolidBlock(int x, int y){
//Implement some kind of check if at (x,y) there's a solid block.
}
Then just do this for the fall calculation:
if(collisionDown == false) {
characterY += moveDown(fall);
}
I am using libgdx for easy 3D game, I need check model is clicked.
It is my code:
public int getObject (int screenX, int screenY) {
Ray ray = cam.getPickRay(screenX, screenY);
int result = -1;
float distance = -1;
for (int i = 0; i < rooms.size; ++i) {
final GameObject instance = rooms.get(i);
instance.transform.getTranslation(position);
position.add(instance.center);
final float len = ray.direction.dot(position.x-ray.origin.x, position.y-ray.origin.y, position.z-ray.origin.z);
if (len < 0f)
continue;
float dist2 = position.dst2(ray.origin.x+ray.direction.x*len, ray.origin.y+ray.direction.y*len, ray.origin.z+ray.direction.z*len);
if (distance >= 0f && dist2 > distance)
continue;
if (dist2 <= instance.radius * instance.radius ) {
result = i;
distance = dist2;
}
}
return result;
}
It it sometimes work.
Is is my model:
http://www6.zippyshare.com/v/97501566/file.html
What do I wrong?
Any help for me?
I am new with libgdx.
When was I press 1 it lights, but when I waas press 2, 1 lights too (instead 2)...
I didn't fully analyze your code nor do I know what It it sometimes work. actually means (e.g. in which circumstances doesn't it work?) but you're using a bounding sphere for detecting whether the object has been clicked or not.
Assuming your calculations are correct (as I said, I didn't check them in depth) you still can have false positives or negatives since the only shape which is perfectly represented by a bounding sphere is ... well... a sphere.
That might be the source for click detection to work "sometimes".
If that is the case and you want more accurate detection you should either use different bound volumes, bounding volumne hierarchies or a rendering based approach (i.e. render the object id into some buffer, which would allow for pixel perfect selection).
UPDATE:
From your post update it seems that bounding spheres are not the problem here, since they should not overlap, unless your data is wrong - which you should check/debug.
So the problem might actually lie in your calculations. From the documentation it looks like the ray you get is projected into the scene (i.e. into world space) so you'd need to transform your objects' center into worldspace as well.
You're currently only applying the position but ignore rotation and scale thus the resulting position might be wrong. I'm sure there's some built-in transform code, so instead of transforming manually you should use that. Please check the docs on how to do that.
I am trying to animate a propeller in java and have come to this code:
int x = 0;
int y = 230;
int h = 40;
int i = 0;
int center = 250;
void setup() {
size(500, 400);
}
void draw () {
if (i == 0) {
if(y>200) {
ellipse(x, y, 20, h);
y--;
h+=2;
x+=1;
} else { i = i + 1; }
}
if (i == 1) {
if(y<=230) {
ellipse(x, y, 20, h);
y++;
h-=2;
x+=1;
} else { i = i + 1; }
}
if (i == 2) {
if(h<70) {
ellipse(x, y, 20, h);
y++;
h+=1;
x+=1;
} else { i = i + 1; }
}
if (i == 3) {
if(h>=40) {
ellipse(x, y, 20, h);
y--;
h-=1;
x+=1;
} else { i = 0; }
}
}
Is there a way of making this shorter, because I want to have 4 propellers and dont want to have so much code for this part.
You're going about this the wrong way. Very wrong, in fact. And the reason might be that you think you're doing this in "Java...in the program 'processing'"
The reason this sort of thinking is wrong is because it is equivalent to someone working with C++ saying, "I am creating classes in C using the program 'C++'". Processing is based on Java but it is a different programming language. If you're uncomfortable stretching the idea of Processing to that of a "programming language" then at least think of it as a framework...a framework that provides you with its own implementation of various tools that are put together to help with the creation of art using computers.
Now your thinking seems to have affected you in your particular case a lot. Just like Jose Gonzalez above suggested, you haven't even thought about rotate(), which is a function built into Processing. Tim B's suggestion about Objects is spot on as well but if you want to do things in Processing, try to do them the Processing way.
Here's a very quick sketch that I did for you to understand what I mean:
Prop myProp1;
Prop myProp2;
Prop myProp3;
Prop myProp4;
float angle;
void setup() {
size(500, 500);
background(255);
angle = 0;
fill(0);
ellipseMode(CENTER);
myProp1 = new Prop(50,50);
myProp2 = new Prop(75,75);
myProp3 = new Prop(100,100);
myProp4 = new Prop(125,125);
}
void draw() {
background(255);
angle = ((angle + 0.1) % 360);
myProp1.buildAndRotate(angle, width*3/4, height/4);
myProp2.buildAndRotate(angle, width/4, height/4);
myProp3.buildAndRotate(angle, width*3/4, height*3/4);
myProp4.buildAndRotate(angle, width/4, height*3/4);
}
class Prop {
int propX;
int propY;
int propW;
int propH;
Prop() {
propX = 0;
propY = 0;
propW = 50;
propH = 50;
}
Prop(int w, int h) {
propX = 0;
propY = 0;
propW = w;
propH = h;
}
void buildAndRotate(float angle, float moveToX, float moveToY) {
pushMatrix();
translate(moveToX, moveToY);
rotate(angle);
ellipse(propX, propY, propW, propH);
ellipse(propX+propW/2, propY+propH/2, propW, propH);
ellipse(propX-propW/2, propY+propH/2, propW, propH);
ellipse(propX+propW/2, propY-propH/2, propW, propH);
ellipse(propX-propW/2, propY-propH/2, propW, propH);
popMatrix();
}
}
Now, this is by no means meant to be the way to do things in Processing but it uses various tools provided by the programming language to do exactly what you want to do. Also, the Object Prop can be built in various different ways and my implementation is not supposed to be top-notch at all.
So what is going on? Well, run the sketch and you will see four propellers rotating on their own axes. I just put four of them there, you can delete them or add more as you please.
What the hell is a Prop made of? It is made of five ellipses. The concept, and this may be different than yours, is based on the idea of a ceiling fan (or other fans for that matter or even a prop engine). These fans have a circular thing in the middle to which all the blades are attached. The center circle rotates and that results in all the blades around it rotating with it. What you get in the end is a rotating fan.
How is this thing rotating? Similar to the fan analogy above, there is an ellipse in the middle that rotates around its center. There are four ellipses "attached" to it that rotate around this center ellipses. This gives the illusion of a prop rotating. What you have to understand is that in Processing rotate() rotates things around the origin. This is the reason the center ellipse starts at (0,0). Then later in buildAndRotate() it is translated using translate(). Using translate() does not move the object, it instead moves the origin resulting in the object moving with it, and then when you execute rotate() it rotates the object around its center. Since all the other ellipses are built around this center ellipse, they all rotate around it too (in actual implementation, they're just rotating around the origin, you can see that by removing the center ellipse). pushMatrix() and popMatrix() are used so all the translate() and rotate() commands don't affect everything else in the sketch and keep all movements and rotations applied to each object to that very object.
What else is going on? The rest is pretty simple (this is all very simple once you get the hang of it). Background is being cleared constantly which is a common animation technique to give the illusion of movement. You can delete the statement for background() from draw() but I wouldn't recommend it because it will leave a big black round circle after a while and you won't be able to see the props. The angle is being changed constantly in the draw() method which is why you see the props rotating. You can speed up or slow down the rotation by changing that + 0.1 value being added to angle if you want.
What else do I do? Read the reference (not the Java reference, Processing has its own reference) by using Google or following links such as: http://www.processing.org/reference/rotate_.html, http://www.processing.org/reference/pushMatrix_.html, http://www.processing.org/reference/popMatrix_.html, http://www.processing.org/reference/translate_.html, and many more.
Hope this helps and leave questions in the comment if you need clarification on something.
You need to think in terms of objects and iteration rather than writing out everything explicitly. You are correct that the code you have above contains a lot of un-needed duplication, which is a bad thing.
For a more complex case you would define each part of the propeller as an object. Have an array of parts within the Propeller object. Each time to do the draw you run through the list of objects and render each one out.
In this case it can be even simpler, just use a for loop.
At the top of your program define:
private static final int NUM_BLADES = 4;
Then you want a loop that looks something like this:
for (int i=0;i<360;i+=360/NUM_BLADES) {
// Draw elipse at current rotation position + the angle for this blade
}
Now you can change the number of blades just by changing the static define as well.
In the game i'm building, I have made a basic collision detection system.
My current method is explained below:
I workout where the player will be in the next step of the game:
double checkforx = x+vx;
double checkfory = y+vy;
I then check for a collision with blocks (1) in mapArray.
public static Boolean checkForMapCollisions(double character_x,double character_y){
//First find our position in the map so we can check for things...
int map_x = (int) Math.round((character_x-10)/20);
int map_y = (int) Math.round((character_y-10)/20);
//Now find out where our bottom corner is on the map
int map_ex = (int) Math.round((character_x+10)/20);
int map_ey = (int) Math.round((character_y+10)/20);
//Now check if there's anything in the way of our character being there...
try{
for(int y = map_y; y <= map_ey; y++){
for(int x = map_x; x <= map_ex; x++){
if (levelArray[y][x] == 1){
return true;
}
}
}
}catch (Exception e){
System.out.println("Player outside the map");
}
return false;
}
If true is returned {nothing}
If false is returned {Player physics}
I need the player to be able to land on a block and then be able to walk around but I cannot find and adequate tutorial for this.
Can someone give me an idea on how to run my collision detection and/or movement?
There are 2 parts to this question. Collision detection, meaning determining whether a volume is touching or intersecting another volume. The second is collision response. Collision response is the physics portion.
I'll cover collision detection here as that's primarily what you asked about.
Ddefine a class for the map like so:
int emptyTile = 0;
//this assumes level is not a ragged array.
public boolean inBounds(int x, int y){
return x>-1 && y>-1 && x<levelArray[0].length && y<levelArray.length;
}
public boolean checkForCollisions(Rectangle rectangle){
boolean wasCollision = false;
for(int x=0;x<rectangle.width && !wasCollision;x++){
int x2 = x+rectangle.x;
for(int y=0;y<rectangle.height && !wasCollision;y++){
int y2 = y+rectangle.y;
if(inBounds(x2,y2) && levelArray[y2][x2] != emptyTile){
//collision, notify listeners.
wasCollision=true;
}
}
}
}
Do not make your methods static. You probably want more than one instance of a level right? Static is for when you need to share state which remains constant across multiple instances of a class. Level data will surely not remain constant for every level.
Instead of passing in a coordinate, try passing in an entire rectangle. This rectangle will be the bounding box of your character (the bounding box is also sometimes referred to as AABB, which means Axis-aligned bounding box, just FYI in case you're reading tutorials online for this sort of thing.) Let your Sprite class decide what its bounding rectangle is, that's not the map class's responsibility. All the map should be used for is maybe rendering, and whether a rectangle is overlapping tiles which are not empty.
I am sorry for a very shitty explanation but here is my github code and it will help better.
https://github.com/Quillion/Engine
Just to explain what I do. I have character object (https://github.com/Quillion/Engine/blob/master/QMControls.java) and it has vectors and a boolean called standing. Every time boolean standing is false. Then we pass it to the engine to check for collision, if collision happens then standing is true and y vector is 0. As to x vector whenever you press any arrow keys you make the xvector of the object to whatever value you want. And in the update loop you displace the given box by the amount of speed.