Popular Post Mallaboro Posted September 10, 2018 Popular Post Share Posted September 10, 2018 (edited) Turns orthogonal images into isometric spritesheets. As of this release (v1.0) it is limited only to size 128x, 64y tiles. Download: IsometricTiled.zip Source: Pastebin (IsometricTiled.cs) Generic on-use UI ✔️ Render Background, ❌Arrange Tiles by Orthogonal Position Having 'Arrange tiles by orthogonal position' unchecked makes tiles arrange in columns, having it checked however, it tries to keep some semblance of its original position. This makes reassembling the image much easier. ✔️ Render Background, ✔️ Arrange Tiles by Orthogonal Position I made this because I'm working on a project that uses isometric tiles, and this way I can paint trees normally, then slice them into tiles and import them into Tiled for making game maps. Issues There is an issue I've not been able to resolve. If the canvas is not large enough to fit all the tiles they will not be added to the canvas. Furthermore, while this isn't an issue it should be noted that if the background is not transparent, the plugin will recognise the background as a tile and copy it as one. Lastly... This is my first plugin for paint.net, and the first thing I've ever published. It was made just for me, so it's missing a few features that I can live without, like the option to change tile dimensions and the background colour. I'll add the option to change tile dimensions sometime later but for now I really want to get back to working on my project. CodeLab Source Spoiler // Name: Isometric Tiled // Submenu: Stylize // Author: Anthony "Mallaboro" // Title: Isometric Builder // Version: 1.0 // Desc: Turns orthogonal images into an array of isometric tiles // Keywords: Orthogonal, Isometric // URL: https://litematrix.blogspot.com/ // Help: anthonyeboothroyd@gmail.com #region UICode bool Amount1 = true;//Render background (black) bool Amount2 = true;//Arrange tiles by orthogonal position #endregion class Tile { //tile width and height public static int Width = 128; public static int Height = 64; //these indexes are used when arranging tiles by orthogonal position public int x = 0; public int y = 0; //the array of pixel data public ColorBgra[,] pixels; public Tile(int x, int y, bool checkers) { pixels = new ColorBgra[ Tile.Width, Tile.Height ]; this.x = x; this.y = y; if(checkers) { //outside for( int _y = 0; _y < Tile.Height; _y++ ) for( int _x = 0; _x < Tile.Width; _x++ ) { if( _y < Tile.Height / 2 ) if( _x <= ( Tile.Width / 2 ) - ( 2 * _y ) || _x >= Tile.Width / 2 + ( 2 * _y ) ) { pixels[ _x, _y ].R = 0; pixels[ _x, _y ].G = 0; pixels[ _x, _y ].B = 0; pixels[ _x, _y ].A = 255; } if( _y >= Tile.Height / 2 ) if( _x <= ( Tile.Width / 2 ) - ( Tile.Width / 2 ) + ( _y - ( Tile.Height / 2 ) ) * 2 || _x >= ( Tile.Width / 2 ) + ( Tile.Width / 2 ) - ( _y - ( Tile.Height / 2 ) ) * 2 ) { pixels[ _x, _y ].R = 0; pixels[ _x, _y ].G = 0; pixels[ _x, _y ].B = 0; pixels[ _x, _y ].A = 255; } } } } //"Input" the incoming pixel data //"x", "y", the pixel index of this tiles pixel array public void Set( ColorBgra input, int x, int y ) { //temporary restriction, we do not accept black pixels //if( pixels[ x, y ] == ColorBgra.Black ) // return; //if the incoming pixel being set is within these parameters, //it is within this tiles shape and will be stored. bool left = x <= Tile.Width / 2; bool right = x >= Tile.Width / 2; bool top = y <= Tile.Height / 2; bool topRight = x < ( Tile.Width / 2 ) + ( y * 2 ); bool topLeft = x > ( Tile.Width / 2 ) - ( y * 2 ); bool bot = y > Tile.Height / 2; bool botLeft = x > ( 2 * ( y - Tile.Height / 2 ) ); bool botRight = x < ( Tile.Width ) - ( 2 * ( y - Tile.Height / 2 ) ); //tiles are seporated into 4 quadrants. If the incoming pixel overlaps one of these 4 quadrants it is stored. if( top ) if( left && topLeft ) { pixels[ x, y ] = input; } if( top ) if( right && topRight ) { pixels[ x, y ] = input; } if( bot ) if( left && botLeft ) { pixels[ x, y ] = input; } if( bot ) if( right && botRight ) { pixels[ x, y ] = input; } } //returns whether or not this tile contains any pixel of color (excluding pure black and pure white) public bool IsOccupied() { for( int y = 0; y < Height; y++ ) for( int x = 0; x < Width; x++ ) { if( pixels[ x, y ].R > 0 && pixels[ x, y ].R < 255 || pixels[ x, y ].G > 0 && pixels[ x, y ].G < 255 || pixels[ x, y ].B > 0 && pixels[ x, y ].B < 255 ) return true; } return false; } //returns the specified pixel at the x, y index. public ColorBgra Get( int x, int y ) { return pixels[ x, y ]; } } void Render( Surface dst, Surface src, Rectangle rect ) { //clear the canvas for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; for (int x = rect.Left; x < rect.Right; x++) dst[x,y] = ColorBgra.Transparent; } //NOTE TO SELF: top-left is 0, 0 //a list of occupied tiles containing data List<Tile> tiles = new List<Tile>( ); //sample tile to check whether it has any data Tile sample; //toggle changes every Y iteration. It keeps the x-axis in the correct position for isometric images //(toggle == true == pixel_x = 0), (else pixel_x = -( Tile.Width / 2 );) bool toggle = false; //pixelX and Y are the top-left corners of the tile being analyzed. These values change. int pixel_x = -( Tile.Width / 2 ); int pixel_y = -( Tile.Height / 2 ); //easy-access int width = src.Bounds.Width; int height = src.Bounds.Height; //tiles wide and tiles tall are incrimented by 1 to capture the image along the edges //to elaborate: tiles[0,0] position is -(Tile.Width / 2, -(Tile.Height / 2 //tiles tall is doubled to account for Tile.Height being half of Tile.Width int tilesWide = (width / Tile.Width) + 1; int tilesTall = (height / Tile.Height) * 2 + 1; //assign each tile their location for (int y = 0; y < tilesTall; y++) { for (int x = 0; x < tilesWide; x++) { sample = new Tile(x, y, Amount1); for (int Y = 0; Y < Tile.Height; Y++) { for (int X = 0; X < Tile.Width; X++) { if ((pixel_x + X < 1) || (pixel_y + Y < 1)) continue; if ((pixel_x + X > width-2) || (pixel_y + Y > height-2)) continue; sample.Set(src[pixel_x + X, pixel_y + Y], X, Y); } } if(sample.IsOccupied()) tiles.Add(sample); pixel_x += Tile.Width; } toggle = !toggle; pixel_x = toggle == true ? 0 : -( Tile.Width / 2); pixel_y += Tile.Height / 2; } int _x = 0; int _y = 0; if(Amount2 == false) { for(int i = 0; i < tiles.Count; i++) { for (pixel_y = 0; pixel_y < Tile.Height; pixel_y++) for (pixel_x = 0; pixel_x < Tile.Width; pixel_x++) { //prevent crashes if screen width or height isn't great enough //to fit the tiles if((_x * Tile.Width) + pixel_x >= width) break; if((_y * Tile.Height) + pixel_y >= height) break; dst[ (_x * Tile.Width) + pixel_x , ( _y * Tile.Height) + pixel_y] = tiles[i].pixels[pixel_x, pixel_y]; } _x++; if(_x >= tilesWide-1) { _x = 0; _y ++; } } } else { for(int i = 0; i < tiles.Count; i++) { for (pixel_y = 0; pixel_y < Tile.Height; pixel_y++) for (pixel_x = 0; pixel_x < Tile.Width; pixel_x++) { //prevent crashes if screen width or height isn't great enough //to fit the tiles if((tiles[i].x * Tile.Width) + pixel_x >= width) break; if((tiles[i].y * Tile.Height) + pixel_y >= height) break; dst[ (tiles[i].x * Tile.Width) + pixel_x , ( tiles[i].y * Tile.Height) + pixel_y] = tiles[i].pixels[pixel_x, pixel_y]; } } } } Edited October 22, 2020 by Ego Eram Reputo Added source 5 5 Quote Link to comment Share on other sites More sharing options...
Seerose Posted September 14, 2018 Share Posted September 14, 2018 (edited) @Mallaboro! Welcome to family. Hopefully you'll have a lot of fun, too. Thank you for the sharing. Edited September 14, 2018 by Seerose Quote Live as if you were to die tomorrow. Learn as if you were to live forever. Gandhi Link to comment Share on other sites More sharing options...
Roly Poly Goblinoli Posted October 3, 2018 Share Posted October 3, 2018 (edited) I'm curious why the tree needs to be split into isometric tiles. I take it everything in Tiled must conform to tile shapes or something. Edited October 3, 2018 by Joshua Lamusga Quote Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted October 3, 2018 Share Posted October 3, 2018 To make a game map. The tiled tree becomes a sprite which can be used over and over. An isometric tile version of this Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
Roly Poly Goblinoli Posted October 3, 2018 Share Posted October 3, 2018 I've never made an isometric game, so I wouldn't know if it's normal to draw multiple sprites to compose one static image, but what I'm suggesting is that the tree shouldn't be split into isometric tiles at all, and the game tile & draw logic should accommodate untiled objects. I suppose it's a restriction of the Tiled software I'm not familiar with right now. Quote Link to comment Share on other sites More sharing options...
RandwulfX49 Posted December 18, 2019 Share Posted December 18, 2019 This looks like it could be great for creating the tile map itself. Maybe add a separate layer on top for the rest of the sprites? That way you could have a layer between where the characters can move and you could have them go behind the other sprites and be hidden momentarily. You would only need isometric sprites for collision detection on the middle (character) layer. Does any of that make sense? Quote Link to comment Share on other sites More sharing options...
Foxxey Posted June 27, 2020 Share Posted June 27, 2020 (edited) Very cool and useful plugin! Great work! Edited June 27, 2020 by Foxxey Quote Link to comment Share on other sites More sharing options...
kratom the tree Posted October 20, 2020 Share Posted October 20, 2020 I apologies but I am a noob at paint.net. But how do I use this tool? I was able to install but I can not figure out where the tool is located or how to use it properly. Im going to poke around some more but any tips would be greatly appreciated. Thank you for developing this tool. It looks like it is going to make my life so much easier. Quote Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted October 20, 2020 Share Posted October 20, 2020 Hey @kratom the tree - welcome to the forum To find this plugin, look in the Effects > Stylize submenu. 1 Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
kratom the tree Posted October 20, 2020 Share Posted October 20, 2020 (edited) @Ego Eram Reputo OMG Thank you so much! That was the fix. How would I go about extracting a individual tile? Also, how would I resize them? Also Is it possible to change the size of a tile? I need it to be this size. I think it is 50x28? Sorry for all the questions. Like I said I am quite a noob. Edited October 20, 2020 by kratom the tree Quote Link to comment Share on other sites More sharing options...
Reptillian Posted October 20, 2020 Share Posted October 20, 2020 10 minutes ago, kratom the tree said: @Ego Eram Reputo OMG Thank you so much! That was the fix. How would I go about extracting a individual tile? Also, how would I resize them? Also Is it possible to change the size of a tile? I need it to be this size. I think it is 50x28? Sorry for all the questions. Like I said I am quite a noob. There isn't, but you are welcome to dive into the source code and try to enable it. Quote G'MIC Filter Developer I am away from this forum for undetermined amount of time: If you really need anything related to my PDN plugin or my G'MIC filter within G'MIC plugin, then you can contact me via Paint.NET discord, and mention me. Link to comment Share on other sites More sharing options...
kratom the tree Posted October 20, 2020 Share Posted October 20, 2020 5 minutes ago, Reptillian said: There isn't, but you are welcome to dive into the source code and try to enable it. Should I just try to crop each individual tile? Quote Link to comment Share on other sites More sharing options...
LoudSilence Posted October 20, 2020 Share Posted October 20, 2020 This plugin should help you depending on what you are using this plugin for Quote PDN Discord Server Link to comment Share on other sites More sharing options...
kratom the tree Posted October 20, 2020 Share Posted October 20, 2020 3 minutes ago, LoudSilence said: This plugin should help you depending on what you are using this plugin for I'm not sure if that is it tbh. I am trying to make tile's for my 2d isometric game. I am trying to mimic this exact size and shape from the game assets. Here are some examples. the first are the tiles after I run the tool. The other 3 are tiles from the game. Quote Link to comment Share on other sites More sharing options...
LoudSilence Posted October 20, 2020 Share Posted October 20, 2020 12 hours ago, kratom the tree said: I am trying to mimic this exact size and shape from the game assets. That was what i was afraid of, it's why i highlighted that it only works depending what you use it for Quote PDN Discord Server Link to comment Share on other sites More sharing options...
Reptillian Posted October 22, 2020 Share Posted October 22, 2020 @kratom the tree I have decided to work on a gmic filter that would address the size issue. I do not know on how to address the OP's source code. Quote G'MIC Filter Developer I am away from this forum for undetermined amount of time: If you really need anything related to my PDN plugin or my G'MIC filter within G'MIC plugin, then you can contact me via Paint.NET discord, and mention me. Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted October 22, 2020 Share Posted October 22, 2020 (edited) 19 minutes ago, Reptillian said: I do not know on how to address the OP's source code. The link in the first post is still active. It's a codelab source file. Simply copy & paste it into the CodeLab editing window. Edit: I've added the source to the first post in case the link dies. Edited October 22, 2020 by Ego Eram Reputo Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
Reptillian Posted October 22, 2020 Share Posted October 22, 2020 4 minutes ago, Ego Eram Reputo said: The link in the first post is still active. It's a codelab source file. Simply copy & paste it into the CodeLab editing window. Edit: I've added the source to the first post in case the link dies. I'm aware of how to copy and paste to there as well as making changes. The thing is I don't understand the OP code well enough to address it as a individual pdn plugin, hence my mentioning of gmic since I know that language really well. Quote G'MIC Filter Developer I am away from this forum for undetermined amount of time: If you really need anything related to my PDN plugin or my G'MIC filter within G'MIC plugin, then you can contact me via Paint.NET discord, and mention me. Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.