123
-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|719|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
Socoder -> Blitz -> Automatically handle menu clicks without a select

Thu, 30 Oct 2008, 00:15
LostUser
In my current game I'm taking several ideas for the GUI from Championship Manager '94 and using rectangle push buttons to display menus on a screen.

ie;


However when it actually parsing the click I have to do a big "SELECT CASE" command. Notice that this is hard-coded and not automatic.

The menus are inside a type object.

ie;


What I'd like to know is if there is a quick way of automatically handling the menu choice without using a select case coding.

As you'll know, in CM94 virtually every rectangle is clickable, and performs an action. Now if I do a similar thing in my game I'm going to have a seriously big SELECT list.

Ideally what I'd like is a way to tell Blitz automatically what to do with a menu selection with my Type object.

But if that isn't possible, is there another way to resolve this?

IE;
I click on menu 1, it will do X.
I click on menu 2, it will do Y.
etc.

Many thanks.
Thu, 30 Oct 2008, 00:59
Cower
Not really, no. As you'll know, I don't know anything about CM94 or what in the heck it even is. I work as a manager though, so I'm guessing it's boring.

As you'll know, since you're not using a language that supports callbacks, or really any good way of doing scripting short of hard-coding every little thing, you're limited to either hard-coding all of this or using a generic sort of menu system that is automated. As you'll know, there are tons of ways to do this, so I don't think I ought to tell you which I'd use.

As you'll know, the best thing you can do if you're concerned about the size of your construct is to split it into different functions. In the end, however, you're limited by the language, and so you're probably going to have to hard-code this if you want to avoid the tedious work of writing a generic way of doing this (which you'll probably never reuse anyway).
Thu, 30 Oct 2008, 02:07
LostUser

writing a generic way of doing this (which you'll probably never reuse anyway).


The generic way of doing it would be used pretty much all the way through the game, and handle all/any rectangle menu objects.

CM94 = Championship Manager 94.
URL: https://en.wikipedia.org/wiki/Championship_Manager_94

Is it boring? It can be I guess, if you're not into Soccer, or as we call it, football.
Thu, 30 Oct 2008, 02:09
Cower
The generic way of doing it would be used pretty much all the way through the game, and handle all/any rectangle menu objects.
I meant reuse in other projects, which is kind of the point of writing generic, reusable code. My point was that you probably wouldn't reuse it, so why go to the trouble if it doesn't benefit you?

Also: yep, looks boring.
Thu, 30 Oct 2008, 02:10
LostUser
Oh I see. Sorry.
Thu, 30 Oct 2008, 04:14
Phoenix
Blitz is a very limited language and wasn't really designed for this kind of thing. The only semi-solution I can come up with is to write a little scripting system and make all the menus read their actions from text files, but that's a lot more work than just hard-coding everything.

You might want to have a look at BlitzMax (although I haven't tried it so I don't know how well it handles this kind of stuff).
Thu, 30 Oct 2008, 04:59
JL235
The select case is the best system I can think of. Although I'd have it only and specifically map from the action to the function. i.e.


If you ever need to hard code things then you should always try to ensure that it's all done in one place, things are only hard coded the once and try to ensure that as little is done as possible there. Typically it's then easier to manage the problem.

My only other suggestion is to use an object-oriented language as typically they are very well suited for GUIs.
Thu, 30 Oct 2008, 05:08
Jayenkai
(*Damnit... restarts typing after PC crashed*)

Whatever you choose, you need a Select.
If you choose a "Proper Language" with "Proper GUI" then you still need a big-ass select.
Remember, you're making a HUGE game with a LOT of little buttons, all over the place. This needs selects. And lots of 'em.
"Proper" GUI's structure these selects using loads and loads of numbers, all over.
In the same way that Blitz loads an image as a number, a GUI loads a button as a number, too.
You've got to replicate that.

Remember.. Blitz is a PROGRAMMING language.. that means to get it to do something, you need to PROGRAM it. Seems a lot of folk around here have forgotten that lately.

Split your menu objects up a little.
Give them a MMU\Func field, so that each object can be assigned a specific function.
Menu buttons that send the program off to another area could be MMU\Func=1. Menu buttons that then request a "Yes/No" message box could be MMU\Func=2. Buttons that ask for Text Input could be 3, and so on.
eg.
If you have a large list of players on the team, and then a batch of little buttons to do Stat based things, then using MMU\Name is a really really bad idea! But if you use the MMU\Func thing, you can instantly reuse that over and over again.

[Mr Happy Sox] [Speed][Range][Aim]
[Speed+][Speed-] [Range+][Range-] [Aim+][Aim-]

(^I've no idea what a football manager looks like, I'm guessing here!!)

Shove a case in to deal with Stat buttons (we'll call that func 5)

select mmu\func
case 5 : AlterStats ("Player's Name",mmu\lbl$)

Then have the stats program deal with the actual longer name based select..

function AlterStats(Playername$,Label$)
ThisPlayer=FindPlayer(PlayerName$)
select Label$
case "Speed+" : Player\Speed=Player\Speed+1
case "Speed-" : Player\Speed=Player\Speed+1
and so on..

You COULD put the "Speed+ : Add 1 to Speed" stuff into a script, and have it deal with that, but as soon as you start creating scripts like that, players can (and usually will) start hacking into them, to make their game easier. So, either encrypt it really well, or keep it hardcoded.

And encrypt the savegame data whilst you're at it!

-=-=-
''Load, Next List!''
Thu, 30 Oct 2008, 06:15
JL235
Jayenkai Whatever you choose, you need a Select.
If you choose a "Proper Language" with "Proper GUI" then you still need a big-ass select.

That's just not true. A better solution would be to pass and store the function against a key as then it's simply a trivial lookup in a map. The function could be passed as a value like in Haskell, a pointer like in C or through passing an object who implements the function (as a method) like in Java. That is three very different languages that use very different styles and paradigms that all allow this.

Even then with polymorphism many GUIs will often make calls and pass values (like an event occuring) to it's generic child components. They can then act in their own GUI widget specific way. This is something you can imitate in a procedural language but it's not anywhere near as simple or clean.

Another non-select alternative (which typically is a lot cleaner then this BB implementation) is the chain of responsibility design pattern. I'm not sure if it's better but it's something to at least consider.

First make a type that can hold all the possible info about an event:

Note that not all of these might be used. For those that aren't I would fill the field with a default valid to state that it's not being used (like -1 for x and y).

When you want to fire an event you create one and pass it to the first function that can handle it. It checks if it can and if so it does and returns. If it cannot it will pass it to the next function. i.e.

To be fair it's still a sort of select statement. However identifying the conditions under why a function should occur can be kept inside the function that is occuring. It's also trivial to add more functions.

Again in an OO or a functional language it would be possible to hide the function chaining from the user and even that the event is passed directly on from one function to the next. In that case the actions would however need to return a boolean value (or similar) to state that it has handled the event.

I'm confident there are other non-select ways to structure this problem in other languages.

@Zardon: unless you are interested in building a GUI in BB I would personally recommend finding a GUI toolkit you can use. Any proper toolkit will handle the GUI management for you.
Thu, 30 Oct 2008, 09:19
Orion Pax
You could give SpriteCandy a try. Its not free...but its WONDERFULL! If you wanna check it out in the works look at my TradeWars 3D demo. I use it there. It cost about $40 USD.
|edit| oh and its not quick. But once in place it doesnt take long to take advantage of! |edit|


Thu, 30 Oct 2008, 11:48
Phoenix
SpriteCandy is excellent (in Blitz-terms) but doesn't really solve the problem.
Fri, 31 Oct 2008, 00:43
LostUser
I've been doing quite a bit of coding in the game, and every time I come to a problem I always try to think of a framework way out of it.

Up to now I've coded a framework for images, fonts, and I code one the other day to handle basic menu objects, so I apologise if I'm sounding like I'm always after a "framework" or simple solution to something that isn't really that simple.

The idea of embedding a function to call (ie: "MMU\Func") inside the type object was something I was thinking about, but wasn't sure how to solve.

I do like the idea of having a "function to call" inside the type object, as it would solve a lot of problems.

I think I'll play with your idea Jay, but I think from reading your post I think you're right about just keeping it hardcoded until I get frustrated and use your idea.


@Zardon: unless you are interested in building a GUI in BB I would personally recommend finding a GUI toolkit you can use. Any proper toolkit will handle the GUI management for you.


No I don't intend to build a GUI in BB. I know BMax does that.


"And encrypt the savegame data whilst you're at it!"


Do you mean encrypting all the type data, the arrays, or the .dat files?

I do have an encryption library, but it does not load the decrypted data into memory, rather it just spits it out into another file (usually a text file), and then I still have to read it back in.


Use SpriteCandy


Is SpriteCandy designed for Blitz Basic, Blitz Plus, 3D or MAX? The website doesn't say. Also, is it a library, or standalone?
Fri, 31 Oct 2008, 06:21
LostUser
I'm going down using the lbl$ route for the moment, but the whole "func" attribute does interest me.

I've programmed a solution which should work for this one game.



And then in my main code/loop I do this;




Although there STILL is a SELECT..CASE, I've been able to use the framework reduced the amount of repetition and coding I've had to do to fix the problem.

I think using/appending a "func" attribute in my type object would certainly be very interesting, but until then I'm just gonna hard-code it and be done with it.

Thanks.
Fri, 31 Oct 2008, 21:28
Orion Pax
Sprite Candy is a library for blitz basic. It is da bomb! I love it!
Mon, 03 Nov 2008, 00:57
LostUser

Sprite Candy is a library for blitz basic. It is da bomb! I love it!


Oh! Is it a standalone package?

Also, if its for BB2D, why are there 3D GUI programs too?

I'm going to contact the developer of SpriteCandy as I have too many questions regarding its usage.
Thu, 06 Nov 2008, 17:24
Hotshot
Menu Buttons....Hmmmm I used play CM on Amiga in old days