Recent Blogposts | Page 8

libgdx pinch to zoom

Aug. 15, 2015, 12:40 p.m. Programming libgdx

I was looking for the code for pinch to zoom on libgdx that zooms with the origin at the center of two fingers. Then I found this. Unfortunately, it seems that the solution there is far from being elegant. Then I figure out a new solution using the camera matrix myself. Here is the code:

this.gestureDetector = new GestureDetector(new GestureAdapter(){
        private Vector2 oldInitialFirstPointer=null, oldInitialSecondPointer=null;
        private float oldScale;
        @Override
        public boolean pan(float x, float y, float deltaX, float deltaY) {
            game.getCamera().update();
            game.getCamera().position.add(
                game.getCamera().unproject(new Vector3(0, 0, 0))
                .add(game.getCamera().unproject(new Vector3(deltaX, deltaY, 0)).scl(-1f))
            );
            return true;
        }
        @Override
        public boolean pinch (Vector2 initialFirstPointer, Vector2 initialSecondPointer, Vector2 firstPointer, Vector2 secondPointer){
            if(!(initialFirstPointer.equals(oldInitialFirstPointer)&&initialSecondPointer.equals(oldInitialSecondPointer))){
                oldInitialFirstPointer = initialFirstPointer.cpy();
                oldInitialSecondPointer = initialSecondPointer.cpy();
                oldScale = game.getCamera().zoom;
            }
            Vector3 center = new Vector3(
                    (firstPointer.x+initialSecondPointer.x)/2,
                    (firstPointer.y+initialSecondPointer.y)/2,
                    0
            );
            zoomCamera(center, oldScale*initialFirstPointer.dst(initialSecondPointer)/firstPointer.dst(secondPointer));
            return true;
        }
        private void zoomCamera(Vector3 origin, float scale){
            game.getCamera().update();
            Vector3 oldUnprojection = game.getCamera().unproject(origin.cpy()).cpy();
            game.getCamera().zoom = scale; //Larger value of zoom = small images, border view
            game.getCamera().zoom = Math.min(2.0f, Math.max(game.getCamera().zoom, 0.5f));
            game.getCamera().update();
            Vector3 newUnprojection = game.getCamera().unproject(origin.cpy()).cpy();
            game.getCamera().position.add(oldUnprojection.cpy().add(newUnprojection.cpy().scl(-1f)));
        }
});

The method Camera.unproject() is used to convert the coordinate of the points you touch(let's say it's coordinate A) to the coordinate that you use for displaying objects(let's say it's coordinate B). For example, if you draw a object on a SpriteBatch, and the batch has set to use a camera, then the coordinate used there is probably in coordinate B. However, another coordinate system, coordinate A is used for touch input. That's why we need to do an unprojection for the conversion between two coordinate systems. Remember to update the camera before using the unproject method. Otherwise, it may do that unprojection based on an outdated transformation matrix of the camera, which make the calculation inaccurate


Half N' Half - One day Android game development project

April 28, 2015, 10:51 a.m. Gamedev Product Release

Today I decide to start a one day project of Android game development. This is the first one day Android game that I've ever developed, and the second Android game that I ever published. :D

The game is based on breakout game with the following rules:

  • There are two sides. Top side and bottom side
  • Initially, there's no brick on both sides
  • There is a ball on each side
  • When a ball hit the edge of the screen, a brick is spawn on another side
  • When a brick is destroyed, there is a chance that a power up is spawn. They can be:
    • Ball speed up
    • Ball speed down
    • Paddle extend
    • Paddle shrink
    • Paddle removal(TROLOLOLOLOLOLO)
  • When you miss a ball, the side that you missed is frozen. After 10 seconds, that side will be unfrozen.
  • If both sides are frozen, you lose
  • You can't win the game. What you need to do is to survive as long as you can

Here is the timeline of the development(time in GMT+8):

4/27/2015(preparation works):
setup development environment of libgdx,
music composition,
drawing graphic
4/28/2015:
0840: start working
1100: implemented movable paddle and basic bouncing balls
1251: implemented power up, ball speed up over time, angle deflection when the ball hit the paddle and brick spawning logic
1310: implemented sfx and bgm
1514: implemented all game logic
1548: implemented menu
1707: implemented score and highscore
1725: implemented animation
1835: Published to Google Play

It's a pretty fun experience. I have never did something like this before. I enjoy it. :) It's easier than I thought, tho. Maybe I should scale up next time! :3

This game proves that I'm capable for developing one day project(which is not something to be proud of because most developers can do that. Still, it's a good proof-of-concept/ability/whatever a.k.a. achievement unlocked :P). I guess I should join Ludum Dare some day later. :D

The game is available here


Trolled myself

April 1, 2015, 4:27 a.m. RPS

Today is the day that The International Asynchronous Rock Scissors Paper Competition starts. I was trying to join it right after it started. But well, due to some file permission issue, the site returned HTTP 500 server error.

It's now fixed. You may now join the competition here

tl;dr: I trolled myself in this April Fool.


UI Revamp

March 11, 2015, 2:22 p.m. Meta

The UI of this blog is revamped! :D


The International Asynchronous Rock Scissors Paper Competition

March 8, 2015, 8:22 p.m. Product Release RPS

We are going to organize The International Asynchronous Rock Scissors Paper Competition!

The International Asynchronous Rock Scissors Paper Competition, as its name suggests, is an asynchronous RSP competition that is available for every human on the earth to join. (To non-human creatures: Sorry about that. You are ineligible for this because you suck.)

This is a sort of competition that couldn't be found elsewhere because similar game was never held before in human history. By joining this game, you are actually creating a new history of the humanity. As an international competition, this game can actually unite our human race. This is because of this, uh... I don't know how to explain it. Just trust me. I'm not even an engineer lol.

This competition is environmentally friendly because it has a simple user interface. Unlike most websites, the design of competition website is simple. It has a white background. If you print our website, it saves the ink being sprayed because the paper itself is white! According to our calculation, printing our competition website can saves up to 80% of ink compared in any other modern website. In other words, you can gain 80% of ink for free by printing out our website(You can actually sell the ink generated to get ∞ profit). To make our next generation a better life, everyone should print out our website. Our earth will appreciate that!

Being a very meaningful event, the competition will be held on Apr 1, 2015, 00:00~23:59 UTC. We strongly believe that this is the best time for the game because that day is in weekend. This will certainly allow much more people to join us!

During the competition, each player is required to carefully decide what to throw for a series of 50 rounds. To make it more fun, the player won't know his score and the score is only calculated upon the end of the competition. Ooohhh! The game is so challenging that you cannot change the things to be thrown even if you summon Satan or Hilter to help you! The result will be displayed in the competition site when it's ended.

The winner of this game will be nominated for Nobel Prize in RSP! Our previous statistic shows that by having our nomination, the chance of actually getting Novel Prize is 0.1%. It is actually pretty high because there are only 860 Nobel Prize recipients in the current. After dividing 860 by the world population, we get 0.0001228%, which is way lower than 0.1%. That says, it's always a good for you to become the winner of our game!

What are you waiting for? Check it out now!