How did you first decide that you want to make a game and what was your first project?
Your first project
I got into games a long time ago when I started playing video games. The first video game I played was Super Mario World and I was blown away by it. I had a lot of ideas of what could be added to Super Mario World to make it even more interesting so I took a programming class in school to learn how to make games. Whole motivation for game-dev is to create my own games and play them!
My first real game project was Bluejay's Quest. It is a 2D platform game where you complete mazes using a bird. It has very simple matrix-like collision detection but was fun to play. Written in C++.
On 25. 08. 2017 at 5:35 PM, francoisdiy said:I got into games a long time ago when I started playing video games. The first video game I played was Super Mario World and I was blown away by it. I had a lot of ideas of what could be added to Super Mario World to make it even more interesting so I took a programming class in school to learn how to make games. Whole motivation for game-dev is to create my own games and play them!
My first real game project was Bluejay's Quest. It is a 2D platform game where you complete mazes using a bird. It has very simple matrix-like collision detection but was fun to play. Written in C++.
So cool mate! Are you still in game development? Can your work be seen anywhere? ^^
Super Mario World, Chrono Trigger, and Final Fantasy VII cemented my idea to become a video-game developer. I created many stages and designs but at around 13 I realized that if any of my designs were going to be made real then I would have to learn to program.
My first project was a text-based guess-the-number “game” in which you entered a number and were told if it matched the number the computer randomly generated. If not, it would cuss at you.
My first “real” project was an online clone of Final Fantasy VII which had 129 players during the short time I kept it online.
L. Spiro
I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid
My first actual game was a "four in line" kind of game, for an university course. Java and Swing. Nothing I had a say about since it was a requirement for the course.
My first very own game-dev related project was a 3D visualizer for a heightmap. I decided I wasn't really interested in 2D graphics, nor in old style "glDrawMeATriangle" OpenGL, so I jumped straight to OpenGL 3.3 core, shaders and all. So I was reading the arcsynthesis's online book in C++ while translating that knowledge to Java+LWJGL.
It was hard, given my coding experience at the time was terribly limited, I had no idea about real-time anything, and my math was very wonky (still is, don't like math), but very rewarding nevertheless.
Never finished a game besides that first one. I started a couple years ago a "game" project, basically in a scale that I cant finish on my own (on purpose). That project kept me on it for 4 years so farm, I think? Nice learning experience for me.
"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"
My journals: dustArtemis ECS framework and Making a Terrain Generator
16 hours ago, TilenM said:So cool mate! Are you still in game development? Can your work be seen anywhere? ^^
Oh yeah! Games rule. I develop games just like before - mostly for myself to play. I did create a level editor:
/*
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;
}
}
This is coded in C++. This is where I started.
Now I'm creating games and streaming on Twitch as francoisdiy.
12 hours ago, L. Spiro said:Super Mario World, Chrono Trigger, and Final Fantasy VII cemented my idea to become a video-game developer. I created many stages and designs but at around 13 I realized that if any of my designs were going to be made real then I would have to learn to program.
My first project was a text-based guess-the-number “game” in which you entered a number and were told if it matched the number the computer randomly generated. If not, it would cuss at you.
My first “real” project was an online clone of Final Fantasy VII which had 129 players during the short time I kept it online.
L. Spiro
Great story! Are you still trying to make it in the game development? Btw, is there a link where I could see that "ff vII clone"? I'd love to check it out ^^
11 hours ago, TheChubu said:My first actual game was a "four in line" kind of game, for an university course. Java and Swing. Nothing I had a say about since it was a requirement for the course.
My first very own game-dev related project was a 3D visualizer for a heightmap. I decided I wasn't really interested in 2D graphics, nor in old style "glDrawMeATriangle" OpenGL, so I jumped straight to OpenGL 3.3 core, shaders and all. So I was reading the arcsynthesis's online book in C++ while translating that knowledge to Java+LWJGL.
It was hard, given my coding experience at the time was terribly limited, I had no idea about real-time anything, and my math was very wonky (still is, don't like math), but very rewarding nevertheless.
Never finished a game besides that first one. I started a couple years ago a "game" project, basically in a scale that I cant finish on my own (on purpose). That project kept me on it for 4 years so farm, I think? Nice learning experience for me.
Well, with that devotion, I think you made a mistake by not sticking to yur dreams. I am sure you could find a team that would appreciate your work.
1 hour ago, francoisdiy said:Oh yeah! Games rule. I develop games just like before - mostly for myself to play. I did create a level editor:
/* 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; } }
This is coded in C++. This is where I started.
Now I'm creating games and streaming on Twitch as francoisdiy.
So cool man! Have you ever considered getting a team to help you out? I droped you a follow, tho I am not into programming myself. I wish you all the best with your channel tho!
1 hour ago, TilenM said:So cool man! Have you ever considered getting a team to help you out? I droped you a follow, tho I am not into programming myself. I wish you all the best with your channel tho!
Thanks a bunch! No, programming and game development are more of a hobby for me so I like to work on my own. The level editor code that I posted is old and runs over Allegro. I do some programming on stream but most build levels and speedrun the games I create.
3 hours ago, TilenM said:Great story! Are you still trying to make it in the game development? Btw, is there a link where I could see that "ff vII clone"? I'd love to check it out ^^
After being in the industry for 14 years I am finally starting to move away from it. I am working on a manga, considering becoming a cartoon animator, and even considering career options involving working with animals.
You can see some of the work on "Something Something 7 Online" here: http://www.memoryhacking.com/SS7O/index.html
L. Spiro
I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid