// Check collision with a diamond shape // This means that the bounding box could be in collision, but the bounding // "radius" is not. The diamond is expressed with a single "radius" - that is, // the diamond is the same height and width. // This arrangement is used so that axis movement can slide off corners by // moving in a diagonal direction. // E.g. this is not a collision: // x // x x // x x // x x // x x // x x wwwww // x w // w // Where 'x' denotes the bounding diamond, and 'w' represents a wall corner. bool IsCollisionDiamond(const Map *map, const Vec2i pos, const Vec2i fullSize) { const Vec2i mapSize = Vec2iNew(map->Size.x * TILE_WIDTH, map->Size.y * TILE_HEIGHT); const Vec2i size = Vec2iScaleDiv(fullSize, 2); if (pos.x - size.x < 0 || pos.x + size.x >= mapSize.x || pos.y - size.y < 0 || pos.y + size.y >= mapSize.y) { return true; } // Only support wider-than-taller collision diamonds for now CASSERT(size.x >= size.y, "not implemented, taller than wider diamond"); const double gradient = (double)size.y / size.x; // Now we need to check in a diamond pattern that the boundary does not // collide // Top to right for (int i = 0; i < size.x; i++) { const int y = (int)Round((-size.x + i)* gradient); const Vec2i p = Vec2iAdd(pos, Vec2iNew(i, y)); if (HitWall(p.x, p.y)) { return true; } } // Right to bottom for (int i = 0; i < size.x; i++) { const int y = (int)Round(i * gradient); const Vec2i p = Vec2iAdd(pos, Vec2iNew(size.x - i, y)); if (HitWall(p.x, p.y)) { return true; } } // Bottom to left for (int i = 0; i < size.x; i++) { const int y = (int)Round((size.x - i) * gradient); const Vec2i p = Vec2iAdd(pos, Vec2iNew(-i, y)); if (HitWall(p.x, p.y)) { return true; } } // Left to top for (int i = 0; i < size.x; i++) { const int y = (int)Round(-i * gradient); const Vec2i p = Vec2iAdd(pos, Vec2iNew(-size.x + i, y)); if (HitWall(p.x, p.y)) { return true; } } return false; }
int IsCollisionWithWall(Vec2i pos, Vec2i size) { if (HitWall(pos.x - size.x, pos.y - size.y) || HitWall(pos.x - size.x, pos.y) || HitWall(pos.x - size.x, pos.y + size.y) || HitWall(pos.x, pos.y + size.y) || HitWall(pos.x + size.x, pos.y + size.y) || HitWall(pos.x + size.x, pos.y) || HitWall(pos.x + size.x, pos.y - size.y) || HitWall(pos.x, pos.y - size.y)) { return 1; } return 0; }
bool IsCollisionWithWall(Vec2i pos, Vec2i size) { if (pos.x - size.x < 0 || pos.y - size.y < 0 || pos.x + size.x >= gMap.Size.x * TILE_WIDTH || pos.y + size.y >= gMap.Size.y * TILE_HEIGHT) { return true; } if (HitWall(pos.x - size.x, pos.y - size.y) || HitWall(pos.x - size.x, pos.y) || HitWall(pos.x - size.x, pos.y + size.y) || HitWall(pos.x, pos.y + size.y) || HitWall(pos.x + size.x, pos.y + size.y) || HitWall(pos.x + size.x, pos.y) || HitWall(pos.x + size.x, pos.y - size.y) || HitWall(pos.x, pos.y - size.y)) { return true; } return false; }
bool IsCollisionWithWall(const Vec2i pos, const Vec2i fullSize) { Vec2i size = Vec2iScaleDiv(fullSize, 2); if (pos.x - size.x < 0 || pos.y - size.y < 0 || pos.x + size.x >= gMap.Size.x * TILE_WIDTH || pos.y + size.y >= gMap.Size.y * TILE_HEIGHT) { return true; } if (HitWall(pos.x - size.x, pos.y - size.y) || HitWall(pos.x - size.x, pos.y) || HitWall(pos.x - size.x, pos.y + size.y) || HitWall(pos.x, pos.y + size.y) || HitWall(pos.x + size.x, pos.y + size.y) || HitWall(pos.x + size.x, pos.y) || HitWall(pos.x + size.x, pos.y - size.y) || HitWall(pos.x, pos.y - size.y)) { return true; } return false; }
//***************************************************************************** // 更新 //***************************************************************************** void CPlayer::Update() { //キー変数と取得 CInputKeyboard *pKeyBoard; pKeyBoard = CManager::GetInputKeyboard();//入力処理へのポインタ取得 //カメラ変数と取得 D3DXVECTOR3 CameraRot = CCamera::GetCameraRot(); //地面の高さの取得変数 CScene3d *pScene3d; pScene3d = CManager::GetScene3D(); //過去の座標を記録 D3DXVECTOR3 oldVtx = m_Vertex_3d.vtx; //ギミックの影響を反映させる if(m_pSceneLink) { //ギミック情報取得 VERTEX_3D pVtx; m_pSceneLink->GetVtx(&pVtx); m_Vertex_3d.vtx += pVtx.Speed_vtx; //m_Vertex_3d.Rot_vtx.y += 0.005f; //プレイヤーの角度の修正 while(m_Vertex_3d.Rot_vtx.y >= 1) { m_Vertex_3d.Rot_vtx.y -= 1 * 2; } while(m_Vertex_3d.Rot_vtx.y <= -1) { m_Vertex_3d.Rot_vtx.y += 1 * 2; } } //プレイヤーの今回の角度 //死亡した場合 if(m_bDeath) { //死亡エフェクト処理 m_Vertex_3d.Scail_vtx -= D3DXVECTOR3(0.02f,0.02f,0.02f); m_Vertex_3d.Rot_vtx.y += 0.2f; m_Vertex_3d.vtx.y += 0.1f; //プレイヤーが消滅したらゲーム終了 if(m_Vertex_3d.Scail_vtx.x < 0.0f) { CScene::Release(); CManager::ChangeMode(CManager::MODE_REZULT_GAMEOVER); } //以下の処理を行わずに終了 return; } //移動処理 //奥移動 if(pKeyBoard->GetkeyboardPress(DIK_W)) { //角度指定 if(pKeyBoard->GetkeyboardPress(DIK_D)) { PurposeRot = 0.25f + CameraRot.y; } else if(pKeyBoard->GetkeyboardPress(DIK_A)) { PurposeRot = -0.25f + CameraRot.y; } else { PurposeRot = 0.0f + CameraRot.y; } ResultRot = PurposeRot - m_Vertex_3d.Rot_vtx.y; m_Vertex_3d.MoveFlag = true; } //手前移動 else if(pKeyBoard->GetkeyboardPress(DIK_S)) { if(pKeyBoard->GetkeyboardPress(DIK_D)) { PurposeRot = 0.75f + CameraRot.y; } else if(pKeyBoard->GetkeyboardPress(DIK_A)) { PurposeRot = -0.75f + CameraRot.y; } else { PurposeRot = 1.0f + CameraRot.y; } ResultRot = PurposeRot - m_Vertex_3d.Rot_vtx.y; m_Vertex_3d.MoveFlag = true; } //左移動 else if(pKeyBoard->GetkeyboardPress(DIK_A)) { PurposeRot = -0.5f + CameraRot.y ; ResultRot = PurposeRot - m_Vertex_3d.Rot_vtx.y; m_Vertex_3d.MoveFlag = true; } //右移動 else if(pKeyBoard->GetkeyboardPress(DIK_D)) { //目的の角度の指定 PurposeRot = 0.5f + CameraRot.y; //角度の結果を計算 ResultRot = PurposeRot - m_Vertex_3d.Rot_vtx.y; m_Vertex_3d.MoveFlag = true; } else { m_Vertex_3d.MoveFlag = false; } //移動処理 if(m_Vertex_3d.MoveFlag) { while(ResultRot >= 1) { ResultRot -= 1 * 2; } while(ResultRot <= -1) { ResultRot += 1 * 2; } m_Vertex_3d.Rot_vtx.y += ResultRot * PLAYER_ROT; m_Vertex_3d.Speed_vtx.x += sin(D3DX_PI * PurposeRot) * MOVE; m_Vertex_3d.Speed_vtx.z += cos(D3DX_PI * PurposeRot) * MOVE; if(!jump && !m_bMotion) { if(m_bBlendMotion) { m_bBlendMotion = false; } SetMotion(MOTIONTYPE_WALK,10,m_bMotion); } } else { if(GetMotion() == MOTIONTYPE_WALK) { m_bFinishMotion = true; } } //ジャンプ if(pKeyBoard->GetkeyboardTrigger(DIK_SPACE) && !jump) { m_Vertex_3d.Speed_vtx.y = 1.0f; SetMotion(MOTIONTYPE_JUMP,10,false); } else if(pKeyBoard->GetkeyboardTrigger(DIK_1)) { SetMotion(MOTIONTYPE_PUNCH,10,m_bMotion); } //重力 m_Vertex_3d.Speed_vtx.y -= 0.03f; //空気抵抗 m_Vertex_3d.Speed_vtx.y -= m_Vertex_3d.Speed_vtx.y * 0.05f; //抵抗摩擦 m_Vertex_3d.Speed_vtx.x -= m_Vertex_3d.Speed_vtx.x * 0.2f; m_Vertex_3d.Speed_vtx.z -= m_Vertex_3d.Speed_vtx.z * 0.2f; //移動 m_Vertex_3d.vtx.x += m_Vertex_3d.Speed_vtx.x; m_Vertex_3d.vtx.y += m_Vertex_3d.Speed_vtx.y; m_Vertex_3d.vtx.z += m_Vertex_3d.Speed_vtx.z; //コインを全て取得したら if(CScore::GetScore() >= 500 && !clear) { CSter::Create(CRenderer::GetDevice(),D3DXVECTOR3(-48.0f,0.0f,48.0f),YEROWW_TEXTURE); clear = true; } //一定以上落下で死亡 if(m_Vertex_3d.vtx.y < -5.0f) { m_bDeath = true; PlaySound(SE_00,false); } //時間終了でもアウト if(CTime::TimeUp()) { m_bDeath = true; PlaySound(SE_00,false); } //地面にいるかの判定 if(m_Vertex_3d.vtx.y < pScene3d->GetHeight(m_Vertex_3d.vtx)) { //高さの指定 m_Vertex_3d.vtx.y = pScene3d->GetHeight(m_Vertex_3d.vtx); jump = false; if(m_motionType == MOTIONTYPE_JUMP) { SetMotion(MOTIONTYPE_NEUTRAL,8,true); } } //宙に浮いている場合 else { jump = true; } //ギミック更新処理 HitGimmick(); //壁にぶつかったかの判定 if(HitWall()) { m_Vertex_3d.vtx = oldVtx; } //モーションの更新 UpdateMotion(); //単発モーションが終了した場合 if(m_bFinishMotion) { if(m_bBlendMotion) { m_bBlendMotion = false; } if(GetMotion() == MOTIONTYPE_WALK) { SetMotion(MOTIONTYPE_NEUTRAL,20,true); } else { SetMotion(MOTIONTYPE_NEUTRAL,10,false); } m_bMotion = false; m_bFinishMotion = false; } }