コードが長いので断片的な部分だけです、コメント部の記入すべきコードです。
2Dアクションゲームでベクトルを使って移動した時にブロックや他の画像と重なってしまういわゆる"めり込み"の修正方が知りたいです。自分はベクトルを使い方向の情報を使ってぶつかってきた方向に追い返す処理を考えました。
図の場合は右と下に進んでいるのでその逆の左上に追い返す(座標をずらす)ということをしたいです。
また水平に並んだブロックに上から下と右に移動しながら進んできた時に上に座標をずらすといった処理を書きたいのですがどうしたらいいのか実装が思いつかないのですが教えてくれますでしょうか?
画像:画像の青がプレイやーで端が紫の青いブロックは移動してる時つまりプレイヤーに移動速度してる情報が追加されたときの画像で赤がブロックです。
環境:dxlibです右がx++で下がy++の座標系です。2Dです。
player_col()部です。
追記ですが下にブロックがあり右の真横にもブロックがる場合上に上がってしましますこれはどうすればいいのでしょうか?
画像の場所です。
Position Map::Collision::isMapCell(const Position pos) { Position p; for (int y = 0; y < MAP_HEIGHT; y++) { for (int x = 0; x < MAP_WIDTH; x++) { } } if (get_mapCell(pos.get_x() / CELL, pos.get_y() / CELL) == (int)mapChip::eBrick || get_mapCell(pos.get_x() / CELL, pos.get_y() / CELL) == (int)mapChip::eQuestion) { p.new_pos_x((pos.get_x() / CELL)); p.new_pos_y((pos.get_y() / CELL)); ofs << "p.get_x(): " << p.get_x() << std::endl; ofs << "p.get_y(): " << p.get_y() << std::endl; return p; } return Position(-1,-1); } //座標が引数 std::optional<Position> Map::Collision::col(const Position p) { Position c_pos(Map::Collision::isMapCell(p)); if (c_pos.get_x() > -1 && c_pos.get_y() > -1) { if (c_pos.get_x() * CELL <= p.get_x() && (c_pos.get_x() * CELL) + CELL >= p.get_x() ) { } } return std::nullopt; } /*全方位の当たり判定 return セル番号を返す*/ std::optional<Position> Map::Collision::player_col(const Position *pos,const Position *move) { Position p; p.new_pos_x( pos->get_x() + move->get_x() + CELL); p.new_pos_y( pos->get_y() + move->get_y() + CELL); static bool isground = false; int px = pos->get_x(); int py = pos->get_y(); int add_x = move->get_x(); int add_y = (int)move->get_y(); // ofs << "move->get_x(): " << move->get_x()<<"\n"; // ofs << "move->get_y(): " << move->get_y() << "\n"; int corr_x = 0; int corr_y = 0; Position pp = Map::Collision::isMapCell(p); if (pp.get_x() > -1) { if (move->get_x() > 0) { //ofs << "x補正" << std::endl; //px = pos->get_x() -CELL; } //ofs << "playe_col isground: " << isground << std::endl; if ((move->get_y() < 0)) { ofs << "ground " << std::endl; isground = true; //py -= ((pos->get_y() + (-move->get_y()) + CELL) - (pp.get_y() * CELL)); //ofs << "pp.get_y(): " << ((pos->get_y() + (-move->get_y()) + CELL) - (pp.get_y() * CELL)); int yy = ((pos->get_y() + (-move->get_y()) + CELL) - ((pp.get_y() * CELL))); py -= yy; } std::optional<Position> p = Position(px, py); return p.value();//セルを返す } return std::nullopt; }
#include <iostream> #include <fstream> #include "Input.h" #include "Player.h" #include "DxLib.h" #include "Map.h" #include "Animation.h" #define MOVE_SPD 5 #define JUMP_FORCE 4.0624 * 3 static std::ofstream ofs("Log.txt"); /*コンストラクタ*/ Player::Player(const char* str, int xx, int yy) { //LoadDivGraph(str,7,7,1,64,64,g_handle); AnimeClip = new Animation(anime_s::ewait,str,7,7,1); pos = new Position(); prev = new Position(); move = new Position(); AnimeClip->setAnime(anime_s::ewalk,1,3,3); AnimeClip->setAnime(anime_s::ewait, 0, 0, 1); AnimeClip->setAnime(anime_s::ejump, 5, 5, 1); } /*計算更新*/ void Player::Update() { gravity(); input_key(); jump_up(); //side_move();// AnimeClip->Update(); DrawFormatString(200, 280, GetColor(255, 255, 255), "y %d", pos->get_y()); DrawFormatString(200, 360, GetColor(255, 255, 255), "x %d", pos->get_x()); // ofs << (double)std::atan2((double)pos->get_x(),(double)pos->get_y()) << std::endl; DrawFormatString(100, 200, GetColor(255, 255, 255), "isGround %d", isGround); DrawFormatString(100, 280, GetColor(255, 255, 255), "isJump %d", isJump); ofs << "pos.x: " << pos->get_x() << std::endl; ofs << "pos.y: " << pos->get_y() << std::endl; *prev = *pos; } /*描画更新*/ void Player::Draw_Update() { if ( key == -1) { //DrawTurnGraph(get_x(), get_y(), g_handle[0], true); /////// DrawTurnGraph(pos->get_x(), pos->get_y(), AnimeClip->draw_setClip(), true); } /*右→*/ if (key == 1) { /// DrawGraph(pos->get_x(), pos->get_y(), AnimeClip->draw_setClip(), true); } AnimeClip->Draw_Update(); } /*キー入力*/ void Player::input_key() { if (keybord(KEY_INPUT_LEFT) > 0)//← { key = -1; AnimeClip->Update_changeAnime(anime_s::ewalk,key); pos->set_x(-MOVE_SPD); move->new_pos_x(-MOVE_SPD); }else if (keybord(KEY_INPUT_RIGHT) > 0)//→ { key = 1; AnimeClip->Update_changeAnime(anime_s::ewalk,key); move->new_pos_x(MOVE_SPD); pos->set_x(+MOVE_SPD); }else if (keybord(KEY_INPUT_UP) > 0)//上 { //pos->set_y(+MOVE_SPD); }else if (keybord(KEY_INPUT_DOWN) > 0)//下 { // pos->set_y(-MOVE_SPD); } else if (keybord(KEY_INPUT_SPACE) > 0)//ジャンプ { //AnimeClip->Update_changeAnime(anime_s::ejump); if (isGround == true && jf == 0) { //isJump = true; isGround = false; jf = JUMP_FORCE; } AnimeClip->Update_changeAnime(anime_s::ejump); } else//何も押していない時 { move->new_pos_x(0); AnimeClip->Update_changeAnime(anime_s::ewait); } } /************************ジャンプ ***********************/ void Player::jump_up() { if (Map::Collision::player_col(pos, move) == std::nullopt) { if (isGround == false) { move->new_pos_y((int)jf); pos->set_y((int)jf); //if (Fps::gframe() % 20 == 0) { jf = ((jf - 0.126953125f * 20.0f)); if (jf < -0.126953125f * 3.0f * 10.0f) { jf = -0.126953125f * 3.0f * 10.0f; //pos->set_y(); } //} } } } /*********************************************************/ /***********************重力*******************************/ void Player::gravity() { /*地面着地*/ if (Map::Collision::player_col(pos, move) != std::nullopt) { // ofs << "test\n"; std::optional<Position> p = Map::Collision::player_col(pos, move); pos->new_pos_x(p->get_x()); pos->new_pos_y(p->get_y()); //pos->set_y(p->get_y()); //pos->set_x(-p->get_x()); // ofs << "under_col true\n"; } else { //ofs << "palyer_col nullopt" <<"\n"; } //落下 if (Map::Collision::player_col(pos,move) == std::nullopt) //if (Map::Collision::under_col(pos, prev) == std::nullopt && isGround == false) { //DrawFormatString(200, 200, GetColor(255, 255, 255), "x %d", pos->get_x()); //if (Map::Collision::player_col(pos, move) == std::nullopt) { if (isGround == false) { move->new_pos_y((int)jf); pos->set_y((int)jf); jf = ((jf - 0.126953125f * 20.0f)); if (jf < -0.126953125f * 3.0f * 10.0f) { jf = -0.126953125f * 3.0f * 10.0f; //pos->set_y(); } } else { } // } } } /**********************************************************/
プログラミングというより数学的なアドバイスがほしいと思うんですが全く理解できません。
方向関係の定義を説明してください。
真横の壁とは何から見て真横なのですか。左に補正されるとは何が左に補正されるのですか。上とはZ座標のこと?空間は2Dですか3Dですか。ソースコード内の各変数は何を示しているのでしょうか。
できれば図形込みで説明してくれたら理解が進みます。
わかりました図を作ります。
文章と図とを追加し質問内容を最適化しました。
回答3件
あなたの回答
tips
プレビュー