又到中秋节,通过C语言利用SimpleCG制作电子贺卡

        感觉现在时间过的真是飞快,很多人都觉得现在的时间比以前缩短了好多,眨眼间又到了中秋了。通过前面对SimpeCG的了解,现在用C语言绘制一张中秋电子贺卡应该不难了,我们在本篇文章就来试试吧。

        不过在这里我们尝试使用SimpleCG的另外一个绘图功能--PencilTurtle,就是小朋友很喜欢的海龟作图方式。这个功能后面再详细介绍,不过很多朋友可能都接触过了,因为早期有很多学习机会附带。

        先看看效果图:

运行程序可以在这里下载

http://simplecg.qqpet.com/AnimateMidAutumn2.zip 

代码可以在这里查看

中秋贺卡代码

全部主体代码如下:

 

// AnimateMidAutumn.cpp : 定义控制台应用程序的入口点。
//
#include "../import/include/CGBoard.h"
#include "math.h"
extern "C"
{
#include "PencileTurtle.h"
#include "Midi.h"
}

#ifdef _DEBUG
#pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
#else
#pragma comment(lib,"../import/lib/SimpleCG_MT.lib")
#endif

int g_nWidth = 640;		//画面宽度
int g_nHeight= 480;		//画面高度
int g_nMusic = 0;
HMIDIOUT g_hMidi = 0;
#define ADDCOLOR(x,y) ((x+y)>255?255:(x+y))

void StartMusic()
{
	g_hMidi = SMidOpenMidi();
	SetTimbre( g_hMidi, 0, 10 );
	g_nMusic = PlaySimpleSongBack( g_hMidi, 0, 90, -1, _T("***1/1-6*5/6+1|*1===|1/1-6*5/6+2|*2===|3/1-6*+3/1-6|+*2/=1*-6=|+44/-6*+1/=|*2===|1/1-6*5/6+1|*1===|1/1-6*5/6+2|*2===|//2**3/1-6/+2**3/1-6|*+2/=1*-6=|+44/-6+*1/=|/2**2===|2-5/7*6/7|/7**+1===|/3232*31|4//4*5432*1|2=/=565|*2===|/3232*31|4//4*5432*1|2=/=565|*2===|2==/22|31*2==|2===|1/1-6*5/6+1|*1===|1/1-6*5/6+2*2===|//2**3/1-6/+2**3/1-6|+*2/=1*-6=|+44/-6+*1/=|/1**2===|2-5/7*6/7|/7**+1===|"));
	
}
void StopPlayMusic()
{
	if( g_nMusic>0 )
	{
		StopMusic(g_nMusic);
	}
	SMidCloseMidi( g_hMidi );
}
void DrawMoon()
{
	PTSetAngle(0);
	setfillcolor(RGB(254,231,122));
	PTMoveTo( 500,150 );
	PTBeginFill();
	PTCircle( 50 );
	PTEndFill();
}
void DrawMoonCake( int nX, int nY )
{
	int i=0;
	int nCount = 18;
	setlinecolor(RGB(0xF2,0x90,0x0));
	setfillcolor(RGB(0xF8,0x80,0x20));
	for(i=0;i<nCount;++i)
	{
		PTMoveTo( nX,nY );
		PTTurnLeft(360 / nCount);
        PTMove(100);
        PTBeginFill();
        PTCircle( 20 );
		PTEndFill();
	}
	setlinewidth(5);
	for(i=0;i<nCount;++i)
	{
		PTMoveTo( nX,nY );
		PTTurnLeft(360 / nCount);
        PTMove(92);
        PTCircle( 20 );
	}
	setlinewidth(10);
	setfillcolor(RGB(0xFF,0x90,0x30));
	PTHome();
	PTMoveTo( nX,nY+95 );
    PTBeginFill();
    PTCircle( 95 );
	PTEndFill();
	
	//setlinecolor(RGB(162,84,13));
	setlinecolor(RGB(248,128,32));
	setlinewidth(5);
	int j=0;
	for(j=0;j<4;++j)
	{
		PTMoveTo( nX + 90*cos(C_PI/2*j),nY - 90*sin(C_PI/2*j) );
		//PTMoveTo( 200,330 );
		PTSetAngle(90*j+90);
		for(i=0;i<1080;++i)
		{
			PTTurnLeft(1*((float)i/1080));
		
			PTForward(.15);
		}
	}
	for(j=0;j<4;++j)
	{
		PTMoveTo( nX + 90*cos(C_PI/2*j),nY - 90*sin(C_PI/2*j) );
		PTSetAngle(90*j-90);
		for(i=0;i<270;++i)
		{
			PTTurnRight(1);
		
			PTForward(.6*((float)(270-i)/180));
		}
	}
}
void DrawWord(int nX,int nY,int nDelay)
{
	settextcolor(RGB(228,108,12));
	setbackmode(enumBKM_TRANSPARENT);
	settextfontWeight(FW_BOLD);
	settextfontPointSize(30);
	outtextXY( nX-20, nY-80, _T("中"));
	if( nDelay>0 )
	{
		Sleep(nDelay);
		ReflushWindow();
	}
	outtextXY( nX-80, nY-20, _T("秋"));
	if( nDelay>0 )
	{
		Sleep(nDelay);
		ReflushWindow();
	}
	outtextXY( nX-20, nY+40, _T("快"));
	if( nDelay>0 )
	{
		Sleep(nDelay);
		ReflushWindow();
	}
	outtextXY( nX+40, nY-20, _T("乐"));
	if( nDelay>0 )
	{
		Sleep(nDelay);
		ReflushWindow();
	}
}
void DrawFiveStar(int nX,int nY,int nLen)
{
	
	int i=0;
	PTMoveTo( nX,nY );
	setlinestyle(PS_NULL);
	setfillcolor(RGB(255,255,0));
	PTTurnRight(rand()%360);
	PTBeginFill();
	for(i=0;i<5;++i)
	{
		PTForward(nLen);
		PTTurnRight(144);
	}
	PTEndFill();
	setlinestyle(PS_SOLID);
}
void DrawStar()
{
	int i=0;
	for(i=0;i<20;++i)
	{
		int nX = rand()%640;
		int nY = rand()%480;
		
		setfillcolor(RGB(245+rand()%10,245+rand()%10,245+rand()%10));
		PTMoveTo( nX,nY );
		PTBeginFill();
		PTCircle( rand()%5 );
		PTEndFill();
	}
	for(i=0;i<8;++i)
	{
		int nX = rand()%640;
		int nY = rand()%480;
		DrawFiveStar( nX, nY, 6+rand()%6);
	}
}
void DrawLeaves(int nX,int nY, int nSize)
{
	setlinecolor(RGB(29,49,84));
	setfillcolor(RGB(29,49,84));
	PTMoveTo( nX,nY );
	PTSetAngle(rand()%80);
	int nWidhth = rand()%30+65;
    PTBeginFill();
	PTArc( nSize, nWidhth );
	PTTurnLeft(10);
	PTArc( nSize, -nWidhth );
	PTEndFill();
	
}
void DrawBack()
{
	int i=0;
	setbackcolor(RGB(45,76,130));
	ClearDevice();
	DrawStar();
	setlinecolor(RGB(43,67,115));
	setfillcolor(RGB(43,67,115));
	
	PTMoveTo( 0,400 );
	PTSetAngle(0);
    PTBeginFill();
    for(i=0;i<90;++i)
	{
		PTTurnRight(1);
		
		PTForward(10*((float)(90-i)/90));
	}
	PTSetAngle(180);
	PTForward(380);
	PTEndFill();

	PTMoveTo( 250,480 );
	PTSetAngle(45);
    PTBeginFill();
    for(i=0;i<90;++i)
	{
		PTTurnRight(1);
		
		PTForward(20*((float)(90-i)/90));
	}
	PTSetAngle(-90);
	PTForward(380);
	PTEndFill();
	for(i=0;i<30;++i)
	{
		DrawLeaves(rand()%600,480, 10+rand()%40);
	}
}
void DrawRabbit(int nX, int nY, float fSize )
{
	int i=0;
	setlinewidth(1);
	setlinecolor(RGB(0,0,0));
	setfillcolor(RGB(255,255,255));
	PTMoveTo( nX,nY );
    PTBeginFill();
	PTSetAngle(80);
	PTArc( -20*fSize, 60 );
	PTArc( -10*fSize, 20 );
	PTTurnRight(85);
	PTArc( -20*fSize, 65 );
		
	PTSetAngle(-40);
	PTArc(-16*fSize, 40);
		
	
	PTTurnLeft(20);
	PTArc(-10*fSize, 90);
	PTSetAngle(-40);
	PTArc(-20*fSize, 69);

	PTSetAngle(240);
	PTArc(-20, 100);
	/*PTForward(34);*/

	PTSetAngle(110);
	PTArc(-20*fSize, 69);
	
	PTTurnLeft(115);
	PTArc(-10*fSize, 90);
	PTSetAngle(85);
	PTArc(-16*fSize, 40);

	PTSetAngle(140);
	PTArc( -20*fSize, 55 );
	PTArc( -10*fSize, 20 );
	PTTurnRight(85);
	PTArc( -20*fSize, 65 );
	PTEndFill();
}
void DrawRabbit2(int nX, int nY, float fSize )
{
	int i=0;
	setlinewidth(1);
	setlinecolor(RGB(0,0,0));
	setfillcolor(RGB(200,200,200));

	PTMoveTo( nX+10,nY-25 );
    PTBeginFill();
	PTSetAngle(30);
	PTArc( 35*fSize, -60 );
	PTSetAngle(30);
	PTArc( -35*fSize, 60 );
	PTEndFill();
	PTSetAngle(30);
	PTArc( 35*fSize, -60 );
	setfillcolor(RGB(255,255,255));
    PTBeginFill();
	PTSetAngle(230);
	PTArc( 35*fSize, -60 );
	PTSetAngle(230);
	PTArc( -35*fSize, 60 );
	PTEndFill();
	
	PTMoveTo( nX-60,nY );
    PTBeginFill();
	PTSetAngle(140);
	PTArc( -25*fSize, 80 );
	PTSetAngle(-140);
	PTArc( 35*fSize, -100 );
	PTEndFill();
	PTMoveTo( nX-20,nY-20 );
    PTBeginFill();
	PTSetAngle(180);
	PTArc( 50*fSize, -90 );
	PTCircle( -6 );
	PTTurnRight(50);
	PTArc( 80*fSize, -50 );
	PTTurnRight(130);
	PTArc( 80*fSize, -10 );
	PTTurnRight(200);
	PTArc( 30*fSize, -130 );
	PTEndFill();

	setlinestyle(PS_NULL);
	setfillcolor(RGB(255,225,200));
    PTBeginFill();
	PTMoveTo( nX-40,nY-15 );
	PTCircle( -7 );
	PTEndFill();
	setfillcolor(RGB(255,191,191));
	PTMoveTo( nX-40,nY-28 );
    PTBeginFill();
	PTCircle( -3 );
	PTEndFill();
	setlinestyle(PS_SOLID);
}
void DrawLight(int nX, int nY,float fSize)
{
	{
		POINT pt[]={{nX,nY},{nX-1.8*fSize,nY-2.3*fSize},{nX+0.5*fSize,nY-4*fSize},{nX+2.6*fSize,nY-4*fSize},{nX+3.6*fSize,nY-fSize},{nX+2*fSize,nY-fSize}};
		setfillcolor(RGB(233,145,66));
		_fillpolygon(pt,sizeof(pt)/sizeof(pt[0]));
		_line(nX+0.5*fSize,nY-4*fSize,nX+2*fSize,nY-fSize);
	}
	{
		POINT pt[]={{nX,nY},{nX+2*fSize,nY-fSize},{nX+3.6*fSize,nY-fSize},{nX+1.6*fSize,nY}};
		setfillcolor(RGB(253,202,59));
		_fillpolygon(pt,sizeof(pt)/sizeof(pt[0]));
	}
	setfillcolor(RGB(253,239,120));
	_solidcircle(nX+2*fSize,nY-0.5*fSize,0.3*fSize);
}
void DrawProcess()
{
	POINT ptLight[10]={0};
	int nSize[10]={0};
	int i=0;
    for(i=0;i<10;++i)
	{
		ptLight[i].x=rand()%200+400;
		
		ptLight[i].y=rand()%200+200;
		nSize[i] = ((float)ptLight[i].y) / 400 *20;
	}
	bool bIsRunning = true;
	StartMusic();
	DrawBack();
	DrawMoon();
	DrawMoonCake(150,150);
	DrawWord( 150,150, 500 );
	DrawRabbit( 80, 360, 1 );
	DrawRabbit( 450, 330, 0.5 );
	DrawRabbit2( 550, 300, 1 );
	while(bIsRunning&&IsShowingWindow())
	{
		PTSpeed(0);
		DrawBack();
		DrawMoon();
		DrawMoonCake(150,150);
		DrawWord( 150,150, 0 );
		DrawRabbit( 80, 360, 1 );
		DrawRabbit( 450, 330, 0.5 );
		DrawRabbit2( 550, 300, 1 );
		for(i=0;i<5;++i)
		{
			DrawLight(ptLight[i].x,ptLight[i].y, nSize[i]);
			if(ptLight[i].y>0)
				ptLight[i].y -= 2;
			else
				ptLight[i].y = rand()%200+200;
			nSize[i] = ((float)ptLight[i].y) / 400 *20;
		}

		ReflushWindow();
		Sleep(100);
	}
	StopPlayMusic();
}
int _tmain(int argc, _TCHAR* argv[])
{
	//初始化
	if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))
		return 1;
	//关闭图库
	CloseBoard();
	return 0;
}


其中有很多功能在之前的教程都还没教到,会在后续的文章中介绍,例如文字的输出,海龟作图的方式,以及乐曲的播放等。

        在这里顺带说一说乐曲的播放,该播放函数可以播放一般的C大调简谱乐曲,如果有同学想现在尝试该功能的话,我这里大概说一说如何转换任意简谱,通过简单学习,你就能将任意简谱转换成MIDI播放。MIDI播放函数如下:

g_nMusic = PlaySimpleSongBack( g_hMidi, 0, 90, -1, _T("***1/1-6*5/6+1|*1===|1/1-6*5/6+2|*2===|3/1-6*+3/1-6|+*2/=1*-6=|+44/-6*+1/=|*2===|1/1-6*5/6+1|*1===|1/1-6*5/6+2|*2===|//2**3/1-6/+2**3/1-6|*+2/=1*-6=|+44/-6+*1/=|/2**2===|2-5/7*6/7|/7**+1===|/3232*31|4//4*5432*1|2=/=565|*2===|/3232*31|4//4*5432*1|2=/=565|*2===|2==/22|31*2==|2===|1/1-6*5/6+1|*1===|1/1-6*5/6+2*2===|//2**3/1-6/+2**3/1-6|+*2/=1*-6=|+44/-6+*1/=|/1**2===|2-5/7*6/7|/7**+1===|"));
	

        首先我们从网上看一下《明月几时有》(网络引用,版权原作者所有)的简谱如下:

这是四四拍的,这首歌简谱是如何转成我们播放的格式的呢?非常简单! 我们的简谱文本主要有六个特殊字符,分别是+、-、*、/、=、|。就是加减乘除等号,其余就是1、2、3、4、5、6 、7音符,还有一个0休止符。下面介绍详细的转换过程。

        首先默认起始状态是C大调、音符是32分音符,此时1、2、3演奏出来的是C大调,就是音符底下和上面都没有点,然后+号升8度,-号降8度,而且输入+、-后影响后面所有的音符,除非再次使用+、-进行调节,乘号*和除号/是改变音符长短,默认是32分音符,输入一个*变成16分音符,再输入*变成8分音符,再一个*就成4分音符,看代码中“ ***1/1-6*5/6+1|*1===|1/1-6*5/6+2|*2===”,开始的三个*就是改变状态为4分音符。然后输出一个1(dou)、紧跟一个/,改变音符为8分音符,然后输出简谱中第二个1(dou),注意第二个1下面的下划线,表示8分音符,接着一个减号-,就把后面降8度,输出的6(啦)就是底下有点的,而且依据前面的音长还是8分音符,到了5(嗦)没有下划线是4分音符,所以要提高音长,我们输入乘号*后再输出5,然后后面的6(啦)又有下划线,音长又变成8分音符,我们输出除号/缩短音长为8分音符后再输出6。接着加号+升8度输出底下没有点的1,|是分段符,跟简谱一样。接着提高音符为4分音符再输出1,就是没有下划线的1(dou)。三个=号对应简谱的-,延长同样的拍。后面类似就不赘述了。对这个演奏有兴趣又没看明白的可以评论告诉我,我后面详细发些例子讲解。理解后还是很简单的。并且可以很方便转换网上的简谱歌曲,例如《罗刹海市》(版权归原作者所有)的简谱片断转换后及播放代码如下,有兴趣的同学可以尝试转换完全。

int _tmain(int argc, _TCHAR* argv[])
{
	
	HMIDIOUT hMidi = SMidOpenMidi();

    PlaySimpleSong( hMidi, 0, 60,1,_T("**333|-5/566+116|*06533/53*32|0313|/23*3-6+1011-5665303+11|-3/=5+*11|122-7|6/=76*53|0+*3/3/3532*-6+1-63/+2-7*6653|+/5665*6|6+/1/=1*-6+1*-5| -635|6/65*6/+11*0-115|/3235**3|/0+*3/3|/3532*-6+1|0-*3//+2-7|*6//67*6*53|"));

	SMidCloseMidi( hMidi );
	return 0;
}

        海龟作图方式和文字也在后续文章详细介绍相关函数。请耐心等待。

        今天的文章就到这里了,想下载SimpleCG库的同学可以在下面下载。

https://gitcode.net/b2b160/simplecg_demo

安装方法如下

SimpleCG库安装使用_b2b160的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

b2b160

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值