⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 run.h

📁 演示一个火车头沿着轨道运行的动画。轨道可自定义(用鼠标绘制)
💻 H
字号:
#ifndef MY_RUN_H
#define MY_RUN_H
/* file: run.h
*/

#include "track.h"
#include "point.h"

static const float vl[5]={0.0, 1.2, 3.0, 6.0, 10.0};/* 每级的速度 */
static const float a=0.03;/* 加速度 */

static unsigned char trackbuf[4096];

/* 以p点为中心 绘制火车,车头朝(dx,dy)方向 */
static void DrawTrain(POINT* p, float dx, float dy)
{
	/* 火车边缘轮廓 */
	POINT shape[]={{-31,-10},{11,-10},{27,-6},{31,0},{27,6},{11,10},{-31,10},{-31,-10}};
	/* 车顶边缘轮廓 */
	POINT topshape[]={{-31,-7},{15,-5},{17,-2},{17,2},{15,5},{-31,7}};
	/* 车前窗轮廓 */
	POINT wndshape[]={{15,-5},{18,-6},{25,-2},{25,2},{18,6},{15,5}};
	POINT ps={29,0};
	POINT pw={22,0};

	int i;

	/* 根据给定坐标和方向将火车坐标进行变换 */
	for( i=0; i<sizeof(shape)/sizeof(POINT); ++i )
		{
		Rotate(shape+i,dx,dy);
		shape[i].x+=p->x;
		shape[i].y+=p->y;
		}/*end for*/
	Rotate(&ps,dx,dy);
	ps.x+=p->x;
	ps.y+=p->y;
	for( i=0; i<sizeof(topshape)/sizeof(POINT); ++i )
		{
		Rotate(topshape+i,dx,dy);
		topshape[i].x+=p->x;
		topshape[i].y+=p->y;
		}/*end for*/
	for( i=0; i<sizeof(wndshape)/sizeof(POINT); ++i )
		{
		Rotate(wndshape+i,dx,dy);
		wndshape[i].x+=p->x;
		wndshape[i].y+=p->y;
		}/*end for*/
	Rotate(&pw,dx,dy);
	pw.x+=p->x;
	pw.y+=p->y;

	/* 绘制边缘 */
	setcolor(WHITE);
	drawpoly(sizeof(shape)/sizeof(POINT),(int*)(shape));
	drawpoly(sizeof(topshape)/sizeof(POINT),(int*)(topshape));
	drawpoly(sizeof(wndshape)/sizeof(POINT),(int*)(wndshape));
	
	/* 上色 */
	setfillstyle(SOLID_FILL,WHITE);
	floodfill(p->x,p->y,WHITE);
	setfillstyle(SOLID_FILL,LIGHTGRAY);
	floodfill(ps.x,ps.y,WHITE);
	setfillstyle(SOLID_FILL,BLUE);
	floodfill(pw.x,pw.y,WHITE);
}/*end DrawTrain*/

/* 火车在给定轨道上运行 */
static void Run(const TRACK* pTrack)
{
	enum{stop, acc, dec, uni} state/* 火车当前状态 */;
	int direction;/* 火车前进方向,+1为前进,-1为后退 */
	int cur;/* 当前出发点下标 */
	int next;/* 下一个转折点下标 */
	int level;/* 火车当前速度等级 */
	float v;/* 火车当前速度 */
	float ov;/* 火车目标速度 */
	float dx,dy;/* 火车头方向(单位向量)*/
	float length;/* 当前这段轨道长度 */
	float curlen;/* 在当前这段轨道上走过的路程 */
	POINT TrainPos;/* 火车当前坐标 */
	POINT LastTPos;/* 火车上次坐标 */
	char c;
	char s[32];

	if( pTrack == NULL )
		{
		return;
		}/*end if*/

	cur=0;
	next=1;
	GetDirection(pTrack->point,pTrack->point+1,&dx,&dy);
	length=Distance(pTrack->point,pTrack->point+1);
	curlen=0.0;
	TrainPos=*pTrack->point;
	state=stop;
	level=0;
	ov=v=0.0;
	direction=1;

	cleardevice();
	setbkcolor(BLACK);
	settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
	setcolor(YELLOW);
	outtextxy(15,60,"Run the Train");
	setcolor(LIGHTRED);
	outtextxy(10,110,"0 ~ 4:");
	outtextxy(10,125,"Velocity Level");
	setcolor(LIGHTCYAN);
	outtextxy(10,160,"R  :");
	outtextxy(10,175,"Backward");
	outtextxy(10,210,"P  : Pause");
	setcolor(BROWN);
	outtextxy(10,250,"ESC: Quit");
	setcolor(YELLOW);
	outtextxy(15,350,"Current State");
	setcolor(LIGHTGREEN);
	outtextxy(10,390,"Velocity Level: 0");
	outtextxy(10,420,"Velocity : 0");
	setcolor(GREEN);
	line(0,300,nWidth-nHeight-1,300);
	line(nWidth-nHeight-1,0,nWidth-nHeight-1,nHeight-1);

	setcolor(RED);
	DrawTrack(pTrack,TRUE);
	getimage(TrainPos.x-34,TrainPos.y-34,TrainPos.x+34,TrainPos.y+34,trackbuf);
	DrawTrain(&TrainPos,dx,dy);
	for( ; ; delay(5000) )
	{
	if( state != stop )
		{
		if( state == acc )/* 加速状态 */
			{
			v+=a;
			if( v>=ov )
				{
				v=ov;
				state=uni;/* 进入匀速状态 */
				}/*end if*/
			}
		else if( state == dec )/* 减速状态 */
			{
			v-=a;
			if( v<=ov )
				{
				v=ov;
				if( level == 0 )
					{
					state=stop;/* 进入停止状态 */
					}
				else	{
					state=uni;/* 进入匀速状态 */
					}/*end if*/
				}/*end if*/
			}/*end if*/

		if( direction>0 )/* 前进 */
			{
			curlen+=v;/* 路程增加 */
			if( curlen>=length )
				{
				/* 离开当前轨道段,进入下一轨道段 */
				do	{
					curlen-=length;
					if( ++cur >= pTrack->size )
						{
						cur=0;
						}/*end if*/
					if( ++next >= pTrack->size )
						{
						next=0;
						}/*end if*/

					/* 新轨道段长度 */
					length=Distance(pTrack->point+cur,pTrack->point+next);
					}while( curlen>=length );

				/* 新轨道段方向 */
				GetDirection(pTrack->point+cur,pTrack->point+next,&dx,&dy);
				}/*end if*/
			}
		else	{/* 后退 */
			curlen-=v;/* 路程减少 */
			if( curlen<=0.0 )
				{
				/* 离开当前轨道段,进入下一轨道段 */
				do	{
					if( --cur < 0 )
						{
						cur=pTrack->size-1;
						}/*end if*/
					if( --next < 0 )
						{
						next=pTrack->size-1;
						}/*end if*/

					/* 新轨道段长度 */
					length=Distance(pTrack->point+cur,pTrack->point+next);
					curlen+=length;
					}while( curlen<=0.0 );

				/* 新轨道段方向 */
				GetDirection(pTrack->point+cur,pTrack->point+next,&dx,&dy);
				}/*end if*/
			}/*end if*/

		/* 更新当前速度 */
		sprintf(s,"%4.1lf",v);
		setfillstyle(SOLID_FILL,BLACK);
		bar(98,420,129,427);
		setcolor(LIGHTGREEN);
		outtextxy(98,420,s);

		/* 更新火车坐标 */
		LastTPos=TrainPos;
		TrainPos.x=0.5+curlen*dx+pTrack->point[cur].x;
		TrainPos.y=0.5+curlen*dy+pTrack->point[cur].y;

		if( ( TrainPos.x != LastTPos.x ) || ( TrainPos.y != LastTPos.y ) )/* 看上去火车移动了 */
			{
			/* 用保留的轨道背景覆盖火车 */
			putimage(LastTPos.x-34,LastTPos.y-34,trackbuf,COPY_PUT);
			/* 保留将被火车覆盖的轨道背景 */
			getimage(TrainPos.x-34,TrainPos.y-34,TrainPos.x+34,TrainPos.y+34,trackbuf);
			/* 重绘火车 */
			DrawTrain(&TrainPos,dx,dy);
			}/*end if*/
		}/*end if*/

	if( bioskey(1) )/* 有按键 */
		{
		switch( c=(char)(getch()) )
			{
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':/* 设置速度等级 */
				{
				level=c-'0';
				ov=vl[level];

				
				/* 更新当前速度等级 */
				sprintf(s,"%d",level);
				setfillstyle(SOLID_FILL,BLACK);
				bar(138,390,145,397);
				setcolor(LIGHTGREEN);
				outtextxy(138,390,s);

				if( v<ov )
					{
					state=acc;/* 进入加速状态 */
					}
				else if( v>ov )
					{
					state=dec;/* 进入减速状态 */
					}/*end if*/
				}break;

			case 'r':
			case 'R':/* 前进/后退 */
				{
				direction=-direction;
				setfillstyle(SOLID_FILL,BLACK);
				bar(10,175,73,182);
				setcolor(LIGHTCYAN);
				outtextxy(10,175,(direction<0)?"Forward":"BackWard");
				}break;

			case 'p':
			case 'P':/* 暂停 */
				{
				setfillstyle(SOLID_FILL,BLACK);
				bar(50,210,89,217);
				setcolor(LIGHTMAGENTA);
				outtextxy(50,210,"Continue");
				do	{
					c=getch();
					}while( c!='p' && c!='P' );
				bar(50,210,113,217);
				setcolor(LIGHTCYAN);
				outtextxy(50,210,"Pause");
				}break;

			case 27:/* Esc */
				{
				return;
				}break;

			default:break;
			}/*end switch*/
		}/*end if*/

	}/*end loop*/

}/*end Run*/


#endif /*define MY_RUN_H*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -