Reputation: 65877
This is my first attempt in game development. I just started experimenting libgdx and understanding the different aspects of game programming. I looked at the sample projects, i can understand the overall architecture of the libgdx game. But to get hold of the basics of game dynamics, i started playing with low level stuff like how to draw simple shapes, how to move them, how to handle collision like that.
So i planned to write a dead simple android game(Its not even a game for sure). This is the idea
1. Create random shapes and make it fly (move)
2. When user touches the shape, it ll explode or hide or play simple animation
3. Has to show Hit & Miss count
Initially i thought of going to try libgdx stage & actor concept, but ruled out that to do without the scene API. And I started this to experiment with different aspects of basic gaming and better understand the concepts behind libgdx. So i made this simple app, i am able to make objects fall random.
public class A1GameScreen implements Screen {
OrthographicCamera camera;
ShapeRenderer debugRenderer = new ShapeRenderer();
Array<Rectangle> boxes;
long lastFlew;
int fliesCaught;
A1GameScreen(){
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
boxes=new Array<Rectangle>();
throwboxes();
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
debugRenderer.setProjectionMatrix(camera.combined);
debugRenderer.begin(ShapeType.Line);
for (Rectangle fly : boxes) {
debugRenderer.rect(fly.x, fly.y, fly.width, fly.height);
}
debugRenderer.end();
//Handle the user input
if (Gdx.input.isTouched()){
hit(Gdx.input.getX(),Gdx.input.getY());
}
if (TimeUtils.nanoTime() - lastFlew > 1000000000)
throwboxes();
Iterator<Rectangle> iter = boxes.iterator();
while (iter.hasNext()) {
Rectangle fly = iter.next();
fly.x -= 2;
if (fly.x + 32 < 0)
iter.remove();
}
}
//Method to create flies at random interval
private void throwBoxes(){
Rectangle fly = new Rectangle();
fly.y = MathUtils.random(0, 480 - 32);
fly.x = 800;
fly.width = 32;
fly.height = 32;
boxes.add(fly);
lastFlew = TimeUtils.nanoTime();
}
private boolean hit (float x, float y) {
boolean found=false;
for (Rectangle fly : boxes) {
found = fly.contains(x,y);
if (found){
found = true;
fly.width=100;
break;
}
}
return found;
}
}
But i couldn't able to find out the touched item from the falling objects. This is what i am doing to find out whether the box is in touched range
contains
method of the Rectangle
(Box) to figure out thatsomething like this
for (Rectangle fly : boxes) {
found = fly.contains(x,y);
if (found){
found = true;
fly.width=100;
break;
}
}
But its not working. I think i figured the problem. Its
My questions are
Update
I see lot of mismatch between the touch co-ordinates and box co-ordinates. None of the boxes in the touch range. Hows that possible. Below the sample trace
Touch coords: x-651.0 y-362.0
Fly coords: x-384.0 y-277.0
Fly coords: x-504.0 y-34.0
Fly coords: x-624.0 y-103.0
Fly coords: x-744.0 y-238.0
Touch coords: x-441.0 y-193.0
Fly coords: x-52.0 y-34.0
Fly coords: x-172.0 y-103.0
Fly coords: x-292.0 y-238.0
Fly coords: x-414.0 y-261.0
Fly coords: x-534.0 y-109.0
Fly coords: x-656.0 y-283.0
Fly coords: x-776.0 y-323.0
Touch coords: x-568.0 y-162.0
Fly coords: x-42.0 y-267.0
Fly coords: x-162.0 y-166.0
Fly coords: x-282.0 y-266.0
Fly coords: x-404.0 y-52.0
Fly coords: x-526.0 y-296.0
Fly coords: x-646.0 y-64.0
Fly coords: x-766.0 y-16.0
Upvotes: 3
Views: 9058
Reputation: 23
I've solved the problem by making an invisible rectangle which will follow the tap location and I made an if statement checking for overlapping of the invisible rectangle and checking for if the screen was just tapped.
Here is the code:
if(Gdx.input.isTouched()) {
Vector3 pointerPos = new Vector3();
pointerPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
cam.unproject(pointerPos);
touchPos.x = pointerPos.x /*+ 64 / 2*/;
touchPos.y = pointerPos.y /*+ 64 / 2*/;
}
Iterator<Rectangle> iter = raindrops.iterator();
while(iter.hasNext()) {
Rectangle raindrop = iter.next();
raindrop.y -= 300 * Gdx.graphics.getDeltaTime();
if(raindrop.y + 64 < 0) {
iter.remove();
}
if(raindrop.overlaps(touchPos) && Gdx.input.justTouched()) {
iter.remove();
dropSound.play();
}
all of this code is in the render method.
P.S: Change raindrops to the fly objects you want
Upvotes: 1
Reputation: 18712
public static boolean pointInRectangle (Rectangle r, float x, float y) {
return r.x <= x && r.x + r.width >= x && r.y <= y && r.y + r.height >= y;
}
In your update-
if(pointInRectangle(flyRectangle, Gdx.input.getX(), Gdx.input.getY())){
// Do whatever you want to do with the rectangle. maybe register them for effect
}
You can also look into Intersector class.
Now for collision, if your game is fast-paced, with lots of enemies moving around that the player can collide with, sooner or later you will use a box2d type library because if the movement speed is high, you might not get any collision callback. Things might go through each other. You can try predicting the collision before it happens using the velocity and deltaTime, but it's still not going to be enough and you will end up reinventing the wheel.
Mario's SuperJumper is a great demo to start libGDX. Try it.
EDIT:
Have an instance member-
Vector3 touchPoint;
On create-
touchPoint = new Vector3();
On update-
camera.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));
if (Gdx.input.justTouched()) {
if (pointInRectangle(rectangle, touchPoint.x, touchPoint.y)) {
}
}
Please take note of the coordinate system in libGDX. For testing, create one rectangle on screen. On click, print/debug the coordinates of both the rectangle and touchPoint.
Upvotes: 5