这是一款数学函数曲线编辑器,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());
//}
}
}
完