📄 gamemain.cpp
字号:
#include"PreDef.h"
//gamestate
#define SHOWLOGO 0
#define MAINTITLE 1
#define DRAWMAP 2
#define INITGAME 3
#define VIEWSTAGE 4
#define PLAYGAME 5
#define GAMEOVER 6
#define GAMECLEAN 7
//ctrlobject
#define OBJ_TILE 0
#define OBJ_SCENERY 1
#define OBJ_ANIMATE 2
//动画类型低位
//所谓单指针指向动画即一个动画元素仅为一个角色服务
//同理,多指针指向动画即一个动画元素为多个同类型角色服务
//多指针指向动画为避免多角色动画播放进度的覆盖,将动画播放当前帧存入角色的独立变量中
//在这里,这个变量为CHARACTER::intvalue[FRAME]和CHARACTER::intvalue[CUR]分别表示当前帧和当前图元
//另,即使一个动画元素为一个角色服务,如果单一角色的不同动画元素要协调步骤,统一帧进度,也可以作为多指针指向动画处理
#define ONE_POINTER_TO_ONE_ANIMATE 0 //单指针指向动画
#define MULTI_POINTER_TO_ONE_ANIMATE 1 //单指针指向动画
//动画类型高位
#define BULLET_DORAEMON_RIGHT 1
#define BULLET_DORAEMON_LEFT 2
#define BULLET_CAT_RIGHT 3
#define BULLET_CAT_LEFT 4
#define BULLET_HACKCAT_RIGHT 5
#define BULLET_HACKCAT_LEFT 6
#define BULLET_HACKCAT_SMALL_RIGHT 7
#define BULLET_HACKCAT_SMALL_LEFT 8
#define BOWL_1 9
#define BOWL_2 10
#define ITEM_1 11
#define ITEM_1_USE 12
#define ITEM_2 13
//道具
#define ITEM_CATE 0 //铜锣烧
TCHAR strbuf[55];
KEYINPUT key;
SAVEFILE savefile;
//状态值
int gamestate; //游戏状态
int item[64]; //道具
int score;
int viewcollide=1,viewlattice=1,viewcollrect=1,ctrlobject,test=0; //按钮状态
int selscenery; //编辑物体
int sceneryused; //物体使用数
int selanimate; //编辑动画
int animateused; //动画使用数
int GetKeyInput();
int ShowLogo();
int MainTitle();
int DrawMap();
int InitGame();
int ViewStage();
int PlayGame();
int GameOver();
int GameClean();
int GetSceneryIndex();
int GetSceneryUsed();
int GetAnimateIndex();
int GetAnimateUsed();
int GetEtcIndex();
int GetEtcUsed();
HRESULT GameMain(HWND hwnd)
{
CleanScreen(RGB(0,0,0));
if(!disinput)
{
GetKeyInput();
if(GetAsyncKeyState(VK_ESCAPE)&0x8000)gamestate=MAINTITLE;
}
switch(gamestate)
{
case SHOWLOGO:
ShowLogo();
break;
case MAINTITLE:
MainTitle();
break;
case DRAWMAP:
DrawMap();
break;
case INITGAME:
InitGame();
break;
case VIEWSTAGE:
ViewStage();
break;
case PLAYGAME:
PlayGame();
break;
case GAMEOVER:
GameOver();
break;
case GAMECLEAN:
GameClean();
break;
}
//关于锁定帧频的解决方案之一,利用最近100帧的数值状态确定修正方向,修正动作每帧进行,确保实时修正.
static int lasttime,timer1,frame,setfps=60,sleeptime=1000/setfps;
static double fps=(double)setfps,normfps=(double)setfps; //瞬时fps和平均fps
static int frametime[10]; //用于存储最近10帧时间
static int totaltime=0; //最近10帧总耗时
int step=1; //计时器控制精度
double error=1; //误差范围
if(timer1==0)
{
timer1=GetTickCount();
int i;
for(i=0;i<sizeof(frametime)/sizeof(int)-1;i++)frametime[i]=1000/setfps*step;
}
if(frame==step)
{
int i,timepass=GetTickCount()-timer1;
totaltime=0;
for(i=0;i<sizeof(frametime)/sizeof(int)-1;i++)
{
frametime[i]=frametime[i+1];
totaltime+=frametime[i];
}
frametime[9]=timepass;
totaltime+=frametime[9];
normfps=(double)step*10*1000/(double)totaltime;
fps=(double)frame*1000/(double)timepass;
if(normfps<setfps&&setfps-fps>error)sleeptime-=1; //均频和瞬频均趋同的条件下变频 均频超过,瞬频呈下降趋势时无需额外变频
if(normfps>setfps&&fps-setfps>error)sleeptime+=1;
if(sleeptime<0)sleeptime=0;
if(sleeptime>100)sleeptime=100;
frame=0;
timer1=GetTickCount();
}
frame+=1;
_stprintf(strbuf,"setfps:%d,sleep:%d,fps:%f",setfps,sleeptime,normfps);
DrawString(301,21,strbuf,0x000000);
DrawString(300,20,strbuf,0xFFFFFF);
if(gamestate!=DRAWMAP)
{
_stprintf(strbuf,"SCORE:%d",score);
DrawString(25,21,strbuf,0xFFFFFF);
DrawString(24,20,strbuf,0x000000);
if(score>savefile.hiscore)savefile.hiscore=score;
_stprintf(strbuf,"HI-SCORE=%d",savefile.hiscore);
DrawString(165,21,strbuf,0xFFFFFF);
DrawString(164,20,strbuf,0x000000);
}
BackToFront(hwnd);
Sleep(sleeptime);
//while(GetTickCount()-lasttime<(int)(1000/(double)vfps))
lasttime=GetTickCount();
return DD_OK;
}
int GetKeyInput()
{
SetRect(&mouserect,mouse_x,mouse_y,mouse_x,mouse_y);
key.left=GetAsyncKeyState(0x41)&0x8000;
key.right=GetAsyncKeyState(0x44)&0x8000;
key.up=GetAsyncKeyState(0x57)&0x8000;
key.down=GetAsyncKeyState(0x53)&0x8000;
key.a=GetAsyncKeyState(0x4a)&0x8000;
key.b=GetAsyncKeyState(0x4b)&0x8000;
if(key.left&&key.left_d)key.left_press=1;
key.left_d=(key.left&&(!key.left_press))?1:0;
if(key.right&&key.right_d)key.right_press=1;
key.right_d=(key.right&&(!key.right_press))?1:0;
if(key.up&&key.up_d)key.up_press=1;
key.up_d=(key.up&&(!key.up_press))?1:0;
if(key.down&&key.down_d)key.down_press=1;
key.down_d=(key.down&&(!key.down_press))?1:0;
if(key.a&&key.a_d)key.a_press=1;
key.a_d=(key.a&&(!key.a_press))?1:0;
if(key.b&&key.b_d)key.b_press=1;
key.b_d=(key.b&&(!key.b_press))?1:0;
if((!key.left)&&(key.left_u))key.left_press=0;
key.left_u=((!key.left)&&(key.left_press))?1:0;
if((!key.right)&&(key.right_u))key.right_press=0;
key.right_u=((!key.right)&&(key.right_press))?1:0;
if((!key.up)&&(key.up_u))key.up_press=0;
key.up_u=((!key.up)&&(key.up_press))?1:0;
if((!key.down)&&(key.down_u))key.down_press=0;
key.down_u=((!key.down)&&(key.down_press))?1:0;
if((!key.a)&&(key.a_u))key.a_press=0;
key.a_u=((!key.a)&&(key.a_press))?1:0;
if((!key.b)&&(key.b_u))key.b_press=0;
key.b_u=((!key.b)&&(key.b_press))?1:0;
return 1;
}
int ShowLogo()
{
static showtime;
if(showtime==0)showtime=GetTickCount()+3000;
if(GetTickCount()>showtime)
{
gamestate=MAINTITLE;
showtime=0;
}
GraphToBack(&graph[0]);
return 1;
}
int MainTitle()
{
static RECT selrect;
static INT select;
stagenum=-1;
score=0;
if(GetAsyncKeyState(VK_F4)&0x8000)gamestate=DRAWMAP;
switch(select)
{
case 0:
SetRectPos(selrect,260,330,94,21);
break;
case 1:
SetRectPos(selrect,260,354,118,21);
break;
case 2:
SetRectPos(selrect,260,378,76,21);
break;
}
if(key.down_d)select+=1;
if(key.up_d)select-=1;
if(select<0)select=2;
if(select>2)select=0;
if(key.a_d)
{
switch(select)
{
case 0:
gamestate=INITGAME;
break;
case 1:
gamestate=SHOWLOGO;
break;
case 2:
PostQuitMessage(0);
break;
}
}
GraphToBack(&graph[1]);
DrawRect(selrect,&lpsurback,RGB(255,255,255));
return 1;
}
int InitGame()
{
WIDTH=MAXWIDTH;
HEIGHT=MAXHEIGHT;
SetRectPos(maprect,0,0,WIDTH,HEIGHT);
doraemon.X=doraemon.Xstart;
doraemon.Y=doraemon.Ystart;
doraemon.intvalue[FRAME]=0;
doraemon.intvalue[CUR]=0;
doraemon.intvalue[HP_MAX]=100;
doraemon.intvalue[HP]=100;
doraemon.intvalue[ATP]=20;
doraemon.intvalue[DEF]=5;
doraemon.lpanimate=&dora_anim[1];
doraemon.type=MULTI_POINTER_TO_ONE_ANIMATE;
doraemon.visible=1;
X=0;
Y=0;
if(stagenum==-1)
{
stagenum=0;
item[ITEM_CATE]=3;
}
memset(&stage,0,sizeof(STAGE));
stage.maplength=normallength;
HFILE hfile;
OFSTRUCT ofdata;
_stprintf(strbuf,"stage\\stage%d.dat",stagenum);
hfile=OpenFile(strbuf,&ofdata,OF_READ|OF_SHARE_COMPAT);
if(hfile!=HFILE_ERROR)
{
_lread(hfile,(LPVOID)&stage,sizeof(STAGE));
_lclose(hfile);
memset(etc,0,sizeof(etc));
gamestate=VIEWSTAGE;
}
else
{
gamestate=GAMECLEAN;
}
return 1;
}
int ViewStage()
{
static showtime=0;
if(showtime==0)showtime=GetTickCount()+2000;
if(GetTickCount()>showtime)
{
showtime=0;
gamestate=PLAYGAME;
}
_stprintf(strbuf,"STAGE %d",stagenum);
DrawString(300,230,strbuf,0xFFFFFF);
return 1;
}
int GameOver()
{
return 1;
}
int GameClean()
{
static showtime=0;
if(showtime==0)showtime=GetTickCount()+5000;
if(GetTickCount()>showtime&&key.a_d)
{
showtime=0;
gamestate=MAINTITLE;
}
GraphToBack(&graph[6]);
return 1;
}
int PlayGame()
{
static int enemynum,enemynum_max,etcnum;
static int timer1=0,timer2=0,timer3=0;
if(enemynum==0)
{
enemynum=GetAnimateUsed();
if(enemynum!=0)enemynum_max=enemynum;
}
if(etcnum==0)etcnum=GetEtcUsed();
/////////////////////////////////////////////////////////////////////////////////////////////
//碰撞
/////////////////////////////////////////////////////////////////////////////////////////////
int i,j;
for(i=(int)(doraemon.X/32);i<(doraemon.X+doraemon.width)/32;i++)
{
for(j=(int)(doraemon.Y/32);j<(doraemon.Y+doraemon.height)/32;j++)
{
SetRectPos(destrect,i*32-(int)X,j*32-(int)Y,32,32);
if(Act(doraemon.colliderect,destrect)&&stage.collide[i][j]==TRUE)
{
doraemon.X=doraemon.Xhis;
doraemon.Y=doraemon.Yhis;
}
}
}
if(doraemon.X<=0||doraemon.X+doraemon.width>=32*stage.maplength||doraemon.Y<=0||doraemon.Y+doraemon.height>=32*16)
{
if(doraemon.Xhis<=0||doraemon.Xhis+doraemon.width>=32*stage.maplength||doraemon.Yhis<=0||doraemon.Yhis+doraemon.height>=32*16)
{
doraemon.X=doraemon.Xstart;
doraemon.Y=doraemon.Ystart;
}
else
{
doraemon.X=doraemon.Xhis;
doraemon.Y=doraemon.Yhis;
}
}
doraemon.Xhis=doraemon.X;
doraemon.Yhis=doraemon.Y;
/////////////////////////////////////////////////////////////////////////////////////////////
//控制一切
/////////////////////////////////////////////////////////////////////////////////////////////
speed=normalspeed;
if(!doraemon.visible)memset(&key,0,sizeof(KEYINPUT));
if((key.left&&key.up)||(key.left&&key.down)||(key.right&&key.up)||(key.right&&key.down))speed=sqrtspeed;
if((key.left&&key.right))
{
key.left=0;
key.right=0;
}
if((key.up&&key.down))
{
key.up=0;
key.down=0;
}
if(key.left)
{
doraemon.lpanimate=&dora_anim[0];
doraemon.X-=speed;
}
if(key.right)
{
doraemon.lpanimate=&dora_anim[1];
doraemon.X+=speed;
}
if(key.down)
{
doraemon.Y+=speed;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -