游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2559|回复: 1

使用盖莫游戏引擎模拟烟花

[复制链接]

50

主题

69

帖子

69

积分

注册会员

Rank: 2

积分
69
发表于 2010-2-25 13:49:00 | 显示全部楼层 |阅读模式
刚给引擎设备新加了一个函数GetLuaStateOwner();
用于获取引擎中的lua上下文
看起来似乎没多大必要但是我有自己的考虑!

另外:我修改了粒子脚本
如下:

-- 这是盖莫引擎中使用lua脚本的测试粒子
-- 定义粒子池粒子个数
max_particles = 5000
-- 定义粒子初始位置
particle_position =
{
   xpos = 0;
   ypos = 0;
   zpos = 4;
}
-- 定义粒子大小
particle_size = 0.7
-- 定义粒子寿命
particle_life = 9
-- 定义粒子批大小
batch_particles = 100

friction = 0.75

fountain_radius = 1.8
particle_r = (fountain_radius + particle_size/2)*(fountain_radius + particle_size/2)

-- 定义粒子速度
particle_vel = 8.0

function GetVelByTime(t)
    return particle_vel*(0.6 + 0.1*(math.sin(0.5*t)+math.sin(0.31*t)));
end
function InitZVel()
    return 0.5 + (0.3/4096.0) * (math.random(1,4095));
end
local function GetRandRotXY()
    return (2.0*3.14159265/4096.0) * math.random(1,4095)
end
function InitXVel(t)
   xy_angle = GetRandRotXY();
   vt = GetVelByTime(t);
   return 0.4 * math.cos(xy_angle)*vt;
end
function InitYVel(t)
   xy_angle = GetRandRotXY();
   vt = GetVelByTime(t);
   return 0.4 * math.sin(xy_angle)*vt;
end
-- 粒子位置
xpos = particle_position[xpos];
ypos = particle_position[ypos];
zpos = particle_position[zpos];

function InitPosition()
   xpos = 2*(particle_position.xpos + 1-math.random());
   ypos = 3*(particle_position.ypos + 1-math.random());
   zpos = particle_position.zpos  + math.random() - 1;
end

function InitColorRed(t)
    return 0.7 + 0.3 * math.sin(0.34*t + 0.1);
end
function InitColorGreen(t)
    return 0.6 + 0.4 * math.sin(0.63*t + 1.1);
end
function InitColorBlue(t)
    return 0.6 + 0.4 * math.sin(0.91*t + 2.1);
end

red = 0;
green = 0;
blue = 0;
xvel = 0;
yvel = 0;
zvel = 0;

function InitParticle(t)
   InitPosition();
   red = InitColorRed(t);
   green = InitColorGreen(t);
   blue = InitColorBlue(t);
   zvel = InitZVel();
   xvel = InitXVel(t);
   yvel = InitYVel(t);
end

new_life = 1;
new_xpos = 0;
new_ypos = 0;
new_zpos = 0;
new_xvel = 1;
new_yvel = 1;
new_zvel = 1;
new_red  = 0.2;
new_green = 0.3;
new_blue  = 0.2;

-- 更新更新粒子颜色
function UpdateColor(red,green,blue)
   if red > 0.2 or red < 0.2 then
      red = red - (red - 0.2)*1/99.0;
      if red > 1 or red < 0 then
         red = 0.5;
         new_red = red;
      end
   end  
   new_red = red;   
   new_green = green;
   new_blue = blue;            
end
  
-- 更新粒子状态
function UpdateParticles(life,xpos,ypos,zpos,xvel,yvel,zvel,dt)
   -- 修正粒子生命
   new_life = life - dt * (1.0 / particle_life);
   -- 修正粒子速度
   new_zvel = zvel;
   new_xpos = xpos + xvel*dt/8*(math.random()-0.5);
   new_ypos = ypos + yvel*dt/8*(math.random()-0.5);
   new_zpos = zpos + new_zvel*dt;        
end

在粒子初始化中,我让粒子的初始位置保持在一个盒子当中,这样其效果就相当于irr中的粒子盒状发射器了。
在粒子更新中变动粒子颜色,修改粒子生命和粒子位置,或者粒子速度
其c++代码如下:

#include <GEngine/Main.hpp>
#include <luaplus/luaplus.h>
#define WIN_WIDTH  640
#define WIN_HEIGHT 480

////////////////////////////////////////////////////////////
/// 给出一个初始化粒子的方法
////////////////////////////////////////////////////////////
void G_CALL InitParticle(core:article* p,float t);
////////////////////////////////////////////////////////////
/// 更新粒子函数
////////////////////////////////////////////////////////////
void G_CALL UpdateParticle(core::Particle* p,float time);
////////////////////////////////////////////////////////////
/// 场景旋转和偏移
////////////////////////////////////////////////////////////
float TransForm(double t);

////////////////////////////////////////////////////////////
/// 渲染场景
////////////////////////////////////////////////////////////
void RenderScene();
core:evice* device = NULL;
LuaPlus:uaStateOwner *state = NULL;
  
////////////////////////////////////////////////////////////
/// 初始化luaplus  
////////////////////////////////////////////////////////////     
void InitLua(const char* lua)
{
    state = device->GetLuaStateOwner();
    // 载入Lua脚本
    (*state)->DoFile(lua);  
}  

////////////////////////////////////////////////////////////
/// 从脚本载入粒子描述数据
////////////////////////////////////////////////////////////
void LoadData(core::ParticleSystemDesc &desc);

int main(int argc, char **argv)
{
    int        i;
    double     t0, t;
   
    core::VideoMode mode;
    mode.width = WIN_WIDTH;
mode.height = WIN_HEIGHT;
   
    device = core::InitDevice("盖莫引擎粒子系统",false,mode);
    InitLua("..\\script\\particle.lua");
   
    //! 获取资源管理器
    core::ResourceManager* resourcemanager = device->GetResourceManager();
    core::RefPtr<core::Image> particleimage = resourcemanager->GetImage("particle","..\\image//particle//flare.bmp");
    core::RefPtr<core::Texture> particletexture = resourcemanager->GetTexture("particle",particleimage);
    particletexture->Bind();
     
    core::ParticleSystemDesc desc;
    desc.texture_id = particletexture->GetTextureId();   
    desc.init_fn = &InitParticle;
    desc.update_fn = &UpdateParticle;
    LoadData(desc);
    core::ParticleSystem* ps = device->GetParticleSystem(desc);

    t0 = device->GetTime();
    BEGIN_LOOP(device)
        t = device->GetTime() - t0;
        RenderScene();
        float dt = TransForm(t);
        ps->Render();
    END_LOOP(device)
   
    device->Close();
    device->Drop();

    return 0;
}

////////////////////////////////////////////////////////////
/// 场景旋转和偏移
////////////////////////////////////////////////////////////
float TransForm(double t)
{
    double xpos, ypos, zpos, angle_x, angle_y, angle_z;
    static double t_old = 0.0;
    float  dt = (float)(t-t_old);
    t_old = t;

    angle_x = 90.0 - 10.0;
    angle_y = 10.0 * sin( 0.3 * t );
    angle_z = 10.0 * t;
    glRotated( -angle_x, 1.0, 0.0, 0.0 );
    glRotated( -angle_y, 0.0, 1.0, 0.0 );
    glRotated( -angle_z, 0.0, 0.0, 1.0 );

    xpos =  15.0 * sin( (M_PI/180.0) * angle_z ) +
             2.0 * sin( (M_PI/180.0) * 3.1 * t );
    ypos = -15.0 * cos( (M_PI/180.0) * angle_z ) +
             2.0 * cos( (M_PI/180.0) * 2.9 * t );
    zpos = 4.0 + 2.0 * cos( (M_PI/180.0) * 4.9 * t );
    glTranslated( -xpos, -ypos, -zpos );
    return dt;
}
void RenderScene()
{
    glViewport( 0, 0, WIN_WIDTH,WIN_HEIGHT);
    glClearColor( 0.1f, 0.1f, 0.1f, 1.0f );
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective(65.0, 640.0/480.0, 1.0, 60.0 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}
////////////////////////////////////////////////////////////
/// 给出一个初始化粒子的方法(t为粒子系统启动时间(单位:秒))
////////////////////////////////////////////////////////////
void G_CALL InitParticle(core::Particle* p,float t)
{
    //! 初始化粒子位置位置
    LuaPlus::LuaFunction<void> initpos(*state,"InitParticle");
    initpos(t);
   
    float xpos =(*state)->GetGlobal("xpos").GetFloat(); //GetByName("xpos").
    float ypos =(*state)->GetGlobal("ypos").GetFloat();
    float zpos =(*state)->GetGlobal("zpos").GetFloat();
    p->position = Vector3f(xpos,ypos,zpos);
   
    //! 初始化粒子颜色
    p->color.red = (*state)->GetGlobal("red").GetFloat();
    p->color.green = (*state)->GetGlobal("green").GetFloat();
    p->color.blue = (*state)->GetGlobal("blue").GetFloat();
   
    //! 初始化粒子初始速度
    float xvel =(*state)->GetGlobal("xvel").GetFloat();
    float yvel =(*state)->GetGlobal("yvel").GetFloat();
    float zvel =(*state)->GetGlobal("zvel").GetFloat();   
    p->velocity = Vector3f(xvel,yvel,zvel);
}
////////////////////////////////////////////////////////////
/// 更新粒子函数
////////////////////////////////////////////////////////////
void G_CALL UpdateParticle(core::Particle* p,float time)
{
    LuaPlus::LuaFunction<void> update_fn(*state,"UpdateParticles");  
    float life = p->life;
    float xpos = p->position.x;
    float ypos = p->position.y;
    float zpos = p->position.z;
    float xvel = p->velocity.x;
    float yvel = p->velocity.y;
    float zvel = p->velocity.z;
    update_fn(life,xpos,ypos,zpos,xvel,yvel,zvel,time);
   
    //! 获取更新后的粒子颜色
    LuaPlus::LuaFunction<void> update_color(*state,"UpdateColor");
    update_color(p->color.red,p->color.green,p->color.blue);
   
    p->color.red = (*state)->GetGlobal("new_red").GetFloat();  
    p->color.green = (*state)->GetGlobal("new_green").GetFloat();
    p->color.blue = (*state)->GetGlobal("new_blue").GetFloat();      
   
    //! 获取粒子的更新后数据
    p->life = (*state)->GetGlobal("new_life").GetFloat();  
    p->position.x = (*state)->GetGlobal("new_xpos").GetFloat();
    p->position.y = (*state)->GetGlobal("new_ypos").GetFloat();
    p->position.z = (*state)->GetGlobal("new_zpos").GetFloat();
    p->velocity.x = (*state)->GetGlobal("new_xvel").GetFloat();  
    p->velocity.y = (*state)->GetGlobal("new_yvel").GetFloat();  
    p->velocity.z = (*state)->GetGlobal("new_zvel").GetFloat();  
}
////////////////////////////////////////////////////////////
/// 从脚本载入粒子描述数据
////////////////////////////////////////////////////////////
void LoadData(core::ParticleSystemDesc &desc)
{
    desc.batch_particles = (*state)->GetGlobal("batch_particles").GetInteger();
    desc.particle_size = (*state)->GetGlobal("particle_size").GetFloat();
    desc.life_span = (*state)->GetGlobal("particle_life").GetFloat();
    int max_particles = (*state)->GetGlobal("max_particles").GetInteger();
    desc.particle_number = max_particles;     
}
当然代码中没有检测错误和异常.
其输出图形如下所示:



50

主题

69

帖子

69

积分

注册会员

Rank: 2

积分
69
 楼主| 发表于 2010-2-25 13:51:00 | 显示全部楼层

Re:使用盖莫游戏引擎模拟烟花

看得使用盖莫游戏引擎设计粒子效果足够简单吧
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-5-11 14:35

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表