« 【JavaSE】サイドビューの実験(5/17) | トップページ | 【JavaSE】サイドビューの実験(7/17) »

2010年9月21日 (火)

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

上下に移動するブロックに乗って上に移動できるようにした。

床に立っている状態のとき、1ピクセル上まで判定範囲を伸ばした。

床を追いかけるように補正がかかるため滑らかに上昇しているように見える。

副作用として固定ブロックでも1ピクセルの段差は駆け上がることになる。

まだ下がるときはワタワタする。

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

SideViewExp06.java

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

@SuppressWarnings("serial")
public class SideViewExp06 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 },
	};
	VGImage[] BG_imgs;

	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;

	int FloatBlockV_x, FloatBlockV_y;
	int FloatBlockV_state, FloatBlockV_count;
	static final int FLOATBLOCKSTATE_STOP = 0;
	static final int FLOATBLOCKSTATE_UP   = 1;
	static final int FLOATBLOCKSTATE_DOWN = 2;

	Rectangle rcBump = new Rectangle(); // 当たり判定対象用

	public SideViewExp06()
	{
		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);

		img = getResourceImage("bg.png");
		BG_imgs = VGImage.createImages(img, 0, 0, 16, 16, 3);

		FloatBlockV_x = 160;
		FloatBlockV_y = 144;
		FloatBlockV_state = FLOATBLOCKSTATE_STOP;
		FloatBlockV_count = 50;
	}

	@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 - 1; // 床と天井の当たり判定除外用
			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_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;
		}

		// 上下に動く浮動ブロック
		switch (FloatBlockV_state) {
		case FLOATBLOCKSTATE_STOP:
			if (FloatBlockV_count > 0) {
				--FloatBlockV_count;
				break;
			}
			FloatBlockV_state = FloatBlockV_y >= 144 ? FLOATBLOCKSTATE_UP : FLOATBLOCKSTATE_DOWN;
			break;
		case FLOATBLOCKSTATE_UP:
			--FloatBlockV_y;
			if (FloatBlockV_y <= 112) {
				FloatBlockV_state = FLOATBLOCKSTATE_STOP;
				FloatBlockV_count = 50;
			}
			break;
		case FLOATBLOCKSTATE_DOWN:
			++FloatBlockV_y;
			if (FloatBlockV_y >= 176) {
				FloatBlockV_state = FLOATBLOCKSTATE_STOP;
				FloatBlockV_count = 50;
			}
		}

		// 固定ブロックとの当たり判定
		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) {
				doCollideBlock(x, y, map[i][j]);
			}
		}
		// 浮動ブロックとの当たり判定
		doCollideBlock(FloatBlockV_x   , FloatBlockV_y, 1);
		doCollideBlock(FloatBlockV_x+16, FloatBlockV_y, 1);

		// 最終座標補正
		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;
	}

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

	@Override
	protected void frameStretchRender(Graphics g)
	{
		// 固定ブロックを描画
		for (int i=0,y=0; i<15; ++i,y+=16) {
			for (int j=0,x=0; j<15; ++j,x+=16) {
				BG_imgs[map[i][j]].paint(g, x, y, 0);
			}
		}
		// 浮動ブロックを描画
		BG_imgs[1].paint(g, FloatBlockV_x   , FloatBlockV_y, 0);
		BG_imgs[1].paint(g, FloatBlockV_x+16, FloatBlockV_y, 0);

		g.setColor(Color.YELLOW);
		g.drawLine(0, Girl_elev, SCREEN_WIDTH-1, Girl_elev);
		g.drawLine(0, Girl_elev+Girl_rc.height-1, SCREEN_WIDTH-1, Girl_elev+Girl_rc.height-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 SideViewExp06
	public static void main(String[] args)
	{
		new VGFrame(new SideViewExp06(), 640, 480, "サイドビュー実験");
	}
}

|

« 【JavaSE】サイドビューの実験(5/17) | トップページ | 【JavaSE】サイドビューの実験(7/17) »

JavaSE」カテゴリの記事

コメント

コメントを書く



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




« 【JavaSE】サイドビューの実験(5/17) | トップページ | 【JavaSE】サイドビューの実験(7/17) »