Trying to make a simple 2D game on sprites
Look my approach, I will appreciate your advices to make it any way better
First:
I have made Objects and Render_Objects classes. Objects are certainly organized tree, Render_Objects - just a sequence (line). One or few Render_Objects can be assigned to an Object. When Object is moved to another branch, left and right Render_Objects pointers get attached to new points.
Here is my RENDER.H:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
#ifndef KRENDER_H_INCLUDED
#define KRENDER_H_INCLUDED
#include <gl/gl.h>
namespace klib {
enum render_sort {
RENDER_SCREEN_COLOR,
RENDER_SPRITE
};
class render_t {
render_t * prev;
render_t * next;
int data_int_1, data_int_2, data_int_3;
float data_float_1, data_float_2, data_float_3, data_float_4, data_float_5, data_float_6, data_float_7, data_float_8;
friend class CreateObject;
public:
//Screen color
render_t(int data_int_1, float data_float_1, float data_float_2, float data_float_3);
//Sprite
render_t(render_t * prev,
int data_int_1, int data_int_2, int data_int_3,
float data_float_1, float data_float_2, float data_float_3, float data_float_4, float data_float_5, float data_float_6, float data_float_7, float data_float_8);
void proc();
};
}
#endif // KRENDER_H_INCLUDED
|
These are 2 sorts of Render_Object: Screen Color (just fills a screen with color) and Sprite.
I use only few int and float variables, common for all the sorts of Render_Object. There will be more sorts in future, but I don't think, the count will be much different.
RENDER_T::PROC() is such a function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
void render_t::proc() {
switch (data_int_1) {
case RENDER_SCREEN_COLOR:
glFlush();
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(data_float_1, data_float_2, data_float_3, 1.0f);
break;
case RENDER_SPRITE:
glLoadIdentity();
glTranslatef(data_float_1, data_float_2, 0.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, data_int_2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, data_int_3);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, data_int_3);
glBegin(GL_POLYGON);
glTexCoord2f(data_float_5, data_float_6);
glVertex2f(0, 0);
glTexCoord2f(data_float_5, data_float_8);
glVertex2f(0, data_float_4);
glTexCoord2f(data_float_7, data_float_8);
glVertex2f(data_float_3, data_float_4);
glTexCoord2f(data_float_7, data_float_6);
glVertex2f(data_float_3, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
break;
//will be more
}
if (next != 0)
next->proc();
}
|
So I use SWITCH here, as you see. Is it ok?
When I did that, I thought, there isn't going to be very many sorts of Render_Object, so switch isn't gonna be large.
(If you look at what I did for Object later, it's completely opposite)
! Screen Color is must have Render_Object. It always exist along with Background Object, so I never check if previous object exist when destroy one.
Here is my OBJECT.H:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
#ifndef KOBJECT_H_INCLUDED
#define KOBJECT_H_INCLUDED
#include "krender.h"
namespace klib {
enum object_sort {
OBJECT_BACKGROUND,
OBJECT_CURSOR,
};
class object_t {
object_t * prev;
object_t * next;
int data_int_1;
float data_float_1, data_float_2, data_float_3;
render_t * render;
friend struct CreateObject;
public:
void proc();
};
struct CreateObject {
static object_t * Background(float r, float g, float b);
static object_t * Cursor();
};
}
#endif // KOBJECT_H_INCLUDED
|
There will be more Object types (sorts) for sure as it will progress
As I think, this is gonna be UNIVERSAL class for any object. Then 1 integer variable determines type (sort) of the Object, and depending on this integer different functions are called upon WORLD_REFRESH_FUNCTION. (Basically, I have an array of such functions)
Unlike Render_Objects created with constructor (as they are all simple), Objects are created with functions of special CreateObject class.
So, if we need to create an object of type BBB, we write CreateObject::BBB(different arguments).
Here is how OBJECT.CPP is written now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#include "kobject.h"
#include "kprog.h"
using namespace klib;
///Create functions
object_t * CreateObject::Background(float r, float g, float b) {
object_t * object = new object_t;
object->prev = 0;
object->next = prog::getObjectList();
prog::setObjectList(object);
object->data_int_1 = OBJECT_BACKGROUND;
object->data_float_1 = r;
object->data_float_2 = g;
object->data_float_3 = b;
object->render = new render_t(RENDER_SCREEN_COLOR, r, g, b);
object->render->prev = 0;
object->render->next = prog::getRenderList();
prog::setRenderList(object->render);
return object;
}
object_t * CreateObject::Cursor() {
object_t * object = new object_t;
object->data_int_1 = OBJECT_CURSOR;
//MISSING CODE
return object;
}
///Refresh functions
void OBJECT_BACKGROUND_FUNC(object_t * object) {
//MISSING CODE
}
void OBJECT_CURSOR_FUNC(object_t * object) {
//MISSING CODE
}
void (* const OBJECT_FUNC[])(object_t * object) = {&OBJECT_BACKGROUND_FUNC,
&OBJECT_CURSOR_FUNC};
///Object
void object_t::proc() {
OBJECT_FUNC[data_int_1](this);
if (next != 0)
next->proc();
}
|
What you think?
Probably, can be done much better?