The Itty Bitty GameEngine

Contents

Understanding the GameEngine
Error Alerts
How To Build a Game
GameMaker Reference
  Event Flags
  Velocity
  Text and Fonts
  Action Buttons
  Tools
    Rect
    Text
    Ball
    SkyRec
    Circle
    Diagonal Line
    RPS Sprite
  Data Structures
  Method Summary
    Useful Tools
    Game Operations
    GameMaker Methods
    Others
Unfinished "Features"
  Known Bugs

Related Documents

The Itty Bitty GameEngine -- Overview (You are here)
Your Own Java Game -- Step by step tutorial to build a simple "Pong" game
Converting Your Game to JavaScript -- What you need to know to run your game in a web browser
Class GameWgt -- The visual components of a GameEngine game
Overriding GameEvent -- The programmatic components of a GameEngine game
Widget Specification Text -- File format for GameMaker.txt and how to make your own
Trouble-Shooting GameEngine
Things You Need to Know in Java -- Technology not specific to Game Engine, but it will help you to understand it
Useful Tech Issues

Understanding the GameEngine

GameEngine is a Java-only sprite-based game engine for writing and playing simple video games. Its frame rate is not particularly fast, and it does only 2D graphics based on simple shapes (called "widgets") presented in a list of game elements. Besides user code controlling the position of the widgets through the defined application program interface ("API"), some widgets can be designated as "sprites" which the engine automatically animates, both in linear motion across the screen, and also in pixel icons that can change appearance repetitively over time. These widgets are described in the Class GameWgt page.

The same GameEngine is used for the user interface of a "GameMaker" tool for constructing the game widget specification of a user-defined video game. The student programmer can lay out a game using GameMaker, then add game-specific Java code to a subclass of the GameEvent class partially generated by GameMaker, then compile it with the GameEngine to be the game so designed.

All the GameEngine code is open-source Java for maximum benefit to the learning experience of beginning programmers. It is expected that this tool will define the third and final segment of an online "Learn Programming in Java" tutorial. The software is still under development. See the "Features" section for a (probably incomplete) list of components or functionality to be added or not yet fully operational.

GameEngine creates a Java "JFrame" window and manages the user interface for timing and keyboard/mouse interaction. The frame rate is set to a leisurely 10fps so that inefficient user code is less likely to cause problems, but this can be adjusted up or down as desired, because the source code is fully available for inspection and modification.

A GameEvent class is defined for the entire student API, so that all they need to do is subclass GameEvent, then override the methods that specify what the game should do in the case of various events. These are described in the "Overriding GameEvent" web page. Included in GameEvent are some methods for initializing the game structure. Some of this information is filled in by the GameMaker, so the you can focus your attention on the essence of your game without worrying about low-level graphical and sequential issues.. The API also defines numerous utility functions for accessing various parts of the game engine to control its behavior.
 

Error Alerts

Things Go Wrong. Some errors are in the code and we don't know about them yet (please tell us). Some errors we know about, but have not yet had time to fix (see "Features"). Some errors happen because you made a correctable mistake, and GameEngine detected it and put up an alert message. If you cannot dismiss the alert by clicking on the OK button (that's a bug, my fault), try pressing the Enter key, or as a last resort, quit out of GameEngine and restart it.

Here are the error alerts GameEngine can give you:
 

'xxx' is not a valid Java class name

You tried to give a name to your game that contains other than letters and digits.

The name 'xxx' is already taken

You can use a widget name for only one widget. Try adding a number to the end.

File xxx.java cannot be upgraded, delete/rename it & retry

When you choose a name for yout game and click the Build button, GameEngine creates a new text (Java) file with the generated code and stubs of the overridable methods for you to modify. Each time you click the Build button, GameEngine reads this file back in and tries to preserve your added code. However, if you modify the lines that are marked "Do not modify" then GameEngine will not be able to update the file while preserving your code. You can just delete the file (in the system File Explorer or OSX Finder) and then GameEngine will create a new one, or else you can move it out of the BlueJ project folder so that you can read it and copy your added code to the new created file).

Oops, GameMaker is corrupted, re-install it

This can only happen if something went badly worng. You might be able to save your working data ("GameMaker.txt" and whatever Java file you are currently working on -- you have backups, right? "Save early, save often" because Bad Things Happen) and re-install GameEngine from the most recent download.


If you get an error message while trying to convert your game to JavaScript, you should look at "Problem Solving" there for additional error messages you might get in that process.
 

How To Build a Game

This might be a good time to work through the "Your Own Java Game" tutorial. Basically you need to do the following things, which are explained in more detail in the "Your Own Java Game" tutorial. This is only an overview:
0. Plan what your game should look like and how it should play. Sketch out your layout on paper if necessary, and write up a play book of how a typical game will proceed.

1. Open up GameMaker with a clean slate. If you have already done some work in it, there may be leftovers to be disposed. The simple way is to use your computer's file manager (Windows Explorer, or OSX Finder) to move the "GameMaker.txt" file to some other folder, or delete it, before you start GameMaker. See the detailed instructions in the "Getting Started with the Java GameEngine" section of the "Your Own Java Game" tutorial to start up GameMaker the first time.

2. Using the widget tool palette, drag widgets onto the game board. Select each one in turn and type in the configuration parameters for that kind of widget. The name you give to the game board widget will be the name of your subclass, for example (in the "Your Own Java Game" tutorial) I named the example "Pong" so GameMaker creates a "Pong.java" file for you to edit with your game semantics code.

3. Open your generated source file (for example, "Pong.java") and add the required Java code for your game semantics and behavior.

4. Compile your source file and run its main() program to play the game. You may need to iterate steps 2 & 3 several times to work out any kinks in your implementation of the initial design. Sometimes -- perhaps often -- it may be necessary to repair your design and start over from step 0 above.

5. After your game is running in Java, (Real Soon Now) there will be a button to convert it to JavaScript and upload it to the internet, so you can share your game with anybody on a modern web browser. For more details, see "Converting Your Game to JavaScript".

GameMaker Reference

I guess this is where I tell you about what you can do in GameMaker. Here are a couple views of the tool panel.

When you click on one of the three tools, the default information for that tool is displayed above. The color swatch changes to match that tool's major color (black text, red ball, etc.) and it puts up the tool name. The size and location is pretty much stuck in its slot in the tool panel, but you can change the color and add flags -- and if it's text, you can also change the font and the actual text -- and when you click OK, those changes become permanent, so that they are replicated onto the game board every time you drag the tool over. Until you change them again. I think they also revert to the original settings next time you start the program.

Even if your widget is not visible on the game board -- perhaps behind some other widget -- you can select it and edit its properties by clicking on its name in the widget list on the right. When the game (the top widget in the list) itself is selected, there is another checkbox "Alert+InputDlog" which enables your game to have access to the built-in alert and user input dialog boxes.

To change the color of a widget, double-click the color swatch square and it will open an input dialog offering the current color value. Back up over what's there [Sorry, the text entry fields do not let you select the whole text for retyping, you need to use the backspace key; Real Soon Now] to type in your replacement color number. See "Useful Tech Issues: Color by the Numbers".

When the Text tool (or a widget it created) is selected, you can 2-click the text to put up an input dialog for you to enter something else as the text.

Once a widget tool has been dragged onto the game board, changing the position numbers will change the position of the widget, and changing the size numbers will change the size -- typically of the containing rectangle, but it does change the ball diameter to whatever known circle size is closest to what you asked for.

After you have instantiated a tool by dragging it onto the game board, you should change the Name to something without a dot (if you want your code to have access to it when the game is running) so it's a legal Java variable name.
 

Event Flags

There are checkboxes for five flags, which control what kinds of events this widget will respond to. Clockwise from the lower left, they are:

Bump (+256)

With this flag enabled, you can get collision events when this widget overlaps another similarly Bump-able widget. See the Collided method for details. When the game (the top widget in the list) itself is selected, its Bump checkbox enables the Collided method to receive event notifications when a sprite strays off the edge of the game board.
 

Key (+512)

With this flag enabled, you can get keyboard events when this widget has focus and the user types something at the keyboard. See the Keyboardable methods.
 

Click (+1024)

With this flag enabled, you can get events when the user clicks this widget (mouse down, then up on the same widget). See the ClickEvt method for details.
 

Drag (+2048)

With this flag enabled, you can get drag events, both when the user presses the mouse on this widget and then releases it, plus all the events related to dragging this widget to some other place. See the Dragable methods.
 

Rollover (+4096)

With this flag enabled, you can get rollover events, starting when the mouse first enters this widget and then repeatedly until finally the mouse leaves it. See the Roll-able methods. [This has not been tested]

Velocity

Sprites of any kind (we only have Ball sprites in the first release) can be given a velocity vector, a signed vertical and horizontal speed in fractional pixels per frame. Positive velocity is Down and Right, negative Up and Left. Each time the sprite is drawn, the velocity is added to the current position (including the fractional part left over from the previous time), and the integer part updates its position on the screen, while the fractional part is saved for the next frame. If the sprite is not shown for any reason, the velocity calculation does not happen that frame.

A GameSprit widget is essentially the same as a group widget, except for the added velocity. Since all child widgets are positioned relative to their parent, when the sprite moves, all its child widgets move with it.
 

Text and Fonts

GameTxLn widgets display one line of text, using one of seven predefined fonts, from which you can select using a set of radio buttons:

Times

The default, it approximates the newspaper font by the same name, and is used in the list of widgets.
 

Bold

This is a thicker sanserif font used in the GameEngine button labels.
 

Large

This is the same typeface as Bold, but larger.
 

MonoSp

A monospaced font like the old typewriters, it has been crafted so that every character is at least slightly different from every other, and where it matters (like within hexadecimal numbers) significantly. It is the default used in GameEngine text input panels.
 

Ital

This resembles the italic face usually associated with Times Roman.
 

tinY

This is a smaller font, probably hard to read on the modern high-res screens. Note that the one-letter designator is not the first letter of its name.
 

Nano

I think this is as small as you can make a readable font. I threw it in for fun, in case you want to put a "Santa Clause" (fine print, like legal documents nobody is expected to read, but they gotcha if you don't) around the edge of your game board.
 

Score

This font doesn't have the whole alphabet, but it's pretty large, so you can use it for game scores and stuff like that. It only has these characters (anything else will not be shown)
! $ % ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 < = > ? A B C D E F O T X x

Action Buttons

There are three buttons that show up in the top right corner of the GameMaker window, depending on the circumstances. Most often you will see the OK button, which indicates that unaccepted changes have been made to the current widget. Basically that applies to everything that you can change above the widget list and tools, including the checkboxes and color swatch. Clicking OK also saves your game as a reloadable "GameMaker.txt" file.

The "GameMaker.txt" file is reloaded the next time GameMaker starts up, so you can resume where you left off. If you copy the file off at various points during your game development, you can restore it from one of those copies, and thus revert to a previous checkpoint. It is a good idea to save what you are doing every hour or so (change the file name to reflect the time and/or what you were doing at that time), so that if Something Bad Happens (it will, count on it), you have not lost everything. I often say, "Save early, save often."

Once OK is dismissed, it is replaced with the Build button, which saves the current game, both as a reloadable "GameMaker.txt" file and also as a Java file with whatever name you gave your game, which you can open in BlueJ and compile into GameEngine as your game. On successful completion output of the Java file, you are offered a third button "->JS" which (Real Soon Now, not the first release) converts your game file into JavaScript for upload to a website where you can play your game on any JavaScript-enabled browser. Right now it doesn't do anything.
 

Tools

There are seven widget tools in the current release. More will be added from time to time.
 

Rect

The rectangle is the simplest possible widget. It has color, position and size, nothing else (besides a name). Because rectangles can be set as buttons (by making them clickable) you can set the otherwise unused information value to a distinctive numeric value and tested at runtime with a Java switch command more quickly than a sequence of name tests. You can also set it to a character (char) value, but the GameEngine will convert it to the corresponding ASCII number; you can still test it as a character at runtime by casting the fetched integer back to (char).
 

Text

The Text widget comprises one line of text. There is no specified limit to the length of that line, except that it cannot contain control characters. There are seven pre-defined fonts, which you can select by a radio button for each text widget. The text itself is the specified color, but the background is transparent (use a Rect behind it, or a group surrounding it) if you want an opaque background).
 

Ball

The Ball tool is a sprite with a flat circular image. Sprites also have a velocity vector specified as signed fixed-point vertical (Down, up is negative) and horizontal (Right, left is negative) components, which represent fractional pixels per frame, where the minimum speed is 256 frames per pixel (about 0.0025 ppf) and the maximum speed is almost 128 ppf. This is in a straight line until the user program changes it (see Pong example).
 

SkyRec (aka Flying Brick)

The SkyRec tool is another sprite, but with a flat rectangular image. Otherwise it is essentially the same as the Ball.
 

Circle

The circle is like a rectangle, but round. It is actually an icon, which is defined by a pixel array. Maybe some day we will have a pixel editor for icons, but not today, but if you create a circle icon, you could change the pixels out at runtime for anything else you want to build up.

The default circles have diameters from 1 to 32 pixels, all filled. If you want sa hollow circle you can overlay two circles of different sizes and a common center, the smaller on top with the same color as the background, or if you really need it to be transparent, you can set your own pixel map.
 
 

Diagonal Line

The diagonal line is essentially a rectangle with an attribute that tells the Game Engine to draw only a diagonal line between opposite corners. You get to specify whether it slants Up or Down, and how many pixels thick it is (up to 9), and of course size and color.

This same tool can fill the half-rectangle Over or uNder the diagonal line by using the respective letters "o" or "n" instead of thickness. You can butt triangles together to get arbitrary polygonal shapes. For example, four half-square rectangles with their right angles all adjacent will make a rotated square (diamond).
 
 

RPS Sprite

We wanted gamers to be able to program a rock-paper-scissors game with suitable icons, and this is it. It's a fixed 32x32 pixel square, but your can select which facet is showing, and do minor animations. It is formally a sprite, so you can also program a velocity for it. For more information, see the ChoseRPS method documentation.
 
 

Data Structures

Skipping over some constants at the front, I will spend this space on the larger and more significant data structures.

Wgt_Macros is the default macro definitions. For more information on the format of this array, see the "Widget Specification Text" documentation.

Following that are the (final=constant) arrays specifying various icon types mostly used in GameMaker, including five hard-coded circle diameters: 4,5,12,13, and 16. These should go away after I write algorithmic code to do circles.

The Antz array has 32x64 full-field diagonal bars, then another 192 1-bit ants, good for horizontal ants out to 256 (see Antsify). Mostly only the leftmost 8 pixels and the top-row (least significant bit) out to 263 are used.

Following the ants are seven pixel tables for the seven built-in fonts. For details on the font table format, see the "GameFont" widget type.

After a few more numbers mostly used for debugging, we have two large arrays, first  thePixels defined to be as big as your game board (512x640 in Maker mode), then AllWgts, with space allocated for a thousand widget pointers. Any more than that and the mechanism will be too slow to be playable as a game.

I always try to declare all my data before all the code, but it doesn't work out that way very well in OOPS languages, where class definitions (containing method code) become data types for defining more data structures. I have some library utility functions I use all over the place (see the Method Summary for Useful Tools), and they get used in the embedded classes, so they come first. Then the widget subclasses, then the game code, which you can review in the documentation that follows next.

The only other structure of concern is the hierarchy of widgets. Games are pretty flat for now. GameMaker's screen is divided into the game board space on the left, and a tool panel on the right, pretty much WYSIWYG (What You See Is What You Get), some entry fields for specifying the widget particulars (some of them optional), and below that, a list of user widgets so far on the right, and a column of tools on the left. See the "Widget Specification Text" documentation for more discussion on the GameMaker widget hierarchy.
 

Method Summary

These ("Useful Tools") methods are generally useful, no matter what kind of program you might be writing. They are static methods, which means you can access them without having an instance (object) of the class to work on, just prefix the class name "JavaGame." (including the period).
 
AddPair IffyStr RestOf SignExtend
CharAt NthItemOf SafeAryElt StrLength
Countem NthOffset SafeArySz Substring
CvInt2Str PairNeg SafeCompare TopBit
FormFixt ReadWholeTextFile SafeParseInt WriteWholeTextFile 
HexIfMore ReplacAll SeeHex  


These next ("Game Operations") methods are useful within the context of a GameEngine game, so you usually need a reference to an object of the JavaGame class to use them, which is captured for you as instance variable "myGame" in overridden method GameList in the generated subclass of GameEvent. Except for the static methods (see above), to use these methods, just prefix the variable name "myGame." (including the period).

 
AntsIcon FindSubWgt KnownCircleSz SetInputText
Antsify FloatDlogs LogAlWgts SetSwatchColor
ChoseFont GameAlert LogWgtTree SpritePause
ChoseRPS GameWinSize MkSpriteAnts StartGame
CircleSize GetGameValue OpenInputDlog SwatchGetColor
DlgEvData GetInputTxt ParseInFld GameWinTall
FormFixt GetIxWgt ParsFixPt GameWinWide
FindListWgt IsDlgEvent SafeWgtNum


The remaining ("GameMaker Methods") methods in this section are internal to the GameMaker subclass of GameEvent (which itself is internal to the JavaGame class), or else ("Others") internal to the operation of the GameEngine, and are included here for completeness. You normally do not need to use them in your own code. These ("GameMaker Methods") are in class GameMakerEv:

 
CapturCoords GotEscKey MakeUserJS NewListName
CapturInfo2Wgt InvalidJava MakeWgtLst Prescan
ChooseBtn IzTool MoveWgtUpDn SelectMe
CliKnownStuff IzUsrWgt NameIsTaken ShoCoords
DoMyButn IzzitMeta NeedsVelo ShoInfoFrom
Fit3 LoadUserWgts NewData
GotEnterKey MakeUserJava NewDragWgt


These ("Others") methods are internal to the JavaGame class:

 
AdjuDim Every100ms LocalizePos paint
Ary2Str ImportGamList main ServerUpload
BestCircData InstallMyEvts MakeJSwgts Str2intAry
BuildThisMacro Int2BufImg MouseDispatch toJS
CloneWgt IzLetter NetEncode TimerStart
Collider JavaMouse NewArray Widen1stWgt
Decapit JstartTimer NewGameWgt  
EncodeID KeyDispatch NewMaker  

Useful Tools

static int AddPair(int here, int thar)
 
Parameters
here The first pair 
thar The second pair 
Returns The pair of sums 
Adds two pairs of half-integers in a single integer, see also PairNeg.

When you write programs that have a lot of data with medium-sized numbers (nothing bigger than a few thousand), and many of those numbers come in pairs, like vertical and horizontal coordinates, then it makes sense  to pack each pair into a single integer. Besides, you only get one result value from a function call, and the function call overhead is much more expensive than packing and unpacking a pair of numbers. Unless it's really trivial like AddPair, which some compilers will back-substitute and eliminate all the overhead of the method call.

So the GameEngine has numerous widget methods that return two coordinates in a single integer. If you just want to do some adding or comparing (subtracting), it's often easier to do both numbers as a single integer. If there are no negatives involved, just to the math on the whole 32-bit integer. Otherwise, you can use AddPair and it gets the carry out of the low half right. To subtract, use PairNeg on the number pair you want to subtract, then AddPair. Or you can just tear the numbers apart, do the math, then put them back together again. See "Packed Numbers" in the Useful Tech page.


static char CharAt(int here, String aStr)
 
Parameters
here The (0-base) character position 
aStr The string from which to extract that character 
Returns The character extracted, or '\0' if out of bounds 
A safe (no exceptions) non-OOPS way to extract a character from a string.

Java has an OOPS-based CharAt method, but it requires a valid object pointer to work correctly; otherwise it just crashes (throws an exception). A well-written program is not going to encounter this problem, so one hopes not to deal with it. But accidents happen. This function returns an easily tested default value when the parameters are out of bounds.


static int Countem(String aWord, String aStr)
 
Parameters
aWord The string to look for 
aStr The string in which to find and count it 
Returns The number of occurrences found, or 0 if none 
A safe (no exceptions) way to count the number of (non-overlapping) occurrences of a particular string within a larger string. An empty string cannot be counted.

Mostly I use this for counting lines or commas, but sometimes a little cleverness will see other uses for it.


static String CvInt2Str(int whom)
 
Parameters
whom The integer 
Returns The same number as String
Converts an integer to String, mostly for JavaScript (because this program is multi-targeted and JS is weakly typed), but Java does not have any consistent (easily remembered) rule for automatic coercion from integer to String. With CvInt2Str I now do.


GameWgt FindListWgt(String msg)
 
Parameters
msg the unique string to search for
Returns the first widget specified in theImpoList with that string
This is search tool to find uniquely identified widgets built from the list returned by the client GameList, so to assign references to them in variables usable in the game. Mostly it is called from pre-built Startup code.


static String FormFixt(String before, int whom)
 
Parameters
before The prefix 
whom The number to be formatted 
Returns The result string 
Formats a 16-bit integer as 8.8 fixed-point and returns it with a prefix.

The GameSprit velocity vector is two 16-bit fixed-point velocity values packed into a single 32-bit integer. This method formats them as two numbers with decimal points, for use in console logs and other places where it could display in human-readable form.


static GameWgt GetIxWgt(int ix)
 
Parameters
ix an index into the AllWgts array = RefNum 
Returns the widget with that RefNum 
GetIxWgt converts a widget reference number (RefNum) into a reference (pointer) to that widget. Every widget, upon creation, is added to a global array of widgets, AllWgts, indexed by the widget's RefNum. GetIxWgt fetches that reference.


static int GetMilliSecs()
 
Returns The number of milliseconds since game start 
A language-neutral way to get a (32-bit) time in milliseconds. The first time this is called the caller sets TimeBase (initially =0), so that all subsequent calls are based off that start value, despite being less precision than normal Java.


static String HexIfMore(String before, int whom, String after)
 
Parameters
before The prefix 
whom The number to be formatted 
after The suffix 
Returns The result string 
Formats an integer as hexadecimal if larger than 32K and returns it with a prefix and suffix, for easier reading.


static String IffyStr(boolean whom, String tru, String fls)
 
Parameters
whom The selector 
tru Returned if whom=true
fls Returned if whom=false
Returns The selected string, tru if whom=true, otherwise fls
Strongly-typed (not overloaded) string selector. This is part of a collection of tools to build diagnostic print lines.


static String LogVH(String before, int whom, String after)
 
Parameters
before The prefix 
whom The number to be formatted 
after The suffix 
Returns The combined string 
Formats a 32-bit integer as two 16-bit values and returns it with a prefix and suffix. This is useful when printing numbers that pack two smaller integers (like widget coordinates) into a single number.


static String NthItemOf(char delim, int whom, String aStr)
 
Parameters
delim Use '\n' to get a whole line, ' ' to get a word 
whom The (1-base) item number to get 
aStr The string from which to extract that item
Returns The extracted string
A safe (no exceptions) way to extract an indexed item (or word or line) from a string. When getting words, excess white space is ignored, so the returned string is empty only when requesting a word beyond the last. Otherwise consecutive delimiters result in empty items being returned, so that you always get the nth item of a multi-item string. Items past the end or before the front (0 or less) are empty.


static int NthOffset(int whom, String aWord, String aStr)
 
Parameters
whom The number of occurrences to skip over 
aWord The string to look for 
aStr The string in which to find it 
Returns The (indexOf) offset, or -1 if not found 
A safe (no exceptions) way to find the (0-based) offset of a particular string within a larger string, while ignoring zero or more initial (non-overlapping) occurrences. An empty string cannot be found.


static int PairNeg(int here)
 
Parameters
here The pair 
Returns Its negative
Returns in a single 32-bit integer the negatives of a pair of half-integers, see also AddPair.

GameEngine has numerous widget methods that return two coordinates in a single integer. If you just want to do some adding or comparing (subtracting), it's often easier to do both numbers as a single integer. When there are no negatives involved, just to the math on the whole 32-bit integer. Otherwise, you can use AddPair and it gets the carry out of the low half right. To subtract, use PairNeg on the number pair you want to subtract, then AddPair. Or you can just tear the numbers apart, do the math, then put them back together again. See "Packed Numbers" in the Useful Tech page.


static String ReadWholeTextFile(String filename)
 
Parameters
filename The name of the text file 
Returns The text as read 
A safe way to read a whole text file. The line-ends in the input file are converted to '\n' regardless of how they are on the file.


static String ReplacAll(String nuly, String prio, String theText)
 
Parameters
nuly The replacement string 
prio The string to replace 
theText The string in which to make the substitutions 
Returns theText as changed 
A safe (non-OOPS, no exceptions) way to replace every instance of a particular string within a larger string. An empty string cannot be replaced.


static String RestOf(int here, String aStr)
 
Parameters
here The (0-base) position to start 
aStr The string from which to extract that substring
Returns The rest of the string, after here
A safe (no exceptions) way to get the rest of a string. Text past the end is considered empty.


static int SafeAryElt(int ix, int[] data, int defalt)
 
Parameters
ix The index into the array 
data The array 
defalt A default value to return if can't access 
Returns Its length, or =0 if null
A safe (no exceptions) way to get an element from a (possibly null) array. Returns a specified default value if the array is null or the given index is out of bounds. The magical index -1 with a default value also -1 returns the array size (if not null).


static int SafeArySz(int[] data)
 
Parameters
data The array 
Returns Its length, or =0 if null
A safe (no exceptions) way to get the size of a (possibly null) array.
 

static int SafeCompare(String aStr)

 
Parameters
aStr The first string to compare
xStr The string to compare it to 
Returns A number which compared to 0 is the same as if aStr were compared to xStr
A safe (no exceptions) way to compare two strings.


static int SafeParseInt(String aStr)

 
Parameters
aStr The string to convert to a number 
Returns The number parsed, or 0 if none 
A safe (no exceptions) way to extract an integer number from a string. If the number begins with "0x" then it is assumed to be hexadecimal. Leading white space is ignored, and the first character that is not part of the number ends the scan.


static String SeeHex(String before, int whom, String after)
 
Parameters
before The prefix 
whom The number to be formatted 
after The suffix 
Returns The combined string 
Formats an integer as hexadecimal and returns it with a prefix and suffix. This is useful when printing numbers that you want to see the bits of.


static int SignExtend(int here)
 
Parameters
here The pair
Returns The low half, sign-extended to a full integer 
Extracts and sign-extends the second (low end) of a pair of half-integers.


static int StrLength(String aStr)
 
Parameters
aStr The string to get the length of 
Returns Its length, or 0 if null
A safe (no exceptions) non-OOPS way to get the length of a string. Part of the reason for this is that GameEngine is multi-targeted, and this provides a consistent API for whichever language is being used.


static String Substring(int here, int lxx, String aStr)
 
Parameters
here The (0-base) position to start 
lxx The desired length (the result could be less) 
aStr The string from which to extract that Substring
Returns The Substring
A safe (no exceptions) way to extract a substring. Text past the end is empty.


static int TopBit(int whom)
 
Parameters
whom an integer 
Returns the most significant bit of that number, or =0 if none 
Find the most significant non-zero bit in a 32-bit integer. The least significant bit is easily extracted by (whom&-whom) but there is no similarly trivial way to get the other end.


static void WriteWholeTextFile(String filename, String data)
 
Parameters
filename The name of the text file 
data The text to be written 
A safe way to write a whole text file.


Game Operations

These operations work on the GameEngine data, and generally require a reference to the currently active JavaGame., which is available in GameMaker-built Java files as myGame.
boolean AntsIcon(boolean sho, GameWgt whom)
 
Parameters
sho true to display the ants, false to hide them
whom the group or sprite widget to turn the ants on or off for
Returns true if successful
There are two ways to display marching ants around the edge of a widget. AntsIcon is used for sprites with specially created animated icons (see MkSpriteAnts) that trace around the odd shape of a sprite.

If the group contains a group with ID 'AntI' it is assumed that AntsIcon can do it. Otherwise Antsify traces its boundary rectangle if it is a widget group head.


void Antsify(int why, String aLine)
 
Parameters
sho true to display the ants, false to hide them
whom the group or sprite widget to turn the ants on or off for
There are two ways to display marching ants around the edge of a widget. Antsify is used for group rectangles which can contain the predefined mAntsWgt group as a sub-widget. Each icon in the ants group is good for one vertical or horizontal line of ants, up to 32 pixels tall or up to 256 pixels wide, and they are mostly pre-positioned for all edges except the bottom and right. Antsify adjusts the positions of those two edges and hides (or shows) the rest as needed for the rectangle size.

If the group contains a group with ID 'AntI' it is assumed that AntsIcon can do it.


int ChoseFont(GameWgt whom, int name)
 
Parameters
whom the widget clicked on 
name either a font name (number) or (negative) RefNum
Returns the chosen/converted font name/RefNum
ChoseFont is a multi-purpose font selector.

If you pass it null for a widget, it converts one form of font selection -- such as the negative of an existing font RefNum, or the numeric (ASCII) value of the 1-letter font name -- into the other. The letter names are:

Bold=66, Head=72, Italic=73, Monosp=77, Nano=78, Text=84, tinY=89
If you give it a GameTxLn widget or a radio button group or the text tool or a user text widget on the game board and a negative number, it will return the numeric font name associated with that widget; if you give it the 1-letter name of a font, it will set that radio button or widget to that font.


int ChoseRPS(GameWgt whom, int doit)
 
Parameters
whom the RPS sprite widget
doit either a setting number or (negative) to ask
Returns the current selection number
ChoseRPS is a RPS icon selector that works more or less like ChoseFont.

These values: 0=none, 2=rock, 1=paper, 3=sci, 4=cloud, 7=all (6 shows cloud) in the 2nd parameter doit select that icon to display.

If you give it a RPS sprite widget or the RPS radio button group and a negative number, it will return the number associated with that widget; if you give it a positive number from the above list, it will set that radio button or widget.

If you give it a RPS sprite widget (tool or deployed) and a number greater than 8, the low 3 bits (3 or 4) selects that one layer to set this animation for, and the next bit (+8) makes it one-shot, and the next four bits is the actual number of frames (scissors=2, cloud=6) and the next six bits is the fractional frame rate, frames*16/100ms, then this call starts the animation on that layer (step size is assumed =32). The two animations of interest at this time are:

   i = ChoseRPS(wgt,0x323); // scissors: snip, snip, ~1 sec cycle
   i = ChoseRPS(wgt,0x86C); // exploding wgt cloud, ~1.2 sec total

   i = ChoseRPS(wgt,0x034); // show small cloud frame
   i = ChoseRPS(wgt,0x081); // hide paper, no effect on others..
                            // .. 0x82: rock, 0x83: scissors

   i = ChoseRPS(wgt,0xCC9933); // change cloud color to gray-red (frex)
          // rec'd animation color sequence: FF0, C93, A75, CA8, DDD

If you give it a RPS sprite widget (tool or deployed) and doit=-32 it will return the animation frame numbers of each of the four icons in the four bytes of the return value, low byte is the cloud, high byte is paper (should always be 0). If doit=-31 it returns the cloud color.


void CircleSize(GameWgt whom, int rx)
 
Parameters
whom the widget to update
rx the desired diameter
Given a widget that is either a circle icon or a group over a circle icon, and a preferred diameter, choose the best circle size and update the widget (and its sub-widget, if so) to be that size, with a data array to match the selected size.

CircleSize is the public access to BestCircData, which does the work.


boolean MkSpriteAnts(GameWgt whom, boolean doit)
 
Parameters
whom the sprite widget to create the ants for
doit true to display the created ants, false to hide them
Returns true if successful
There are two ways to display marching ants around the edge of a widget. AntsIcon is used for sprites with specially created animated icons that trace around the odd shape of the sprite. MkSpriteAnts creates those icons.

The first step is to work through all the visible sub-widgets and accumulate their opaque pixels into an array of pixels.

Then the resulting blob of opaque pixels is examined from all sides to find the edges, in a second icon-ready array. This will be the icon data for the white outline [and for now, also the black outline that blinks on and off in lieu of ants].

Then [TBD RSN] the outline is traced and the number of pixels counted, so to divide them into an integral number of 6- to 10-pixel white/black ants (nominally four on then four off).

The outline is then traced again (nominally eight times) to turn off the white segments (the black is overlaid on the solid white outline, so the transparent pixels show white), but advanced one more step each iteration, so when the sequence is animated, the ants appear to march around the composite sprite body. [TBD RSN]


boolean SetInputText(GameWgt whom, String prompt, String data, boolean doit)
 
Parameters
whom the group widget over a pair of GameTxLn widgets
prompt the prompt text, or "" to leave it unchanged
data the predefined input text
doit true to set the predefined input
Returns true if successful
SetInputText is a utility to set up an input macro panel with its prompt and predefined input text. Use GetInputTxt to capture the input text after the user has clicked "OK" or otherwise accepted it.


String GetInputTxt(GameWgt whom)
 
Parameters
whom the group widget over at least a GameTxLn input widget
Returns the text from that widget
GetInputTxt is a utility to capture the input text after the user has clicked "OK" or partial input any time before then. Use SetInputText to set up the input panel with its prompt and predefined input text.


int KnownCircleSz(int whom)
 
Parameters
whom the requested circle diameter, in pixels
Returns the implemented diameter closest to whom
This returns the nearest circle diameter, 0<whom<33.


void LogAlWgts(String why)
 
Parameters
why a prefix string inserted in front of first/each log line
All known widgets are logged to the system console. Short prefixes are repeated every line, longer prefixes are replaced with ".. " after the first line.


void LogWgtTree(GameWgt whom, int deep)
 
Parameters
whom The pixel array
deep Its height
This prints out to the console log an (indented) tree representation of a specified widget with all its sub-widgets. It calls itself recursively with deeper indentations for the sub-widgets.


int ParseInFld(GameWgt whom)
 
Parameters
whom the group widget over at least a GameTxLn input widget
Returns the numeric (integer) value from that widget's text
Calls GetInputTxt to capture the input text, then converts it to a number using SafeParseInt.


int ParsFixPt(String whom)
 
Parameters
whom a string containing a number
Returns the same number as a fixed-point integer, or =0 if fails
A safe (no exceptions) non-OOPS way to convert a text number into a fixed-point value with eights bits to the right of the binary point.


int SafeWgtNum(GameWgt whom)
 
Parameters
whom the widget, or null if none
Returns that widget's RefNum, or =0 if none
A safe (no exceptions) way get the reference number from a (possibly null) widget. If it is null, SafeWgtNum returns zero.


boolean OpenInputDlog(String prompt, String data)
 
Parameters
prompt the prompt text
data the predefined input text
Returns true if successful, false if it failed
Open the Input Dialog (macro) widget with a specified prompt and predefined input text.


void FloatDlogs()

Floats alert & input dialogs to top of sprite list. Called once, either the first time one of these dialogs is opened, or else from your StartUp.


void GameAlert(String msg)
 
Parameters
msg the message text
Open the Alert (macro) widget with a specified message.


int IsDlgEvent(GameWgt whom, int vert, int horz)
 
Parameters
whom The widget that was clicked
vert The vertical offset into this widget where it was clicked
horz The horizontal offset into this widget
Returns 1 if OK, 2 if Cancel, -1 if not Alert or Input, otherwise 0
Determines if this ClickEvt was directed to an open Alert or Input Dialog, and returns 1 if the OK button was clicked, 2 if the Cancel button was clicked, otherwise 0 if the dialog is still open and used this event, or -1 if it's not an Alert or Input Dialog.


void SetSwatchColor(GameWgt whom, int info)
 
Parameters
whom the group widget over a color swatch widget group resembling the one created by that macro
info the color to set it to, 0x00RRGGBB or -1 if none 
One of the features of the GameMaker tool palette is a color swatch representing the designated color of whatever tool or user game widget is currently selected, or else a checkerboard gray if no color is set. SetSwatchColor sets the swatch color to a numeric value, 0x00RRGGBB, or else -1 if none.


int SwatchGetColor(GameWgt whom)
 
Parameters
whom the group widget over a color swatch widget group resembling the one created by that macro
Returns the current swatch color, 0x00RRGGBB or -1 if none 
One of the features of the GameMaker tool palette is a color swatch representing the designated color of whatever tool or user game widget is currently selected, or else a checkerboard gray if no color is set. SwatchGetColor returns the currently visible swatch color as a number, 0x00RRGGBB, or else -1 if none.


String DlgEvData()
 
Returns the most recent text value from the Input Dialog
Gets the current or most recent input text (see OpenInputDlog).


GameWgt FindSubWgt(GameWgt whom, int data, int deep)
 
Parameters
whom the unique string to search for
data the unique value to search for
deep the current search depth, and if greater than 999, a unique logging identifier
Returns the widget found that matches data
A search tool to find uniquely identified widgets based on their Ginfo values or a combination of type and info. The whom parameter is the widget to start this search, and is returned if it matches the criteria. Otherwise FindSubWgt searches its sub-widgets (if any) recursively.

If the search number is larger than 16 bits, and it is equal to Ginfo of the widget, then that widget is returned. Otherwise the upper half of the search number is compared to the low 14 bits of Ginfo, and the lower half of the search number is compared to the type+plus flags for each respective widget. The usual search values are either a 4-char ID value, or else a GameTxLn with specified flags and a particular font #, so to pick out the parameters of a draggable widget or tool.

Null is returned if the specified widget is not found.

The code is not very robust, so sometimes it fails when the sought widget is actually there. It probably needs to be rewritten, but it seems to be good enough for now.


int GameWinSize()
 
Returns The (packed) window size = (height<<16)+width
A safe (no exceptions) way to get the size of the game window.


int GameWinTall()
 
Returns The window height
A safe (no exceptions) way to get the height of the game window.


int GameWinWide()
 
Returns The window width
A safe (no exceptions) way to get the width of the game window.


GameMaker Methods

These are the internal methods used in the GameMakerEv subclass of GameEvent. They are inaccesible to your code, but documented here for completeness.
void CapturCoords(GameWgt whom)
 
Parameters
whom the selected widget 
Whenever you click on the OK button, CapturCoords is called to parse and copy the position and size values to the selected widget group, hopefully not a tool (but the caller should check) because the position of the tool group widget is fixed in its frame.


void CapturInfo2Wgt(GameWgt whom, boolean doit, boolean dont)
 
Parameters
whom the widget clicked on 
doit true to update position and size (not a tool) 
dont true to stop after updating the font 
Whenever you click on the OK button, CapturInfo2Wgt is called to copy the displayed attributes to the selected widget group.


void ChooseBtn(int whom)
 
Parameters
whom the chosen button 1..4 
There are four global response buttons in GameMaker: 1=OK, 2=Undo, 3=Build, and 4="->JS". ChooseBtn exposes one of the four response buttons and hides the others.


boolean CliKnownStuff(GameWgt whom, int vert, int horz)
 
Parameters
whom the widget clicked on 
Returns true if it succeeded 
CliKnownStuff tries to find what widget got clicked among the known widgets it manages, such as a tool or a game widget or a radio button (checkboxes and buttons are handled elsewhere), and does it if so, otherwise returns false.


boolean DoMyButn(GameWgt whom)
 
Parameters
whom the widget clicked on 
Returns true if it did it, false if not one of these 4 buttons 
Where ChooseBtn selects one (or none) of four buttons for the user to click on, DoMyButn does whatever that button is specified to do when the user clicks on it, and returns true if it did it.


String Fit3(int whom)
 
Parameters
whom the number to be formatted
Returns the 3-digit text as formatted
GameMaker sizes and positions are limited to three decimal digits. Fit3 tries to format whatever number you give it into three characters.


void GotEnterKey(GameWgt whom)
 
Parameters
whom The widget that has focus
Returns true if taken (by alert or input dlog)
GotEnterKey is called when the user types the EnterKey, if FocusWgt is not null, or else if DefaultFocus is not null, and that widget accepts keystrokes. This override lets super handle an open alert or input dialog, and if true it acts accordingly. Otherwise it directs the action to whatever OK button is showing, or if none, then if the color swatch is selected, it opens the input dialog to accept a new color, or if a text tool or game widget is selected, it opens the input dialog to accept new text.


void GotEscKey(GameWgt whom)
 
Parameters
whom The widget that has focus
GotEscKey is called when the user types the EscapeKey, if FocusWgt is not null, or else if DefaultFocus is not null, and that widget accepts keystrokes. This override also looks to see if a dialog is open, and closes it.


boolean InvalidJava(String aWord)
 
Parameters
aWord the proposed variable name 
Returns true if it's not valid 
InvalidJava tests if a name is valid Java for a variable name and returns true if not. Reserved words are thus disallowed for widget names in your game code.


boolean IzTool(GameWgt whom)
 
Parameters
whom the widget clicked on
Returns true if it's a tool 
IzTool distinguishes between tools in the tool palette and other things the user might click on in a GameMaker window.


boolean IzUsrWgt(GameWgt whom)
 
Parameters
whom the widget clicked on 
Returns true if it's on the game board 
IzUsrWgt examines a group widget clicked on, and returns true if it's a widget already on the game board.


boolean IzzitMeta(GameWgt whom, int prnt)
 
Parameters
whom the widget being considered for export
prnt the widget's presumed parent
Returns true if it's a meta-widget
When creating an exported widget list, it is important to ignore the "meta-widgets" which carry extra information needed for selection and dragging, but are not part of the user data. IzzitMeta returns true for those widgets that are not part of the user's game.


void LoadUserWgts()

LoadUserWgts takes the import file "GameMaker.txt" (currently in instance variable AddUserWgts) and feeds it one line at a time to NewDragWgt to populate the game board as it was when the file was saved.


void MakeUserJava()

MakeUserJava calls MakeWgtLst to build an exportable widget list, then copies the relevant information to the .java file with the game name. If successful, and if it can also convert the game to JS, it puts up the button to create a JavaScript version of the game.


void MakeUserJS(String whom)
 
Parameters
whom the user name, or none to ask for it
This is a driver to convert the user's (Java) game code into JavaScript and upload it to the game server. This method is called twice, the first time with no user name (it asks you), then again with your reply. The user name should be the same name you created for Chomp. If is not, then your game will not upload. See "Converting Your Game to JavaScript" for what you need to do to make this tricky process work.


boolean MakeWgtLst()
 
Returns true if it failed 
MakeWgtLst builds an exportable widget list in instance variable WgtList and writes it to file "GameMaker.txt", or else returns true to signal failure.


void MoveWgtUpDn(GameWgt whom, boolean uppy)
 
Parameters
whom The widget to be moved
uppy true to move it up in the list
If this widget is a group child, move it up or down in its group's data.


boolean NameIsTaken(String aWord)
 
Parameters
aWord the proposed variable name 
Returns true if it's taken 
NameIsTaken compares a proposed variable name against those already used and returns true if it is taken. It is used with InvalidJava so that widget names in your game code will be consistent and valid Java.


boolean NeedsVelo(GameWgt whom)
 
Parameters
whom the widget clicked on 
Returns true if it's a sprite 
NeedsVelo returns true if the tool or game board widget is a sprite (and therefore needs to have the velocity entry fields shown).


void NewData(boolean doit)
 
Parameters
doit true to force the condition 
NewData is informed when the user has made some change to the game which should be saved, and displays the OK button to do it.


void NewDragWgt(String aLine, int lino)
 
Parameters
aLine one line of import data to convert to game widget
lino its line number
NewDragWgt creates a draggable game widget corresponding to a line from the saved file "GameMaker.txt" and updates its parameters from the attributes on the input line. This is more complicated than just creating a widget from the input line as normally happens at startup, because the items on the GameMaker game board have all the attributes of a tool, so that their meta-info can be displayed when selected.


boolean NewListName(GameWgt whom)
 
Parameters
whom the widget to be added to the list 
Returns true if it succeeded 
When a tool is dragged to the game board, NewListName is called to add its name to the list of user game widgets and then to select it.


int Prescan(GameWgt whom, int bitz, int omit)
 
Parameters
whom the root group widget to export
bitz one bit for each known used font
omit <0 (draggable group head) to search this level but not list
Returns updated bitz
When preparing to export a widget list, it is necessary to pre-scan all candidates to find all fonts that might be in use, and to build a list of exportable widgets so they can be renumbered in the export file. Prescan calls itself recursively from the game list root. The listing is made in instance variable WgtMap, which is used by the caller to build an export file.


boolean SelectMe(int user, GameWgt whom)
 
Parameters
user >0 if it's a user game widget, =0 if a tool
whom the widget clicked on 
Returns true if it's now selected, false if failed 
When the user clicks on a tool or game widget, SelectMe is called to put that widget's information up on the tool panel. It returns false if it is not a tool or game widget.


void ShoCoords(GameWgt whom, boolean all)
 
Parameters
whom the widget being shown 
all true forces display even if no obvious change 
Whenever a tool or user widget is displayed or dragged, ShoCoords is called to put its position and size up on the tool pane.


void ShoInfoFrom(GameWgt whom)
 
Parameters
whom the widget clicked on 
Whenever a tool or user widget is selected, ShoInfoFrom is called to display it attributes.


Others

These are mostly private methods in the JavaGame class, used by the GameEngine but not much value to other programmers. They are described here for completeness.
int AdjuDim(int why, int thar, int norm, int act)
 
Parameters
why a reference number, for diagnostic log
thar the default size in the macro
norm the nominal size, against which to measure the default
act the actual size supplied by the container
Returns the calculated adjusted size = act-(norm-thar)
An internal way to adjust one dimension of a newly created widget from its default (created) size to conform to the user-specified size of its containing widget.

For a nominal size of (frex) 64, if the macro specifies 62, then the returned value is the actual container size reduced by -2 (the difference) unless the macro default is not close to the nominal (like being at the other end of the created widget).


String Ary2Str(int[] whom, int fold, char sep, String before, String after)
 
Parameters
whom The array to turn into a string 
fold The number of items per line, negative if the result should be quoted, or if unfolded then negative is the max length 
sep The character to separate items, (=space if unfolded) 
before The string to put at the front 
after The string to to put at the end 
Returns The resulting string 
A type-safe method to build a string representation of an array of integers. The string is folded into lines after a specified number of items, or else <80 unless sep is less than a space, in which case it is not folded.


int BestCircData(GameWgt whom, int tall, int ins)
 
Parameters
whom the widget to update
tall the desired diameter
ins if >0, the size of a space to center the widget in
Returns the chosen size
Given a widget that is either a circle icon or a group over a circle icon, and a preferred diameter, choose the best circle size and update the widget (and its sub-widget, if so) to be that size, with a Gdata array chosen to match the selected size.

BestCircData is recursive and private, it is expected that clients will call CircleSize and not BestCircData directly.


int BuildThisMacro(GameWgt whom, String aLine, int why)
 
Parameters
whom the parent group widget to build this macro under
aLine the text line containing parameters this macro can use
why an error code base (the highest used in the caller) so that returned error codes (if any) will not collide
Returns an error code > why, or else =0 if no error
Widgets are specified by text returned by the user's override of the GameList method, each widget defined as ten or more integer numbers on a single line, the second number being a type number (plus flags). Type numbers >224 are deemed to be macros, where multiple widgets are created under a single group. BuildThisMacro adds them as sub-widgets to an existing group, whatever the specified macro calls for. For more information see the "Widget Specification Text" documentation.
 


GameWgt CloneWgt(GameWgt whom, int prnt)
 
Parameters
whom a widget to copy
prnt a parent reference number, or 0 to copy it from whom
Returns the copied widget group, or null if it failed
Recursively copy a widget with all its sub-widgets. This recognizes tool widgets as a special case, so that these differences happen:
  (a) the parent is changed to be the Sprite list,
  (b) the top coordinates are globalized,
  (c) an unparented text (tool name) is preserved, and
  (d) the ID info is changed to `**DW`


void Collider(GameWgt whom)
 
Parameters
whom A sprite or list that wants collision testing 
Test for GameWgt collision. Only sprites can move on their own, so they only can collide, but only if collidable ("Bump") and only with objects marked collidable (+256).


String Decapit(String aLine)
 
Parameters
aLine The text to decapitalize 
Returns The decapitalized text 
Safe (no exceptions) decapitalizer.


int EncodeID(String aLine)
 
Parameters
aLine the string to find the code in
Returns the calculated (integer) ID code
An internal way to construct a 32-bit integer representation of a 4-char string ID code. The code is enclosed in reverse-single-quotes `xxxx` in the input line, and if not there or invalid, 0 is returned.


void Every100ms()

This is the timer-driven animation engine. The timer is started by TimerStart and fires ten times per second. This handler is responsible for redrawing the game board (see DrawMe), which also drives any animation.


void ImportGamList(int why, String aLine)

A text list of widgets is retrieved from the user's GameList method, and a complete set of game widgets is constructed from it. For more information on the format of this text list, see the "Widget Specification Text" documentation.


static int GetGameValue(int whom)
 
Parameters
whom A selector, 0..9 
Returns the selected value 
GetGameValue is an access method to get one of the private data items from outside the JavaGame game instance. These are the defined access codes:
0..6: The current widget RefNum for one of the defined fonts (if installed) or else 0.
0: MonoFontNo
1: TextFontNo
2: TinyFontNo ('Y')
3: BoldFontNo
4: ItalFontNo
5: HeadFontNo
6: NanoFontNo
7: LocalVert, the other half of the result after calling LocalizePos
8: MouseVert, the vertical component of the window-relative current mouse position
9: MouseHorz, the horizontal component of the window-relative current mouse position
10: DlogIsOpen, non-zero if the alert or input dialog box is currently open, zero if neither
The mouse position comes from the Java run-time in screen coordinates, which is quickly converted to window-relative before looking to see which widget it hits on. Because GameEngine defines the mouse coordinates as widget-relative, LocalizePos is called to do that conversion. If you need the mouse position relative to the window, you can call AddPrntsPos to convert it back, or you can reach down into the GameEngine to get MouseVert and MouseHorz (but they might have changed).

The font widget numbers are necessary to display a GameTxLn in that font. Usually the font is set up in GameMaker when you choose it from the radio button, but if you want to change the font on the fly, you would need the widget number. Be sure that any font you want is used in your game somewhere when you Build it, or GameMaker will not include it in the widget load.


void InstallMyEvts(GameEvent whom)
 
Parameters
whom A subclass of GameEvent that handles the desired events 
Install user event handler. StartGame, which is called by your main(), uses this to install your event handler. You should not try to change it.


BufferedImage Int2BufImg(int[] pixels, int width, int height)
 
Parameters
pixels The pixel array 
width Its width
height Its height
Returns The BufferedImage result 
Converts a RGB pixel array to BufferedImage used in painting. This is Java magic adapted from example code found on StackExchange.


boolean IzLetter(int whom)
 
Parameters
whom the ASCII code of a character
Returns true if it's a letter or digit
Determines if the ASCII code of a character is a valid letter or digit. Only the original ASCII character set is supported. '_' is a letter.


void JavaMouse(int whom, MouseEvent evt)
 
Parameters
whom activity kind: 0=enter/roll, 1=press/click, 3=up, -1=exit 
evt some kind of Java magic containing the click location 
JavaMouse accepts mouse activity from whatever source, translates the coordinates to window-content-relative, then directs it to MouseDispatch, which then calls your event handlers.


void JstartTimer(int ms)
 
Parameters
why =100, nominally the number of milliseconds
Starts the game timer. See Every100ms.


void KeyDispatch(char xCh, int mods)
 
Parameters
xCh the key code 
mods modifiers (unused, always =0) 
KeyDispatch accepts keystroke activity from whatever source, then directs it to the KeyData event handler, which then calls your event handlers.


@Override public void keyPressed(KeyEvent evt)

Accepts keystrokes to control action, because Java does not do these as keyTyped.


@Override public void keyTyped(KeyEvent evt)

Accepts keystrokes to input text.


@Override public void mouseClicked(MouseEvent evt)

Accepts clicks on the screen image to control operation.


int LocalizePos(GameWgt whom, int vert, int horz)
 
Parameters
whom The widget that was clicked
vert The vertical offset relative to the window
horz The horizontal offset relative to the window
Returns The horizontal offset into this widget
Converts a mouse click position from window-relative coordinates to be relative to the widget clicked in. The calculated horizontal offset is returned directly, the vertical offset is cached in LocalVert for later recovery (see GetGameValue).


static void main()

This main should be called to run JavaGame in GameMaker mode. To run in user game mode, use the main() code in the generated Java file.


String MakeJSwgts(String theText)
 
Parameters
theText the widget list as returned by GameList
Returns the text of an array of numbers for the JS GameEngine
Constructs an array representation of the widget list for JavaScript.


void MouseDispatch(int msg, int vert, int horz)
 
Parameters
msg a number representing what happened to the mouse: =0: rollover/idle, 1: mouse down, 2: drag, 3: mouse up, +4: right-click, +8* gives reason/source for log 
MouseDispatch accepts mouse activity from whatever source, then chooses one or more event handlers to direct it to.


@Override public void mouseEntered(MouseEvent evt)

Accepts clicks on screen image to control operation.


@Override public void mouseExited(MouseEvent evt)

Accepts clicks on screen image to control operation.


@Override public void mousePressed(MouseEvent evt)

Accepts clicks on screen image to control operation.


@Override public void mouseReleased(MouseEvent evt)

Accepts clicks on screen image to control operation.


String NetEncode(String theText)
 
Parameters
theText the raw text
Returns the same text as encoded
Converts the plain-text user name or JS code into a form suitable for upload over the internet. All non-letters are converted to the form %xx where xx is the hexadecimal code for that character.


int[] NewArray(int lxx)
 
Parameters
lxx The length desired 
Returns The array new int[lxx] 
Returns a (language-neutral) new int array of the specified length. This exists because GameEngine is multi-targeted and the syntax is different in Java vs JavaScript.


GameWgt NewGameWgt(int tye, int top, int left, int tall, int wide, int prnt, int color, int info, int[] data, GameWgt whom)
 
Parameters
tye the type of the new widget, or -1 to clone whom
top the vertical component of the top-left corner
left the horizontal component of the top-left corner
tall the vertical height
wide the horizontal width
prnt the parent reference number, or 0 if none
color the widget color, or -1 if none
info the information value
data an array to use for its Gdata, or null if none
whom a widget to copy or update, or null if none
Returns the created widget, or null if it failed
Create a new widget with specified properties, or copy an existing widget, or apply the properties to an existing widget.

The recommended way to make new widgets in a running game is to call NewGameWgt to clone an existing game widget (originally created in GameMaker), then to adjust the properties as needed. Don't forget to add your new widget to its parent's child list, or it will not display [this will become automatic in a future revision].

If the specified type is negative and the given widget is not null, then that widget is mined for the type and all the parameter values given as 0. In particular, a reference to the same data array is used in the copy, unless a non-null data is supplied. So if you want a nullGdata to replace an existing array in whom, or an actual value 0 for Gcolor or Parent when the original is non-zero, you need to fix it after the new widget is returned.

If the type (without flags) is greater than 7, then the only way to create a widget of that type is to create it yourself, then (optionally) call NewGameWgt to populate the base class instance variables in it.


GameMakerEv NewMaker()
 
Returns the new GameMakerEv instance 
NewMaker is an access function to create a new GameMakerEv instance when JavaGame is started from its own main().


@Override public void paint(Graphics graf)

All the heavy lifting happens here. Called on timer activation.


boolean SpritePause()
 
Returns true to pause
SpritePause is called by sprite widgets to see if they should pause their motion (like when an alert or input dialog is open).


void StartGame(int tall, int wide, int color, String title, GameEvent evh)
 
Parameters
tall the window height 
wide the window width 
color the window background color
title the window title
evh the GameEvent subclass instance 
StartGame is called from either the user game's main() or else from JavaGame's main(), in either case with the desired window title, size, and base color, plus an instance of the GameEvent subclass that will be implementing the game (or GameMaker) logic. StartGame creates the specified window, builds all the widgets, calls the user StartUp method, then begins processing timer (and mouse and keyboard) events.


int ServerUpload(String whom, String data)
 
Parameters
whom the user name and password as name_password
data the JS program as translated by toJS()
Returns an error code, or =0 if none
Uploads a particular user's (JS) game code to a game server.


int[] Str2intAry(int why, String aLine)
 
Parameters
why A reference number (for the log, if needed), who called it 
aLine The string to parse 
Returns The resulting array 
A type-safe method to extract an array of integers from a string source text. Java Script is untyped, but this only makes int[] arrays.


boolean toJS(String theText, String fiName)
 
Parameters
theText the Java code
fiName the game name, should = the class name
Returns true if successful
Converts the Java code of your game into JavaScript and stores the result in class variable JSinfo, and also writes to fiName.js if successful. If there's an error, the error description is stored in class variable JSinfo (length less than 99).


void TimerStart(int why)
 
Parameters
why The initial timer count, >0 when animating 
Start the animation timer. See Every100ms.


void Widen1stWgt(GameWgt whom, int plus)
 
Parameters
whom the parent group widget to look under
plus how to adjust its size
Widgets specified by macro do not always get their dimensions adjusted properly by AdjuDim. This is one of several ad-hoc fixups.

The caller gives a negative number to adjust the child widget width down from its parent, then this is added to the group widget size to give a smaller (positive) number to set the size of the child widget.


String toString()
 
Returns The reference String for this widget 
Return the class name and RefNum for this widget, plus its ID code if any.


@Override public void windowClosing(WindowEvent evt)

Accepts window-about-to-close notification. (Not known to work)


Unfinished "Features" (Rev. 21/5/22)

The joke among software developers is "If you have a bug that isn't going to be fixed, promote it and call it a "feature." Not just software: a few years ago garment manufacturers figured out that burning a label onto the fabric with a laser is cheaper than sewing a cloth label on; the laser burn weakens the fabric so it wears out faster -- there, where the label was -- but they now promote it "tagless(R)" as if it were better. It's not. Here below are problems, most of which will be fixed in future versions because they are not better:

GameEngine does not support the full range of UniCode characters, only the ASCII subset (' '..'~').

In this alpha release there are seven widget tools in the tool palette. I expect to add a scrollbar widget for building objects larger than the available window space; a full-featured sprite widget, complete with a pixel editor probably won't happen this year.

The only way to delete an unwanted widget is to drag it off the top or bottom of the game board (onto the gray background, where it will disappear) and then it will not show up in the Build, so when you reload (next time you start GameEngine) it will be gone. If you change your mind (before you quit), you can select the widget name in the list, then type in coordinates that are on the game board and click OK, and it will come back.

When typing stuff into a text field, there is no way to select a range to delete them, the work-around is to click to the right of what you want deleted, then back up over it, one character at a time. If you click or back up to the left edge the cursor may disappear; it's still there, but not drawn.

The tab key should advance to next entry field, but it doesn't yet. It doesn't know about the "forward delete" key, so you may get strange results. Too many things to fix in not enough time.

(More TBD)
 

Known Bugs

I noticed that the alert message box sometimes does not respond to mouse clicks in its OK box, but usually it still will respond to the Enter key from your keyboard. If all else fails, quit and restart GameEngine.

When you are modifying the properties of a widget, you can usually go from item to item in the entry panel entering new values, then click the OK button once to accept all those changes. However if you do anything that opens a dialog box, your changes may be lost. I recommend you "Save early, save often" to prevent losing your work.

Double-clicking a widget on the game board (or the board itself) jumps that widget so the top-left corner is where you clicked. This is a bug, to be fixed as soon as possible. Work-around: you get to reset the coordinates of your text widgets after changing the text. Don't 2-click the other widgets.

If you drag a widget from the tool panel, but off the game board, the OK button may stop appearing. Work-around: quit and restart GameMaker. It will revert to the last time you clicked OK.

If you want to discard your current game and you click on the Start Over button (and confirm it), it seems to get into an unstable state until you also click the OK button (and maybe also Quit and restart the GameEngine). Dunno yet what the problem is.

When you have more than 15 or 16 widgets, a scrollbar appears in the widget list. Mostly it works OK, but I have not yet connected the mouse scrollwheel to it. Also, it overlaps the widget list slightly, so if you click too near the left edge , GameMaker might think you meant to click the widget there.

So many bugs, so little time.

Rev. 2023 February 2