libGDXのSprite座標の謎

libGDXでは基本的に、原点が左下になります。
Spriteも左下の座標を基準に描画されます。
では拡大縮小した際は？回転した際は？

それぞれ検証してみました。

#スプライト生成(共通)
```java
// テクスチャー読み込み (256x256 px)
img = new Texture("badlogic.jpg");
// スプライト初期化
sprite = new Sprite( new TextureRegion(img,0,0,256,256));
sprite.setSize(256, 256);
```
![badlogic.jpg](https://qiita-image-store.s3.amazonaws.com/0/42140/f231c376-9cc2-a1a7-d263-54d7e1394eca.jpeg)

スプライトサイズは256x256 pixelです。

#描画1：スプライトを使わず直接描画
```java
batch.draw(img, 200, 200);
```
![2014-04-20 06.55.32.png](https://qiita-image-store.s3.amazonaws.com/0/42140/23a071b9-06fb-5125-bbb0-197fc81b7276.png)

スプライトの左下を起点に描画されました。

#描画2：スプライトで200,200座標に描画
```java
sprite.setPosition(200, 200);
sprite.draw(batch);

```
![2014-04-20 06.55.32.png](https://qiita-image-store.s3.amazonaws.com/0/42140/23a071b9-06fb-5125-bbb0-197fc81b7276.png)
スプライトを使わない時と同様にスプライトの左下を起点に描画されました。

#描画3：スプライトを２倍に拡大して描画
```java
sprite.setPosition(200, 200);
sprite.setScale(2);
sprite.draw(batch);
```

![2014-04-20 07.10.53.png](https://qiita-image-store.s3.amazonaws.com/0/42140/828aa485-6f6d-0246-60ef-2c475cc41a61.png)

ちょっとこれは予想外です。
スプライトの中心を基準に拡大されました。
※ 拡大縮小や回転の基準となるorigin座標はスプライトの中心がデフォルトのようです。

#描画4：スプライトを４５度回転して描画
```java
sprite.setPosition(200, 200);
sprite.setRotation(45);
sprite.draw(batch);
```
![2014-04-20 07.19.46.png](https://qiita-image-store.s3.amazonaws.com/0/42140/9191a704-a09d-34ed-e170-52f323694189.png)

スプライトの中心を基準に回転しました。
また正の値で反時計回りに回転します。
※ 拡大縮小や回転の基準となるorigin座標はスプライトの中心がデフォルトのようです。



#描画5：Originを指定してスプライトを２倍に拡大して描画
```java
sprite.setPosition(200, 200);
sprite.setOrigin(0, 0);
sprite.setScale(2);
sprite.draw(batch);
```
![2014-04-20 07.15.54.png](https://qiita-image-store.s3.amazonaws.com/0/42140/4bc738ae-204c-dbd7-c778-9bfdc42b673b.png)


スプライトの左下（原点指定した 0,0)を基準に拡大されました。


#描画6：Originを指定してスプライトを45度回転して描画
```java
sprite.setPosition(200, 200);
sprite.setOrigin(0, 0);
sprite.setRotation(45);
sprite.draw(batch);
```
![2014-04-20 07.18.47.png](https://qiita-image-store.s3.amazonaws.com/0/42140/ee2ad580-7b99-dacb-5c7e-2864377eaeda.png)


スプライトの左下（原点指定した 0,0)を基準に回転しました。

ふむふむなるほど…


#BitMapフォントの描画
フォントは左上が原点なので注意
##1倍で200,200に描画
```java
font.setScale(1f);
font.setColor(Color.RED);
font.draw(batch,"Font Draw Test!",200,200);
```
![2014-04-20 07.26.40.png](https://qiita-image-store.s3.amazonaws.com/0/42140/406dc3e0-e4a1-cf6c-ac71-364c906cb7b4.png)

赤い文字で「Font Draw Test!」と描画しています。
座標値とかぶって見辛いですが・・・
フォントの場合は左上が原点となります。

##4倍サイズで200,200に描画
```java
font.setScale(4f);
font.setColor(Color.RED);
font.draw(batch,"Font Draw Test!",200,200);
```
![2014-04-20 07.27.07.png](https://qiita-image-store.s3.amazonaws.com/0/42140/6eeb8b38-2453-19ed-da89-476fa2bde541.png)

赤い文字で「Font Draw Test!」と描画しています。
拡大もフォントの場合は左上が起点となります。

##テキスト描画サイズの取得
```java
font.setScale(4f);
font.setColor(Color.RED);
font.draw(batch,"Font Draw Test!",200,200);

TextBounds bounds = font.getBounds("Font Draw Test!");
font.setScale(2f);
font.setColor(Color.YELLOW);
font.draw(batch, "TextBounds width:" + bounds.width + " height:" + bounds.height, 200, 50);
```
![2014-04-20 07.43.09.png](https://qiita-image-store.s3.amazonaws.com/0/42140/74b89ace-9e1b-34bb-bfe2-ad7e3b6e7551.png)

Scaleで拡大したサイズが反映される。



Bitmapフォントにいては、以下のサイトが大変参考になります。
libgdxメモ
http://doc.tir.ne.jp/devel/clan/libgdx


#今回使用したソース全体

```java
package com.dokokano.gdxviewporttest1;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.ScalingViewport;
import com.badlogic.gdx.utils.viewport.ScreenViewport;

public class GdxViewportTest extends ApplicationAdapter {

	static final int LOGICAL_WIDTH = 800;		// ゲーム内の論理座標 幅
	static final int LOGICAL_HEIGHT = 600;	// ゲーム内の論理座標 高さ

	Stage stage;	// ViewportとCameraの管理をさせる

	SpriteBatch batch;
	private ShapeRenderer renderer;

	Texture img;
	BitmapFont font;
	private Sprite sprite;

	@Override
	public void create () {
		renderer = new ShapeRenderer();
		batch = new SpriteBatch();
		img = new Texture("badlogic.jpg");	// 256x256 px
		font = new BitmapFont();

		// スプライト初期化
		sprite = new Sprite( new TextureRegion(img,0,0,256,256));
		sprite.setSize(256, 256);

		// Initialite Stage & View port
		stage = new Stage(new FitViewport(LOGICAL_WIDTH,LOGICAL_HEIGHT));
//		stage = new Stage(new ExtendViewport(LOGICAL_WIDTH,LOGICAL_HEIGHT));
//		stage = new Stage(new ScalingViewport(Scaling.fill ,  LOGICAL_WIDTH,LOGICAL_HEIGHT));
//		stage = new Stage(new ScreenViewport());

		Matrix4 cameraMatrix = stage.getViewport().getCamera().combined;
		batch.setProjectionMatrix(cameraMatrix);
		renderer.setProjectionMatrix(cameraMatrix);
	}

	@Override
	public void render () {

		// 背景塗りつぶし（全体を黒）
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);


		// 論理表示領域を青で塗りつぶし
	    renderer.begin(ShapeType.Filled);
    	renderer.setColor(0,0,0.5f,1);
	    renderer.rect(0, 0,LOGICAL_WIDTH,LOGICAL_HEIGHT);
	    renderer.end();

		batch.begin();
		// ビットマップ描画(0,0)-(256,256)
//		batch.setColor(1,1,1,0.5f);

//		// 1
//		batch.draw(img, 200, 200);

		// スプライト描画
//		// 2
//		sprite.setPosition(200, 200);
//		sprite.draw(batch);

//		// 3
//		sprite.setPosition(200, 200);
//		sprite.setScale(2);
//		sprite.draw(batch);

//		// 4
//		sprite.setPosition(200, 200);
//		sprite.setRotation(45);
//		sprite.draw(batch);


//		// 5
//		sprite.setPosition(200, 200);
//		sprite.setOrigin(0, 0);
//		sprite.setScale(2);
//		sprite.draw(batch);

		// 6
		sprite.setPosition(200, 200);
		sprite.setOrigin(0, 0);
		sprite.setRotation(45);
		sprite.draw(batch);


		// 100x100グリッドにあわせて座標の数値描画
	    for ( int x=-1000; x<=1000; x+=100) {
		    for ( int y=-1000; y<1000; y+=100) {
			    font.setScale(1f);
			    font.setColor(Color.WHITE);
			    font.draw(batch, "("+x + ","+y +")" , x, y);
		    }
	    }

		// bitmap font
		font.setScale(4f);
		font.setColor(Color.RED);
		font.draw(batch,"Font Draw Test!",200,200);

		TextBounds bounds = font.getBounds("Font Draw Test!");
		font.setScale(2f);
		font.setColor(Color.YELLOW);
		font.draw(batch, "TextBounds width:" + bounds.width + " height:" + bounds.height, 200, 50);


		batch.end();

		renderer.begin(ShapeType.Line);
		// 原点からの100pxごとに四角形描画(緑）
	    for ( int i=-1000; i<=1000; i+=100 ) {
	    	renderer.setColor(Color.GREEN);
		    renderer.rect(0, 0, i	, i);
	    }
	    // 100x100グリッドを描画（白いクロス）
	    for ( int x=-1000; x<=1000; x+=100) {
		    for ( int y=-1000; y<1000; y+=100) {
		    	renderer.setColor(Color.WHITE);
			    renderer.x(x, y, 10);
		    }
	    }
	    renderer.end();


        if (Gdx.input.isTouched()) {
            Vector3 touchPos = new Vector3();
            touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
            stage.getViewport().getCamera().unproject(touchPos);

    		renderer.begin(ShapeType.Filled);
	    	renderer.setColor(Color.RED);
	    	renderer.circle(touchPos.x, touchPos.y, 50);
    	    renderer.end();
        }


	}

	@Override
	public void resize(int width, int height) {
		stage.getViewport().update(width, height,true);
	}


}

```