Framework

Previous topic - Next topic

MrTAToad

One thing I've wanted to do for a long time is a fully integrated framework.  This would allow the display of all sprites and 3D objects to be display with one line of code.

I originally was going to convert Matt Bennett's MBM Framework, but I soon stopped that and instead started devising my own.

One important thing that is needed is the ability to reload all graphics automatically after a screen resolution change, which I think I've got in.  Other important items are music fading without pausing the program and adding a simple scripting system (for automatic movement, rotation etc) without the need for the programmer to do it.

In addition, it should also be by module defined "sandbox" event-based system, whereby game areas (for example logo, title screen, main game, ending etc) are treated as totally separate sections whereby each area has no knowledge (or access to) other sections.  This may make things a bit more complicated but could allow easier coding and testing.

Moving from one module to another whilst in a module would be determined by the value returned by the Processing function.

I will also be using a new timer system (borrowed from the aforementioned MBM framework).

Another important thing is the fact that items will be access by name (as well as by index), as sprites, music etc will be sorted and can be searched by using a fast binary search routine.

A quick program preview can be found here : http://dl.dropbox.com/u/25216439/GameKit.app.rar

It is notable for the simple scripting system I've got for the sprite, the automatic FPS display and red text.

Sprites, fonts, 3D objects, etc will have their own unique directories (if not using shoebox, which I haven't implemented yet).

The code that runs this is :

Code (glbasic) Select
// --------------------------------- //
// Project: GameKit
// Start: Wednesday, May 23, 2012
// IDE Version: 11.001

LOCAL gameKit AS TGameKit
LOCAL module AS TModule

IF module.Initialise()=FALSE
DEBUG "Module initialiation error\n"
ENDIF

module.initialiseFunction=Test1_Initialise
module.startFunction=Test1_Start
module.displayFunction=Test1_Display
module.processFunction=Test1_Process
module.animFunction=Test1_Animation

gameKit.Initialise("test")
gameKit.RegisterModule(-1,module) // ,Test1_Start,Test1_Display)
gameKit.SetCurrentModule(0)
gameKit.Start()

WHILE TRUE
gameKit.Display()
gameKit.Process()
SHOWSCREEN
WEND

//! Initisation function.  This is only called once when the gameKit.Start() function is about to finish
//! All loadings should be performed here
FUNCTION Test1_Initialise%:module AS TModule
IF module.sprite.Load("user","Media/untitled.png")=FALSE THEN RETURN FALSE
IF module.standardText.Load("test","test.png")=FALSE THEN RETURN FALSE

module.sprite.Add("user","user",0,100,100)
module.sprite.AddAnimation_Name("user",1,0.1)
module.standardText.AddText_Name("Testing auto text display","test","test",100,100,0,-1,TRUE)
RETURN TRUE
ENDFUNCTION

//! Called at the end of each gameKit.Start() function
FUNCTION Test1_Start%:module AS TModule
ENDFUNCTION

//! Called once per frame
FUNCTION Test1_Display%:module AS TModule
module.sprite.Display()
module.sprite.Display_Name("user",0,0,0)
module.standardText.Display()
ENDFUNCTION

//! Called once per frame
FUNCTION Test1_Process%:speed
RETURN MODULE_CONTINUE%
ENDFUNCTION

//! Called only if an item has animation and after all its animation has finished
FUNCTION Test1_Animation%:sprite AS tSpriteInfo
IF sprite.x<=0.0
sprite.animations[0].speed=0.0-sprite.animations[0].speed
DEBUG "It is <= 0!\n"
ELSEIF sprite.x>=200.0
sprite.animations[0].speed=0.0-sprite.animations[0].speed
DEBUG "It is >=1024!\n"
ENDIF
ENDFUNCTION

Wampus

This sounds promising. Great stuff.

Quote from: MrTAToad on 2012-May-26
One thing I've wanted to do for a long time is a fully integrated framework.  This would allow the display of all sprites and 3D objects to be display with one line of code.

Do you mean sprites, 3d objects, etc. could be added to a list then all drawn at once later on? for example, calling for a sprite to be drawn could be placed anywhere in a routine, then later all sprites stacked to be drawn are sent to screen at once with a simple command?

I ask because I have made a framework which does that. It works on the principle of having layers, a little bit like the SNES system used only a lot more flexible and powerful of course. After defining how many layers are needed (background 1, background 2, tiles, sprites, particles, HUD, etc.) a sprite can be drawn onto a layer at any point in the main loop. It uses Polyvectors but there is no need to manually set the texture or whatnot because the routine checks to see if it needs to do that itself. Just before SHOWSCREEN a command called RENDER() is called which draws all the sprites ordered first by layer and then by the sequence they were assigned. Doing this takes up only a small amount of memory and CPU for a lot of advantages in ease of coding, amongst other things.

MrTAToad

Esssentially what I mean that any sprite, text or 3D object added to it's groups process list will automatically be display at a objects position and size etc

Currently, the rendering is done in the following order :

For each viewport
    Call user 3D routine
    Display 3D objects
    Call user 2D routine
    Display vector graphics (later)
    Display sprites
    Display text (Moru's text system will be added later)
    Display particles (later)
next

The framework uses its own loop, which calls the current modules routines (which are functions defined by the user). 

MrTAToad

#3
Work on the framework is progressing.. slowly :)

A very quick example of it running :



Some unique things about it :

Each sprite (and when I get around to it 3D objects too) can be assigned a value - the idea is to replace the need for global variables and keep them local to the sprite.  Each sprite needs a unique name, but also can have a non-unique group name so similar sprites can be processed in one group.

For example, the following code :

Code (glbasic) Select
IF self.timeForNextDrop<=0.0 OR self.numGoodBallZ%<=0
self.addBallZ(setup,self.firstTime,self.ballMaximumAmount%)
self.timeForNextDrop=RndRange(64,TIME_NEXTDROP)
self.firstTime%=FALSE
IF self.isTitle%=FALSE THEN setup.playSND(SAMPLE_ELECTRIC%,FALSE)
ELSE
DEC self.timeForNextDrop,speed
ENDIF

// IF self.sparkTime>0.0 THEN DEC self.sparkTime,0.2*speed

IF self.mustAddTargetBallZ%=TRUE
self.addBallZ(setup,0.0,1,TRUE,RndRange(self.xSize/2.0,self.screenWidth%-(self.xSize/2.0)),RndRange(self.ySize/2.0,self.screenHeight%-(self.ySize/2.0)))
self.mustAddTargetBallZ%=FALSE
ENDIF

self.xPos=wrap(self.xPos+(speed*SIN(self.moveAngle)),0.0-self.xSize,self.screenWidth%+self.xSize)
self.yPos=wrap(self.yPos+(speed*COS(self.moveAngle)),0.0-self.ySize,self.screenHeight%+self.ySize)


Would be :

Code (glbasic) Select
FUNCTION Game_Animation%:resourceManager AS TResourceManager,module AS TModule,speed,sprite AS TSpriteInfo
// Make sure sprite is always in the area
// Change later for size
sprite.SetX(wrap(sprite.GetX(),0.0-(sprite.GetWidth()/2.0),module.GetScreenWidth()+(sprite.GetWidth()/2.0)))
sprite.SetY(wrap(sprite.GetY(),0.0-(sprite.GetHeight()/2.0),module.GetScreenHeight()+(sprite.GetHeight()/2.0)))

SELECT sprite.GetGroupName$()
CASE "ballz" // Process BallZ

// Update shadow
module.sprite.SetPosition_Name(sprite.GetValue$("shadowName"),sprite.GetX()+4.0,sprite.GetY()+4.0)

CASE "balldropper" // Process Balldropper
LOCAL timeForNextDrop

timeForNextDrop=sprite.GetValue$("timeForNextDrop")
IF timeForNextDrop<=0.0
//AddBallZ()
sprite.SetValue("timeForNextDrop",RND(100)+64)
sprite.SetValue("firstTime",FALSE)
ELSE
sprite.SetValue("timeForNextDrop",(timeForNextDrop-speed))
ENDIF

// Update balldroppers shadow
module.sprite.SetPosition_Name(sprite.GetValue$("shadowName"),sprite.GetX()+4.0,sprite.GetY()+4.0)
ENDSELECT
ENDFUNCTION


with the Framework