VgaGames 3 - Tutorial 4

[.. upper level ..]

Tutorial 4

For simple games like the ping-pong game the former manner of programming games may be ok.
Complexer games with a lot of objects should be more clearly arranged by separating these objects with their attributes from the main code.
Using C++ could be an option, but VgaGames also supports separating objects for the C-language using VgaGames3-objects.

VgaGames3-objects are contained in the structure struct vg3_ofunc which is created by the function ofunc_new() and destroyed by the function VG3_ofunc_free().

Files for VgaGames3-objects

A VgaGames3-object is of type struct vg3_ofunc_object and should be defined in a separate C-file.
The corresponding H-file defines a private structure for this object containing variables it needs.
Each VgaGames3-object must have an individual object-ID, an unique arbitrary string.

In the C-file several functions must be defined, at least a construction function (f_new()), a destroying function (f_free()), and normally a running function (f_run()) and a drawing function (f_draw()).
These functions must be declared according to struct vg3_ofunc_objfunc and will be retrieved by other objects or the main program with VG3_ofunc_get_objfunc().

An example for a VgaGames3-object in this tutorial are the files obj-player.h and obj-player.c.

The proceedings are always the same for each object-file:
  1. in the construction function (f_new())
    - allocate and fill the private structure
    - allocate and fill the VgaGames3-object structure (struct vg3_ofunc_object) and set the private structure into it
    - insert this object-instance into the list of object-instances with VG3_ofunc_objlist_insert()
    - insert this object-instance with its position and size into the global collision-quadtree with VG3_coll_q_insert()
    - return the object-instance
  2. in the destroying function (f_free())
    - remove the object-instance from the global collision-quadtree with VG3_coll_q_remove()
    - remove the object-instance from the list of object-instances with VG3_ofunc_objlist_remove()
    - clean up the private structure and free it
    - free the VgaGames3-object structure
  3. in the optional running function (f_run())
    - remove the object-instance from the global collision-quadtree with VG3_coll_q_remove()
    - move the object-instance and check for collisions, e.g. using VG3_coll_q_find() or using the more complex but comfortable function VG3_move_object_check_collision()
    - insert the object-instance with its new position and size into the global collision-quadtree again with VG3_coll_q_insert()
  4. in the optional drawing function (f_draw())
    - draw the object-instance onto the window with VG3_image_copy()
  5. the optional function (f_data())
    - is used to modify or return data of the object-instance
There can be more functions which have to be defined in a individual structure (void *vpriv)
contained in the structure struct vg3_ofunc_objfunc.

The functions f_new() and f_data() and the functions in the individual structure void *vpriv have to be called manually.
The function f_free() is being called with VG3_ofunc_objlist_call_free() from the main program.
The function f_run() is being called with VG3_ofunc_objlist_call_run() from the main program.
The function f_draw() is being called with VG3_ofunc_objlist_call_draw() from the main program.

Now we know how to instantiate, run, draw and destroy an instance of an object using VgaGames3-objects.
We also know how to retrieve functions from an object by another object or the main program.

But how do we process the interaction of the objects?
Do we have to include all possible collisions with other objects into f_run() when moving and checking for collision?
We need another sort of files, which contain the interaction of two objects, mainly the collision.
This we will do with object-to-object-functions for VgaGames3-objects.

Files for object-to-object-functions for two VgaGames3-objects

Two VgaGames3-objects interact in a separate C-file which contains object-to-object-functions for the two VgaGames3-objects.
This C-file includes the H-files of both VgaGames3-objects to have access to their private structures.
Object-to-object-functions for the two VgaGames3-objects are defined in the structure struct vg3_ofunc_objobjfunc.

In the C-file two functions may be defined, the collision function (f_collision()) and a quit function (f_quit()), which informs the parent which child object is being destroyed.
These functions must be declared according to struct vg3_ofunc_objobjfunc and will be retrieved by other objects or the main program with VG3_ofunc_get_objobjfunc().

An example for a object-to-object functions in this tutorial is the file objobj-player-ball.c.

The proceedings are always the same for each object-to-object function file:
  1. in the function (f_collision())
    - determine which of both passed VgaGames3-objects is which object
    - according to moving object (first passed object) and hit object (second passed object) and hit-side do actions
    - if the hit object is being destroyed call its f_free() function
    - return one of VGAG3_COLL_RETURNS
  2. in the optional function (f_quit())
    - determine which of both passed VgaGames3-objects is which object
    - do actions
The function f_collision() may be called manually, but is normally called in the function VG3_move_object_check_collision().
It should return how to go on:
- VGAG3_COLL_RETURN_NOOP: no collision, go on
- VGAG3_COLL_RETURN_HIT: moving object has been hit
- VGAG3_COLL_RETURN_DEAD: moving object has been hit and freed
- VGAG3_COLL_RETURN_HALFSTOP: moving object has been stopped in x- or y-direction
- VGAG3_COLL_RETURN_FULLSTOP: moving object has been stopped totally
- VGAG3_COLL_RETURN_CONTINUE: collision, but go on with new calculation of direction

The function f_quit() must be called manually by the child object, which calls f_quit() of the parent object.

The tutorial ping-pong game - a complete rewrite

In step 1 we create the main-program.
In step 2 we create the object files.
In step 3 we create the object-to-object function files, i.e. the files for interaction of the objects.

<<Prev Top Next>>