一、前言
网上有个很流行的手机小游戏--见缝插针,它是一个不断往旋转的圆球插针的游戏,游戏规则就是不要碰到前面已经插上的针,插的针越多分数越高。
在前面文章中我们介绍了旋转函数,可以用来旋转绘制的所有对象。我们似乎可以利用该函数制作此游戏。不过在这里,我们通过这个小游戏的制作来介绍另外一种旋转图形的方法,利用旋转公式来计算旋转点。
二、关键逻辑算法
想写一个见缝插针的游戏,最重要的是了解旋转公式,有了旋转公式就可以绘制旋转的图形,也就可以显示旋转的针效果了。一般来说,绕中心点旋转一个几何体,可以用以下公式表达:(x, y) = (xcosθ-ysinθ, xsinθ+ycosθ),但是我们可以直接以0度角开始简化公式为(x,y)=(r*cosθ,r*sinθ),同时加上坐标平移,以及考虑到SimpleCG沿用的windows窗口坐标系统,y轴朝下。 所以假设旋转中心坐标(C_CENTER_X,C_CENTER_Y),那么假设初始角度0度点坐标(r,0),顺时针旋转fAngle后,最终坐标为(C_CENTER_X + r * cos(fAngle),C_CENTER_Y + r * sin(fAngle))。
三、关键游戏代码
#include "Needle.h"
#include "math.h"
#define C_CENTER_X 300
#define C_CENTER_Y 250
#define C_GAMEOVER_RANK 0.015
enum ENUM_GAMESTATE
{
enumGS_RUNNING,
enumGS_GAMEOVER
};
float g_fCurAngle = 0; //当前角度
float g_fNeedleAngle[1024] = {0.0f};
int g_nNeedle = 0;
int g_nameState = enumGS_RUNNING;
int g_nScore = 0;
float g_fSpeed = 0.005;
//初始化
bool Init( )
{
setfillcolor(0x555555);
settextcolor(0xFFFFFF);
g_nNeedle = 0;
g_nameState = enumGS_RUNNING;
g_nScore = 0;
g_fSpeed = 0.005;
return true;
}
//释放
void Release()
{
}
//绘制游戏
void DrawGame()
{
int i=0;
float fAngle = 0.0f;
ClearDevice();
fillcircle( C_CENTER_X, C_CENTER_Y, 105 );
for(i=0; i<g_nNeedle; ++i)
{
fAngle = g_fNeedleAngle[i] + g_fCurAngle;
line(C_CENTER_X + 200 * cos(fAngle)+0.5,C_CENTER_Y + 200 * sin(fAngle)+0.5,C_CENTER_X + 100 * cos(fAngle)+0.5,C_CENTER_Y + 101 * sin(fAngle)+0.5);
fillcircle( C_CENTER_X + 200 * cos(fAngle),C_CENTER_Y + 200 * sin(fAngle), 5 );
}
line(C_CENTER_X,C_CENTER_Y + 250,C_CENTER_X,C_CENTER_Y + 350);
fillcircle( C_CENTER_X,C_CENTER_Y + 350, 5 );
setbackmode(0);
printfRectEx( C_CENTER_X-50, C_CENTER_Y-50,100, 100,SCG_TEXT_MIDDLE,_T("%d"), g_nNeedle);
if(g_nameState == enumGS_GAMEOVER)
printfRectEx( C_CENTER_X-50, C_CENTER_Y-100,100, 100,SCG_TEXT_MIDDLE,_T("GAME OVER"));
}
//更新游戏状态
void UpdateGameState( UINT nElapse )
{
if(g_nameState == enumGS_GAMEOVER )
return;
g_fCurAngle += g_fSpeed * (g_nNeedle / 20+1);
if(g_fCurAngle>2*C_PI)
g_fCurAngle -= 2*C_PI;
}
//发射
void Shoot( )
{
if(g_nameState == enumGS_GAMEOVER )
{
Init();
return;
}
int i=0;
float fShootangle = 0.5*C_PI-g_fCurAngle;
if(fShootangle<0)
fShootangle += 2*C_PI;
for(i=0; i<g_nNeedle; ++i)
{
if(g_fNeedleAngle[i] - C_GAMEOVER_RANK <= fShootangle && g_fNeedleAngle[i]+C_GAMEOVER_RANK>=fShootangle )
{
g_nameState = enumGS_GAMEOVER;
return;
}
}
g_fNeedleAngle[g_nNeedle++] = fShootangle;
}
四、源码及库下载
编译此程序需安装SimpleCG库,安装方法如下: