[PAID] Screen Framework for AGK?

Started by Amon, May 26, 2019, 16:27:52

Previous topic - Next topic

Derron

I wanted to know why he praised it as I do not see it doing stuff we others would not do too.

Also I wrote that I do not want to offend Qube but wanted to know why the code was found as being "loveable". I also explained why I would use some kind of "hooking/callback" system (OOP based or not).
Repeat: I do not want to sound arrogant. But please remember that Rick is no beginner in programming - he wrote some cool looking stuff in the past which is why I questioned the piece of code being "loveable". Maybe I just am not able to see what it does differently to how we others would tackle it. So please explain what this code does what you did not think of before .. what makes it "very special"?


@ Adam
Of course fading a screen can be "very special" - but the routine posted here is ... update a value, handle stuff and render your fading effect according to the value. It's how we all would handle it - just not in the way _I_ would do it. Maybe AGK even does not allow that, dunno, am not using AGK.

I understand what you mean with controls - controls need to be "scaleable", multiple alpha effects need to take a "global alpha" into consideration (best is to have all rendered on a single texture - which your global fading thing then fades/scales/rotates/... for you).

I think above's stuff is best handled in a OOP/hook/callback system - and everything of course under the assumption of being "library" code not just something you have in your prototype app.


bye
Ron

Qube

Quotebut the routine posted here is ... update a value, handle stuff and render your fading effect according to the value
Not to drag this pointless debate on but it's not strictly that. It's a simple method to fade out your screen, change level ( scene ), take any actions after fade out and then fade in the screen with just calling one command.

While simple to you and no doubt many others it may be helpful to someone who's never done this before and as it's simple code perhaps that why *some* just like it as it doesn't involve anything complex or OOP gymnastic with hooks and callbacks and before, mid, during fluffy bits.

Just a simple approach to use one command to fade out, change scene and fade in the next scene.
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

Derron

Maybe it needs to be done that way as AGK limits the user with its language/syntax?


Of course a screen fader does what you describe - in this or another style/approach. I just thought it is a bit tedious if you needed a multitude of little variations - copy pasting functionality and hoping that the basics never change (as it meant a dozen of manual replacements then).

I understand that for _some_ this code looks interesting but as said I took Rick Nasher's "knowledge" (comments, posts, projects) into account too - which made me wonder as I assume he would be able to do that too - except (see first sentence) it was a bit of tricky to achieve with AGK (dunno about limitations there).


Nonetheless: you made it available for free - and this is always cool beans!


bye
Ron

Qube

QuoteMaybe it needs to be done that way as AGK limits the user with its language/syntax?
Exactly, you do not know AGK and it's has no OOP so saying it SHOULD be done via OOP in an AGK based thread is mute.

I can't stress enough that the code was just some tiny example I whipped up on how I currently code this in my games to do something that Amon was interested in.

As also stated I don't have a proper game framework yet, hence "this is just the method I use". It's not clever code, smart code or impressive code. Its just a simple example of doing something. Perhaps Rick just liked the overall simplicity of being able to fade out / in / change game scenes with just one command, I don't know.

I'm sure Rick will explain to you why he happened to like it if it's bothering you that much.
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

Derron

Yes it is bothering me - as the code itself is not doing some black magic stuff but pure "logic" and I want to know whether he liked it as he learned something new out of it or did not know of a way on how to achieve that with AGK (which might be an issue of the language).


Also I do not say you need to do it "OOP" - I said you could use callbacks or other options to have a dynamic behaviour. Something which allows to reuse your code or even to use it multiple times simultaneously. I assume in AGK it would need some arrays or so but still the code would be more flexible then. Same for callbacks or other "hook your functionality into existing code without requiring altering this code".
So maybe you can tell me (so I can learn something) if such "dynamic connections" are not possible with AGK that easily. Think it is needed for a proper (and flexible) framework and as you are writing one for you I assume there are ways to achieve that.


bye
Ron

LineOf7s

Wow.

In a programming forum: someone asked a question, someone else provided an example of how he could do it, and someone else again expressed appreciation for the method.

If any part of that is "bothering" anybody, perhaps this forum is a little too uncomfortable for you.
"Life's biggest obstacles are your greatest opportunities to excel"

Qube

QuoteSo maybe you can tell me (so I can learn something) if such "dynamic connections" are not possible with AGK that easily.
OK, very quick crash course in AGK's language structure.

1.. No OOP.
2.. The closest thing to OOP is Types to which you can use to store data like : bullet.xpos bullet.ypos bullet.speed etc etc.
3.. It's procedural programming ( functions )
4.. You can return a variable from a function. For example :


If AddThis( 2, 2 ) = 5 Then END

Function AddThis( var1 As Integer, var2 As Integer )
   Local answer As Integer
   answer = var1 + var2
EndFunction answer


5.. You can have Types in Types ( + insert, delete, sort types )
6.. You can pass Types via reference

And that's pretty much it in regards to any fancy language features. The rest is down to the built in commands and your coding imagination :)
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

Derron

So you cannot pass a function reference to another function to call it there then?
Or store function references at least in an array or so...so you pass an integer to somehow reference / identify a dynamically positioned entry of that function array?

Would be pretty limiting in my opinion (way less flexible). Only reason I see for this would be optimization as all potential paths are known on compilation not execution.


Thanks for the crash course.


Bye
Ron

Qube

You can call a function from another function but you can't have a function in a function. You can pass and return variables to / from a function.
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

Derron

I am talking about something like this:

Code (BlitzMax) Select

Function CallFunction:int(func:int())
  if func then func()
End Function

Function MyFunction:int()
  print "hi"
End Function


CallFunction(MyFunction)


So in essence something which allows callbacks.
For now I think you can only have stuff like "DrawButton(index)" with "index" pointing to various arrays for "x, y, w, h, label, clickState" ... but if you eg. intend to have a button get drawn differently (icon added or so) you have to prepare it in your "DrawButton()" function already (with another "icon array/dim" even if only 2 of 100 buttons require an icon). Your code / loop would need to always check button states of all buttons to see they are clicked - or your "UpdateButton()" would need to get tinted with game logic ("If MouseClicked ... if buttonStates[10] = 1 Then FadeToMainMenu()").

This is btw something I found notionworthy in your code (the mix of fade - and gamelogic). But it seems that this is a limitation in the AGK language enforcing such a coding style.
So now I am even more interested in how you tackle it in your new framework code (no real code needed, just want to know how you make it "flexible" - if possible).

I can imagine that for rapid prototyping this might be maintainable but I wonder how to do a proper (customizable) framework then. Might lead to a lot of hoops to jump?


bye
Ron

TomToad

Quote from: Derron on June 01, 2019, 10:44:14
I am talking about something like this:

You can do that with tier 2 AGK, but not tier 1.  Tier 1 is a BASIC syntax with some added functionality, more akin to Blitz3D or BlitzBasic.

QuoteFor now I think you can only have stuff like "DrawButton(index)" with "index" pointing to various arrays for "x, y, w, h, label, clickState"
AGK has its own virtual button routines, but if you want to create your own:  You would only need 1 array of type "Button" which would hold all the info you need.
Quotebut if you eg. intend to have a button get drawn differently (icon added or so) you have to prepare it in your "DrawButton()" function already (with another "icon array/dim" even if only 2 of 100 buttons require an icon).
Unless you want flat 2d butons, they probably all need some sort of image already.  Otherwise, your statement is true, any extra information would need to be stored whether you need it or not. No class ButtonWithImage extends Button possible.
QuoteYour code / loop would need to always check button states of all buttons to see they are clicked - or your "UpdateButton()" would need to get tinted with game logic ("If MouseClicked ... if buttonStates[10] = 1 Then FadeToMainMenu()").
This is how procedural languages work.  You control when io gets polled, Why have the game pause during AI or physics calculations just to change the state of a button or respond to a keypress?

QuoteThis is btw something I found notionworthy in your code (the mix of fade - and gamelogic). But it seems that this is a limitation in the AGK language enforcing such a coding style.
Not a limitation, just a preference.  Personally, I prefer a more OOP approach, but some prefer a more procedural approach.  One reason I liked Blitzmax as it seemed a good balance between the two.
------------------------------------------------
8 rabbits equals 1 rabbyte.

Derron

#41
QuoteThis is how procedural languages work.  You control when io gets polled, Why have the game pause during AI or physics calculations just to change the state of a button or respond to a keypress?

Maybe this is why I buried it so far far far in the darkest corners of my brains ;-)
Dunno if I got your last sentence correct but callbacks/events do not do something differently than a function you call in your loop - just with the possibility to change this function more flexible. They all "block" as they do something (even if it is just setting a variable for a thread).


Thanks for your elaboration about (Tier 1) AGK. Wonder why they kept it that way instead of extending the language here and there (...as long as nobody is forced to use it people should be happy). As said BlitzMax offers a kind of "mix" between both things (as for many modules a procedural interface is provided).

Regarding "Not a limitation, just a preference." I think it is a kind of limitation except it was possible to do differently. Same for a languages having other limits (Lua's interpreter is having an odd time with break/return - especially prior 5.2). It's not a preference but a limitation (intented or not).


Still eager to read how Qube plans to tackle / tackles flexibility aspects in his GUI framework or scene management functionality.

Qube

#42
Quote from: Derron on June 01, 2019, 10:44:14
I am talking about something like this:

Code (BlitzMax) Select

Function CallFunction:int(func:int())
  if func then func()
End Function

Function MyFunction:int()
  print "hi"
End Function


CallFunction(MyFunction)


No, you can't do that, you'd have to do something like silly like :


Function CallFunction( func As String )
  if func = "MyFunction1" then MyFunction1()
End Function

Function MyFunction1:int()
  print "hi"
End Function

Function MyFunction2:int()
  print "me"
End Function

CallFunction( "MyFunction1" )


Quote from: Derron on June 01, 2019, 10:44:14
So now I am even more interested in how you tackle it in your new framework code (no real code needed, just want to know how you make it "flexible" - if possible).

I sort of cheat a lot using Types and of course well thought out clean coding. For example in my GUI ( which is almost complete including designer \o/ ) you can do something like this to get / change things :


// say I have 10 windows open which are all the same and each one has a slider to change the red colour of a text label - here's the code which works automatically for every window but only on the window in focus.

If guiEvent.label = "colour slider red"
   guiFindGaget( guiEvent.window, "my boring label" )
   guiGadgets[ guiFoundGadget ].red = guiGadgets[ guiEvent.id ].value
EndIf


Simple example of course but shows I'm not having to do mad coding when it comes to actually using the GUI. The whole GUI and event system is based on Types so no hard limit based on DIM's. I can also change gadgets in other windows which are not in focus or not even shown using the same code base as above.

Also the GUI designer spits out the source code for all windows and gadgets including all the possible events in that window so all I need to manually code is the actions for each gadget.

Overall the GUI has been coded to offer enough flexibility for most circumstances.

* updated *

Soon I'll be moving on to a fresh new approach to my framework which currently is causing way too much repeated code with every game I do.  Again it will be designed around Types so I can set the scene with things like :


scene.fadeOut
scene.pause
scene.muteAudio
scene.slowTime
scene.saveData


All the commands for drawing and doing other stuff are designed around the scene framework so we will then be able to do something like :


   If scene.keyPressed = "SPACE" Then scene.pause = 1
   If scene.isGameOver Then scene.fade = 1


This would then trigger the framework to pause all sprite movement and pause any audio. Pressing space again then does the reverse.
You won't code your game using the built in commands but instead be using the frameworks version.
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

Derron

Sounds kind of clever regarding "sailing around" these obstacles hidden in the shallow AGK waters :)



   guiFindGaget( guiEvent.window, "my boring label" )
   guiGadgets[ guiFoundGadget ].red = guiGadgets[ guiEvent.id ].value

So your guiFindGadget() is populating "guiFoundGadget" with an ID (or instance reference) of the found widget?
If that happens: what happens if you call a function for a "widget" which does a "guiFindGadget()" too (eg in a dragndrop-interaction). Your functions would need to be aware of that culprit and backup "guiFoundGadget" into another variable, do their lookup + interaction and then finally restore the backup again into "guiFoundGadget".

Or do you handle it differently? Above is - as said - an assumption of something like a global variable which you use over and over and it works until some other code line is modifying it too.



@ scene management
Yes such stuff eases pain a lot.

GetCurrentScreen().FadeToScreen( GetScreen("mainmenu"), 0.2)
-> fade the current screen to the screen stored at "mainmenu". Fade duration is 200ms

There is a lot of convenience you can put into your framework functions. Eg. the screen gets informed about the pause/fadeout and would either stop game logic or pause it or ...


@ game project + framework
Think a lot of stuff would benefit from such managers: sound (music manager + sfx playlists for randomized usage of "boom" sounds and so on). bitmap font classes (styled block text, text animations, ...).
Cannot imagine what a hell that must be without "oop" (or similar approaches).

Again: all this is under the topic "framework" so something we plan to reuse over and over - compared to specific "only game x" logic.


Can't you use Tier2 to provide yourself some basic functionality which you then use in your Tier1 code? Kind of a "DLL" ?


bye
Ron

Qube

QuoteSo your guiFindGadget() is populating "guiFoundGadget" with an ID (or instance reference) of the found widget?
Yes, that's pretty much it.

QuoteIf that happens: what happens if you call a function for a "widget" which does a "guiFindGadget()" too (eg in a dragndrop-interaction). Your functions would need to be aware of that culprit and backup "guiFoundGadget" into another variable, do their lookup + interaction and then finally restore the backup again into "guiFoundGadget".
I don't do it that way as any gadgets which interact with other gadgets have their own dedicated code to avoid conflicts.

For example a listbox is made up of a vertical slider and a multiline textbox these two separate widgets are joined together by a guiGadgets[ ].childOf - When I move the slider, it knows there is a child gadget and the code to handle the multiline textbox gets fired.

In regards to drag and drop each relevant widget has a guiGadgets[ ].dragFrom, guiGadgets[ ].dragTo and guiGadgets[ ].dragInfo which again is all handled via dedicated code for that action. If I still need to find a gadget then there is a guiFindGadgetPrivate function ( this is only used by the GUI itself and not the user ) which goes into a queuing system and won't take any actions from the queue list until the guiFoundPrivate is -1 ( 0 means nothing found and then returns to -1 )

There's quite a lot of work around systems that result in the user end being neat enough and flexible enough to use, hence the auto code generation from the designer which saves even more typing and mistakes. I had to spend a lot of time building up the GUI core as I didn't want any limits on windows, gadgets, events etc.

There's an Early Video showing 15 windows with timers being fired and still interacting with different GUI windows. Although the example syntax in the post has been streamlined since then too.

Quote@ scene management
Yes such stuff eases pain a lot.
That's the plan :) - I have a set of helper function when writing games which save time but every game I've done I'm always writing a lot of stuff over and over again but just in a different way. I thought it was about time I coded up some proper game based tools ( hence the gui and gui designer ) and code a proper framework system so all tasks like scenes, game gui's, fading, pausing / resuming action and music etc etc are all coded in an optimised manner as possible.

I have great plans for the map maker / level designer buts that's for another thread ;D
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.