1 registered members (TipmyPip),
18,633
guests, and 5
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: More than 1000 entities = death for a game?
[Re: EvilSOB]
#228488
09/19/08 21:40
09/19/08 21:40
|
Joined: Aug 2008
Posts: 55 United Kingdom
CdeathJD
OP
Junior Member
|
OP
Junior Member
Joined: Aug 2008
Posts: 55
United Kingdom
|
That would be handy in this particular example. I think yuo pretty much have the gist of what im getting at, but we'll have to see if it runs any faster! Here is my code:
#include <acknex.h>
#include <default.c>
ENTITY* FLOOR;
VECTOR box_rotation;
VECTOR centre = vector(0,0,0);
var dampener;
var c1;
var num_box;
var new_ball_delay;
STRING* num_box_string;
d3d_alpharef = 180;
typedef struct
{
var velx;
var vely;
var velz;
var lifetime;
ENTITY* model;
} box;
PANEL* panDisplay =
{
digits(35, 10, "smokes = %0.f", *, 1, num_box);
flags = VISIBLE;
}
function do_sprite(ENTITY* ThisModel,var xv,var yv,var zv)
{
while(ThisModel.skill25>0)
{
//wait(1); //wait 1 frame
ThisModel.skill25 -= 15; //reduce counter
if (random(100)>97)
{
ThisModel.skill25 += 150; //reduce counter
}
ThisModel.x += xv;
ThisModel.y += yv;
ThisModel.z += zv - (ThisModel.skill27/8);
ThisModel.skill27 += 1;
if (ThisModel.skill25>ThisModel.skill26)
{
ThisModel.scale_x = (ThisModel.skill25 * ThisModel.skill25)/14000;
ThisModel.scale_y = (ThisModel.skill25 * ThisModel.skill25)/14000;
}
if (ThisModel.skill25<10)
{
ThisModel.alpha = ThisModel.skill25*0.01;
}
wait(1);
}
ent_remove(ThisModel); //remove timed-out model
num_box -= 1;
}
function new_sprite(var xpos, var ypos, var zpos)
{
c1 = 0;
while (c1<35)
{
c1 += 1;
box my_box;
my_box.model = ent_create("bluspark.bmp",vector(xpos,ypos,zpos),NULL);
my_box.model.skill25 = 200+random(500);
//my_box.model.pan = 180 - angle1;
my_box.model.scale_x = 1.925;
my_box.model.scale_y = 1.925;
wait(1);
c_setminmax(my_box.model);
my_box.model.roll = 1;
my_box.velx = (random(25)-12.5)/2;
my_box.vely = (random(25)-12.5)/2;
my_box.velz = (-5+random(25))*5;
my_box.model.skill26 = 180 - random(100);
set(my_box.model,BRIGHT|OVERLAY|TRANSLUCENT|PASSABLE|MOVE);
my_box.model.alpha = 50;
do_sprite(my_box.model,my_box.velx,my_box.vely,my_box.velz);
//my_box.model.scale_z = 10.925;
my_box.lifetime = 100;
num_box += 1;
wait(1);
}
}
function do_bomb(ENTITY* ThisModel)
{
while(ThisModel.skill25>0)
{
ThisModel.skill25 -= 2; //reduce counter
wait(1); //wait 1 frame
}
new_sprite(ThisModel.x,ThisModel.y,ThisModel.z);
ent_remove(ThisModel); //remove timed-out model
num_box -= 1;
}
function new_bomb()
{
box my_box;
my_box.model = ent_create("cube_smaller.mdl",vector(0,0,0),NULL);
my_box.model.x = 0;
my_box.model.y = 0;
my_box.model.z = 800;
my_box.model.scale_x = 16.925;
my_box.model.scale_y = 16.925;
my_box.model.scale_z = 16.925;
my_box.model.skill25 = 500 + random(1000);
wait(1);
c_setminmax(my_box.model);
//wait(1);
phent_settype (my_box.model, PH_RIGID, PH_SPHERE); // set the physics entity type
phent_setmass (my_box.model, 200, PH_SPHERE); // and its mass
phent_setfriction (my_box.model, 68); // set the friction
phent_setdamping (my_box.model, 5, 5); // set the damping
phent_setelasticity (my_box.model, 62, 12); // set the elasticity
dampener = 0.285;
phent_addvelglobal(my_box.model, vector((-50+random(100))*dampener,(-50+random(100))*dampener,(-5+random(10))*dampener), vector(100,0,0) );
do_bomb(my_box.model);
//wait(1);
}
function main()
{
video_mode=9;
fps_max = 60;
max_entities = 15000;
max_nexus = 100000;
level_load("");
vec_set(screen_color,vector(0,0,0));
wait(1);
ph_setautodisable(0.00001, 0.0002, 4, 41); // turn on and set default values
camera.ambient = -92;
FLOOR = ent_create ("plain3d1.mdl", vector(-400, 0, -4800), NULL); // create the floor
set(FLOOR,LIGHT);
camera.x = 5500;
camera.y = 20;
camera.z = 250;
camera.arc = 110;
camera.pan = 180;
FLOOR.scale_x=5000;
FLOOR.scale_y=5000;
FLOOR.scale_z=30;
FLOOR.z = -5;
FLOOR.red = 0;
FLOOR.green =0;
FLOOR.blue =0;
FLOOR.ambient = 25;
FLOOR.z=-50;
ph_setgravity (vector(0, 0, -886)); // set the gravity
while (1)
{
new_ball_delay -= 1;
// CONTROLS
mouse_pos.x = mouse_cursor.x;
mouse_pos.y = mouse_cursor.y;
camera.pan -= mouse_force.x * 26;
camera.tilt += mouse_force.y * 26;
mouse_pos.x = 160;
mouse_pos.y = 120;
if (key_cuu) camera.x -= 52 * time_step;
if (key_cud) camera.x += 52 * time_step;
if (key_cul) camera.y += 52 * time_step;
if (key_cur) camera.y -= 52 * time_step;
if (key_ins) camera.z -= 52 * time_step;
if (key_del) camera.z += 52 * time_step;
if (mouse_left)
{
camera.ambient += 1;
//bowling_ball();
}
if (mouse_right)
camera.ambient -= 1;
if (key_e)
{
if (new_ball_delay<0)
{
new_sprite(0,0,800);
new_ball_delay = 1;
}
}
if (random(100)>97)
{
new_bomb();
}
//on_e =
wait(1);
}
}
I am a noob to this... Blitz3D is where i am best at!
|
|
|
Re: More than 1000 entities = death for a game?
[Re: CdeathJD]
#228515
09/20/08 02:40
09/20/08 02:40
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Just getting started now but is ugly to look at.
Please supply me with physical dimensions X x Y x Z (in quants) of your two models and the width X height of bluspark.bmp.
Thay way I dont need to fiddle scale_xyz.
Thanks
[edit] Im going to do a trimmed down one first as this is very hard trying to keep your struct implementations intact. I'll give the same behaviours but using a single frame-by-frame hunk of code in main, rather than lots of OOP functions, as I promised.
Last edited by EvilSOB; 09/20/08 11:20. Reason: DAMN this is hard!
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: More than 1000 entities = death for a game?
[Re: EvilSOB]
#228551
09/20/08 13:31
09/20/08 13:31
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Heres the trimmed down version ready to run. It LOOKS to produce objects that behave exactly the same to me. But its your baby. Ive ditched the custom struct as it made things really messy, and Ive implemented a #define based replacement that I would use. It does all the same things as before, just all driven from the ...
var idx; for(idx=0; idx<Top_obj; idx++)
... loop in the main function loop,so it get run as close to once per frame as the 3DGS engine will allow. The separate new_bomb and new_fragment(was new_sprite) are only run once per new object, in-between frames and close when completed. So no memory wastage there. The key "F" will spew out Fragments manually, like you had the "E" key doing, and Ive added a "B" key to spew out Bombs the same way, just a bit slower. Just beware, thres no check to see if you go over 10,000 objects (bombs + fragments), and it WILL crash if you over as thats how big the storage array is. But if you ever hit it, I would be surprised. Any questions, fire away. #include <acknex.h>
#include <default.c>
var num_boxes = 0;
var num_fragments = 0;
d3d_alpharef = 180;
ENTITY* Objects[10000];
#define otype skill20 //0=bomb 1=fragment
#define velx skill21
#define vely skill22
#define velz skill23
#define lifetime skill25
//#define ???????? skill26
//#define ???????? skill27
var Top_obj=1; //'current' highest used index for optimising main-loop check
PANEL* panDisplay =
{
digits(535, 10, "boxes = %0.f", "Courier#18", 1, num_boxes);
digits(535, 40, "fragments = %0.f", "Courier#18", 1, num_fragments);
flags = VISIBLE;
}
function new_fragment(VECTOR* pos )
{
var c1; for(c1=0; c1<35; c1++)
{
var idx; for(idx=0; idx<1000; idx++) if(Objects[idx]==NULL) break;
Objects[idx] = ent_create("bluspark.bmp",vector(pos.x,pos.y,pos.z),NULL);
if(idx>Top_obj) Top_obj=idx; //raise Top_obj if this is highest
Objects[idx].otype = 1; //set to "fragment" type
Objects[idx].lifetime = 200+random(500);
//Objects[idx].pan = 180 - angle1;
vec_scale(Objects[idx].scale_x,1.925);
Objects[idx].roll = 1;
vec_set(Objects[idx].velx,vector((random(25)-12.5)/2,(random(25)-12.5)/2,(-5+random(25))*5));
Objects[idx].skill26 = 180 - random(100);
set(Objects[idx],BRIGHT|OVERLAY|TRANSLUCENT|PASSABLE|MOVE);
Objects[idx].alpha = 50;
//do_sprite(Objects[idx],Objects[idx].velx,Objects[idx].vely,Objects[idx].velz);
num_fragments += 1;
}
}
function new_bomb()
{
wait(1);
var idx; for(idx=0; idx<1000; idx++) if(Objects[idx]==NULL) break;
Objects[idx] = ent_create("cube_smaller.mdl",vector(0,0,800),NULL);
if(idx>Top_obj) Top_obj=idx; //raise Top_obj if this is highest
Objects[idx].otype = 0; //set to "bomb" type
vec_scale(Objects[idx].scale_x,16.925);
Objects[idx].lifetime = 500 + random(1000);
wait(1);
c_setminmax(Objects[idx]);
phent_settype (Objects[idx], PH_RIGID, PH_SPHERE); // set the physics entity type
phent_setmass (Objects[idx], 200, PH_SPHERE); // and its mass
phent_setfriction (Objects[idx], 68); // set the friction
phent_setdamping (Objects[idx], 5, 5); // set the damping
phent_setelasticity (Objects[idx], 62, 12); // set the elasticity
var dampener = 0.285;
phent_addvelglobal(Objects[idx], vector((-50+random(100))*dampener,(-50+random(100))*dampener,(-5+random(10))*dampener), vector(100,0,0) );
num_boxes += 1;
}
function main()
{
var idx; for(idx=0; idx<1000; idx++) Objects[idx]=NULL; // initialise object array
video_mode=9;
fps_max = 60;
max_entities = 15000;
max_nexus = 100000;
vec_set(screen_color,vector(0,0,0));
level_load("");
wait(1);
ph_setautodisable(0.00001, 0.0002, 4, 41); // turn on and set default values
ENTITY* FLOOR = ent_create ("plain3d1.mdl", vector(-400, 0, -50), NULL); // create the floor
FLOOR.scale_x=5000;
FLOOR.scale_y=5000;
FLOOR.scale_z=30;
vec_set(FLOOR.blue,nullvector);
FLOOR.ambient = 25;
set(FLOOR,LIGHT);
vec_set(camera.x,vector(5500,20,250));
camera.arc = 110;
camera.pan = 180;
camera.ambient = -92;
ph_setgravity (vector(0, 0, -886)); // set the gravity
var new_ball_delay = 0;
while (1)
{
new_ball_delay -= 1;
// CONTROLS
mouse_pos.x = mouse_cursor.x;
mouse_pos.y = mouse_cursor.y;
camera.pan -= mouse_force.x * 26;
camera.tilt += mouse_force.y * 26;
mouse_pos.x = 160;
mouse_pos.y = 120;
if(key_cuu) camera.x -= 52 * time_step;
if(key_cud) camera.x += 52 * time_step;
if(key_cul) camera.y += 52 * time_step;
if(key_cur) camera.y -= 52 * time_step;
if(key_ins) camera.z -= 52 * time_step;
if(key_del) camera.z += 52 * time_step;
if(mouse_left) camera.ambient += 1;
if(mouse_right) camera.ambient -= 1;
if((key_f)&&(new_ball_delay<0))
{
new_fragment(vector(0,0,800));
new_ball_delay = 1;
}
if((key_b)&&(new_ball_delay<0))
{
new_bomb();
new_ball_delay = 5;
}
//
if (random(100)>97) new_bomb();
//
var idx; for(idx=0; idx<Top_obj; idx++) //check all possible objects
{ if(Objects[idx]!=NULL) //if not empty, then check it
{ if(Objects[idx].otype==0) //if its a bomb, do this
{ Objects[idx].lifetime -= 2; //reduce bomb counter
if(Objects[idx].lifetime<=0)
{ new_fragment(Objects[idx].x); //trigger explosion
phent_settype(Objects[idx], NULL, NULL); //remove object from physics
ent_remove(Objects[idx]); //remove timed-out bomb
Objects[idx] = NULL; //cleanup empty pointer
if(Top_obj==idx) Top_obj--; //lower Top_obj if it was this one.
num_boxes -= 1;
}
}
else if(Objects[idx].otype==1) //if its a fragment, do this
{ Objects[idx].lifetime -= 15; //reduce counter
if (random(100)>97) Objects[idx].lifetime += 150; //boost counter
vec_add(Objects[idx].x, Objects[idx].velx);
Objects[idx].z -= Objects[idx].skill27/8;
Objects[idx].skill27 += 1;
if (Objects[idx].lifetime>Objects[idx].skill26)
{ Objects[idx].scale_x = (Objects[idx].lifetime * Objects[idx].lifetime)/14000;
Objects[idx].scale_y = (Objects[idx].lifetime * Objects[idx].lifetime)/14000;
}
if (Objects[idx].lifetime<10) Objects[idx].alpha = Objects[idx].lifetime * 0.01;
if(Objects[idx].lifetime<=0)
{ ent_remove(Objects[idx]); //remove timed-out fragment
Objects[idx] = NULL; //cleanup empty pointer
if(Top_obj==idx) Top_obj--; //lower Top_obj if it was this one.
num_fragments -= 1;
}
}
}
}
//
wait(1);
}
}
PS If you REALLLY want to go back to using your custom struct, ask away and I'll look into it but it may be too much work. For me anyway.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: More than 1000 entities = death for a game?
[Re: EvilSOB]
#228599
09/20/08 21:21
09/20/08 21:21
|
Joined: Aug 2008
Posts: 55 United Kingdom
CdeathJD
OP
Junior Member
|
OP
Junior Member
Joined: Aug 2008
Posts: 55
United Kingdom
|
Thanks for that! However the problem still happens! When i change the code to force the program to be creating up to 2000 particles the framerate drops to less than 1 frame a second. Interestingly, not looking at the particles increases the framerate very substantially, but makes the production of such particles useless.
Im quite intrigued as to why a more up to date programming language such as this simply can't handle even a fraction of the (12000 or so) sprites that 7 year old blitz3d can :s
However unless theres a nifty command buried in the system somewhere (i've come across something called nexus in the horrifically bad documentation but have no idea what it is) i think i'll be moving along to something else to be honest!
I am a noob to this... Blitz3D is where i am best at!
|
|
|
Re: More than 1000 entities = death for a game?
[Re: CdeathJD]
#228654
09/21/08 10:40
09/21/08 10:40
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
I cant help mush more, but when the bombs 'explode', have you tried using actual PARTICLE's [see effects(...)] instead of entities?
Entities are much more complex from an engine point of view, and I cant really see anything in your code that warrants using entities over particles.
PS particle objects are NOT sprite entities, but a sepatate engine object.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
|