Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Questions regarding a 2D tile map editor!

Author
Message
Yodaman Jer
User Banned
Posted: 25th Jul 2015 03:29 Edited at: 25th Jul 2015 03:30
OK, this is something that I *know* I should know by now, but honestly it has been so long since I've programmed everything from scratch I'm having a hard time remembering how to do these basic things.

I want to create a tile map editor for my game, and I know the best way to store map data is an array. My problem is... I can't quite work out how to do that! And nay tutorials I google for some reason skip over this part and automatically use something like Tiled, which is a great idea but I want to make my own system.


Can someone help point me in the right direction please? Just give me some ideas and maybe an example or two? I know I figured this out ages ago in DBP but I can't remember how I did it.

Thanks y'all!

EDIT: Specifically, I'm wondering HOW I would store a tile that was just created in that array. And should the array be predefined or can I make it an expandable list? Just curious!


Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
MrValentine
AGK Backer
13
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 25th Jul 2015 23:59
I don't know if AppGameKit supports Token Keys, but you could just throw everything into an array cell and use a token key to separate each value?

Yup I do have a headache right now...

Yodaman Jer
User Banned
Posted: 26th Jul 2015 00:09
I will copy my post from another thread here to make it a bit clearer as to what I'm trying to achieve.

I am wondering how I would store 2D map data in an array. It seems the most common thing to do in this type of situation is to make the array two dimensional, so that one array focuses on the vertical lines and the other the horizontal. So, how I would I store data in that?

I know in general, it seems to be something like...



That part seems fairly simple, at least creating the tile, but HOW do I store it in those two indices?

@MrV:

I could do something like that, you mean something similar to a UDT and just use one indice to store the data? That would be a huge variable haha


Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Yodaman Jer
User Banned
Posted: 26th Jul 2015 05:07
Pretty sure I solved this one (with all the advice I got in the Posting Competition as well as some of my own Googling and finally remembering how I did a few things ).

Basically, this is what I have:



This is pretty much exactly what I wanted! Now it should be easy to store level data

However! There are still a few questions I have.

What is the best way to determine if a tile already exists in a grid space so that you can't create a new tile there until you delete the previous one? Should I use some kind of collision detection system, or is there another more elegant way? Ideas are appreciated!


Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
MrValentine
AGK Backer
13
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 26th Jul 2015 05:20
I mentioned it in the PConp already... Dirty...

Yodaman Jer
User Banned
Posted: 26th Jul 2015 05:35
Ah what a clever clue!

A flag variable is an idea I thought of as well, however it doesn't seem to work :/ Here's what I tried:




Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
MrValentine
AGK Backer
13
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 26th Jul 2015 06:40
Why are you using an integer for a bool? Or are you using states/types on it? (InUse)

Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 26th Jul 2015 06:59 Edited at: 26th Jul 2015 07:00
With tile maps I would be simply recording whether there's a tile there in the data, like so:



Usually in these cases I just set the variable recording the sprite's number to -1 if the tile hasn't been used yet. If for some reason that's not viable, I just include an "exist" variable like the above code.

EDIT:

Quote: "Why are you using an integer for a bool? Or are you using states/types on it? (InUse)"


AFAIK AppGameKit uses integers internally for bools anyway and therefore there's no reason to use them. Or it doesn't support them. Can't remember. I think DBPro at least used ints internally instead of real bools.

Yodaman Jer
User Banned
Posted: 26th Jul 2015 16:11
@MrV:

Eventually my integers will be replaced with constants I've declared. I just haven't gotten around to it. I believe Clonkex is correct about AppGameKit using ints internally and so it doesn't support proper bools.

I tried using the exist flag, and I think I'm getting closer! But now after I create the first tile nothing happens.

Code:


If someone could tell me what exactly it is I'm doing wrong, I would be ever so indebted unto you!


Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 27th Jul 2015 09:35 Edited at: 27th Jul 2015 09:39
You're only exiting one loop. You need to use a variable instead and check it in both loops to ensure you get out of both. Like so:



That's one problem. The other is that you've completely misunderstood the point of the 2D array (*facepalm*) Here is how I would do this (untested):



Yodaman Jer
User Banned
Posted: 27th Jul 2015 13:04
Thanks Clonkex! I had to change some stuff around a bit but once I saw your code I finally see what you mean about about the indices being the coordinates for the sprites!

Final code:


I think part of my problem (and thus misunderstanding) was because I was trying to convert a bunch of C++ code I had seen for this type of thing that used for loops and still stored the position of sprites in the array. SHould I not do that just as a safety measure?

One thing I noticed too, was that in order to get the amount of tiles that I wanted, I had to multiply my width and height variables. For example, if I wanted my level to be 8 tiles high, the value for height has to be 256, like you see in the code. Does this make sense, or should I multiply my variables in the If statement that checks if the mouse is in the correct coordinates?


Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 27th Jul 2015 15:09
Quote: "I had to change some stuff around a bit but once I saw your code I finally see what you mean about about the indices being the coordinates for the sprites!"


Haha I'm glad

Quote: "SHould I not do that just as a safety measure?"


I don't see why. You should always be able to reliably get the theoretical tile position based on its grid position (the array indices) and if you need the graphical sprite position, that's recorded by AppGameKit in the sprite itself. Basically, if you need to use a safety measure to make your code work, some part of your code is broken.

Quote: "One thing I noticed too, was that in order to get the amount of tiles that I wanted, I had to multiply my width and height variables. For example, if I wanted my level to be 8 tiles high, the value for height has to be 256, like you see in the code. Does this make sense, or should I multiply my variables in the If statement that checks if the mouse is in the correct coordinates?"


Ah no! If you're multiplying the width and height vars, you're making the array exponentially larger than it needs to be! (Specifically, at 32*8 it contains 256 elements; at 2048*256 it contains 524,288 elements ) I just didn't look at how GridSnap actually worked. I've worked it out now; put the array sizes (the width and height vars) back to whatever you had them at (32*8 I think) and change this bit of code to look like this:



Yodaman Jer
User Banned
Posted: 28th Jul 2015 04:34 Edited at: 28th Jul 2015 04:42
Yeah, I realized once I got to work (15 minutes after my post! ) that THAT was a ridiculous idea I had, and then had pretty much the same solution in mind when I got home and read your post!

EDIT: That is to say, I had the same solution that you had proposed in your post, in my head, so when I came home and read your post and saw that it made me happy haha!

Thanks for the help! Mucho appreciado!


Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 28th Jul 2015 10:44
No problem! I'm just glad it's clicked for you and you understand what we were babbling on about

Yodaman Jer
User Banned
Posted: 29th Jul 2015 01:48 Edited at: 29th Jul 2015 02:28
ISSUE SOLVED!

Hmm well now I have another question!

I didn't get this far with my last attempt so I don't really have any ideas. How would I make it so that when I scroll the map around (using the middle mouse button), my grid lines and sprites get drawn correctly?

It seems that I when I use SetViewOffset(), it messes with the creation/placing of new sprites and it gets offset by quite a bit.* This is the code I have now...



What would I need to do to correct my aforementioned issues?

EDIT: This issue I solved by doing this:


So that's all well and good! Now I just need to figure out how to get my grid to align properly...

EDIT 2: Oh well duh, why don't I just use the above technique for positioning my grid lines? Hmm what do you know, that works just dandy!



Now everything works just as expected!


Official Forum President from June 20th, 2015 - June 20th, 2016 (when my successor is elected, whomever that may be!).
Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 29th Jul 2015 10:39
I like you post with a problem and by the time I see it you've solved it already

Duncro
8
Years of Service
User Offline
Joined: 25th Jul 2015
Location:
Posted: 29th Jul 2015 20:22 Edited at: 29th Jul 2015 21:55
Im currently making a tilemap editor as well.
What i did is define a tilemap size by nr of tiles in x and y, then create blank sprites with 1 pixel spacing in between.
Each sprite ID is stored in an [i,j] array, as well as the tile id according to the atlas i imported.
You can then use "getspriteid()" according to the mouse pointer to get the sprite id you want to modify.



Maybe this could be a bit easier to manage?
I'll be putting the final product on the forum for anyone to use. Just having an issue with the menu atm to define all the variables

Ps, I noticed the code above isnt quite doing what it is supposed to. Currently implementing the write to file part of it
Yodaman Jer
User Banned
Posted: 2nd Aug 2015 17:40
So now I have a new issue, sort of.

I want to make it so that I can set the width and height of the map within the editor itself. The problem is that AppGameKit doesn't like how I try to do this.

Currently, I'm using constants to define my map array:



Since it can only be define with constants or literal integers, I thought that maybe assigning a variable like so would work...



But this still doesn't work. What can I do so that I can make the array resizable within the editor?


Forum President until June 20th, 2016. Bow down to me!
JLMoondog
Moderator
15
Years of Service
User Offline
Joined: 18th Jan 2009
Location: Paradox
Posted: 3rd Aug 2015 05:58 Edited at: 3rd Aug 2015 06:01
Hey Yodaman Jer, I'm also currently building a tile map editor for my game. Thought I'd give you some tips..

Quote: "I want to make it so that I can set the width and height of the map within the editor itself. The problem is that AppGameKit doesn't like how I try to do this. "


When you create your tile map array, define it's x and y sizes with a maximum amount. Basically, what's the largest size map you'd ever want to be able to build?



Then when you go to create a map or edit the size, use a defined size for x and y..



When you do a function check with your TileData array, use the defined sizes..



Now when you want to increase your map size, you just increase your defined sizes.



If you want to decrease your map size, you decrease your defined size, but you also need to get rid of whatever data you had stored outside the defined bounds..



Hope that clears it up a bit.

Try and keep it as simple as possible when building a map editor. If your function/code seems too complicated, than it probably is.

Good luck!

Uncle Martin
17
Years of Service
User Offline
Joined: 9th Jul 2006
Location: Tampa, Florida, USA
Posted: 3rd Aug 2015 06:12 Edited at: 3rd Aug 2015 06:20
JLMoondog's suggested approach is of course solid, you probably need to decide on worst case dimensions for GUI reasons; but to address the question of resizing arrays, if need be...

From the AGK2 Help Guide regarding new features of Arrays...

myArray as integer[5,10,15]

note that in these cases
"myArray.length" would return 5,
"myArray[0].length" would return 10 and
"myArray[0,0].length" would return 15,
and each dimension can be resized individually
myArray[0,0].length = 20
myArray[0,1].length = 30


I don't quite understand this syntax & I couldn't seem to get it to work. If someone knows how this works or can see an error in the help file, it would be good for us to know.

Anyway, reverting to the old array syntax, you could use DIM initially & then DIM again when you want to resize. The following code does all that.

NOTE: I'm not sure what happens to the data in the array when it is resized, probably safest to assume it is undefined, but in my example where both dimensions are enlarged, the initial data seems to remain intact.



I hope this helps.

Code every line like it might be your last...
Someday it will be.
Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 3rd Aug 2015 10:08
Quote: "When you create your tile map array, define it's x and y sizes with a maximum amount. Basically, what's the largest size map you'd ever want to be able to build?"


That has a couple of rather nasty disadvantages; one, and the most important, is the excessive memory usage (i.e, the memory used with be far more than necessary); two, how do you decide what size to limit the map to? If you make it too small, maps will be limited; make it too big, and the memory usage will be too great.

Quote: "From the AGK2 Help Guide regarding new features of Arrays..."


This, on the other hand, would be ideal, but I don't know much about AppGameKit arrays so I can't help much on actually writing code

JLMoondog
Moderator
15
Years of Service
User Offline
Joined: 18th Jan 2009
Location: Paradox
Posted: 3rd Aug 2015 10:36
Quote: "That has a couple of rather nasty disadvantages; one, and the most important, is the excessive memory usage (i.e, the memory used with be far more than necessary); two, how do you decide what size to limit the map to? If you make it too small, maps will be limited; make it too big, and the memory usage will be too great."


Lol what? I doubt believe that for a second. throw me some actual tested figures and I'll eat my words.

Hockeykid
DBPro Tool Maker
16
Years of Service
User Offline
Joined: 26th Sep 2007
Location:
Posted: 3rd Aug 2015 12:06
Quote: "That has a couple of rather nasty disadvantages; one, and the most important, is the excessive memory usage (i.e, the memory used with be far more than necessary);"


An integer array of [1000, 1000] (Equivalent to 1,000,000 integer variables) like the one from JLMoondog's example would only be 4 Megabytes of memory, which for a PC (I assume that's what this is for) would be nothing. A grid of 1,000 x 1,000 with 32x32 pixel tiles would be a huge 32,0000x32,0000 map.

Quote: "That has a couple of rather nasty disadvantages;"

It has the disadvantage of using more memory (very little memory) than needed, but the advantage of not having to find adjacent memory later when needing to reallocate the array which could negatively affect performance (especially when the array gets to be [1000, 1000]).

The best solution is to combine the two methods. Make your array a decent size at first for example: [100, 100]. Later when more space is needed in the array, allocate a decent amount more at a time rather than a single tiles worth. For example, increase each dimension of the array by 20 so your [100, 100] array would become [120, 120]. The reason for allocating a chunk at a time is to less frequently have to resize the array. When resizing an array, the memory locations must be adjacent. If an adjacent block of memory is being used by something else the entire array must be copied to a different location in memory so it can be expanded.


Sean

Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 3rd Aug 2015 14:32
Quote: "Lol what? I doubt believe that for a second. throw me some actual tested figures and I'll eat my words."


What are you going on about? It's a simple fact that you can't deny. Hard-coding the array at a worst-case size will use more memory than dynamically allocating memory as needed, unless the map happens to reach the maximum size. I don't know what you want me to test.

Quote: "An integer array of [1000, 1000] (Equivalent to 1,000,000 integer variables) like the one from JLMoondog's example would only be 4 Megabytes of memory, which for a PC (I assume that's what this is for) would be nothing. A grid of 1,000 x 1,000 with 32x32 pixel tiles would be a huge 32,0000x32,0000 map."


Fine, whatever. All I'm saying is that it's a bad way to write code, to just assume the array will never need more elements than it starts with. Hard-coding values is almost always bad practice, and it annoys me no end. It's why I so often felt frustrated with the way Lee was writing Game Guru. Maybe it's just my OCD, but deliberately writing inefficient code tends to drive me crazy.

Quote: "It has the disadvantage of using more memory (very little memory) than needed, but the advantage of not having to find adjacent memory later when needing to reallocate the array which could negatively affect performance (especially when the array gets to be [1000, 1000]).

The best solution is to combine the two methods. Make your array a decent size at first for example: [100, 100]. Later when more space is needed in the array, allocate a decent amount more at a time rather than a single tiles worth. For example, increase each dimension of the array by 20 so your [100, 100] array would become [120, 120]."


Depends on the situation. In this case, it's a tile map editor where you set the size once and then edit the map. A slight delay while the array resizes is totally acceptable in this case, and a fully dynamic array would probably be preferable. However, in a real-time situation (can't think of any right now - too tired), your suggestion of "chunk allocation" (the way C++ Vectors work) would probably be ideal.

Yodaman Jer
User Banned
Posted: 10th Aug 2015 05:36
@JLMoondog:

Thanks for those tips! I shall modify my editor in the appropriate manner

Sorry it took so long to respond, been a rather crazy week.


Forum President until June 20th, 2016. Bow down to me!

Login to post a reply

Server time is: 2024-04-25 11:01:31
Your offset time is: 2024-04-25 11:01:31