关于vector容器在射击游戏中的运动和消失

冷雨夜刀锋 2008-03-10 04:40:26
void circle_3D() //3D中的循环,不包括渲染
{
switch(it_mode)
{
case 1:
io1.write_debugfile("循环起");
input1.check_io(engine1->TimeElapsed(),1500);
//input1.check_fire(engine1->TickCount());

boat1.set_position(input1.get_mboat_xpos(10*(1+val1.move_speed*0.1)),HOR_LEVEL,POSZ);
boat1.set_flag_position();
my_x=boat1.get_mboat_xpos();

//boat1.be_hurt(engine1->TickCount());
int i;

for(i=0;i<e_boats.size();i++)
{
e_boats.at(i).hurt_it(engine1->TickCount(),boat1.get_mboat_xpos(),HOR_LEVEL);
e_boats.at(i).be_hurt(engine1->TickCount());
}


set_plane_position(engine1->TickCount());
io1.write_debugfile(" 机飞行完 ");
check_plane_behurt(engine1->TickCount());
io1.write_debugfile(" 机被打完 ");

landx.be_hurt(engine1->TickCount());
io1.write_debugfile(" 陆地完 ");

del_unable_plane();
io1.write_debugfile(" 删机2完 ");

set_armo_position(engine1->TickCount());
io1.write_debugfile(" 弹飞完 ");;
//set_hplane_position();
show_bomb();
show_waters();
io1.write_debugfile("循环完\n");
break;
case 2:
gd2.init_logo();
break;
}

}

这是一个游戏的循环部分,里面有几个类:plane飞机类,planes是<plane>的vector
armo类,armos是<armo>的vector,其他的无关。
目的是让弹运动、让飞机运动,运动如下:
void set_armo_position(long tkcount) //用遍历的方法将每个armo放在其时间应该在的位置上
{
vector <Armo2>::iterator del_it;
for(del_it=armos.begin();del_it!=armos.end()&&armos.size()>0;++del_it)
{
del_it->set_now_pos(tkcount);
if(del_it->get_is_enable()==false)
{
del_it->destroy_armo();
armos.erase(del_it);
}
}
}

void set_plane_position(long tkcount) //用遍历的方法将每个plane放在其时间应该在的位置上
{
vector <plane1>::iterator pl_it;
for(pl_it=planes.begin();pl_it!=planes.end()&&planes.size()>0;++pl_it)
{
pl_it->set_now_pos(tkcount);
}
}


void check_plane_behurt(long tkcount) //用遍历的方法检查每个plane是否被炮弹攻击?
{
vector <plane1>::iterator del_it;
for(del_it=planes.begin();del_it!=planes.end()&&planes.size()>0;++del_it)
{
del_it->be_hurt(tkcount);
}
}

飞机的删除是单独列的,当然也可以写到运动中去。
而飞机类中的be_hurt是这样写的:
void be_hurt(long tkcount) //根据传来的炮弹模型的序列来判断是否被击中
{ //击中将显爆炸,并消失炮弹,并将飞机设置为false;
vector<Armo2>::iterator del_it;
for(del_it=armos.begin();del_it!=armos.end()&&armos.size()>0;++del_it)
{
if(status!=2&&del_it->get_team()==0&&(xpos>del_it->get_xpos()-20)&&(xpos<del_it->get_xpos()+20)&&(ypos>del_it->get_ypos()-20)&&(ypos<del_it->get_ypos()+20)) //判断炮弹
{
del_it->set_is_enable(false);
status=2;
d_xpos=xpos; //将当前位置设置给被击中点
d_ypos=ypos;
down_jiao=210+rand()%55; //落下角度
}
}
}

飞机的关于落下部分的运动是这样写的:
void set_now_pos(long tkcount) //获得飞机目前的位置,并不断看我舰的位置是否进入可攻击位置
{ //飞机飞行的思路为,定义一个比起始高度还高的位置,直接升到此位置后,然后以正铉线方式进行飞行,控制正弦的左右拉伸
int xt,yt;
flyed_time=tkcount-b_time;

switch(status)
{
case 0: //向上飞
case 1: //平飞
case 2: //落下
paowu_4(d_xpos,d_ypos,down_jiao,xt,yt,jiao);
xpos=xt;
ypos=yt;
break;
}
set_position(xpos,ypos,POSZ);
set_rotation(jiao);
}
现在的问题是,这个程序经常在运行时产生错误,因为在一个vector中,你不能同时让它计算每个成员的运动轨迹 和 被攻击后的消灭,
消灭的位置应该放在哪里呢?是最后吗?因为实际上消灭是运动所引起的,运动位置到x<0或者y<0既引发类的is_enbale变化,到循环的最后再来判断是否该被消灭呢?还是在运动函数中判断或在被伤害be_hurt中判断呢?由于判断的不明导致有些已经无效的vector成员仍然运行最后导致程序的跳出。
现在我想请教有过使用vector而非链编程这方面经验的人,如何设置弹的运动、无用弹的消灭、飞机运动、无用飞机的消灭这4者在循环中的顺序?


...全文
51 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
用DDraw实现射击游戏说明文档 要点一:画图自动切割 IDirectDrawSurface7::BltFast()方法没有自动切割功能,即当画图元素超出窗口以外时不会自动切割,DDraw选择自动忽略不画,造成一旦超出窗口,画图元素会突然消失。 解决这一问题的方法是手动切割,代码如下: //自动切割 RECT scRect; //存放当前窗口大小区域 ZeroMemory( &scRect, sizeof( scRect ) ); GetWindowRect( GetActiveWindow(), &scRect ); //防止图片左上角超过窗口左上角 if ( x < 0 ) { m_rect.left -= x; x = 0; } if ( y scRect.right ? scRect.right : x; y = y > scRect.bottom ? scRect.bottom : y; m_rect.right = x + m_rect.right - m_rect.left > scRect.right ? scRect.right - x + m_rect.left : m_rect.right; m_rect.bottom = y + m_rect.bottom - m_rect.top > scRect.bottom ? scRect.bottom - y + m_rect.top : m_rect.bottom; 只需将上述代码加在CGraphic::BltBBuffer() 的m_bRect = m_rect; 前即可。 要点二:背景的滚轴实现 画背景可以分为以下三种情况: 情况一:背景图片与窗口等高 情况二:背景图片高度小于窗口高度 情况三:背景图片高度大于窗口高度 上述讲解图与代码相对应地看,有助于容易理解。 另外,要点一实现之后,由于已经可以自动切割,画背景可以用其它方法。 要点三:精灵图的实现 在游戏,如RPG游戏的人物图、射击类游戏的飞机、爆炸等,叫做精灵图。 精灵图实际上是将所有帧的图片放在一个文件,游戏时靠一个RECT来控制画图像文件的哪一部分,进而控制游戏显示哪一帧图,只需控制好RECT的位置即可。如下图: 控制RECT的四个角的坐标的移动,有以下代码: if (m_timeEnd – m_timeStart > 100) //只有到了100ms之后才绘图 { m_ImageID++; if(m_ImageID - m_beginID >= num) { m_ImageID = m_beginID; //最后一帧的下一帧是第一帧 } m_timeStart = timeGetTime(); } int id = m_ImageID++; SetRect(&m_rect, 41 * id, 0, 41 * (id + 1), 41); //飞机精灵图大小是41×41 m_pGraph->BltBBuffer(m_pImageBuffer, true, m_Pos.x, m_Pos.y, m_rect); 这样就实现了精灵动画的效果。 要点四:拿STL进行子弹的实现 子弹的实现可以使用STLvector,当按下开火键时发出一颗子弹,就往vector添加一个结点;当子弹飞出窗口或击敌机时,再将结点从vector删除。每帧游戏画面子弹飞行时只需将vector的所有子弹进行处理、绘画即可。 参考代码如下: 1.添加子弹 if (g_ctrlDown) //当ctrl键按下时开炮! { m_BulletEnd = m_Gtime->GetTime(); if ((m_BulletEnd - m_BulletStart) * 1000 > 120) //如果连续按着开火键不放,这里控制不会发出太多子弹 { m_BulletStart = m_BulletEnd; MBULLET tmpBullet; tmpBullet.pos.x = m_SPos.x - 1; //记录开火时的子弹位置 tmpBullet.pos.y = m_SPos.y - 26; tmpBullet.speed = 5; //该子弹的飞行速度 m_BulletList.push_back(tmpBullet); //将子弹添加到vector

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧