游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2227|回复: 6

请教人物在地图中移动碰壁的问题!

[复制链接]

17

主题

61

帖子

61

积分

注册会员

Rank: 2

积分
61
发表于 2004-6-12 20:30:00 | 显示全部楼层 |阅读模式
望高人指点,人物在屏幕的坐标移动是连续变化的,地图是一块一块的整数坐标;
比如在(地图块为32x32大小)横32块竖20块的地图中,有好多的障碍(32*32pixel)人物大小为28*28,检查人物矩形是否与每个地图块相交,如果相交
设置人物移动为速度0,但是由于误差,有可能相交后再也出来不了,我有个办法是让人物从相交的位置弹出来,使之不相交,但是在弹出来的过程中,如果按下了其他的方向键
就会控制不了,反正我奔,请教好的办法。 [em3]

9

主题

198

帖子

198

积分

注册会员

Rank: 2

积分
198
发表于 2004-6-12 21:11:00 | 显示全部楼层

Re:请教人物在地图中移动碰壁的问题!

可以列出你的碰撞检测的代码或者伪代码吗?否则没有办法给你建议

17

主题

61

帖子

61

积分

注册会员

Rank: 2

积分
61
 楼主| 发表于 2004-6-12 21:21:00 | 显示全部楼层

Re:请教人物在地图中移动碰壁的问题!

好麻烦的,不容易看。我的水平差,我把原码改了在上传哈了

17

主题

61

帖子

61

积分

注册会员

Rank: 2

积分
61
 楼主| 发表于 2004-6-12 21:22:00 | 显示全部楼层

Re:请教人物在地图中移动碰壁的问题!

麻烦说说你们是怎么搞的?

9

主题

50

帖子

70

积分

注册会员

Rank: 2

积分
70
发表于 2004-6-14 08:37:00 | 显示全部楼层

Re:请教人物在地图中移动碰壁的问题!

我也是菜鸟, 以下是我得想法:

//地图块为32x32大小
#define TILE_H 32
#define TILE_W 32

struct TILE //地图块结构
{
    int x;//本地图块的x、y坐标
    int y;
    int bitmap_index;//本地图块的图片索引
    bool pass; //如果人能通过则pass = true, 否则pass = false
    ……//其他属性
}
class CMap
{
public:
    TILE& GetElem(int row, int col)
    {
           return m_map[row][col];
    }
private:
     TILE m_map[20][32];//横32块竖20块的地图
}

class CSprite
{
public:
     bool MoveUp(CMap &map);
     bool MoveDown(CMap &map);
     bool MoveLeft(CMap &map);
     bool MoveRight(CMap &map);

     void Draw(LPDIRECTDRAWSURFACE7 pBBuf);
private:
     int m_x, m_y;//人物当前的x、y坐标
   int m_width, m_height;//人物的长和宽
   ……//其他属性
}

bool CSprite::MoveUp(CMap &map)
{
    int old_y = m_y;
   
    m_y -= 8;//假设一次移动8个象素

    int x1 = m_x;
    int x2 = m_x + m_width ;
    int y1 = m_y;

    int row = y1 / TILE_H;
    int col1 = x1 / TILE_W;
    int col2 = x2 / TILE_W;

    if (map.GetElem(row, col1).pass == false
         || map.GetElem(row, col2).pass == false)
   {
           m_y = old_y;
           return false;
  }

   return true;
}

bool CMan::MoveDown(CMap &map)
{
     int old_y = m_y;

     m_y += 8;

    int x1 = m_x ;
    int x2 = m_x + m_width ;
    int y2 = m_y + m_height;
   

    int row = y2 / TILE_H;
    int col1 = x1 / TILE_W;
    int col2 = x2 / TILE_W;

     if (map.GetElem(row, col1).pass == false
         || map.GetElem(row, col2).pass == false)
   {
           m_y = old_y;
           return false;
  }

   return true;
}

左右的方向的类似。

19

主题

202

帖子

214

积分

中级会员

Rank: 3Rank: 3

积分
214
QQ
发表于 2004-6-15 09:02:00 | 显示全部楼层

Re:请教人物在地图中移动碰壁的问题!

不要等到相交之后在修改位置,做一个预判,如果在下一帧就会相交,那么把人物移动到合适的位置上

21

主题

182

帖子

192

积分

注册会员

Rank: 2

积分
192
发表于 2004-6-15 09:37:00 | 显示全部楼层

Re:请教人物在地图中移动碰壁的问题!

我写的一段delphi的,通过检查x/y 是否在一个rect 范围内实现的,另外,分别检测物体的四个角的碰撞情况
[a]   
   [Sp]
[c]    [d]

//分别传入a..b的x/y/width/height 和sprite 的x/y/width/height 和方向
//判断四个方向为Up = a .. b down=c..d  left=a...c right=b..d

function CheckSpriteRect(x1, y1, w1, h1, x2, y2, w2, h2, px, py, pw, ph, dir:
  Integer): TCheckResult;
var
  r1, r2            : TRect;
  p1, p2            : TPoint;
  m1, m2            : integer;
  cb                : boolean;
begin
  SetRect(r1, x1, y1, x1 + w1, y1 + h1); //第一个
  SetRect(r2, x2, y2, x2 + w2, y2 + h2); //第二个
  m1 := 0;
  m2 := 0;
  case dir of
    0:                                  //up
      begin
        p1.X := px;
        p1.Y := py;
        p2.X := px + pw;
        p2.Y := py;
        m1 := w1 div 3;
        m2 := w2 div 3;
      end;
    1:                                  //down
      begin
        p1.X := px;
        p1.Y := py + ph;
        p2.X := px + pw;
        p2.Y := py + ph;
        m1 := w1 div 3;
        m2 := w2 div 3;
      end;
    2:                                  //left
      begin
        p1.X := px;
        p1.Y := py;
        p2.X := px;
        p2.Y := py + ph;
        m1 := h1 div 3;
        m2 := h2 div 3;
      end;
    3:                                  //right
      begin
        p1.x := px + pw;
        p1.Y := py;
        p2.x := px + pw;
        p2.Y := py + ph;
        m1 := h1 div 3;
        m2 := h2 div 3;
      end;
  end;

  cb := PtInRect(r1, p1) or PtInRect(r2, p2);
  result.Stop := cb;

  if result.Stop then
  begin

    if PtInRect(R1, p1) then
    begin
      result.Id := 1;
      case Dir of
        0, 1:                           //up;
          if (R1.Right - p1.X) > m1 then
            result.Id := 0;
        2, 3:
          if (r1.Bottom - p1.Y) > m1 then
            result.Id := 0;
      end;
    end;

    if PtInRect(R2, p2) then
    begin
      result.Id := 2;
      case Dir of
        0, 1:
          if (p2.X - r2.Left) > m2 then
            result.Id := 0;
        2, 3:
          if (p2.Y - r2.Top) > m2 then
            result.Id := 0;
      end;
    end;
  end
  else
    result.Id := -1;

end;


//返回类型为
type
  TCheckResult = record
    Stop: boolean;                      //是否停止
    Id: integer;                        //0表示不调整坐标,1/2分别调整++/--
  end;

//有相交的地方进行坐标调整,也就是人物贴与墙面时刻进行滑动的效果(C伪码)
if(result.id=1&&isLeft||isRight)Y++;
if(result.id=2&&isLeft||isRight)Y--;
if(result.id=1&&isUp||isDown)X++;
if(result.id=2&&isUp||isDown)X--;

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-7-1 21:58

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表