Author Topic: mainloop()  (Read 3131 times)

Offline sf-in-sf

  • Mr. Drawsprite
  • **
  • Posts: 93
  • Artist F.P. Brixey
    • View Profile
    • My computed art project
mainloop()
« on: 2013-Jul-24 »
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!
Code: GLBasic [Select]
// --------------------------------- //
// 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

 
« Last Edit: 2013-Aug-02 by sf-in-sf »
On the day the atom is a cube I will start believing in the square pixel.

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1578
  • Particle Hawk
    • View Profile
Re: mainloop()
« Reply #1 on: 2014-Aug-16 »
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"
Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)

Offline spacefractal

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 3447
    • View Profile
    • Space Fractal
Re: mainloop()
« Reply #2 on: 2014-Aug-16 »
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.
Greedy Mouse - Karma Miwa - Spot Race - CatchOut - Android Extras - is on a vacation trip, home before end of few days in jan.

Offline MrPlow

  • Prof. Inline
  • *****
  • Posts: 1300
    • View Profile
Re: mainloop()
« Reply #3 on: 2014-Aug-16 »
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.
Comp:
Speccy-48k, Speccy-128k, Amigas, PCs

Offline erico

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 4101
    • View Profile
    • Portfolio
Re: mainloop()
« Reply #4 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:

Offline kanonet

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1142
    • View Profile
    • My GLBasic code archiv
Re: mainloop()
« Reply #5 on: 2014-Aug-18 »
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).
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Offline Moru

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1750
    • View Profile
    • Homepage
Re: mainloop()
« Reply #6 on: 2014-Aug-18 »
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.

Offline sf-in-sf

  • Mr. Drawsprite
  • **
  • Posts: 93
  • Artist F.P. Brixey
    • View Profile
    • My computed art project
Re: mainloop()
« Reply #7 on: 2014-Aug-22 »
 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?
On the day the atom is a cube I will start believing in the square pixel.