Hi!
Here is an attempt at running a "mainloop" for all objects at once, like in python. Interesting for gaming or GUI design. Objects of different types get created and deleted dynamically. It's also a solution to get an abstract class functionnality in GLb, without C++.
Have good fun!
// --------------------------------- //
// Project: TYPE_1 (pure abstract classes in C++ failed)
// Start: Saturday, July 20, 2013
// IDE Version: 10.244
// --------------------------------- //
// Project: TYPE_2
// Start: Tuesday, July 16, 2013
// IDE Version: 10.244
// SETCURRENTDIR("Media") // go to media files
SETSCREEN 500,500,0
SYSTEMPOINTER FALSE
//LIMITFPS 30
GLOBAL oblist%[] AS ob // like a pure abstract class, an array of various objects.
//GLOBAL collist%[] ; DIMDATA collist%[],0xcc66ff,0x00bb55, 0x0055ff,0xcc7777, 0x777777
TYPE ob
shape$ ="sq" // is the TYPE of each object, in fact.
// used later in a "switch" to apply the correct drawing function,
// like a function member of each object in C++.
color% = 0x666666 //default color
val1=0 ; val2=0 ; val3=0 // generic, use varies depending on the type of object.
px ; py ; vx ; vy
// weapons% =0
intelligence% = 4 // (bonus included, haha)
dizziness% =1
bounces%=4 // max. bounces allowed, the deletion criterium.
ENDTYPE
start:
FOR bzzz% = 1 TO 440 ; new_ob() ; NEXT // create n objects
GLOBAL t0%, t% , stamp%
LOCAL ciao%
t0=GETTIMERALL() ; t=t0+2000
mainloop://____run_all_objects_at_once__________________._____________________
WHILE TRUE
FOREACH z IN oblist[]
ciao=animate(z)
IF ciao >0 THEN DELETE z // [death]
//DELETE must be inside a loop, otherwise you need to know
// the (int) position of object z inside the array oblist[]. How do you get that?
// Please post me the answer if you know it.
NEXT
PRINT LEN(oblist[]), 5,5
SHOWSCREEN
stamp=GETTIMERALL() // MUST be GLOBAL apparently, too tricky otherwise.
IF stamp >t
t=t+500+RND(700) //1789+RND(1984)
new_ob() // [birth]
// DRAWRECT 10,10,222,222, RGB(255,255,0) // visualize creation time
ENDIF
WEND
//______________________________________________________._____________________
FUNCTION new_ob:
LOCAL z AS ob // new, inherits default values
// z.color = collist[RND(4)]
z.color = bOR(RND(0xffffff), ASL(0x000000f0,8*RND(2)))
// avoiding dark or unsaturated colors.
IF RND(1) // if shape is sq
z.px =250.0 ; z.py =250.0
z.vx =rnddr2() ; z.vy =rnddr2()
z.val1=6+RND(30) ; z.val2=6+RND(30)
// more t.b.c.
ELSE
z.px =250.0 ; z.py =250.0
z.vx =rnddr2() ; z.vy =rnddr2()
z.shape$="tri" ; z.val1=RND(84)-42
ENDIF
DIMPUSH oblist[], z
ENDFUNCTION
FUNCTION animate: z AS ob
INLINE
//moves, common, C-style:
z.px +=z.vx ; z.py+=z.vy;
if(z.px <50)
{z.vx =rnddr(); z.vy=rnddr2() ; z.px=50; z.bounces-=1 ; if (z.bounces <1) {return(7);}}
if(z.py <50)
{z.vy =rnddr(); z.vx=rnddr2() ; z.py=50; z.bounces-=1 ; if (z.bounces <1) {return(7);}}
if(z.px >450)
{z.vx = -rnddr(); z.vy=rnddr2(); z.px =450; z.bounces-=1 ; if (z.bounces <1) {return(7);}}
if(z.py >450)
{z.vy = -rnddr(); z.vx=rnddr2(); z.py=450; z.bounces-=1 ; if (z.bounces <1) {return(7);}}
ENDINLINE
//switch to apply the right function:
IF z.shape$ = "sq" // "according to the type" like an abstract class.
DRAWRECT z.px,z.py,z.val1,z.val2,z.color
ELSEIF z.shape$="tri"
STARTPOLY -1,1 //no texture, iMode=tri
POLYVECTOR z.px, z.py-z.val1, 0,0, z.color
POLYVECTOR z.px+10, z.py, 0,0, z.color
POLYVECTOR z.px-10, z.py, 0,0, z.color
ENDPOLY
ELSE
// another default type of object.
ENDIF // ...should be usable to make a custom GUI.
RETURN 0 // i.e. "don't delete this element"
ENDFUNCTION
FUNCTION rnddr:
RETURN (RND(3000)+5)/1000.0
ENDFUNCTION
FUNCTION rnddr2:
IF (RND(1)) ; RETURN rnddr()
ELSE
RETURN -rnddr()
ENDIF
ENDFUNCTION
Not intentionally bumping this dead thread...
But i must say, as rough as this code may be....
It is definetly a super powerful way to program anything at all.
Sf you python addict!
Good stuff here and i personally cant live without using routines this way too.
As a matter of fact, im in the procress of creating a very large lib/api.
Point is..my lib of object style code is designed in this way to use GLBasic native commands internally.
And the next module im adding is a database structure which absolutely needs this sort of schmema.
String.is$ = "hello world!"
String.upper()
~ "Hello World"
im did same sort of array loop for enemies in Karma Miwa and discovered there issues when DELETE a object in a for, which might cause the app to crash. Instead im used a struct (TYPE) which can make if the object is dead, and then remove those later on (often in the Paint() section), so its dont conflict.
My 2 cents worth:
I had numerous bugs and crashes early on in Viking Invaders due to delete objects in a for-loop.
I found it better to set a flag for the object status
obj.status = 1 // 0 = alive, 1=dead , etc...
cleanup = true
.
.
// end of sequence
if cleanup then cleanup()
Function cleanup:
// Perform
Foreach i in vikings[]
if obj.status = 1 then delete i
Next
Foreach b in boats[]
if obj.status = 1 then delete b
Next
endfunction
And if the game was depending upon animation of many screen objects I sometimes never deleted the objects as the speed of the game was sometimes slightly affected.
Quote from: MrPlow on 2014-Aug-16
...
I found it better to set a flag for the object status
obj.status = 1 // 0 = alive, 1=dead , etc...
...
Pretty much what I do too. :good:
Did you do anything liek accessing dim size etc? Cause DELETE should not crash you (at least not on single dimension arrays, multi are bugged IIRC...) Would be interesting to know what caused your crash (and how to fix it).
Isn't this a sort of entity system? There are a few 2D and 3D starts of entity systems on the forums if you want to have a look.
In general: If the array is small, the most efficient is usually to delete items. If the array is very big it's better to just flag them active/inactive and overwrite with new data later because the release of memory and allocating more memory is slow.
I would be curious to see some code that crashes with delete in foreach loops because I have never had any problems with that.
MrPlow, I'm totally with you about your fix. Yet I don't remember having any crash. So I agree with Kanonet, if DELETE inside a loop is safe, what else caused the crash?