sega 500 gui & menus jeff “ezeikeil” giles jgiles@artschool.com jgiles

Post on 13-Dec-2015

214 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Sega 500

GUI & Menus

Jeff “Ezeikeil” Gilesjgiles@artschool.comhttp://gamestudies.cdis.org/~jgiles

So far

We’ve spent lots of time futzing with the game itself and making it do all sorts of new, weird and wonderful things.

…but it’s menus & stuff look so UT it’s not funny.

Today

We’re going to take our first steps into changing UT2003’s front end.

E.g. we start playing with and customizing the menu system.

The goal?

Nothing overly complex of fancy today.

Simply to get a mutator dialogue box to display to the screen with some buttons and information.

The goal?

I’m going to take the adrenalin bounce mutator we made a few classes back and build a menu for it.

Ultimately, were going to have the jump height adjustable from this menu.

The goal?

Thus illustrating, in it’s infancy, how to pass information to the game from the menus.

And back again…

Before we code…

There are a tone of GUI classes already created for us. Thus, most of the core functionality is already in place.

We just have to sift through it to find what we need…no small task.

Have a boo…

Take a look at what you have…for a change lots of classes…very well documented …

Having a peak at what we need today, we’re just going to walk down the inheritance chain to checkout all the assets we get.

XInterface.GUI

GUI is an abstract class that holds all of the enums and structs for the UI system

It also has its own controller, specificly for the GUI.

xInterface.GUIComponent

GUIComponents are the most basic building blocks of menus.

This class has some weirdness in it…the inclusion of cpptext.

A long list of delegates for the core functionality of the menus.

From here we have access to the player via pawn owner.

xInterface.GUILabel

GUILabel - A text label that get's displayed. By default, it uses the default font, however

you can override it if you wish.

Our “Draw Text” tool

xInterface.GUIMultiComponent

GUIMultiComponents are collections of components that work together.

When initialized, GUIMultiComponents transfer all of their components to the GUIPage that owns them.

xInterface.GUIPage

GUIPages are the base for a full page menu. They contain the control stack for the page.

This is the base class from which we derive our menu.

Also has a bunch of page specific delegates.

xInterface.GUIButton

GUIButton - The basic button class

With 2 function stubs of interest event ButtonPressed();

// Called when the button is pressed; event ButtonReleased();

// Called when the button is released; Defines the core button functionality

Getting started…

If you recall from our class on mutators, there was a default property named:

ConfigMenuClassName=“”

Which we left uninitalized. This is actually what’s going to be the “handle” to your menu.

What menu to use…

In our mutator we simple tell this to point at our menu type.

ConfigMenuClassName="eze.EzeBounceConfig"

Building your menu

As promised, deriving from GUIPage, we declare our menu.

class EzeBounceConfig extends GUIPage;

And this is where it gets a bit weird…

Building your menu

In out default properties, we add the definition of the button.

WinLeft=0.25 //placement multipliers from top leftWinTop=0.3WinWidth=0.5 //multipliers to window's w&h valuesWinHeight=0.4 //relative to the screen resolutionbRequire640x480=True

These are the widows own properties.

Building your menu

And the dialogue box…which is in fact a button…which is in fact a window…

Begin Object Class=GUIButton name=DialogBackgroundWinWidth=1.0WinHeight=1.0WinTop=0WinLeft=0bAcceptsInput=falsebNeverFocus=trueStyleName="ComboListBox"bBoundToParent=truebScaleToParent=true

End ObjectControls(0)=GUIButton'DialogBackground'

Building your menu

What we get?

Ooo…exciting…

The screen coord layout

The placement numbers are multipliers which work very similar to UV coords.

0,0

1,1

Building your menu

So what the heck is going on, that button declaration came totally out of left field!

Ok, yeah. This might seem a little weird to you (it sure did to me when I first saw it), but don’t worry, it is really simple!

Building your menu

UT2003 has completely changed the way the menus and button system works…It’s much simpler…despite being what appears to be a twisted form of object orientation…

In the classic UT, we had to create around 3 or 4 classes just to make one window, basically what all this code does is create this window for you using only one class.

Here’s what’s going on…

Begin Object Class=GUIButton name=DialogBackgroundWinWidth=1.0WinHeight=1.0WinTop=0WinLeft=0bAcceptsInput=falsebNeverFocus=trueStyleName="ComboListBox"bBoundToParent=truebScaleToParent=true

End ObjectControls(0)=GUIButton'DialogBackground'

Begin a new object The objects nameClass type

Sets Controls[0] to the DialogBackround.Should match name .

End this object

Controls is an array of elementsthat make up this window

Kinda like the aliases we looked at in the User.ini.

Here’s what’s going on…

Begin Object Class=GUIButton name=DialogBackgroundWinWidth=1.0WinHeight=1.0WinTop=0WinLeft=0bAcceptsInput=falsebNeverFocus=trueStyleName="ComboListBox"bBoundToParent=truebScaleToParent=true

End ObjectControls(0)=GUIButton'DialogBackground'

Window width & height 1 == full

Top left of screen

Accept inputs, falsefor backgroundstyle to use

Here’s what’s going on…

Basically, Begin Object creates an object, names it, manipulates its variables and then assigns it to something.

Here’s what’s going on…

But look just a smidge closer…

WinLeft=0.25WinTop=0.3WinWidth=0.5 WinHeight=0.4 bRequire640x480=True

0.25

0.30.4

0.5

These values are relative to the whole viewable area.

Here’s what’s going on…

And looking at the other block… Begin Object Class=GUIButton name=DialogBackground

WinWidth=1.0WinHeight=1.0WinTop=0WinLeft=0 0,0

1,1

Here’s what’s going on…

Why does this happen?

Two very helpful parameters…

bBoundToParent=truebScaleToParent=true

Here’s what’s going on…

In effect the coordinates are relative to the parent window’s dimensions.

Thus placement of the window is almost like doing a SetPos with the canvas in the HUD…almost.

Here’s what’s going on…

Lets add an OK button.

Adding another button

Do another begin / end object set.

Begin Object Class=GUIButton Name=OkButtonCaption="OK"WinWidth=0.2WinHeight=0.04WinLeft=0.4WinTop=0.6

bBoundToParent=true bScaleToParent=true

OnClick=EzeOnClick //delegate assignEnd ObjectControls(1)=GUIButton'OkButton'

Hey a button

Wow…

Hey a button

But first, notice the placement is relative to the dialogue box…

Begin Object Class=GUIButton Name=OkButtonCaption="OK"WinWidth=0.2WinHeight=0.04WinLeft=0.4WinTop=0.6

0.2

0.40.6

0.04

Here’s what’s going on…

Most of this is the same, but here’s the changes

Begin Object Class=GUIButton Name=OkButtonCaption="OK"WinWidth=0.2WinHeight=0.04WinLeft=0.4WinTop=0.6OnClick=EzeOnClick

End ObjectControls(1)=GUIButton'OkButton'

A caption

Control is Incremented by one

Onclick is Assigned a value

Here’s what’s going on…

Caption: is simple text for the button.

Control: is an array, we just add this

functionality to the next index. Onclick:

is a delegate that we point at afunction…which is run when clicked.

Here’s what’s going on…

Ours, simply closes the window.function bool EzeOnClick(GUIComponent Sender){ Controller.CloseMenu(); return true;}

This would be where you save to an ini or execute you changes from the mutator.

Let me show ya something

Now there’s obviously a connection between the buttons and the declarations in our page…but what are they?

See if you can spot the similarities.

Let me show ya something

Begin Object Class=GUIButton name=DBWinWidth=1.0WinHeight=1.0WinTop=0WinLeft=0bAcceptsInput=falsebNeverFocus=trueStyleName="ComboListBox"bBoundToParent=truebScaleToParent=true

End ObjectControls(0)=GUIButton'DB'

defaultproperties{

StyleName="RoundButton"

bAcceptsInput=truebCaptureMouse=TruebNeverFocus=false;bTabStop=trueWinHeight=0.04bMouseOverSound=trueOnClickSound=CS_Click

}

Our class GUIButton class

Let me show ya something

Let me make it a bit more obvious…

Same thing, I’ve just included some of the inherited defaults in the GUIButton and removed repeat declarations.

Let me show ya something

Begin Object Class=GUIButton name=DBWinWidth=1.0WinHeight=1.0WinTop=0WinLeft=0bAcceptsInput=falsebNeverFocus=trueStyleName="ComboListBox"bBoundToParent=truebScaleToParent=true

End ObjectControls(0)=GUIButton'DB'

defaultproperties{

WinTop=0.0WinLeft=0.0WinWidth=1.0WinHeight1.0

bAcceptsInput=false bNeverFocus=false

StyleName="RoundButton"bNeverFocus=false;

bBoundToParent=falsebScaleToParent=false

}

Our class GUIButton class

Let me show ya something

Hmmm…same variable names are showing up…

Could it be…that were simply setting defaults?

Looks to me like that’s exactly what’s going down.

Adding some text

Now that we’ve gone through the above, this is actually stupid easy…

Just following the same pattern the next object is:

Adding some text

Begin Object class=GUILabel Name=DialogTextCaption="On the bounce!!!"TextALign=TXTA_CenterTextColor=(R=220,G=180,B=0,A=255)TextFont="UT2HeaderFont"WinWidth=1.0WinHeight=32.0WinLeft=0.0WinTop=0.3bBoundToParent=truebScaleToParent=true

End ObjectControls(2)=GUILabel'DialogText'

GUILabel class

New caption Text align

Text colour

The font

Adding some text

What about pictures?

Sure no problem after poking around for a suitable texture…

Cool! Finally cool!

So how did we do that?

Once again, very similar to the above…

Begin Object class=GUIImage Name=aPic WinLeft=0.25 WinTop=0.3 WinWidth=0.5 WinHeight=0.4

Image=Material'ExitScreen.splash.QuitA2'ImageColor=(R=255,G=255,B=255,A=255);ImageRenderStyle=MSTY_NormalImageStyle=ISTY_Scaled

End ObjectControls(3)=GUIImage'aPic'

GUIImage class

The image

Colour

Render styleImage draw style

But there’s a problem…

Where did the “On the Bounce!!!” caption go?

Here’s a hint…

Actually it’s still there…

Order counts!

Like so may things in programming…order counts!

Just swap the controller indexes around some so that the image is drawn before the title…

Controls(2)=GUIImage'aPic‘…Controls(3)=GUILabel'DialogText'

Nuh-huh…order counts

Next up

Ok, starting to look different…which is good. But can we make some noise with it.

In short, yes. But it is a bit finicky in terms of how.

GUI Noise Makers

The easies way to get the GUI to make some sounds is like this… You have to call a function declared in the GUI controller

PlayerOwner()

GUI Noise Makers

Ok, sounds simple enough, bu tlook at what it does.

It accesses the VIEWPORT to get a hold of the player.

function PlayerController PlayerOwner(){

return Controller.ViewportOwner.Actor;}

GUI Noise Makers

Ok, why do we have to go this route?

Well, in short, GUIControllers are completely different that the regular controllers. As a matter of fact, they are not even an actor. They derive from Interactions…

GUI Noise Makers

But, from here you can call the play sound function.

So, I’m going to start by making noise with every keystroke…making is sound like an old style typewriter

Not going to do anything with the keystrokes yet…

GUI Noise Makers

Simple as that….now try the keyboard

Delegate bool OnKeyType(out byte Key, optional string Unicode) { PlayerOwner().PlayOwnedSound(sound'MenuSounds.MS_MouseOver',

SLOT_Interface,1.0); return false;}

GUI Noise Makers

So, running with is a bit, I override another function:

function PlayOpenSound(){

PlayerOwner().PlayOwnedSound(sound'PickupSounds.LargeShieldPickup',SLOT_Interface,1.0);}

GUI Noise Makers

Doing this will cause a nice shield charge sound to play when the menu opens.

Yeah, simple…But, since we have access to the GUIController, we can also change the default sounds…

GUI Noise Makers

Try adding this to the PlayOpenSound function:

Any idea what this will do?...other than make some noise I mean.

Controller.MouseOverSound=Sound'WeaponSounds.BExplosion3';

GUI Noise Makers

Ok, that one is a bit of a keeper…changing all the GUI sounds…

Definitely going to need that!

That’s all for today

This should be more that enough to wet the appetite…

Tomorrow, we’ll look at how to get information into and out of the menus.

top related