Saya mengembangkan permainan menembak dalam ruang 3D (3D space shooter game). Logika internal permainan ini ditulis dalam C + +, namun, saya ingin menggunakan script Ruby.Disini saya akan menampilkan apa yang telah saya lakukan. Tutorial ini tidak begitu lengkap, tapi mudah-mudahan bisa bermanfaat dan saya berharap seseorang bisa mengedit halaman ini dan menambahkan saran / koreksi.
Saya mendapatkan banyak info dari sini.
Pertama, anda harus mengatur ruby dan delta3D. Pada Windows, one-click-installer installs dan header files beserta library-nya.
Kemudian, anda harus memilih strategi komunikasi antara Ruby dan C + +. Saya memilih kelas C + + sederhana yang mewakili sebuah pesawat ruang angkasa. Kelas ini terlihat di C + + dan Ruby.Ini adalah tahapannya:
1. C + + memanggil Ruby
2. Ruby mengumpulkan informasi; menciptakan kelas RShipInfo dan menempatkan mereka dalam array.
3. C + + membaca array dan mengoreksinya (menempatkan pesawat, menghancurkan pesawat, menempatkan lokasi, dsb.)
4. C + + sebagai frame, lalu setting status ruang angkasa (jika satu pesawat hancur karena terkena rudal atau tabrakan, sets alive= 0)
5. Kembali ke langkah 1
Saat pertama kali Ruby di panggil (disebut "initmission"), maka argumen berikutnya adalah "runmission".
#ifndef _H_MISSIONCONTROL
#define _H_MISSIONCONTROL
#include
#include
#include
#include
namespace boost {}
namespace dtCore {}
namespace std {}
using namespace dtCore;
using namespace std;
using namespace boost;
//structure for communication
typedef struct tdefshipinfo
{
public:
tdefshipinfo()
:
name(""),
id(0),
type(""),
side(0),
alive(1),
command(""),
player("")
{ }
string name;
int id;
string type;
int side;
int alive;
string command;
string player;
}
RShipInfo;
//ruby initialization
class RubyEnv
{
public:
void static InitRuby();
void static EndRuby();
};
//running and init mission
void InitMission();
void RunMission();
std::vector * GetRShipInfoList(); //returns the list of spaceships visible both from c++
void CopyListFromRuby(); //copy list from ruby to c++
#endif
ini file cpp nya:
#include "MissionControl.h"
#include "stdio.h"
#include "ruby.h"
std::vector Rlist;
VALUE cRShipInfo; //ruby class for ship info
VALUE objectlist; //array of ship infos
RShipInfo * GetStructure(VALUE self) //returns structure out from ruby VALUE. The ruby class is represented with c++ structure, so here
//this structure is extracted out of ruby class
{
RShipInfo *ptr;
Data_Get_Struct(self,RShipInfo,ptr);
return ptr;
}
VALUE AccessorGetName(VALUE self) //returns name of spaceship
{
return rb_str_new2(GetStructure(self)->name.c_str());
}
VALUE AccessorSetName(VALUE self,VALUE val) //sets name of spaceship
{
long len;
string str=rb_str2cstr(val,&len);
GetStructure(self)->name=str;
return self;
}
VALUE AccessorGetType(VALUE self) //gets type of spaceship
{
return rb_str_new2(GetStructure(self)->type.c_str());
}
VALUE AccessorSetType(VALUE self,VALUE val) //sets type of spaceship
{
long len;
string str=rb_str2cstr(val,&len);
GetStructure(self)->type=str;
return self;
}
VALUE AccessorGetID(VALUE self) //get id of spaceship
{
return INT2NUM(GetStructure(self)->id);
}
VALUE AccessorSetID(VALUE self,VALUE val) //set id of spaceship
{
GetStructure(self)->id=NUM2INT(val);
return self;
}
VALUE AccessorGetSide(VALUE self) //gets side of spaceship
{
return INT2NUM(GetStructure(self)->side);
}
VALUE AccessorSetSide(VALUE self,VALUE val) //sets side of spaceship
{
GetStructure(self)->side=NUM2INT(val);
return self;
}
VALUE AccessorGetAlive(VALUE self) //is alive
{
return INT2NUM(GetStructure(self)->alive);
}
VALUE AccessorSetAlive(VALUE self,VALUE val) //sets alive
{
GetStructure(self)->alive=NUM2INT(val);
return self;
}
VALUE AccessorGetPlayer(VALUE self) //name of player
{
return rb_str_new2(GetStructure(self)->player.c_str());
}
VALUE AccessorSetPlayer(VALUE self,VALUE val) //name of player
{
long len;
string str=rb_str2cstr(val,&len);
GetStructure(self)->player=str;
return self;
}
VALUE AccessorGetCommand(VALUE self) //command to do on spaceship
{
return rb_str_new2(GetStructure(self)->command.c_str());
}
VALUE AccessorSetCommand(VALUE self,VALUE val) //command to do on spaceship
{
long len;
string str=rb_str2cstr(val,&len);
GetStructure(self)->command=str;
return self;
}
void FreeRubyShipInfo(void *p) //deletes object
{
RShipInfo *pp=(RShipInfo*) p;
delete pp;
}
VALUE InitRubyShipInfo(VALUE first,...) //ruby constructor
{
return first;
}
VALUE NewRubyShipInfo(VALUE first, ...) //c++ constructor called from ruby
{
RShipInfo * ptr=new RShipInfo();
VALUE tdata=Data_Wrap_Struct(cRShipInfo,0,0,ptr);
rb_obj_call_init(tdata,0,0);
return tdata;
}
void CreateRubyClass_ShipInfo() //dynamically register new class with ruby
{
cRShipInfo=rb_define_class("RShipInfo",rb_cObject);
rb_define_singleton_method(cRShipInfo,"new",(VALUE (*) (...))NewRubyShipInfo,0);
rb_define_method(cRShipInfo,"initialize",(VALUE (*) (...))InitRubyShipInfo,0);
rb_define_method(cRShipInfo,"getname",(VALUE (*) (...))AccessorGetName,0);
rb_define_method(cRShipInfo,"setname",(VALUE (*) (...))AccessorSetName,1);
rb_define_method(cRShipInfo,"getid",(VALUE (*) (...))AccessorGetID,0);
rb_define_method(cRShipInfo,"setid",(VALUE (*) (...))AccessorSetID,1);
rb_define_method(cRShipInfo,"gettype",(VALUE (*) (...))AccessorGetType,0);
rb_define_method(cRShipInfo,"settype",(VALUE (*) (...))AccessorSetType,1);
rb_define_method(cRShipInfo,"getside",(VALUE (*) (...))AccessorGetSide,0);
rb_define_method(cRShipInfo,"setside",(VALUE (*) (...))AccessorSetSide,1);
rb_define_method(cRShipInfo,"getalive",(VALUE (*) (...))AccessorGetAlive,0);
rb_define_method(cRShipInfo,"setalive",(VALUE (*) (...))AccessorSetAlive,1);
rb_define_method(cRShipInfo,"getplayer",(VALUE (*) (...))AccessorGetPlayer,0);
rb_define_method(cRShipInfo,"setplayer",(VALUE (*) (...))AccessorSetPlayer,1);
rb_define_method(cRShipInfo,"getcommand",(VALUE (*) (...))AccessorGetCommand,0);
rb_define_method(cRShipInfo,"setcommand",(VALUE (*) (...))AccessorSetCommand,1);
}
void RubyEnv::InitRuby() //this is how to init ruby environment
{
ruby_init();
ruby_init_loadpath();
ruby_incpush("scripts");
objectlist=rb_ary_new();
rb_define_variable("$sslist",&objectlist);
CreateRubyClass_ShipInfo();
}
void RubyEnv::EndRuby() //and finalize ruby environment
{
ruby_finalize();
}
void InitMission() //init mission
{
ruby_script("init");
int status;
rb_load_protect(rb_str_new2("start.rb"), 0, &status);
ruby_script("initmission");
int state = ruby_exec();
CopyListFromRuby();
}
void RunMission() //run mission, once a second
{
ruby_script("runmission");
int state = ruby_exec();
CopyListFromRuby();
}
std::vector * GetRShipInfoList() //list of spaceships
{
return &Rlist;
}
void CopyListFromRuby() //copies list from ruby to c++
{
Rlist.clear();
VALUE curr;
int len=(RARRAY(objectlist)->len);
for (int i=0;i
{
curr=rb_ary_entry(objectlist,i);
RShipInfo *ptr;
Data_Get_Struct(curr,RShipInfo,ptr);
Rlist.push_back(ptr);
}
}
Ruby scriptnya :
def initmission
puts "start of mission"
r=RShipInfo.new
r.setid 1
r.setname("moja ladja")
r.setside 1
r.settype("tip1")
r.setalive 1
r.setplayer "human"
r.setcommand "create"
$sslist << r
puts "id=" + r.getid.to_s
puts "name=" + r.getname
puts "side=" + r.getside.to_s
puts "tip=" + r.gettype
puts "alive=" +r.getalive.to_s
puts "player=" +r.getplayer
puts "command="+r.getcommand
for i in 2..20 do
r=RShipInfo.new
r.setid i
r.setname("enemy 1")
r.setside 2
r.settype("tip1")
r.setalive 1
r.setplayer "computer"
r.setcommand "create"
$sslist << r
end
puts $sslist.length
end
def runmission
puts "just idle running"
end
if $0 == "init"
puts "init"
end
if $0 == "runmission"
puts "runmission"
runmission
end
if $0 == "initmission"
puts "initmission"
initmission
end
Sumber : http//sourceforge.net/apps/mediawiki/delta3d/index.php?title=Delta3D_and_Ruby
Subscribe to:
Post Comments (Atom)
0 komentar:
Post a Comment