用minscript脚本语言实现数学函数曲线编辑器

这是一款数学函数曲线编辑器,c++开发,函数解析使用了自己开发的脚本语言minscript。

编辑器支持以下类型的函数曲线。
    MT_Normal     ,//一般方程 
    MT_Implicit   ,//参数方程 
    MT_Polar      ,//极坐标方程 
    MT_UVsurface  ,//uv曲面
    MT_Programable,//可编程

每种曲线类型都可以带动画,只需要勾选动画选项,然后在函数公式中引入变量time。
可以通过数学函数设置曲线颜色。

可以设置自变量的作用域,动画的时间范围等。
可编程效果可以自定义变量,使用预置的绘图函数。

 

编辑器下载:

数学函数曲线编辑器(可带动画)

 

这个编辑器中隐藏着一个用mincsript脚本语言编写的测试小游戏,引擎将c++实现的渲染及输入等接口绑定到了mincsript脚本语言,由脚本语言编写游戏逻辑。要运行游戏 修改data\script\startup.script文件为 
ExecFile("data/script/test_game.script"); 即可。


测试游戏脚本:




//敌人类
class Enemy
{
	function Enemy(var id)
	{
		this->nID = id;
		this->texPtr = TexturePtr();
		G_TextureMgr->AddTexture(this->texPtr,"data/minigame/fpshoot/enemy1.png");
		this->Regen();
	}
	//重生
	function Regen()
	{
		this->cPos = vec3(Rand()%G_Window.GetWidth(),RandRange(100,400),0);
		var ran;
		if(this->cPos.y<300)
			ran = vec3(RandRange(-1,1),RandRange(-0.1,1),0);
		else
			ran = vec3(RandRange(-1,1),RandRange(-0.5,1),0);
		ran.Normalize();
		this->cRect = RectF(0,0,1,1);
		this->cSpeed = ran*10;
		this->strState = "wander";
		this->nStateTime = 0;
		this->nLife = 100;
		this->nScale = 1;
	}
	function Update()
	{
		var time = G_Timer->GetStepTimeLimited();
		this->nStateTime += time;
		if(this->strState=="wander")
		{
			var ran;		
			if(this->cPos.y<300)
				ran = vec3(RandRange(-1,1),RandRange(-0.9,1),0);
			else
				ran = vec3(RandRange(-1,1),RandRange(-1,1),0);
			ran.Normalize();
			this->cSpeed += ran*3;

			//this->cPos += 0.1*this->cSpeed;
			this->cPos += this->cSpeed*time;

			if(this->cPos.x > G_Window.GetWidth() || this->cPos.x <0
				|| this->cPos.y > G_Window.GetHeight() || this->cPos.y <0
			  )
				this->Regen();
						
			if(this->nStateTime > 3)
			{
				this->nStateTime = 0;
				this->strState = "attack";
			}
		}
		else if(this->strState=="attack")
		{
			if(this->nStateTime > 3)
			{
				this->nStateTime = 0;
				this->strState = "wander";
			}

			//do hurt
			G_FirstGame.cRole.nLife-=0.01;
			if(G_FirstGame.cRole.nLife<0)
				G_FirstGame.cRole.nLife = 0;
		}
		else if(this->strState=="dead")
		{
			if(this->nStateTime > 3)
				this->Regen();
			return;
		}
	
		this->nScale += time/10;
		if(this->nScale>2)
			this->nScale = 2;

		ref texAim = this->texPtr->GetPtr();
		var w = texAim->GetWidth()/4*this->nScale;
		var h = texAim->GetHeight()/4*this->nScale;
		this->cRect = RectF(this->cPos.x-w/2,this->cPos.y-h*2,w,h);
	}
	function Render()
	{
		this->texPtr->GetPtr()->Bind();
		
		if(this->strState=="wander")
		{
			G_RendDriver->DrawTextureRect(this->cRect,RectF(0.25*((this->nStateTime*5)%4),0,0.25,1.0/3));
		}
		else if(this->strState=="attack")
		{
			G_RendDriver->DrawTextureRect(this->cRect,RectF(0.25*((this->nStateTime*5)%3),1.0/3,0.25,1.0/3));
		}
		else if(this->strState=="dead")
		{
			G_RendDriver->DrawTextureRect(this->cRect,RectF(0.25*((this->nStateTime*2)%4),2.0/3,0.25,1.0/3));
		}
	}
	function CollidBullet(var pos)
	{
		if(this->cRect.IsPointIn(pos))
		{
			this->nLife -= G_FirstGame.cRole.nAttack;
			if(this->nLife<0)
			{
				this->nStateTime = 0;
				this->strState = "dead";
				G_FirstGame.cRole.nScore++;
			}
			return true;
		}
		else
			return false;
	}
	var nID;
	var texPtr;
	var strState;
	var cPos;
	var cSpeed;
	var nLife;
	var nStateTime;
	var nScale;
	var cRect;
}

//主角
class Role
{
	function Role()
	{
		this->nLife = 100;
		this->nAttack = 10;
		this->nScore = 0;
	}
	var nLife;
	var nAttack;
	var nScore;
}

//游戏类
class Game
{
	function Game()
	{
		//Init();//  new game 拷贝game时 使得 playGui成为野指针???
	}

	function Init()
	{
		this->texPtrBackground = TexturePtr();
		G_TextureMgr->AddTexture(this->texPtrBackground,"data/minigame/fpshoot/scene1.png");

		this->texPtrAim = TexturePtr();
		G_TextureMgr->AddTexture(this->texPtrAim,"data/minigame/fpshoot/aim1.png");

		this->texPtrHand = TexturePtr();
		G_TextureMgr->AddTexture(this->texPtrHand,"data/minigame/fpshoot/hand1.png");
				
		this->texPtrFire = TexturePtr();
		G_TextureMgr->AddTexture(this->texPtrFire,"data/minigame/fpshoot/fire1.png");
		//this->texPtrHand2 = TexturePtr();
		//G_TextureMgr->AddTexture(this->texPtrHand2,"data/minigame/fpshoot/hand2.png");
		//

		//创建ui
		this->cPlayGui = GuiDialogBase();                                   //两次拷贝?,加断点发现匿名临时变量调用~GuiDialogBase一次,todo特殊优化处理省略一次

		this->cPlayGui.LoadFromFile("data/gui/minigame/gladiator/gladiator_play.gui"); //def num调用~GuiDialogBase一次
		this->cPlayGui.SetIDName("playGui");                                //ref num不在调用~GuiDialogBase

		G_GuiMgr->AddGuiStyle("playGui",this->cPlayGui,false);
		//  new game 拷贝game时 使得 playGui成为野指针???

		//弹出ui
		G_GuiMgr->PushGui("playGui",GL_DIALOG);
		//注册ui回调
		this->cPlayGui.RegistScriptProc(SDP_Sleep     ,"PlayGuiProcSleep");
		this->cPlayGui.RegistScriptProc(SDP_ButtonUp  ,"PlayGuiProcButtonUp");
		this->cPlayGui.RegistScriptProc(SDP_Update    ,"PlayGuiProcUpdate");
		this->cPlayGui.RegistScriptProc(SDP_RendBefore,"PlayGuiProcRenderBefore");
		this->cPlayGui.RegistScriptProc(SDP_RendAfter ,"PlayGuiProcRenderAfter");

		//创建敌人
		this->vEnemyArr = vector();
		for(var i=0; i<8; i++)
		{
			this->vEnemyArr.push_back(new("Enemy",i));
		}
		//
		this->cRole = new("Role");

		//this->movieScene = new("MovieClip");
		this->movieScene = MovieClip();
		var loadcfg = LoadConfig(0,1,1,0,0);
		this->movieScene.LoadFromFile("data/minigame/fpshoot/scene.movie",loadcfg);

		this->cSound = SoundChannel();
	}

	//function ~Game()
	//{
	//	G_GuiMgr->RemoveGuiStyle("playGui");
	//}

	function Update()
	{
		//ref consoleDlg = cPlayGui;//G_GuiMgr->GetGui("ConsoleDialog");
		//bullet
		var bulletPos = G_Mouse->GetMousePos();
		if(G_Mouse->IsButtonPressed(BUTTON_LEFT))
		{
			for(var i=0;i<this->vEnemyArr.size();i++)
			{
				if(this->vEnemyArr.at(i).CollidBullet(bulletPos))
					break;
			}
		}

		if(G_Mouse->IsButtonDowning(BUTTON_LEFT))
		{
			this->cSound.PlaySound__("data/sound/obj_armybirds.wav",true);
		}
		if(G_Mouse->IsButtonUping(BUTTON_LEFT))
		{
			this->cSound.StopSound();
		}

		

		for(var i=0;i<this->vEnemyArr.size();i++)
		{
			this->vEnemyArr.at(i).Update();
		}

		G_RendDriver->BeginUI(0,0,G_Window.GetWidth(),G_Window.GetHeight());
		this->movieScene->Advance(-1);//ortho skip
	}
	function RenderBefore()
	{
		var accTime = G_Timer->GetAccumTime();
		var mousePos = G_Mouse->GetMousePos();

		//G_RendDriver->BeginUI(0,0,G_Window.GetWidth(),G_Window.GetHeight());
		G_RendDriver->Color3f(1,1,1);

		绘制背景
		//this->texPtrBackground->GetPtr()->Bind();
		//G_RendDriver->DrawTextureRect(G_Window->m_rect);
		this->movieScene->RendClip(0);

		//绘制敌人
		for(var i=0;i<this->vEnemyArr.size();i++)
		{
			this->vEnemyArr.at(i).Render();
		}

		//绘制准星
		ref texAim = this->texPtrAim->GetPtr();
		texAim->Bind();
		if(G_Mouse->IsButtonPressed(BUTTON_LEFT) && G_Timer->GetCurrentFrame()%2)
		{
			G_RendDriver->DrawTextureRect(RectF(mousePos.x-texAim->GetWidth()*0.45,mousePos.y-texAim->GetHeight()*0.45,
			                                texAim->GetWidth()*0.9,texAim->GetHeight()*0.9));
		}
		else
		{
			G_RendDriver->DrawTextureRect(RectF(mousePos.x-texAim->GetWidth()*0.5,mousePos.y-texAim->GetHeight()*0.5,
			                                texAim->GetWidth(),texAim->GetHeight()));
		}

		//绘制手部
		G_RendDriver->Color3f(1,this->cRole.nLife/100,this->cRole.nLife/100);

		ref texAim = this->texPtrHand->GetPtr();
		texAim->Bind();
		var dis = 100;
		if(dis > G_Window.GetHeight()-mousePos.y-200)
			dis = G_Window.GetHeight()-mousePos.y-200;
		if(dis > mousePos.x-200)
			dis = mousePos.x-200;
		if(dis < -50)
			dis = -50;
		if(G_Mouse->IsButtonPressed(BUTTON_LEFT) && G_Timer->GetCurrentFrame()%2)
		{
			dis += 10;
		}

		//手部右上角
		var rtpos  = vec3(mousePos.x-dis,mousePos.y+dis,0);
		G_RendDriver->DrawTextureRect(RectF(rtpos.x-texAim->GetWidth(),rtpos.y,
			                                texAim->GetWidth(),texAim->GetHeight()));

		//枪管转盘
		//ref texAim = this->texPtrHand2->GetPtr();
		//texAim->Bind();
		//var frame = 0;
		//if(G_Mouse->IsButtonPressed(BUTTON_LEFT) && G_Timer->GetCurrentFrame()%2)
		//{
		//	dis += 10;
		//	frame = G_Timer->GetCurrentFrame()%5;
		//}
		//G_RendDriver->DrawTextureRect(RectF(mousePos.x-texAim->GetWidth()-dis-115,mousePos.y+dis-72,
		//	                                texAim->GetWidth(),texAim->GetHeight()),
		//							  RectF(0.2*frame,0,0.2,1));


		//绘制火线
		if(G_Mouse->IsButtonPressed(BUTTON_LEFT))
		{
			G_RendDriver->Color3f(1,1,1);
			ref texAim = this->texPtrFire->GetPtr();
			texAim->Bind();
						
			//var muzzle  = vec3(rtpos.x-70,rtpos.y+48,0);
			//G_RendDriver->DrawTextureRect(RectF(muzzle.x,mousePos.y,dis+70,dis+48),RectF(accTime*1.1,1-accTime*1.1,(dis)/256,(dis)/256));

			var muzzle  = vec3(rtpos.x-70,G_Window.GetHeight()-(rtpos.y+48),0);
			G_RendDriver->DrawLighting(muzzle,vec3(mousePos.x,G_Window.GetHeight()-mousePos.y,0),32,10,10);
		}


	}

	function RenderAfter()
	{

	}

	var movieScene;

	//背景
	var texPtrBackground; 
	//准星
	var texPtrAim;
	//手部
	var texPtrHand;
	//火线
	var texPtrFire;

	//敌人数组
	var vEnemyArr;
	//游戏界面
	var cPlayGui;

	//主角
	var cRole;

	//
	var cSound;

	//枪械
}

var G_FirstGame = new("Game");
G_FirstGame.Init();

//界面关闭回调
function PlayGuiProcSleep()
{
	//防止释放两次:全局脚本变量释放一次后成野指针 guimgr再释放时crash  => c++ 层面解决了
	//G_GuiMgr->RemoveGuiStyle("playGui");
}

//界面更新回调
function PlayGuiProcUpdate()
{
	G_FirstGame.Update();
}
//界面渲染回调
function PlayGuiProcRenderBefore()
{
	G_FirstGame.RenderBefore();
}
function PlayGuiProcRenderAfter()
{
	G_FirstGame.RenderAfter();
}
//界面按钮事件回调
function PlayGuiProcButtonUp(ref ctrl)
{
	var name = ctrl->GetIdName();
	//printf(name);
	//if (name == "button_pause")
	{
		//G_MidiDevice->SetCurSong(NULL);
		//bool pause = !m_sound->GetPause();
		//m_sound->SetPause(pause);
		//if (pause)
		//{
		//	m_buttonSongstate->SetText(M2U("状态:暂停").c_str());
		//}
		//else
		//{
		//	m_buttonSongstate->SetText(M2U("状态:播放").c_str());
		//}
	}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值