|
3 registered members (AndrewAMD, Grant, Neb),
908
guests, and 6
spiders. |
|
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: Joozey]
#239230
12/03/08 13:33
12/03/08 13:33
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
create the "tile map" as a greyscale Bitmap with 1 PIXEL per tile. That will give you 256 possible tile "types". Then read off each pixel as you need it using the pixel_for_bmap() function.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: EvilSOB]
#239234
12/03/08 14:23
12/03/08 14:23
|
Joined: Apr 2008
Posts: 144 Germany | Niedersachsen (Lower...
Roxas
OP
Member
|
OP
Member
Joined: Apr 2008
Posts: 144
Germany | Niedersachsen (Lower...
|
@Joozey Well I guess that's too high for my abilities. I don't understand the function or not completely how its working. BUT as far as I can see, does this function nothing but fill the array with 0's, doesn't it? =O The problem is, I don't want to fill the array only with 0's or 1's or something else. imagine the following:
0 = player 1 = ground 2 = tree 3 = stone 4 = house
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1, 1, 1, 1, 1, 3, 1, 1, 4, 4, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
this is the map. every number stands for a tile that's how I determine the look of the map. and then i need a code that converts this "grid" into the specific tile.
but I can't do this arrangement with lite-c or am I wrong? ^^'
think of multilayering. the first layer determines if a tile is passable or not. the second layer determines the ground of the map the third layer determines the details. on the fourth layer the player and npc's walk around and finally the fifth layer shows details which are ABOVE the player (like treetops)
some of you might say "yeah you could go and buy RPG Maker XP thats the crap you want" but well actually i want to code something like this myself. but unfortunately I think that I'm not able to do that =O. because like i said, my abilities are very limited.
@EvilSOB I took a look at the command in the manual. and tried it but didn't come up with good results. maybe i didn't get what you exactly mean =O.
Roxas.
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: Roxas]
#239235
12/03/08 14:36
12/03/08 14:36
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
I'll try and put a working example together tomorrow. Its 2am here and I gotta be at work in 5 hours, and I havent slept yet.... 8(
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: EvilSOB]
#239244
12/03/08 15:46
12/03/08 15:46
|
Joined: Oct 2004
Posts: 4,134 Netherlands
Joozey
Expert
|
Expert
Joined: Oct 2004
Posts: 4,134
Netherlands
|
create the "tile map" as a greyscale Bitmap with 1 PIXEL per tile. That will give you 256 possible tile "types". 25600 possible tile types if you involve the alpha bit in a tga format  . But I wouldn't advise to do it this way. Aside that pixel functions and bitmaps are not intended to use as storage, they are also remarkably slower than reading/writing to matrixes or arrays. The method will work, of course, but it's very dirty modelling  . @Joozey Well I guess that's too high for my abilities. I don't understand the function or not completely how its working. BUT as far as I can see, does this function nothing but fill the array with 0's, doesn't it? =O The problem is, I don't want to fill the array only with 0's or 1's or something else. Of course, but you can't do that at initialisation. When you create something new that needs to hold values, it's very wise to always fill this object with an initialising value. Whether it be 0, NULL -1, "", always fill empty objects as they otherwise can cause very strange behaviour, untraceable errors, and a lot of headaches  . So, what I did with my function was dynamically creating a matrix: map[width][height] You can then use this matrix in a new function to fill its indexes. void set_maptile(int** map, int x, int y, int value) {
map[x][y] = value;
}Now you can fill the matrix to your needs. and then i need a code that converts this "grid" into the specific tile.
but I can't do this arrangement with lite-c or am I wrong? ^^'
think of multilayering. the first layer determines if a tile is passable or not. the second layer determines the ground of the map the third layer determines the details. on the fourth layer the player and npc's walk around and finally the fifth layer shows details which are ABOVE the player (like treetops) Make more maps then?  The same way I set a value in the map, you can read a value from the map. Just return the integer stored in map[x][y] instead of putting value in it. some of you might say "yeah you could go and buy RPG Maker XP thats the crap you want" but well actually i want to code something like this myself. but unfortunately I think that I'm not able to do that =O. because like i said, my abilities are very limited. If you feel this is too hard, take a step back, and go along with the code that you already have. It's not such a big code you had there, really. And it's fine as you did so far. Where you said: I think this is far to complicated for a 2D Tile-Based System. I say that it's not even nearly complicated enough :P. But I understand your problem so far. You are declaring each and every tile and its properties on absolute base (on top of your .c file). But you don't need to declare 650000 tiles in order to get a 256*256 grid, there are many other solutions. Try using and researching some more of the following methods in the 3dgs manual and on the internet: - function arguments -- e.g. void test(int a, int b) {...} -- manual, internet - structures (structs) -- typedef struct {} MYSTRUCT; -- manual, internet - pointers -- int**, MyStruct* -- internet - memory allocation -- malloc(), free(), sizeof() -- internet - pointer management -- linked lists, hash tables, faking classes in C -- internet The hardest part is how you assemble all those functions into a good working design or method. This needs experience, trial and error, and practically nobody can learn this to you. You just need to start, and your first 20 attempts will be poorly designed, fail and malfunction, but that's just fine  . One has got to start somewhere, and if I look back to my old projects, I laugh (and sometimes cry), like everyone else.
Last edited by Joozey; 12/03/08 16:08.
Click and join the 3dgs irc community! Room: #3dgs
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: Joozey]
#239336
12/04/08 01:17
12/04/08 01:17
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Heres the sample code I promised, a little larger than I expected, but a more flexible design than I originally thought of. Has been fully compiled and tested to what I believe you want. It lookes horrible in the forum, but cut it out and paste it into SED and it will be much more readable. Then create yourself a 24-bit image (BMP preferably) using the colors listed in the top defines to create a map. Please keep it less than 50x50 for now, or you will need to change the Max_Map_Width define to be bigger. This image should be saved as "map.bmp" 24bit uncompressed, and is for testing the Load_TokenMap_To_Zero() function. This function takes all the pixels that match the colors listed in the defines 'Zero Layer Color' comment column, and adds them into the Token table "TokenMap" as the color-matching number/token. EG Pure Green pixels create a TM_Tree token, and pure Blue create water tokens. Any space in the Table not "covered" by the bitmap will be left at a value of -1 or TM_Unused. Then create yourself a 32-bit image (TGA preferably) using the colors listed in the top defines to create a map. Please keep it less than 50x50 for now, or you will need to change the Max_Map_Width define to be bigger. This image should be saved as "map3d.tga" 32bit uncompressed, and is for testing the Load_TokenMap_To_3D() function. This function takes all the pixels that match the colors listed in the defines 'Multi-Layer Color' comment column, and adds them into the Token table "TokenMap" as the color-matching number/token. BUT unlike Load_TokenMap_To_Zero, this function treats each primary color and the alpha channel as separate layers, so for example a pixel with a red level of 50 will put a Ground token in layer zero, no matter what its green, blue or alpha levels are. So each pixel can now carry up to 4 tokens. Again, any space in the Table not "covered" by the bitmap will be left at a value of -1 or TM_Unused. These functions are free-standing, that is you can delete the one you dont need and the other will still run. The other function TokenMap_startup() is an initialiser just to clear garbage data on startup and when translating BMAPs. At the moment, the color 'values' of the Tokens are hard-coded into the functions, I would suggest using defines for them instead. Also, function main has two data dumps in it to put the contents of the TokenMap table into the ACKLOG.TXT file, so you can see its contents in a readable format. I wouldnt suggest increasing the size of Max_Map_Width or Max_Map_Layer by much more, its already a bit over-sized. If you NEED it enlarging, let me know and I will redo the definition of TokenMap and the TokenMap_startup function. Using pointers and MALLOC would be better, but Im not that good with it yet. Everything else should stay (more or less) the same. If youve got any questions on how it works, or need changes you dont know how to implement, just let me know. On a final note, like Joozey said, using the pixel access functions IS slow, so unless the game has losts of spare CPU time, its best to leave those Load_TokenMap_... function to be used only when loading a new level or area. #include <acknex.h>
//
//
#define Max_Map_Width 50 //maximum height or width ever used by tile map in WHOLE game.
#define Max_Map_Layer 5 //maximum number of layers(depth) ever used by tile map in WHOLE game.
//
// TokenMap Tile types Zero Layer Multi-Layer (red OR green OR blue)
// Color(RGB) or BYTE (0->255)
#define TM_Unused -1 //TokenMap enum n/a n/a
#define TM_Ground 0 //TokenMap enum 0, 0, 0 or 50
#define TM_Player 1 //TokenMap enum n/a n/a
#define TM_Tree 2 //TokenMap enum 0,255,0 or 100
#define TM_Stone 3 //TokenMap enum 255,0, 0 or 150
#define TM_House 4 //TokenMap enum 255,0,255 or 200
#define TM_Water 5 //TokenMap enum 0, 0,255 or 250
//
//
int Tx, Ty, Tz;
int TokenMap[Max_Map_Width][Max_Map_Width][Max_Map_Layer]; //Tile Tokens Map storage. TokenMap[X][Y][Z]
//
void TokenMap_startup() //automatic and manual initialisation of TokenMap with "empty" entries
{ for(Tx=0; Tx<Max_Map_Width; Tx++)
{ for(Ty=0; Ty<Max_Map_Width; Ty++)
{ for(Tz=0; Tz<Max_Map_Layer; Tz++)
TokenMap[Tx][Ty][Tz] = TM_Unused; //Fill with empties
}
}
}
//
//
//
//
function Load_TokenMap_To_Zero(STRING* MapName) //Load 24-bit image into layer ZERO of TokenMap Table
{
TokenMap_startup(); //optional - keep to make sure table is empty before filling.
BMAP* TokenBMAP = bmap_create(MapName);
var ColorType = bmap_lock(TokenBMAP,0);
COLOR ThisColor;
//
for(Tx=0; Tx<TokenBMAP.width; Tx++)
{ for(Ty=0; Ty<TokenBMAP.height; Ty++)
{ var ThisPixel = pixel_for_bmap(TokenBMAP, Tx, Ty); //get pixel
pixel_to_vec(&ThisColor, NULL, ColorType, ThisPixel); //extract color
//
//Load LAYER ZERO with Tile Tokens based on BMAP data
if((ThisColor.red==0 )&&(ThisColor.green==0 )&&(ThisColor.blue==0 )) TokenMap[Tx][Ty][0] = TM_Ground;
else if((ThisColor.red==0 )&&(ThisColor.green==255)&&(ThisColor.blue==0 )) TokenMap[Tx][Ty][0] = TM_Tree;
else if((ThisColor.red==255)&&(ThisColor.green==0 )&&(ThisColor.blue==0 )) TokenMap[Tx][Ty][0] = TM_Stone;
else if((ThisColor.red==255)&&(ThisColor.green==0 )&&(ThisColor.blue==255)) TokenMap[Tx][Ty][0] = TM_House;
else if((ThisColor.red==0 )&&(ThisColor.green==0 )&&(ThisColor.blue==255)) TokenMap[Tx][Ty][0] = TM_Water;
else TokenMap[Tx][Ty][0] = TM_Ground; //default to ground on bad data (needed for edge-of-level checking)
}
}
bmap_remove(TokenBMAP);
}
//
//
//
//
function Load_TokenMap_To_3D(STRING* MapName) //Load 32-bit image into multiple layers.
{
TokenMap_startup(); //optional - keep to make sure table is empty before filling.
BMAP* TokenBMAP = bmap_create(MapName);
var ColorType = bmap_lock(TokenBMAP,0);
COLOR ThisColor; var AlphaLevel;
//
for(Tx=0; Tx<TokenBMAP.width; Tx++)
{ for(Ty=0; Ty<TokenBMAP.height; Ty++)
{ var ThisPixel = pixel_for_bmap(TokenBMAP, Tx, Ty); //get pixel
pixel_to_vec(&ThisColor, AlphaLevel, ColorType, ThisPixel); //extract color
//
//Load LAYER ZERO with Tile Tokens based on RED color data (passable determination)
if(ThisColor.red== 50) TokenMap[Tx][Ty][0] = TM_Ground;
else if(ThisColor.red==100) TokenMap[Tx][Ty][0] = TM_Tree;
else if(ThisColor.red==150) TokenMap[Tx][Ty][0] = TM_Stone;
else if(ThisColor.red==200) TokenMap[Tx][Ty][0] = TM_House;
else if(ThisColor.red==250) TokenMap[Tx][Ty][0] = TM_Water;
else TokenMap[Tx][Ty][0] = TM_Ground; //default to ground on bad data (needed for edge-of-level checking)
//
//Load LAYER ONE with Tile Tokens based on GREEN color data (ground (color/texture?) determination)
if(ThisColor.green== 50) TokenMap[Tx][Ty][1] = TM_Ground;
if(ThisColor.green==100) TokenMap[Tx][Ty][1] = TM_Tree;
if(ThisColor.green==150) TokenMap[Tx][Ty][1] = TM_Stone;
if(ThisColor.green==200) TokenMap[Tx][Ty][1] = TM_House;
if(ThisColor.green==250) TokenMap[Tx][Ty][1] = TM_Water;
//
//Load LAYER TWO with Tile Tokens based on BLUE color data (details determination)
if(ThisColor.blue== 50) TokenMap[Tx][Ty][2] = TM_Ground;
if(ThisColor.blue==100) TokenMap[Tx][Ty][2] = TM_Tree;
if(ThisColor.blue==150) TokenMap[Tx][Ty][2] = TM_Stone;
if(ThisColor.blue==200) TokenMap[Tx][Ty][2] = TM_House;
if(ThisColor.blue==250) TokenMap[Tx][Ty][2] = TM_Water;
//
//Leave LAYER THREE alone for players and NPC's to live in
//
//Load LAYER FOUR with Tile Tokens based on ALPHA color data (sky detail determination)
if(AlphaLevel== 50) TokenMap[Tx][Ty][4] = TM_Ground;
if(AlphaLevel==100) TokenMap[Tx][Ty][4] = TM_Tree;
if(AlphaLevel==150) TokenMap[Tx][Ty][4] = TM_Stone;
if(AlphaLevel==200) TokenMap[Tx][Ty][4] = TM_House;
if(AlphaLevel==250) TokenMap[Tx][Ty][4] = TM_Water;
}
}
bmap_remove(TokenBMAP);
}
//
//
//
//
function main()
{
wait(1); //allow time for automatic TokenMap_startup to complete
//##### DEBUGGING Zero Layer ONLY - writing table contents to ACKLOG.TXT
Load_TokenMap_To_Zero("map.bmp"); //Load all TileType data into layer Zero
diag("\n\nDump TokenMap Table (Layer Zero Only)\n");
for(Tx=0; Tx<Max_Map_Width; Tx++)
{ diag_var("Row#%.0f = '", Tx);
for(Ty=0; Ty<Max_Map_Width; Ty++)
diag_var("%.0f,",TokenMap[Tx][Ty][0]);
diag("'\n");
}
diag("Dump TokenMap Table Complete\n\n\n");
//##### Finished DEBUGGING Zero Layer
//##### DEBUGGING Multi-Layer ONLY - writing table contents to ACKLOG.TXT
Load_TokenMap_To_3D("map3d.tga"); //Load all TileType data into color-specified layer
diag("\n\nDump TokenMap Table (All Layers)\n");
for(Tx=0; Tx<Max_Map_Width; Tx++)
{ diag_var("Row#%.0f = '", Tx);
for(Ty=0; Ty<Max_Map_Width; Ty++)
{ diag("[");
for(Tz=0; Tz<Max_Map_Layer; Tz++)
diag_var("%.0f,",TokenMap[Tx][Ty][Tz]);
diag("], ");
}
diag("'\n");
}
diag("Dump TokenMap Table Complete\n\n\n");
//##### Finished DEBUGGING Multi-Layer
}
//
//
//
//
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: EvilSOB]
#239426
12/04/08 16:26
12/04/08 16:26
|
Joined: Apr 2008
Posts: 144 Germany | Niedersachsen (Lower...
Roxas
OP
Member
|
OP
Member
Joined: Apr 2008
Posts: 144
Germany | Niedersachsen (Lower...
|
o_O woho. Thank you guys for your detailed answers up there!
@ Joozey: thank you for your big answer. I had to read it several times because it's so huge.
well: I searched for the things you listed up and found some interesting things, but thats very hard to understand, and slowly I get the feeling that you guys do overestimate me ^^'
I didn't think that this is gotta be THAT hard to realize, because I've read some Java and Ruby and Basic-Tutorials that are dealing with stuff like that and so on and it seemed very simple, but with 3DGS it seems to be overwhelming =O.
And I know that your supposed to do a lot of trial and error~ but I think maybe this programming language and engine is supposed to be used with 3D stuff. All of my "projects" I started so far failed because of my limited abilites.
First I started to code a simple 3D Jump n Run game. The First problem I had to solve were the game physics. Until now I gave up at least 15-20 attempts because of physics. I can't even code a simple, working Jumping Script and even the KH Tutorial didn't help me.
Then I started to code something like a Yu-Gi-Oh Clone > failed because I didn't even knew how to realize that.
Later on I tried to code a strategy game like C&C. The pathfinding was my greatest enemy -.-
Another thing I tried was a final fantasy like game animations, character modelling and again simple game physic were the problem.
and so on...
To be honest I wasn't able to code something that realy worked so far.
Now I thought "well ~ you did a lot of stuff with the RPG Maker etc, 2D isn't that bad at all and you know how it works." so i tried to code simple 2D Games.
the first thing i tried was a "space shooter side scrolling game" like jets n guns. failed.
am I trying to hard or am I starting with the wrong things?
The next thing I tried was to code this "simple" 2D Tile Based Engine, like the RPG Maker is one. But it seems that this is to hard for me, too oO.
Maybe you got some suggestions for starting 2D Games? Because you said, you're projects were mainly 2D Games. so how do you start a little 2D project, what genre?
Im grateful for everything you can tell me ^^
@ EvilSOB:
First: Thank you for your efforts! ^^ I didn't think that you would come up with something so big. thats great.
the problem. I don't know what this script is doing, and I don't know how to use it.
I made 2 images, as you said, and started the script. no errors. all was workin fine. but nothing happened. black screen and no "Acklog.txt"
The only thing I understood was, that this functions are converting colors of pixels to numbers in a table from the images. so when I take a 50*50 bmap fill it with pure black and would paint 2 pure green dots into it and save it, the function "load_tokenmap_to_zero" would convert the 2 green dots into a table which would contain a lot of 1's for the ground and two 2's for the tree's. am i right?
but where is the table =O? "Acklog.txt"? (which isn't created when i start the script) and how do I convert the table into tile's and show them on the screen?
and again: Thank you so far! I think I learned something until now, even when I'm not able to comprehend most of the things. I'm afraid so..
Roxas.
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: Roxas]
#239443
12/04/08 17:17
12/04/08 17:17
|
Joined: Oct 2004
Posts: 4,134 Netherlands
Joozey
Expert
|
Expert
Joined: Oct 2004
Posts: 4,134
Netherlands
|
 I hear your pain on all those frustrations, but it's something we all deal with; half finished projects because AI programming got too complicated, physics and mathematics keep failing, the most simple functions refuse to work, you freeze the project intentionally for a few days... to never return, the code turned into spaghetti with no comments anywhere, unsolvable bugs (yay pointers), the development got boring, the graphics suck and the models suck too.  Don't underestimate 2D with this engine though, it's still pretty complicated. Presumably more difficult than 3D, as most of the documentation, example codes and overall support are for 3D. Maybe you got some suggestions for starting 2D Games? Because you said, you're projects were mainly 2D Games. so how do you start a little 2D project, what genre? Duckhunt sounds easy enough, or similar in concept: a balloon-pop game. A one-player memory game should be possible as well. I think card games get more complicated already, as you need to deal with more players and more data to store. But it's a good second step. Instead of a sidescroller, try a screen-per-screen jump 'n run game. But programming collisions is quite hard. If you program a duckhunt game however, you'll recognise that the same detection for clicking on panels is the base for a collision system. Perhaps snake will qualify as a simple game as well. Just try to keep it very basic, and extend it later on, when the rough game works.
Click and join the 3dgs irc community! Room: #3dgs
|
|
|
Re: 2D Tile Based Engine with 3DGS
[Re: Joozey]
#239471
12/04/08 21:01
12/04/08 21:01
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Hmm, tricky. I do think you are diving a bit too deep to start off with. Hell, I should know, my first project is a World Of Warcraft look-alike! Megabytes of code chunks and design notes, but no actual game yet, not even a menu or title screen after a year of work. But Ive learned lite-c by looking at other peoples problems, and other peoples solutions to them, and figuring out my own answers to them. Thats why I 'live' in this forum, its a learning exercise. And what Ive learned in a year (yes I am procrastinating a lot...) has taught me enough that I was able to code my above sample code on a couple of hours. I would suggest the same as Joozey, start REALLY simple. I would go so far as to go as simple as a game like "Pong", the first real 'computer' game ever. WikiPedia - Pong Dont use real physics or mouse, keep it simple. Then once it works 100%, start the upgrades. 3D models, real collision detection, wandering obstacles, powerups, etc. One at a time though.If you have a "real" game already in mind for when you are good enough, try to make some of the mods to pong the same as what your game will need. Best of luck.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
|