Im learning libgdx and one of the things that really confuses me its raycasting. I read a tutorial of how to use it and I understand it but I really want to know what's in the back. I searched for the source code of this method.
public void rayCast (final RayCastCallback callback, float point1X, float point1Y, float point2X, float point2Y) { // FIXME pool RayCastCallback?
world.raycast(new org.jbox2d.callbacks.RayCastCallback() {
#Override
public float reportFixture (org.jbox2d.dynamics.Fixture f, Vec2 p, Vec2 n, float fraction) {
return callback.reportRayFixture(fixtures.get(f), point.set(p.x, p.y), normal.set(n.x, n.y), fraction);
}
}, this.point1.set(point1X, point1Y), this.point2.set(point2X, point2Y));
}
How we can see this method calls itself recursively and returns a call to reportRayFixture of the callback variable. The thing that really confused me it's from where the code select the Fixture, and how its checks every fixture. Can someone explain me really how its works.
This its the source code page https://github.com/libgdx/libgdx/blob/master/extensions/gdx-box2d/gdx-box2d-gwt/src/com/badlogic/gdx/physics/box2d/gwt/emu/com/badlogic/gdx/physics/box2d/World.java
I will appreciate it!
Raycasting is when we draw an invisible line through space and see what it intersects with. A common use for this is to figure out what a player is clicking on- we draw a line from the camera in the direction that the player is clicking, and the first object our line touches is the line the player clicked on.
In Box2D, the RayCastCallback interface is used to allow you to write code that gets executed when your ray hits a Fixture (for example, you may want to ignore certain fixtures). I haven't used this personally, but I imagine you could use something like this in a shooter game to see if a wall-penetrating weapon could hit an object behind a wall (or something like that).
At a high level, what this lovely piece of code is doing is a little slight of hand- if you look at it really closely, what it's doing is taking in the libGDX RayCastCallback and wrapping it in a JBox2D RayCastCallback which has a slightly different API. It's more like it's overloading the method than calling it recursively.
What I don't know is why the author chose to create the Point1 and Point2 instance variables. I would think if you had multiple fixtures they would get overridden, so perhaps they are supposed to contain the last fixture hit by the ray? Even so, it looks like multiple raycasts would overwrite them.
Related
I'm currently developing an Air Hockey game in Java, using libgdx.
The point of the game is to move the handle using touch or mouse, according to the platform, and use it to touch the puck in order for it to move around.
I've searched around for a bit but couldn't find a suitable solution. I know there's methods like gesture listeners, touchDragged, setTransform, applyForce, etc...
Right now, in order to test it, I'm using setLinearVelocity, the body gains velocity towards the mouse click. This way, when the handle touches the puck it does exactly what I want, the contact listener works and the puck moves in the correct direction, but obviously I don't want this method to apply movement to the handle.
So how can I move it using touch and making sure that the handle hits the puck?
You can set the body position using setTransform. In order to move it with mouse/finger you can implement touchDragged method of InputAdapter, like this:
Gdx.input.setInputProcessor(new InputAdapter() {
public boolean touchDragged(int screenX, int screenY, int pointer) {
body.setTransform(screenX, Gdx.graphics.getHeight() - screenY, 0);
return true;
}
});
Also I think you should define your stick as kinematic body:
Like static bodies, they do not react to forces, but like dynamic
bodies, they do have the ability to move. Kinematic bodies are great
for things where you, the programmer, want to be in full control of a
body's motion, such as a moving platform in a platform game.
For curiosity I made a test myself. The stick is a kinematic body, and the ball is dynamic. As you see the stick is not affected by any forces:
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;
}
I am using Slick2D to make a simple game with a number of sprites. There is a player sprite which will push other object sprites around the map.
I have used an ArrayList to store all the sprite types created, but when I use the player to push a particular type of sprite (for example a wooden block) all the occurrences of that particular sprite type in that map gets updated as well. How do I specify to update that one particular wooden block rather than updating all the wooden blocks loaded in the game?
ArrayList:
private ArrayList<Sprite> sprites;
Creating all the sprites and storing them inside the ArrayList:
public static ArrayList<Sprite> loadSprites(String filename) {
ArrayList<Sprite> list = new ArrayList<>();
/*bunch of code to load the sprite*/
list.add(World.createSprite(name, x, y));
return list;
}
here types is a 2D array where I am storing all the names of the sprites according to their map coordinates, which I am getting from a csv file.
public static Sprite createSprite(String name, float x, float y) {
switch (name) {
case "player":
return new Player(x, y, "player");
case "wood":
return new Wall(x, y, "wood");
case "tile":
return new Floor(x, y, "tile");
case "wall":
return new Stone(x, y, "wall");
case "metal":
return new Target(x, y, "metal");
}
return null;
}
Thanks in advance. :)
What you need to do is to identify the object the player pushes. Let's assume you have three sprites in your list all of the type wood. From what you wrote in your question it seems like if the player starts pushing obviously all sprites get updated as well because either:
Your program can't determine what sprite exactly is supposed to be pushed.
Your program knows what sprite is supposed to be pushed but cant determine what sprite to update visually (hard to tell with your provided code)
So what you should do is to ensure that the pushing action is only performed to the object/sprite the player is interacting with. You need to have constraints to check for this interaction this constraint might be pushing a button or intersecting with that one particular sprite / object. So you could do for example the following:
Iterate through your arraylist and check with which object/sprite your player is intersecting.
If there is an intersection with an object of your list you exactly know what object that is and you could call the update, push or any other method on the object.
If you have more than one possible candidate to update you need to specify your search, for example you could only interact with objects / sprites your player is looking at.
Call the needed method of that particular one object (eg. push()).
What also might be a solution is that you should be sure about your game architecture. By this I mean that you should be certain about how your game is internally designed. Generally each gameobject in your game should have sprite and maybe a sound or certain other attributes. By this you make sure that each object has a specific sprite just for itself, so you wont get into trouble with updating any other sprites because you only can access this specific sprite by this specific object. So maybe you should consider not iterating over a list of sprites but rather iterate over a list of gameobjects in your world (I'm not sure but maybe a sprite is a gameobject for you, but a sprite is just the graphical representation of a gameobject.). Check for interaction with each of these gameobjects and in case perform a specific action. Such code could look like the following:
//inside the update method of your player
for(GameObject gameObject : world.getAllGameObjects()){
if(player.getHitbox().intersects(gameObject.hitbox())){
gameObject.update() //push, update sprite, whatever
}
}
Checking for intersection is only one solution as I already said you could also check for the pressing of a key or for a certain distance. From my understanding what is important for you is the identification of a single object and to update that single object.
It's hard to tell what exactly your problem is because I dont have insight in your entire code, but if you ensure to find the right object to interact with and also making sure that only this object is graphically updated this will work.
Beside the architecture it self the problem might be here:
if (Loader.getSpriteOfType("wood", Player.getPlayerX() - 1, Player.getPlayerY())) {
dir = DIR_LEFT;
}
I'm not sure what Loader.getSpriteOfType(..) does since I don't know how sprites or objects are entirly stored and handled in your game cycle, but I'd assume that it returns all (not only a specific one) sprites of type "wood" because it's searching for "wood" and finds all objects which "wood", but you want only the exact one which your player is interacting with so maybe you should be more specific in that if-clause (just an assumption though since I don't know your code).
Hope this helps you and gives you something to think about.
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.
Lets suppose we have a class Shape which has a method rotate(int velocity). This method makes a shape rotate with a speed of velocity(the parameter passed to rotate). This method has been called in a project, say at 100 places.
But now a new requirement comes, that the rotate functionality will also depend on the color of the shape, i.e. if the color is blue then the velocity should be decreased by 1, else no change should be made.
One solution to this problem would be to change the rotate(int velocity) method to rotate(int velocity, Color color), then add an if statement inside rotate method to check for the color, and make a change in 100 calls of rotate.
E.g.
shape.rotate(50, blue) ;
Inside the rotate method,
void rotate(int velocity, Color color) {
if(color == blue)
--velocity ;
}
Another solution would be to make color as an instance variable of the shape object, and then without adding a new argument to the rotate method, simply set the color before calling it, and squeeze the if check inside the rotate method.
E.g.
shape.setColor(blue) ;
shape.rotate(50) ;
Inside the rotate method,
void rotate(int velocity) {
if(this.color == blue)
--velocity ;
}
Yet another solution would be to overload the rotate method and create a new method named rotate(int velocity, Color color) and use it in the new calls. This would leave the existing code which uses rotate(int velocity) unchanged.
Which of these would be the best possible solution? Or, does there exist a better solution? If yes, then what could it be?
Regards
I'd say there are a couple of questions you need to ask yourself.
Do you care about the color outside of the rotate method? If yes, make it an instance variable; if no, pass it to the rotate method.
Are you likely to care about the color outside of the rotate method further down the line? If yes, make it an instance variable; if no, pass it to the rotate method.
Are you always going to care about the color when calling the rotate method? If yes, make it an argument (to force them to set the color when rotating the shape).
A good principle of OO is to co-locate related behavior and state. In this case the rotate behavior of shape depends on the colour state of shape, so it makes sense to co-locate both in the Shape class, c.q. create a field 'colour' and use it within the rotate method to customize the rotation behavior.
Apart from this design decision, you are really also asking about a refactoring decision: how do I handle the application code that depends on shape? My approach in cases like this is to think ahead: how many changes like these to the Shape class can we expect? If this is a rare change then you could just go ahead and change all the code locations that initialize the shape class so a colour is set. If shape changes more often, then you should be more rigorous and make your code less tightly coupled. A way to do that in this case is to create an abstract factory (or use the factory offered by a D.I. framework like Spring) so that the application code does not need to know the creation details of shape.
BTW your third option seems sub-optimal to me: part of the code is not made aware of the addition of the colour state to shape, and keeps calling the old 'deprecated' rotate method. This means that setting a shape's colour to blue will not universally affect the rotation behavior, but only in 'special cases'. This weakens the design and makes it harder for the developers after you to understand it.
I think the first option is is tedious to implement. What if you miss at one place, what if later u realize that you need rotate(single parameter) again.
The second option is irrelevant as many have already pointed out.
3rd I think is the best solution, as it will not break your code. You can have both the overloaded method, can use any of them as per requirement.
As for me, I see classic example of inheritance usage here.
class Shape {
public void rotate(int v) {}
}
class GreenShape extends Shape {
public void rotate(int v){
super.rotate(v + 10);
}
}