マップスクロールがうまくできない
Posted: 2012年5月03日(木) 22:20
現在のろのろと不定期にC#とDXライブラリでアクションゲームを制作しています。先日こちらの掲示板でマップとキャラの当たり判定の処理についてお尋ねしたところ大変満足する処理を実装できましたので,また質問させていただきます。
今度はマップスクロールで悩んでいます。マップは正方形型のブロックが配置された単純なものです。絶対に間違っているという予想の下,とりあえずキャラクタが動いたら動いた分だけ逆向きにブロックを動かしてやるというやり方をしてみたところ,案の定ブロックが吹っ飛んでしまい,しかも当たり判定はそのまま(ブロックのグラフィックはそこにないが,当たり判定はそのままあるという状態。文章だとわかりにくいですね)という風になってしまいました。
以下にコードを載せます。
スクロールを行なっている関数は
ですが,どうみても間違っているように思えます。
正しいやり方をどなたか教えてください。
今度はマップスクロールで悩んでいます。マップは正方形型のブロックが配置された単純なものです。絶対に間違っているという予想の下,とりあえずキャラクタが動いたら動いた分だけ逆向きにブロックを動かしてやるというやり方をしてみたところ,案の定ブロックが吹っ飛んでしまい,しかも当たり判定はそのまま(ブロックのグラフィックはそこにないが,当たり判定はそのままあるという状態。文章だとわかりにくいですね)という風になってしまいました。
以下にコードを載せます。
using System;
using System.Windows.Forms;
using DxLibDLL;
namespace SampleGame
{
public class Game
{
[STAThread]
public static void Main()
{
Ziki ziki; //Zikiクラスのziki変数を用意
Teki[] teki;
Block block;//Blockクラスのblocks変数を用意
Haikei haikei;
int input;//自機の操作を割り当てる変数
int zikigraph;//自機の画像を割り当てる変数
int tekigraph;
const int TEKI_NUM = 16;
DX.ChangeWindowMode(1);
if (DX.DxLib_Init() == -1) return;
DX.SetDrawScreen(DX.DX_SCREEN_BACK);
//画像ハンドルの読み込み
zikigraph = DX.LoadGraph("data\\自機.png");
tekigraph = DX.LoadGraph("data\\敵.jpg");
//オブジェクトの生成
ziki = new Ziki(zikigraph);
teki = new Teki[TEKI_NUM];
teki[0] = new Teki(tekigraph, 40*1, 40*1);
teki[1] = new Teki(tekigraph, 40*4, 40*1);
teki[2] = new Teki(tekigraph, 40*6, 40*1);
teki[3] = new Teki(tekigraph, 40*8, 40*10);
teki[4] = new Teki(tekigraph, 40*10, 40*10);
teki[5] = new Teki(tekigraph, 40*14, 40*10);
teki[6] = new Teki(tekigraph, 70, 310);
teki[7] = new Teki(tekigraph, 100, 390);
teki[8] = new Teki(tekigraph, 20, 400);
teki[9] = new Teki(tekigraph, 80, 300);
teki[10] = new Teki(tekigraph, 80, 300);
teki[11] = new Teki(tekigraph, 80, 300);
teki[12] = new Teki(tekigraph, 80, 300);
teki[13] = new Teki(tekigraph, 80, 300);
teki[14] = new Teki(tekigraph, 80, 300);
teki[15] = new Teki(tekigraph, 80, 300);
block = new Block();
haikei = new Haikei();
block.LoadGraph();
haikei.LoadGraph();
block.Init();
while (DX.ProcessMessage() == 0)
{
input = DX.GetJoypadInputState(DX.DX_INPUT_KEY);//inputにこのキー操作を割り当てる
ziki.Update(input);//Update関数(操作)にinputを渡す
foreach (Teki te in teki)
{
te.Move();
te.gravityflag = true;
te.Gravity();
}
ziki.gravityflag = true;
ziki.Gravity();//重力を実際に与える関数
ziki.Jump(input);
ziki.Genkai();
DX.ClearDrawScreen();
haikei.Draw();
block.Draw();
block.BlockAtari(ziki.x, ziki.y);
block.Scroll(ziki.x, ziki.y, input);
foreach (Teki te in teki)
{
te.Draw();
}
ziki.Draw();//自機の描画
ziki.Kakunin();
DX.ScreenFlip();
}
DX.DxLib_End();
}
}
public class Character//後で敵キャラクターを作るためにひとまずキャラクター全体の基盤クラスをつくる
{
int graph;
public int gravity = 3;//重力の大きさ
public bool gravityflag;//重力がかかっているかないかのフラグ
public int x, y;//キャラクターの座標
public int movex, movey;//移動距離
public int width, height;//キャラクターのタテヨコの長さ
public int x_temp, y_temp,z_temp;//移動時の仮座標
public int jump_power;//ジャンプ時の移動距離(初期)
public bool jump_flag;//ジャンプ中かどうかのフラグ
public bool run_flag;//走っているかどうかのフラグ
public bool ontheground_flag; // 地面についているかどうかのフラグ
public bool jump_key_previous;
public bool muki;
public Character(int gr)
{
graph = gr;
}
public void Draw()
{
DX.DrawGraph(x, y, graph, 1);//描画
}
public void Gravity()
{
while (gravityflag == true)
{
x_temp = x+6;
y_temp = y+gravity+39;
z_temp = x + 34;
x_temp = x_temp / 40;
y_temp = y_temp / 40;
z_temp = z_temp / 40;
if (Block.haiti[y_temp, x_temp] == 0 && Block.haiti[y_temp, z_temp] == 0)
{
y += gravity;
}
if (Block.haiti[y_temp, x_temp] == 1 || Block.haiti[y_temp, z_temp] == 1)
{
ontheground_flag = true;
jump_flag = false;
jump_power = 20;
}
break;
}
}
}
public class Ziki : Character
{
const int zeki_jump_power = 20;
public Ziki(int gr)
: base(gr)
{
x = 40;
y = 40;
width = 40;
height = 40;
jump_power = zeki_jump_power;
jump_flag = false;
run_flag = false;
ontheground_flag = false;
jump_key_previous = false;
movex = 2;
muki = true;
}
public void Update(int input)//自機の操作
{
if ((input & DX.PAD_INPUT_LEFT) != 0)
{
x_temp = x - movex;
y_temp = y;
z_temp = y + 39;
x_temp = x_temp / 40;
y_temp = y_temp / 40;
z_temp = z_temp / 40;
if (Block.haiti[y_temp, x_temp] == 0 && Block.haiti[z_temp, x_temp] == 0)
{
x -= movex;
if (DX.CheckHitKey(DX.KEY_INPUT_LSHIFT) != 0)
{
run_flag = true;
x -= movex;
}
else
{
run_flag = false;
}
}
}
if ((input & DX.PAD_INPUT_RIGHT) != 0)
{
x_temp = x + movex + 39;
y_temp = y;
z_temp = y + 39;
x_temp = x_temp / 40;
y_temp = y_temp / 40;
z_temp = z_temp / 40;
if (Block.haiti[y_temp, x_temp] == 0 && Block.haiti[z_temp, x_temp] == 0)
{
x += movex;
if (DX.CheckHitKey(DX.KEY_INPUT_LSHIFT) != 0)
{
run_flag = true;
x += movex;
}
else
{
run_flag = false;
}
}
}
}
public void Genkai()
{
if (x < 0)
{
x = 0;
}
}
public void Jump(int input)
{
if ((input & DX.PAD_INPUT_A) != 0 && jump_flag == false && ontheground_flag == true)
{
if (jump_key_previous == false)
{
jump_flag = true;
ontheground_flag = false;
jump_key_previous = true;
}
}
else
{
jump_key_previous = false;
}
if(jump_flag == true)
{
x_temp = x+6;
y_temp = y - jump_power;
z_temp = x + 34;
x_temp = x_temp / 40;
y_temp = y_temp / 40;
z_temp = z_temp / 40;
if (Block.haiti[y_temp, x_temp] == 0 && Block.haiti[y_temp, z_temp] == 0)
{
y -= jump_power;
if (jump_power > 0)
{
jump_power--;
}
else
{
jump_power = 0;
}
}
if (Block.haiti[y_temp, x_temp] == 1 || Block.haiti[y_temp, z_temp] == 1)
{
jump_power = 0;
}
}
}
public void Kakunin()
{
if (ontheground_flag == true)
{
DX.DrawString(0, 0, "着地", DX.GetColor(255, 255, 255));
}
else
{
DX.DrawString(0, 0, "着地していない", DX.GetColor(255, 255, 255));
}
}
}
public class Teki : Character
{
const int zeki_jump_power = 17;
public Teki(int gr,int tx,int ty)
: base(gr)
{
x = tx;
y = ty;
width = 40;
height = 40;
jump_power = zeki_jump_power;
jump_flag = false;
run_flag = false;
ontheground_flag = false;
jump_key_previous = false;
movex = 1;
muki = true;
}
public void Move()
{
if (muki == true)
{
x_temp = x + movex + 39;
y_temp = y;
z_temp = y + 39;
x_temp = x_temp / 40;
y_temp = y_temp / 40;
z_temp = z_temp / 40;
if (Block.haiti[y_temp, x_temp] == 0 && Block.haiti[z_temp, x_temp] == 0)
{
x += movex;
if (run_flag == true)
{
x += movex;
}
}
if (Block.haiti[y_temp, x_temp] == 1 && Block.haiti[z_temp, x_temp] == 1)
{
muki = false;
}
}
if (muki == false)
{
x_temp = x - movex;
y_temp = y;
z_temp = y + 39;
x_temp = x_temp / 40;
y_temp = y_temp / 40;
z_temp = z_temp / 40;
if (Block.haiti[y_temp, x_temp] == 0 && Block.haiti[z_temp, x_temp] == 0)
{
x -= movex;
if (run_flag == true)
{
x -= movex;
}
}
if (Block.haiti[y_temp, x_temp] == 1 && Block.haiti[z_temp, x_temp] == 1)
{
muki = true;
}
}
}
}
public class Block
{
int blockgraph1;
public static int[,] haiti =
{
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1},
{1,0,0,1,1,1,1,1,0,1,1,0,0,0,0,1},
{1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,1},
{1,0,0,1,1,0,1,0,0,1,0,0,0,0,0,1},
{1,0,0,1,1,0,1,1,0,1,0,0,0,0,0,1},
{1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1},
{1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,1},
{1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};//ブロックの配置,1なら配置,0なら配置しない
const int CHIP_SIZE = 40;//ブロックひとつあたりの大きさ
const int XKOSUU = 640 / CHIP_SIZE;//ブロックが画面横(X)に埋まる個数
const int YKOSUU = 480 / CHIP_SIZE;//ブロックが画面縦(Y)に埋まる個数]
int[] x = new int[XKOSUU];
int[] y = new int[YKOSUU];
public void LoadGraph()
{
blockgraph1 = DX.LoadGraph("data\\ブロック.png");//同上
}
public void Init()
{
for (int i = 0; i < YKOSUU; ++i)
{
for (int j = 0; j < XKOSUU; ++j)
{
if (haiti[i, j] == 1)
{
x[j] = j * CHIP_SIZE;
y[i] = i * CHIP_SIZE;
}
}
}
}
public void Draw()
{
for (int i = 0; i < YKOSUU; ++i)
{
for (int j = 0; j < XKOSUU; ++j)
{
if (haiti[i, j] == 1)
{
DX.DrawGraph(x[j], y[i], blockgraph1, 1);
}
}
}
}
public void BlockAtari(int x,int y)
{
int px, py;
px = x / CHIP_SIZE;
py = y / CHIP_SIZE;
string pxstring = px.ToString();
string pystring = py.ToString();
string zahyou = "x座標のmap:" + pxstring + " " + "y座標のmap:" + pystring;
DX.DrawString(160,240,zahyou,DX.GetColor(255,255,255));
}
public void Scroll(int px, int py,int input)
{
if(px>320)
{
if ((input & DX.PAD_INPUT_RIGHT) != 0)
{
for (int i = 0; i < YKOSUU; ++i)
{
for (int j = 0; j < XKOSUU; ++j)
{
if (haiti[i, j] == 1)
{
x[j] -= 2;
}
}
}
}
}
}
}
public class Haikei
{
int graph;
int x = 0;
int y = 0;
public void LoadGraph()
{
graph = DX.LoadGraph("data\\背景.jpg");
}
public void Draw()
{
DX.DrawGraph(x, y, graph, 1);
}
}
}
public void Scroll(int px, int py,int input)
{
if(px>320)
{
if ((input & DX.PAD_INPUT_RIGHT) != 0)
{
for (int i = 0; i < YKOSUU; ++i)
{
for (int j = 0; j < XKOSUU; ++j)
{
if (haiti[i, j] == 1)
{
x[j] -= 2;
}
}
}
}
}
}
正しいやり方をどなたか教えてください。