« 【WindowsSDK】自作TRACE | トップページ | 【JavaSE】サイドビューの実験(4/17) »

2010年9月 2日 (木)

【JavaSE】サイドビューの実験(3/17)

通り抜けることのできないブロックを実装。

今回は横からぶつかったときにのみ対応。

ジャンプして下からぶつかったときは不自然な挙動になる。

  • カーソルキーで左右移動
  • Zキーでジャンプ

SideViewExp03.java

import isle.videogame.*;
import isle.videogame.image.*;
import java.awt.*;

@SuppressWarnings("serial")
public class SideViewExp03 extends VGStretchCanvas
{
	static final int SCREEN_WIDTH  = 240;
	static final int SCREEN_HEIGHT = 240;

	int pad_states_last;

	byte[][] map = {
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 },
		{ 1,1,2,2,0,0,2,2,1,1,1,1,1,2,2 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 1,1,0,0,0,0,0,0,0,0,0,0,1,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
		{ 0,0,0,0,0,0,0,2,0,0,0,0,0,0,1 },
		{ 2,0,0,0,0,0,0,2,0,0,0,0,0,1,2 },
		{ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 },
	};
	static final Color[] colorBlock = {
		new Color(127,127,255), Color.BLUE,
	};

	VGImage[] Girl_imgs;
	Rectangle Girl_rc = new Rectangle();
	int Girl_nImg;
	int Girl_cWalk;
	boolean Girl_bLeft;
	int Girl_ga;
	int Girl_elev;

	static final int GIRLSTATE_WALK = 0;
	static final int GIRLSTATE_FALL = 1;
	static final int GIRLSTATE_JUMP = 2;
	int Girl_state = GIRLSTATE_FALL;

	public SideViewExp03()
	{
		super(SCREEN_WIDTH, SCREEN_HEIGHT, 60);
		setBackground(Color.DARK_GRAY);

		Image img = getResourceImage("buruma.png");
		Girl_imgs = VGImage.createImages(img, 0, 0, 16, 24, 6);
		Girl_rc.setSize(32-3*2, 48); // 当たり判定基準
		Girl_rc.setLocation(3, 0);
	}

	@Override
	protected void frameUpdate(int skipped)
	{
		int pad_states = getPadStates();
		int pad_trigger = (pad_states_last ^ pad_states) & pad_states;
		pad_states_last = pad_states;
		switch (Girl_state) {
		case GIRLSTATE_WALK:
			// 移動前の足元を床当たり判定除外の基準座標に
			Girl_elev = Girl_rc.y + Girl_rc.height;
			Girl_nImg = 4;
			Girl_ga = 0;
			if ((pad_states & (1<<PAD_LEFT))  != 0) {
				--Girl_rc.x;
				++Girl_cWalk;
				Girl_cWalk %= 16;
				Girl_nImg = Girl_cWalk / 4;
				Girl_bLeft = true;
			}
			if ((pad_states & (1<<PAD_RIGHT)) != 0) {
				++Girl_rc.x;
				++Girl_cWalk;
				Girl_cWalk %= 16;
				Girl_nImg = Girl_cWalk / 4;
				Girl_bLeft = false;
			}
			if ((pad_trigger & (1<<PAD_BUTTON1)) != 0) {
				Girl_ga = -12;
			}
			break;
		case GIRLSTATE_FALL:
		case GIRLSTATE_JUMP:
			// 移動前の足元を床当たり判定除外の基準座標に
			Girl_elev = Girl_rc.y + Girl_rc.height;
			Girl_nImg = 5;
			if (Girl_ga < 8) ++Girl_ga;
			Girl_rc.y += Girl_ga;
			if ((pad_states & (1<<PAD_LEFT))  != 0) {
				--Girl_rc.x;
			}
			if ((pad_states & (1<<PAD_RIGHT)) != 0) {
				++Girl_rc.x;
			}
			break;
		}

		// ブロックとの当たり判定
		Girl_state = Girl_ga < 0 ? GIRLSTATE_JUMP : GIRLSTATE_FALL;
		for (int i=0,y=0; i<15; ++i,y+=16) {
			for (int j=0,x=0; j<15; ++j,x+=16) {
				// 床の判定
				switch (map[i][j]) {
				case 1: case 2:
					if (Girl_state != GIRLSTATE_FALL) break;
					// 引っ張り上げられないための除外
					if (y < Girl_elev) break;
					if (Girl_rc.x >= x + 16) break;
					if (Girl_rc.x + Girl_rc.width <= x) break;
					// 床の当たり判定はブロックの上端だけ
					if (Girl_rc.y >= y) break;
					// 足元の当たり判定を1ピクセル伸ばすことで
					// 座標補正後もブロックの上に居る状態を維持
					//if (Girl_rc.y + Girl_rc.height <= y - 1) break;
					if (Girl_rc.y + Girl_rc.height < y) break;
					Girl_rc.y = y - Girl_rc.height;
					Girl_state = GIRLSTATE_WALK;
				}
				// 壁の判定 ※要床の補正後
				switch (map[i][j]) {
				case 2:
					if (Girl_rc.x >= x + 16) break;
					if (Girl_rc.x + Girl_rc.width <= x) break;
					if (Girl_rc.y >= y + 16) break;
					if (Girl_rc.y + Girl_rc.height <= y) break;
					// 壁にめり込んでいる
					if (Girl_rc.x < x) {
						// ブロックより左寄りなら左に座標補正
						Girl_rc.x = x - Girl_rc.width;
					}
					else {
						// 右に座標補正
						Girl_rc.x = x + 16;
					}
				}
			}
		}

		// 最終座標補正
		if (Girl_rc.x < 0) Girl_rc.x = 0;
		if (Girl_rc.x > SCREEN_WIDTH-Girl_rc.width) Girl_rc.x = SCREEN_WIDTH-Girl_rc.width;
	}

	@Override
	protected void frameStretchRender(Graphics g)
	{
		g.setColor(Color.CYAN);
		g.fillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);

		for (int i=0,y=0; i<15; ++i,y+=16) {
			for (int j=0,x=0; j<15; ++j,x+=16) {
				switch (map[i][j]) {
				case 1: case 2:
					g.setColor(colorBlock[map[i][j]-1]);
					g.fillRect(x, y, 16, 16);
					g.setColor(Color.MAGENTA);
					g.drawLine(x, y, x+16-1, y);
				}
			}
		}

		g.setColor(Color.YELLOW);
		g.drawLine(0, Girl_elev-1, SCREEN_WIDTH-1, Girl_elev-1);
		Girl_imgs[Girl_nImg].paint(g, Girl_rc.x-3, Girl_rc.y, 32, 48, Girl_bLeft ? 0 : VGImage.FLIP_HORIZONTAL);
		g.setColor(Color.RED);
		g.drawRect(Girl_rc.x, Girl_rc.y, Girl_rc.width-1, Girl_rc.height-1);
	}

	// $> java -cp SideViewExp.jar SideViewExp03
	public static void main(String[] args)
	{
		new VGFrame(new SideViewExp03(), 640, 480, "サイドビュー実験");
	}
}

|

« 【WindowsSDK】自作TRACE | トップページ | 【JavaSE】サイドビューの実験(4/17) »

JavaSE」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« 【WindowsSDK】自作TRACE | トップページ | 【JavaSE】サイドビューの実験(4/17) »