超级玛丽制作揭秘23玩家动作控制
来源:互联网 发布:c 窗口程序编程教程 编辑:程序博客网 时间:2024/05/04 05:02
玩家移动:把行走和跳跃看成两个状态,各自用不同的变量表示横纵方向的速度。
相关属性:
行走:横向速度为movex,纵向不移动。
跳跃:横向速度为jumpx,纵向速度为movey。当前跳跃高度jumpheight
运动方向:idirec
思路:
第一步:玩家按键,按键处理函数设置这些属性。按键松开,清除动作属性。
第二步:用一个函数不停检测这些变量,控制玩家移动。
1. 按键触发:
按键处理函数:int GAMEMAP::KeyProc(int iKey)
代码:
switch(iKey)
{
case VK_RIGHT: //按右
//判断是否正在跳跃, 即纵向速度不为0
if(rmain.movey!=0)
{
//跳跃过程中, 设置横向速度, 方向向右, 大小为4像素
rmain.jumpx=4;
}
rmain.movex=4; //设置横向速度, 方向向右, 大小为4像素
rmain.idirec=0; //设置玩家方向, 向右
break;
case VK_LEFT: //按左
//如果是跳跃过程中, 设置横向速度, 方向向左, 大小为4像素
if(rmain.movey!=0)
{
rmain.jumpx=-4;
}
rmain.movex=-4; //设置横向速度, 方向向左, 大小为4像素
rmain.idirec=1; //设置玩家方向, 向左
break;
case KEY_X: //X键跳
//如果已经是跳跃状态,不作处理,代码中断
if(rmain.movey!=0)
break;
//设置纵向速度,方向向上(负值),大小为13
rmain.movey=-SPEED_JUMP;
//将当前的横向速度,赋值给“跳跃”中的横向速度
rmain.jumpx=rmain.movex;
break;
case KEY_Z: //FIRE
if(iBeginFire)
break; //如果已经开始攻击,代码中断
iTimeFire=0; //初始化子弹间隔时间
iBeginFire=1; //置1,表示开始攻击
break;
按键松开处理函数:void GAMEMAP::KeyUpProc(int iKey)
代码:
//松开左右键,清除横向速度
case VK_RIGHT:
rmain.movex=0;
break;
case VK_LEFT:
rmain.movex=0;
break;
case KEY_X: //跳
//不能清除跳跃的横向速度jumpx
//例如,移动过程中起跳,整个跳跃过程中都要有横向速度
break;
case KEY_Z: //FIRE
iBeginFire=0; //停止攻击
break;
2. 控制移动。
动作检测函数:WndProc
代码:时间片的处理中,根据不同状态,调用各种检测函数。
case WM_TIMER:
switch(gamemap.iGameState)
{
case GAME_IN:
rmain.Move();//人物移动
……
break;
说明:每45毫秒产生一个WM_TIMER消息,在GAME_IN状态下,调用各种检测函数。其中rmain.Move()就是不断检测玩家动作属性,实现移动。
函数:void MYROLE::Move()
代码:
if(0 == movey)
{
//如果不是跳跃, 横向移动
MoveOffset(movex, 0);
}
else
{
//跳跃, 先横向移动, 再纵向移动
MoveOffset(jumpx, 0);
MoveOffset(0, movey);
}
//玩家帧控制 ”纠错法”
if(movex<0 && iFrame<3)
{
iFrame=3; //如果玩家向左移动, 而图片向右, 则设置为3(第4张图片)
}
if(movex>0 && iFrame>=3)
{
iFrame=0; //如果玩家向右移动, 而图片向右, 则设置为0(第1张图片)
}
//帧刷新
if(movex!=0)
{
if(0==idirec)
iFrame=1-iFrame; //如果方向向右, 图片循环播放0,1帧
else
iFrame=7-iFrame; //如果方向向左, 图片循环播放3,4帧
}
if(movey!=0)
{
//跳跃过程中, 帧设置为0(向右),3(向左)
//帧刷新后, 重新设置帧, 就实现了跳跃过程中, 图片静止
iFrame=idirec*3;
}
//跳跃控制
if(movey<0)
{
//向上运动(纵向速度movey为负值)
jumpheight+=(-movey); //增加跳跃高度
//重力影响,速度减慢
if(movey<-1)
{
movey++;
}
//到达顶点后向下落, 最大跳跃高度为JUMP_HEIGHT * 32, 即3个格子的高度
if(jumpheight >= JUMP_HEIGHT * 32)
{
jumpheight = JUMP_HEIGHT * 32; //跳跃高度置为最大
movey=4; //纵向速度置为4, 表示开始下落
}
}
else if(movey>0)
{
//下落过程, 跳跃高度减少
jumpheight -= movey;
//重力影响,速度增大
movey++;
}
玩家移动函数:void MYROLE::MoveOffset(int x,int y)
代码:根据增量设置坐标
//横纵增量为0,不移动,代码结束
if(x==0 && y==0)
return;
//如果碰到物体,不移动,代码结束
if(!gamemap.RoleCanMove(x,y))
return;
//修改玩家坐标
xpos+=x;
ypos+=y;
//判断是否超出左边界
if(xpos<minx)
xpos=minx; //设置玩家坐标为左边界
//判断是否超出右边界
if(xpos>maxx)
xpos=maxx;
3. 碰撞检测
无论行走,跳跃,都是用函数MoveOffset操纵玩家坐标。这时,就要判断是否碰到物体。如果正在行走,则不能前进;如果是跳跃上升,则开始下落。
函数:int GAMEMAP::RoleCanMove(int xoff, int yoff)
代码:
int canmove=1;//初始化, 1表示能移动
for(i=0;i<iMapObjNum;i++)
{
if( RECT_HIT_RECT(玩家坐标加增量,地图物品坐标))
{
//碰到物体,不能移动
canmove=0;
if(yoff<0)
{
//纵向增量为负(即上升运动), 碰到物体开始下落
rmain.movey=1;
}
if(yoff>0)
{
//纵向增量为正(即下落运动), 碰到物体, 停止下落
rmain.jumpheight=0;//清除跳跃高度
rmain.movey=0;//清除纵向速度
rmain.ypos=MapArray[i].y*32-32;//纵坐标刷新,保证玩家站在物品上
}
break;
}
}
return canmove;
玩家移动的过程中,要不断检测是否站在地图物品上。如果在行走过程中,且没有站在任何物品上,则开始下落。
函数:int GAMEMAP::CheckRole()
代码:
if(rmain.movey == 0 )
{
//检测角色是否站在某个物体上
for(i=0;i<iMapObjNum;i++)
{
//玩家的下边线,是否和物品的上边线重叠
if( LINE_ON_LINE(rmain.xpos,
rmain.ypos+32,
32,
MapArray[i].x*32,
MapArray[i].y*32,
MapArray[i].w*32)
)
{
//返回1,表示玩家踩在这个物品上
return 1;
}
}
//角色开始下落
rmain.movey=1;
rmain.jumpx=0;//此时要清除跳跃速度,否则将变成跳跃,而不是落体
return 0;
至此,玩家在这个虚拟世界可以做出各种动作,跳跃,行走,攻击。增强版中,加入了水管,玩家在进出水管,就需要两个动画?怎么实现,且听下回分解。
附:
超级玛丽第一版源码链接:http://download.csdn.net/source/497676
超级玛丽增强版源码链接:http://download.csdn.net/source/584350
- 超级玛丽制作揭秘23玩家动作控制
- 超级玛丽制作揭秘22玩家角色类MYROLE
- 超级玛丽制作揭秘6时钟控制 类MYCLOCK
- 超级玛丽制作揭秘26菜单控制 窗口缩放
- 超级玛丽制作揭秘1
- 超级玛丽制作揭秘2
- 超级玛丽制作揭秘17地图物品
- 超级玛丽制作揭秘18背景物品
- 超级玛丽制作揭秘19视图
- 超级玛丽制作揭秘20地图切换
- 超级玛丽制作揭秘21游戏数据管理
- 超级玛丽制作揭秘24角色动画
- 超级玛丽制作揭秘文档发布
- 超级玛丽制作揭秘3 游戏背景类MYBKSKY
- 超级玛丽制作揭秘4图片显示 类MYANIOBJ
- 超级玛丽制作揭秘5魔法攻击 类MYANIMAGIC
- 超级玛丽制作揭秘7字体管理 类MYFONT
- 超级玛丽制作揭秘8跟踪打印 类FILEREPORT
- 实战:结合Dr.Watson系统日志和Vc6来定位多线程环境下程序异常退出的错误
- GridView的一些控制样式显示的小技巧(合并列的显示,DataFormatingString的控制)
- 超级玛丽制作揭秘22玩家角色类MYROLE
- VC++6.0调试篇:远程调试
- [Serializable]在C#中的作用-NET 中的对象序列化
- 超级玛丽制作揭秘23玩家动作控制
- The right way to maintain build grid for continuous integration is virtualization.
- 史玉柱的地头力
- Velocity 1.6 Changes Report
- 关于 ORA-00937: 非单组分组函数 异常
- 超级玛丽制作揭秘24角色动画
- 音乐收藏
- 飯桌上的禮儀
- 如何用ASP.NET实现验证码