![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#21 |
|
Programming Guru
![]() |
Hehe. This thread gave me a good laugh. Funny guys.
Or maybe I'm just high on chocolate and alcohol. Oh well, either way. I laugh . . . ![]() |
|
|
|
|
|
#22 |
|
I eat cake for breakfast.
![]() ![]() ![]() ![]() Join Date: Jul 2004
Location: In my box.
Posts: 4,434
Rep Power: 9
![]() |
I find it funny because usually level editors are designed for their games. A level editor with nothing else is kinda useless in every sense of the word.
![]() Also, I'm hyper. |
|
|
|
|
|
#23 | |
|
Programmer
|
Quote:
-thondal-
__________________
"die" he screamed at the polygon man. When he was done with him, only four points remained, a quad of what he once was. |
|
|
|
|
|
|
#24 |
|
Professional Programmer
Join Date: Jan 2006
Location: Ontario, Canada
Posts: 376
Rep Power: 0
![]() |
Frankish, if you would give us the source we might be able to actually do something with it. You are not going to be able to sell it, and right now you can't use it for anything, so what is the point of not giving the source?
__________________
I am Addicted to Linux! |
|
|
|
|
|
#25 | |
|
I eat cake for breakfast.
![]() ![]() ![]() ![]() Join Date: Jul 2004
Location: In my box.
Posts: 4,434
Rep Power: 9
![]() |
Quote:
![]() |
|
|
|
|
|
|
#26 |
|
Hobbyist Programmer
Join Date: Oct 2005
Location: Ohio
Posts: 177
Rep Power: 0
![]() |
Ok, 0k, I'll give you the source. But obviously you guys have never dealt with isometric games.
/*
Level Editor
by Francois S. Lamini
Copyright (c) 2006 Francois S. Lamini
26/6/2006: set up allegro system, declared some variables, etc.
28/6/2006: finished up the level editor, no testing has been done on it yet
29/6/2006: added code to change sprite property value (that was missing), changed level file
format a bit
2/7/2006: some file reading problems, added flags to prevent key repeats, the level editor
is fully tested and ready for use
3/7/2006: added music track support
*/
#include <allegro.h>
#include <cstdio>
#include <cstring>
#include <cctype>
#define BACKGROUND_OBJECT 1
#define MIDDLE_OBJECT 2
#define FOREGROUND_OBJECT 3
#define MAX_OBJECT_CATALOG_SIZE 1000
#define MAX_OBJECT_LIST_SIZE 3000
#define MAX_BACKGROUND_COLORS 100
#define MAX_MUSIC_TRACKS 50
using namespace std;
struct Object_Info
{
char name[30+1];
char properties[10][30+1];
int type;
int bitmap;
int number_of_properties;
int initial_property_values[10];
};
struct Object
{
Object_Info* object_info_ptr;
int property_values[10];
int x;
int y;
};
int object_catalog_size = 0;
int object_list_size = 0;
int number_of_background_colors = 0;
int number_of_music_tracks = 0;
int error = 0; // indicates if an error has occurred
int level_x = 0;
int level_y = 0;
int selected_background_color = 0;
int selected_music_track = 0;
volatile int tick_count = 0;
char level_file_name[30+1];
int* background_color_ptr;
BITMAP** bitmap_dptr;
BITMAP* canvas_ptr;
Object_Info* object_catalog_ptr;
Object* object_list_ptr;
MIDI** music_track_dptr;
void Load_Level();
void Save_Level();
void Load_Object_Catalog(char* object_catalog_file_name_ptr);
void Load_Background_Colors(char* color_file_name_ptr);
void Load_Music_Tracks(char* music_tracks_file_name_ptr);
void Tick_Handler();
void Chomp_Line(char* line_ptr);
int Is_System_Ok();
int Is_Point_In_Object(Object* object_ptr, int x, int y);
int main()
{
char color_file_name[30+1];
char catalog_file_name[30+1];
char music_tracks_file_name[30+1];
printf("color file=? ");
gets(color_file_name);
printf("music tracks file=? ");
gets(music_tracks_file_name);
printf("object catalog file=? ");
gets(catalog_file_name);
printf("level file=? ");
gets(level_file_name);
allegro_init();
if (Is_System_Ok())
{
int done = 0;
int bitmap = 0;
int cursor_x = 0;
int cursor_y = 0;
int work_layer = 1; // the layer that the user is working on
int selected_object = -1; // means that no object was selected
int selected_object_type = 0;
int selected_property = 0;
int key_pressed = 0; // flag to prevent key repeat
int key_timer = 0;
int track = 0;
set_color_depth(desktop_color_depth());
set_gfx_mode(GFX_AUTODETECT, 800, 600, 0, 0);
install_keyboard();
install_timer();
install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL);
LOCK_VARIABLE(tick_count);
LOCK_FUNCTION(Tick_Handler);
install_int(Tick_Handler, 15);
canvas_ptr = create_bitmap(400, 300);
bitmap_dptr = new BITMAP* [MAX_OBJECT_CATALOG_SIZE];
object_catalog_ptr = new Object_Info[MAX_OBJECT_CATALOG_SIZE];
object_list_ptr = new Object[MAX_OBJECT_LIST_SIZE];
background_color_ptr = new int[MAX_BACKGROUND_COLORS];
music_track_dptr = new MIDI* [MAX_MUSIC_TRACKS];
Load_Background_Colors(color_file_name);
Load_Music_Tracks(music_tracks_file_name);
Load_Object_Catalog(catalog_file_name);
done = error; // if an error occurred we're done
set_write_alpha_blender();
if (exists(level_file_name))
{
Load_Level();
}
while (!done)
{
if ((tick_count%2) == 0)
{
int object = 0;
clear_keybuf();
poll_keyboard();
key_timer++;
// process control keys
if (key[KEY_Q])
{
done = 1;
continue;
}
if (key[KEY_Z] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
selected_background_color++;
if (selected_background_color >= number_of_background_colors)
{
selected_background_color = 0;
}
}
if (key[KEY_LEFT])
{
selected_object = -1;
level_x -= 10;
if (level_x < 0)
{
level_x = 0;
}
}
if (key[KEY_RIGHT])
{
selected_object = -1;
level_x += 10;
}
if (key[KEY_UP])
{
selected_object = -1;
level_y -= 10;
}
if (key[KEY_DOWN])
{
selected_object = -1;
level_y += 10;
}
if (key[KEY_X] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
selected_object_type++;
if (selected_object_type >= object_catalog_size)
{
selected_object_type = 0;
}
}
if (key[KEY_C] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
work_layer++;
if (work_layer > 3)
{
work_layer = 1;
}
}
if (selected_object != -1) // make sure an object is selected
{
if (key[KEY_V] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
selected_property++;
if (selected_property >= object_list_ptr[selected_object].object_info_ptr->number_of_properties)
{
selected_property = 0;
}
}
if (key[KEY_B] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
object_list_ptr[selected_object].property_values[selected_property]--;
}
if (key[KEY_N] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
object_list_ptr[selected_object].property_values[selected_property]++;
}
if (key[KEY_J])
{
object_list_ptr[selected_object].x--;
if ((object_list_ptr[selected_object].x-level_x) < 0)
{
object_list_ptr[selected_object].x = level_x;
}
}
if (key[KEY_L])
{
object_list_ptr[selected_object].x++;
if ((object_list_ptr[selected_object].x-level_x) > 399)
{
object_list_ptr[selected_object].x = level_x+399;
}
}
if (key[KEY_I])
{
object_list_ptr[selected_object].y--;
if ((object_list_ptr[selected_object].y-level_y) < 0)
{
object_list_ptr[selected_object].y = level_y;
}
}
if (key[KEY_M])
{
object_list_ptr[selected_object].y++;
if ((object_list_ptr[selected_object].y-level_y) > 299)
{
object_list_ptr[selected_object].y = level_y+299;
}
}
if (key[KEY_DEL] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
memcpy(&object_list_ptr[selected_object], &object_list_ptr[object_list_size-1],
sizeof(Object));
object_list_size--;
selected_object = -1;
}
}
if (key[KEY_R] && !key_pressed) // selects objects
{
selected_object = 0;
key_pressed = 1;
key_timer = 0;
while (selected_object < object_list_size)
{
// only objects on the work layer can be selected
if (object_list_ptr[selected_object].object_info_ptr->type == work_layer)
{
if (Is_Point_In_Object(&object_list_ptr[selected_object], cursor_x, cursor_y))
{
break;
}
}
selected_object++;
}
if (selected_object == object_list_size)
{
selected_object = -1;
}
}
if (key[KEY_INSERT] && !key_pressed) // lays down objects
{
key_pressed = 1;
key_timer = 0;
if (object_list_size < MAX_OBJECT_LIST_SIZE)
{
selected_object = object_list_size;
object_list_size++;
object_list_ptr[selected_object].x = level_x+cursor_x;
object_list_ptr[selected_object].y = level_y+cursor_y;
object_list_ptr[selected_object].object_info_ptr = &object_catalog_ptr[selected_object_type];
memcpy(object_list_ptr[selected_object].property_values,
object_list_ptr[selected_object].object_info_ptr->initial_property_values,
(object_list_ptr[selected_object].object_info_ptr->number_of_properties*sizeof(int)));
}
}
if (key[KEY_4])
{
cursor_y--;
if (cursor_y < 0)
{
cursor_y = 0;
}
}
if (key[KEY_E])
{
cursor_x--;
if (cursor_x < 0)
{
cursor_x = 0;
}
}
if (key[KEY_T])
{
cursor_x++;
if (cursor_x > 399)
{
cursor_x = 399;
}
}
if (key[KEY_D])
{
cursor_y++;
if (cursor_y > 299)
{
cursor_y = 299;
}
}
if (key[KEY_COMMA] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
selected_music_track++;
if (selected_music_track >= number_of_music_tracks)
{
selected_music_track = 0;
}
}
if (key[KEY_STOP] && !key_pressed)
{
key_pressed = 1;
key_timer = 0;
play_midi(music_track_dptr[selected_music_track], 0);
}
// save level every 5 minutes
if ((tick_count%(2*60*5)) == 0)
{
Save_Level();
}
if (key_timer == 8)
{
key_pressed = 0; // release synchronized keys
}
rectfill(canvas_ptr, 0, 0, 399, 299, background_color_ptr[selected_background_color]);
// object movement processing
while (object < object_list_size)
{
if (object_list_ptr[object].object_info_ptr->type == BACKGROUND_OBJECT)
{
draw_sprite(canvas_ptr,
bitmap_dptr[object_list_ptr[object].object_info_ptr->bitmap],
(object_list_ptr[object].x-level_x),
(object_list_ptr[object].y-level_y));
}
object++;
}
object = 0;
while (object < object_list_size)
{
if (object_list_ptr[object].object_info_ptr->type == MIDDLE_OBJECT)
{
draw_sprite(canvas_ptr,
bitmap_dptr[object_list_ptr[object].object_info_ptr->bitmap],
(object_list_ptr[object].x-level_x),
(object_list_ptr[object].y-level_y));
}
object++;
}
object = 0;
while (object < object_list_size)
{
if (object_list_ptr[object].object_info_ptr->type == FOREGROUND_OBJECT)
{
draw_sprite(canvas_ptr,
bitmap_dptr[object_list_ptr[object].object_info_ptr->bitmap],
(object_list_ptr[object].x-level_x),
(object_list_ptr[object].y-level_y));
}
object++;
}
// display stats
if (key_shifts & KB_CAPSLOCK_FLAG)
{
textprintf_ex(canvas_ptr, font, 1, 1, makecol(255, 255, 255), -1, "(%i, %i)", level_x,
level_y);
textprintf_ex(canvas_ptr, font, 1, (1+text_height(font)), makecol(255, 255, 255), -1,
"Layer: %i", work_layer);
textprintf_ex(canvas_ptr, font, 1, (1+(2*text_height(font))), makecol(255, 255, 255),
-1, "Object type: %s", object_catalog_ptr[selected_object_type].name);
textprintf_ex(canvas_ptr, font, 1, (1+(3*text_height(font))), makecol(255, 255, 255),
-1, "Object layer: %i", object_catalog_ptr[selected_object_type].type);
if (selected_object != -1)
{
textprintf_ex(canvas_ptr, font, 1, (1+(4*text_height(font))), makecol(255, 255, 255),
-1, "Property: %s=%i", object_list_ptr[selected_object].object_info_ptr->properties[selected_property],
object_list_ptr[selected_object].property_values[selected_property]);
}
}
// display the cursor
drawing_mode(DRAW_MODE_XOR, NULL, 0, 0);
line(canvas_ptr, (cursor_x-4), cursor_y, (cursor_x-1), cursor_y, makecol(255, 255, 255));
line(canvas_ptr, (cursor_x+1), cursor_y, (cursor_x+4), cursor_y, makecol(255, 255, 255));
line(canvas_ptr, cursor_x, (cursor_y-4), cursor_x, (cursor_y-1), makecol(255, 255, 255));
line(canvas_ptr, cursor_x, (cursor_y+1), cursor_x, (cursor_y+4), makecol(255, 255, 255));
solid_mode();
// display canvas
acquire_screen();
vsync();
stretch_blit(canvas_ptr, screen, 0, 0, 400, 300, 0, 0, 800, 600);
release_screen();
}
}
Save_Level();
delete[] object_catalog_ptr;
delete[] object_list_ptr;
delete[] background_color_ptr;
destroy_bitmap(canvas_ptr);
while (bitmap < object_catalog_size)
{
destroy_bitmap(bitmap_dptr[bitmap]);
bitmap++;
}
while (track < MAX_MUSIC_TRACKS)
{
destroy_midi(music_track_dptr[track]);
track++;
}
delete[] bitmap_dptr;
delete[] music_track_dptr;
}
else // system is not ok for running the level editor
{
printf("This level editor runs in truecolor so if you are running in 256 color change\n");
printf("the color depth. Additionally you may be missing some required files. If this\n");
printf("is the case then please reinstall.\n");
}
return 0;
}
END_OF_MAIN()
/*
the first line in the level file is a number specifying the background color selected this is
followed by another line containing another number specifying the music track selected, the
rest of the file contains one or more records describing the objects in the level
records are formatted as follows:
name of object
property value 1
.
.
.
property value n
x coordinate
y coordinate
*/
void Load_Level()
{
FILE* level_file_ptr = fopen(level_file_name, "r");
if (level_file_ptr && !error)
{
char line[30+1];
fgets(line, sizeof(line), level_file_ptr);
Chomp_Line(line);
selected_background_color = atoi(line);
fgets(line, sizeof(line), level_file_ptr);
Chomp_Line(line);
selected_music_track = atoi(line);
while (object_catalog_size < MAX_OBJECT_LIST_SIZE)
{
char object_name[30+1];
int object_info = 0;
int property = 0;
char* line_ptr;
line_ptr = fgets(object_name, sizeof(object_name), level_file_ptr);
if (!line_ptr)
{
break;
}
Chomp_Line(object_name);
// look for the object info matching the name read
while (object_info < object_catalog_size)
{
if (strcmp(object_catalog_ptr[object_info].name, object_name) == 0) // we have a match
{
break;
}
object_info++;
}
object_list_ptr[object_list_size].object_info_ptr = &object_catalog_ptr[object_info];
while (property < object_catalog_ptr[object_info].number_of_properties)
{
fgets(line, sizeof(line), level_file_ptr);
Chomp_Line(line);
object_list_ptr[object_list_size].property_values[property] = atoi(line);
property++;
}
fgets(line, sizeof(line), level_file_ptr);
Chomp_Line(line);
object_list_ptr[object_list_size].x = atoi(line);
fgets(line, sizeof(line), level_file_ptr);
Chomp_Line(line);
object_list_ptr[object_list_size].y = atoi(line);
object_list_size++;
}
fclose(level_file_ptr);
}
}
void Save_Level()
{
FILE* level_file_ptr = fopen(level_file_name, "w");
if (level_file_ptr && !error)
{
int object = 0;
fprintf(level_file_ptr, "%i\n", selected_background_color);
fprintf(level_file_ptr, "%i\n", selected_music_track);
while (object < object_list_size)
{
int property = 0;
fprintf(level_file_ptr, "%s\n", object_list_ptr[object].object_info_ptr->name);
while (property < object_list_ptr[object].object_info_ptr->number_of_properties)
{
fprintf(level_file_ptr, "%i\n", object_list_ptr[object].property_values[property]);
property++;
}
fprintf(level_file_ptr, "%i\n", object_list_ptr[object].x);
fprintf(level_file_ptr, "%i\n", object_list_ptr[object].y);
object++;
}
fclose(level_file_ptr);
}
}
/*
catalog files contain a lot of information, a catalog file contains nothing but records which
are formatted as follows:
name of object
name of bitmap
number of properties
property name 1
.
.
.
property name n
initial property value 1
.
.
.
initial property value n
type of object
*/
void Load_Object_Catalog(char* object_catalog_file_name_ptr)
{
FILE* catalog_file_ptr = fopen(object_catalog_file_name_ptr, "r");
if (catalog_file_ptr && !error)
{
while (object_catalog_size < MAX_OBJECT_CATALOG_SIZE)
{
char bitmap_name[30+1];
char object_type[30+1];
char line[30+1];
int property = 0;
char* line_ptr;
line_ptr = fgets(object_catalog_ptr[object_catalog_size].name,
sizeof(object_catalog_ptr[object_catalog_size].name), catalog_file_ptr);
if (!line_ptr) // no line?
{
break;
}
Chomp_Line(object_catalog_ptr[object_catalog_size].name);
fgets(bitmap_name, sizeof(bitmap_name), catalog_file_ptr);
Chomp_Line(bitmap_name);
bitmap_dptr[object_catalog_size] = load_bitmap(bitmap_name, NULL);
object_catalog_ptr[object_catalog_size].bitmap = object_catalog_size;
fgets(line, sizeof(line), catalog_file_ptr);
Chomp_Line(line);
object_catalog_ptr[object_catalog_size].number_of_properties = atoi(line);
// read property names
while (property < object_catalog_ptr[object_catalog_size].number_of_properties)
{
fgets(object_catalog_ptr[object_catalog_size].properties[property],
sizeof(object_catalog_ptr[object_catalog_size].properties[property]),
catalog_file_ptr);
Chomp_Line(object_catalog_ptr[object_catalog_size].properties[property]);
property++;
}
property = 0;
// read initial property values
while (property < object_catalog_ptr[object_catalog_size].number_of_properties)
{
fgets(line, sizeof(line), catalog_file_ptr);
Chomp_Line(line);
object_catalog_ptr[object_catalog_size].initial_property_values[property] = atoi(line);
property++;
}
fgets(object_type, sizeof(object_type), catalog_file_ptr);
Chomp_Line(object_type);
if (strcmp(object_type, "background object") == 0)
{
object_catalog_ptr[object_catalog_size].type = BACKGROUND_OBJECT;
}
else if (strcmp(object_type, "middle object") == 0)
{
object_catalog_ptr[object_catalog_size].type = MIDDLE_OBJECT;
}
else // "foreground object" (maybe)
{
object_catalog_ptr[object_catalog_size].type = FOREGROUND_OBJECT;
}
object_catalog_size++;
}
fclose(catalog_file_ptr);
}
else // catalog file not opened
{
error = 1;
}
}
// background colors are stored in red-green-blue triplets within a color file
void Load_Background_Colors(char* color_file_name_ptr)
{
FILE* color_file_ptr = fopen(color_file_name_ptr, "r");
if (color_file_ptr)
{
while (number_of_background_colors < MAX_BACKGROUND_COLORS)
{
int red;
int green;
int blue;
char line[30+1];
char* line_ptr;
line_ptr = fgets(line, sizeof(line), color_file_ptr);
if (!line_ptr)
{
break;
}
Chomp_Line(line);
red = atoi(line);
fgets(line, sizeof(line), color_file_ptr);
Chomp_Line(line);
green = atoi(line);
fgets(line, sizeof(line), color_file_ptr);
Chomp_Line(line);
blue = atoi(line);
background_color_ptr[number_of_background_colors] = makecol(red, green, blue);
number_of_background_colors++;
}
fclose(color_file_ptr);
}
else // color file not opened
{
error = 1;
}
}
void Tick_Handler()
{
tick_count++;
}
END_OF_FUNCTION(Tick_Handler)
int Is_System_Ok()
{
return ((desktop_color_depth() >= 16) &&
exists("allegro.cfg") &&
exists("keyboard.dat") &&
exists("language.dat"));
}
int Is_Point_In_Object(Object* object_ptr, int x, int y)
{
int left = object_ptr->x-level_x;
int right = left+bitmap_dptr[object_ptr->object_info_ptr->bitmap]->w-1;
int top = object_ptr->y-level_y;
int bottom = top+bitmap_dptr[object_ptr->object_info_ptr->bitmap]->h-1;
return ((x >= left) && (x <= right) && (y >= top) && (y <= bottom));
}
// this subroutine removes the newline at the end of the line
void Chomp_Line(char* line_ptr)
{
int character = 0;
while (line_ptr[character] != '\n')
{
character++;
}
line_ptr[character] = 0;
}
void Load_Music_Tracks(char* music_tracks_file_name_ptr)
{
FILE* music_tracks_file_ptr = fopen(music_tracks_file_name_ptr, "r");
if (music_tracks_file_ptr)
{
while (number_of_music_tracks < MAX_MUSIC_TRACKS)
{
char track_file_name[30+1];
char* line_ptr;
line_ptr = fgets(track_file_name, sizeof(track_file_name), music_tracks_file_ptr);
if (!line_ptr)
{
break;
}
Chomp_Line(track_file_name);
music_track_dptr[number_of_music_tracks] = load_midi(track_file_name);
number_of_music_tracks++;
}
}
else // music tracks file not opened
{
error = 1;
}
}* You will need Allegro to compile this. |
|
|
|
|
|
#27 |
|
I eat cake for breakfast.
![]() ![]() ![]() ![]() Join Date: Jul 2004
Location: In my box.
Posts: 4,434
Rep Power: 9
![]() |
It's not that we don't understand the idea of a level editor, genius - what we don't understand is how a generic level editor is useful. A specialised one, customised for your specific game, is always worth coding.
|
|
|
|
|
|
#28 |
|
Hobbyist Programmer
Join Date: Oct 2005
Location: Ohio
Posts: 177
Rep Power: 0
![]() |
I am a genius, thank you. If you read the manual you will understand how this level editor can be useful for any isometric game.
|
|
|
|
|
|
#29 |
|
Professional Programmer
Join Date: Jan 2006
Location: Ontario, Canada
Posts: 376
Rep Power: 0
![]() |
This needs some work.... First of all multiple files would be a good idea, and your main should only be like 10 lines of code, not a couple hundred.
__________________
I am Addicted to Linux! |
|
|
|
|
|
#30 |
|
Hobbyist Programmer
Join Date: Jun 2006
Location: at my computer desk
Posts: 138
Rep Power: 3
![]() |
i know i am new to C++, but isnt #define antiquated? dont people just use const char nowadays?
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|