HowTo for Developers
< Start
Create a new class
Every class must comply to certain rules, so we can verify that the code works as expected. When creating a new class this means:
- Adding an annotation @ClassCategory describing the category the class falls into
- Any collection type (List, Set, Map, Multimap) and any other generic typed member field must be annotated to indicate the types containing (the type information is not available at runtime)
- We have tests to check that the saved objects can properly be restored. For this to work these annotations are required.
Mapping on rendered images
There are three use cases for mapping areas in a rendered image:
- The image was newly rendered and the existing mappings must be adjusted
- Add a new mapped area in an existing image
- The rendering is new
The first and the last case are very similar. Only in the first case the entries already exist and have to be replaced. All the mapping in the game (not the startup) are defined in mainScreen.xml. For each rendering there is a image section. within this section each area is defined with a polygon. The polygon has a speaking name identifying the part of the image in a unique way. A z-index can also be specified. This index specifies the back to front order. This allows simpler definitions of shapes if another shape is in the forefront. A high index indicates the object to be in the back. An area is defined by a number of points.
<!-- Properties for the images -->
<images>
<image name="portScene.png" crop="BOTTOM" maxCrop="920" type="o">
<!-- coordinates of the polygon in the unmodified image -->
<polygons>
<polygon name="LoadingCrane" z-index="1">
<point x="558" y="755"/>
<point x="558" y="628"/>
<point x="591" y="583"/>
<point x="610" y="494"/>
<point x="762" y="500"/>
<point x="760" y="538"/>
<point x="720" y="634"/>
<point x="716" y="755"/>
</polygon>
...
</polygons>
</image>
...
</images>
To figure out the coordinates open the image in painting application like Gimp. Move the cursor to a location that defines a corner of the shape and note the location within the image. Repeat this until you have all the points making up the shape. The coordinates reference points in the image with the original resolution. In the game the image will probably be scaled. The same scaling will be applied to the coordinates.
Image optimisation
As there might be different resolutions there are three ways the image is prepared before it is displayed:
- If it is to large and part of it can be cut away to get a better match that is done as a first step
- Proportional scaling
- Adding black borders
For the first step to work additional data must be specified in the image tag. The optional crop attribute defines where the image can be croped (TOP, RIGHT, LEFT, BOTTOM). The cropMax attribute then defines the maximal amount that can be cut away.
Add a new scene
- Create an entry in mainScreen.xml to define the image that is used in the scene. Define at least one polygon to get back to the previous scene
- Add a polygon in the previous scene to navigate to the new scene
- Create an event handler for the scene extending ScenePolygonInitialzer. It must have a default constructor, using the scene image name to call the super constructor and be declared as Component
- For each polygon defined in for the scene add a case in the createEventHandler method. The case is the name of the polygon.
- Create a new enumeration entry for the scene in EScene
- Add the event handler initializer in PolygonInitializerFactory and add a case for the new scene in getScenePolygonInitializer
- In MainGameView.getImageNameFromScene add the case for the image name
- Add a new enumation entry in EViewChangeEvent
- Implement the handling of the switch to the new scene.
- Implement the interface ch.sahits.game.graphic.javafx.display.ISceneEventHandler for the scene
- In SceneEventHandlerFactory wire and initialize the implemented interface. Add the initialisation in setUpDialogController(..) and the case in getSceneEventHandler().
All these steps are staigt forward when starting at the definition of the scene in the mainScreen.xml and implementing the switch to the new scene. Starting the application now will gradualy pop up exceptions pointing to the next step to be implemented.
Add new dialog
- Create a new implementation of the dialog as a subclass of Dialog or probably more appropriatly CloseButtonDialog
- The dialog must be annotated as @Protype bean and have a @PostConstruct initialisation method named initializeDialog. In this method goes the setup of the dialog. It is suggested to create the content of the dialog as DecoratedText through the DecoratedTextFactory.
- If the closing of the dialog should update the noticeboard the executeOnCloseButtonClicked must be overridden
- Create a Main class for the dialog in the test directory tree for the testing of the dialog outside the whole application. This main class extends DialogTestApplicationContainer.
- The method getDialog contains the setup with suppling all the data and services for the dialog.
- The method startupFakeApplication should have an empty implementation.
- In the getDialog method the starupFakeApplication method must be called before the dialog is instantiated.
- Implement a test class extending the Main class.
- The test class implements the startupFakeApplication by calling FakeApplicationStartup.startupFakeApplication()
- Test actions and dialog navigation
- In DialogFactory add a case for retrieving the dialog bean
- Where the dialog should be opened call the dialogContoller to replace the dialog.