Qbasicnews.com

Full Version: Help with and array of classes for use with a game
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I want to make a game that deals with a lot of things on the screen like bubbles and fish, using classes. I know how to use classes by themselves (mostly), but I'm not sure what would be the best technique for a game that I would want to have an array of things on the screen (bubbles, fish, etc). When an object leaves the field of view I want it to be deleted and move all the objects following it up one slot. I guess that would work, but is there a better way? Also, could somebody show me the best way to set up and array of objects derived from a single class?
Well, in my miniscule programming experience, when A bubble hits the top of the screen, I put it in a new spot, preferable somewhere at the bottom of the screen.

BTW, you ever do that platformer game?
Quote:I want to make a game that deals with a lot of things on the screen like bubbles and fish, using classes. I know how to use classes by themselves (mostly), but I'm not sure what would be the best technique for a game that I would want to have an array of things on the screen (bubbles, fish, etc). When an object leaves the field of view I want it to be deleted and move all the objects following it up one slot. I guess that would work, but is there a better way? Also, could somebody show me the best way to set up and array of objects derived from a single class?

Are you planning on having a fixed number of objects? If so, array is prolly your speediest bet. Object arrays are declared the same as normal, but you must have a default constructor that takes no arguments so the objects can be created when the array is defined.

por ejemplo:
Code:
class Peach
{
   public:
      Peach() { juiciness = 99; }
      ~Peach() {}
   private:
      int juiciness;
};
.........

and to declare a Peach array..
Code:
Peach myPeaches[10];

or to declare that juicy fruit on the free store..
Code:
Peach *myPeaches = new Peach[10];

Either way, each array element will hold a Peach, each with a juiciness = 99. AFAIK, there's no way to pass constructor parameters when declaring arrays of objects.
okay, I'll try to whip something up.

toonski:
I made the level editor for the platform type game, but I didn't think it out, and I'll have to remake a lot of it. I'm going to make this bubble game as it needs way less graphics and development time. I'll make the platformer ped xing game when I finish this one.
I think that make an array of objects is bad idea. This restrict a lot the objects (they must have an constructor that takes no parameters). Without count the overhead of copying objects. Also for this approach you must overload the = operator, the copy constructor and so on.

My personal opinion is that you make an array of pointers to objects.

You can use the "list", "vector" of STL. Warning the disvantage of this is you must take care of allocation and deallocation of objects.
so if I use the pointer example piptol gave:
Quote:Peach *myPeaches = new Peach[10];
It would work the same way. But why would I use vector and list from STL (or maybe I don't know what that means)?
What you with

Quote:Peach *myPeaches = new Peach[10];

is to create an array of objects.

What i say is to create an array of pointer to objects

Quote:typedef Peach* ptrPeach;
ptrPeach myArrayOfPeaches[10];
int i;

// to allocate ten Peach
for(i=0;i<10;i++)
myArrayOfPeaches[i] = new Peach();

// to do something with each Peach
for(i=0;i<10;i++)
myArrayOfPeaches[i]->doSomething();

// to free ten Peach
for(i=0;i<10;i++)
delete myArrayOfPeaches[i];

Using stl it may look like

Quote:typedef Peach* ptrPeach;
vector<ptrPeach> myArrayOfPeaches;
vector<ptrPeach>::iterator myIterator;
int i;

// to allocate ten Peach
for(i=0;i<10;i++)
myArrayOfPeaches.push_back(new Peach());

// to do something with each Peach
myIterator=myArrayOfPeaches.begin();
while(myIterator!=myArrayOfPeaches.end())
(*myIterator++)->doSomething();

// to free all Peaches
myIterator=myArrayOfPeaches.back();
while(!myArrayOfPeaches.empty())
{
delete myArrayOfPeaches.back();
myArrayOfPeaches.pop_back();
}

Look at this page for more info on STL.
http://www.sgi.com/tech/stl/
Quote:I want to make a game that deals with a lot of things on the screen like bubbles and fish, using classes. I know how to use classes by themselves (mostly), but I'm not sure what would be the best technique for a game that I would want to have an array of things on the screen (bubbles, fish, etc). When an object leaves the field of view I want it to be deleted and move all the objects following it up one slot. I guess that would work, but is there a better way? Also, could somebody show me the best way to set up and array of objects derived from a single class?


Typesoft. I don't know what language you are using...I assume C++? Anyway, if you want to do this in QB, here is an example from the "25 line graphics demo" challenge.
Code:
'This is my starfield entry hacked down to 25 lines
'It needs a pretty fast computer...looks OK on my 1.5 GHz
'JKC 2003

1 TYPE star
  x AS INTEGER
  y AS INTEGER
  z AS INTEGER
  END TYPE
6 DIM astar(0 TO 300) AS star
7 DIM oldstar(0 TO 300) AS star
8 FOR i = 0 TO 300
9  astar(i).x = RND * 640
10  astar(i).y = RND * 480
11  astar(i).z = RND * 300
12 NEXT i
13 SCREEN 11
14 DO
15 FOR i = 0 TO 300
16   IF astar(i).z < 1 THEN astar(i).z = 300 ELSE astar(i).z = astar(i).z - 1
17   FOR p% = 0 TO oldstar(i).z
18     CIRCLE (oldstar(i).x, oldstar(i).y), p%, 0
19     IF astar(i).z <> 300 THEN CIRCLE (INT(2 * astar(i).z + astar(i).x / (1 + astar(i).z / 30)), INT(astar(i).z + astar(i).y / (1 + astar(i).z / 30))), p%
20   NEXT p%
21   oldstar(i).x = INT(2 * astar(i).z + astar(i).x / (1 + astar(i).z / 30))
22   oldstar(i).y = INT(astar(i).z + astar(i).y / (1 + astar(i).z / 30))
23   oldstar(i).z = 5 / (1 + astar(i).z / 20)
24 NEXT i
25 LOOP UNTIL INKEY$ <> ""

it may be a hard to follow...I'll try to clear it up a little.


lines 1-12 create "star" and "oldstar" objects and give them x, y, z values.
line 14/25 main loop
line 15/24 loops through each object
line 16 if z is "near" (0) then z = "far" (300) else z gets nearer by one
line 17-20 erase then draw an object as a series of concentric circles
lines 21-23 keep track of old objects so they can be erased

note that if this hadn't been a limited line challenge, then on line 18.5 each parameter of the circle would be assigned to a variable (eg xpos, ypos, rad) then used in the circle statement, and in lines 21-23.
Use interfaces. In JAVA this is done quite simple, and as JAVA comes from C++, I think this could be done.

You have a set of different classes that implement the interface, but differently. If the interface defines a constructor, a "move" method and a "die" method, for example, all the classes that implement such interface will have their own implementation of constructor, move and die, so they can act differently.

In java (sorry, I don't know that weird C++ syntax) it is done somewhat like:

Code:
public interface GameObject
{
   public void move(int parameter);
   public void die(int parameter);
}

public class Ship implements GameObject
{
   public Ship(...)
   {
      // constructor
   }

   public void move(int parameter)
   {
      // actual implementation of a ship moving
   }

   public void die(int parameter)
   {
      // actual implementation of a ship dying
   }
}

public class Meteoroid implements GameObject
{
   public Meteoroid(...)
   {
      // constructor
   }

   public void move(int parameter)
   {
      // actual implementation of a meteoroid moving
   }

   public void die(int parameter)
   {
      // actual implementation of a meteoroid dying
   }
}

...

public class game
{
   public static void main(String args[])
   {
      // This way we define an array of general game objects:
      GameObject objects = new GameObject[10];

      // Now every member of "objects" array can be defined as
      // a concrete class which implements the "GameObject"
      // interface:

      objects[7] = new Ship(...);
      objects[2] = new Meteoroid();

      ...

      // As they all implement the same interface, you can make
      // the same operations for everyone, so, for example, to
      // make everything move one frame...

      // (we are now inside the game loop)

      ...

      for(int i=0; i<objects.length; i++)
         objects[i].move(...);

   }
}

As you see, this is the best approach (IMHO). If you can find the way to port this to C++ (it may be just a matter of different syntax), you're done Big Grin

PS: Java rocks. Someone write a native compiler!
I am now trying to make a class that'll handle some of the gfx calls using C++ and Allegro. I want to have a class sub that'll load a bitmap and return a pointer to a BITMAP struct. For some reason this doesn't work. Anyone know why?
Code:
class cGfx
{
    public:
        int ResX, ResY;
        BITMAP* load_bmp(BITMAP *buff, char *file);
        void drawtile(BITMAP *to_buff, BITMAP *from_buff, int tile, int x, int y, int wx, int wy);        
}

BITMAP* cGfx::load_bmp(BITMAP *buff, char *file)
{
    buff = load_bitmap(file, NULL);
    if (!buff) {
        set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
        allegro_message("Error reading bitmap file '%s'\n", file);
        return NULL;
    }
    return buff;
}
also, here is my attempt at a class that hanldes FPS:
Code:
class cFPS
{
    public:
        cFPS();
        void second_counter(void);
        void ticker(void);
        void wait_fps(void);
    
    private:    
        volatile unsigned int frames, fps, ticks;        
};

cFPS::cFPS()
{
    LOCK_FUNCTION(second_counter); LOCK_VARIABLE(fps);
    LOCK_VARIABLE(frames); LOCK_FUNCTION(ticker);
    LOCK_VARIABLE(ticks);
    install_int_ex(second_counter, BPS_TO_TIMER(1));
    install_int_ex(ticker, BPS_TO_TIMER(400));
}

void cFPS::second_counter(void)
{
    fps=frames; frames=0;
} END_OF_FUNCTION(second_counter);

void cFPS::ticker(void)
{
    ++ticks;
} END_OF_FUNCTION(ticker);

void cFPS::wait_fps(void)
{
    while (ticks < 1 && !key[KEY_ESC]) yield_timeslice();
    ticks = 0; ++frames;
}
But when I try to compile that, I get:
Quote:c:\bubble\bubble_main.h(150) : error C2664: 'install_int_ex' : cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void)'
None of the functions with this name in scope match the target type
c:\bubble\bubble_main.h(151) : error C2664: 'install_int_ex' : cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void)'
None of the functions with this name in scope match the target type
My functions for FPS worked fine before I tried to put them in a class, so I have no idea.
Pages: 1 2