Tile Swap

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Tile Swap

Author: Tsukihime



Overview

This script allows you to easily change tiles on the map.

Download

Script: Get it at Hime Works

Tutorial: Easy Tile Swapping. I would recommend reading this to see how this script works.

Extensions

"Swap From" functions - specify tile to swap using an existing tile on the map

Examples:

Making a bridge

A crack in the wall

Credits

KilloZapit, for providing the code for auto-tile generation.

Usage

There are three types of tile swaps

1. Change by tile id

-All tiles on the map with the specified ID will be changed to a new tile

tile_swap(old_tileID, new_tileID, layer, map_id)2. Change by region id-All tiles that are covered by the specified region ID will be changed to a new tile

region_swap(regionID, tileID, layer, map_id)3. Change by position-The tile at the specified position will be changed to a new tile

pos_swap(x, y, tileID, layer, map_id)]You can undo changes by using the following calls 

Code:
tile_revert(tid, layer, map_id)pos_revert(x, y, tid, layer, map_id)region_revert(rid, layer, map_id)revert_all
Understanding tilesThis script uses the concept of a "tile ID", which is a special string

that represents a particular tile on your tileset.

The format of this tile ID is a letter, followed by a number.

The letters available are based on the tileset names

A, B, C, D, E

The number represents the ID of the tile.

So for example, "A3" would be the the third tile in tileset A, whereas

"B12" would be the 12th tile of tileset B.

An example usage would be

tile_swap("A9", "A1", 0)Which will swap all "A9" tiles on layer 0 with "A1" tiles. As usual, because I did not pass in a map ID, it is assumed to be the current map. Please check the new script call format for details.It is very easy to look up the appropriate ID: just look at your tileset and number the top-left tile as 1. Then, numbering left-to-right, top-to-bottom, you would get something like this



For tileset A, it is a little different. This is assuming you have all 5 parts in tileset A.

You will need to skip over any missing pieces appropriately if you do not have all 5 parts.

To avoid all this unnecessary math, simply fill up the empty slots with dummy tilesets to make things easier.
 
Last edited by a moderator:

Monthigos

Tata
Veteran
Joined
Mar 21, 2012
Messages
53
Reaction score
11
First Language
English
Primarily Uses
This is a great script! So far I've used it to make an extending bridge.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Script updated.

Some bugs fixed.

Auto-tile updating has been implemented. Thanks to KilloZapit for the auto-tile generation code.

Now the tiles look proper after swapping



Usage same as before.

I have added support for using letters instead of just numbers for the tileset.

For example:

pos_swap(10, 15, 8, 0, "A")pos_swap(10, 15, 8, 0, 1)This changes layer 0 of the tile at position (10, 15) to tile 8 of tileset A.

Both statements do the same thing, except maybe the letter makes it easier to remember what's going on.

If you have any suggestions for improving the script calls I will consider them. Right now it seems too verbose and unintuitive.
 
Last edited by a moderator:

dragonborn99

Veteran
Veteran
Joined
Nov 15, 2012
Messages
229
Reaction score
3
First Language
Australian
Primarily Uses
This pretty cool and handy... I am going to save this script and use it for sure


This is awesome!!!
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
I have revised the entire script.

Please be aware of the following changes.

The changes were made in order to increase user-friendliness of the script.

1. The input tile ID is now a string composed of two pieces of information: the tileset as a letter, and the ID as a number.

"A7" would be the 7th tile in tileset A

"B2" would be the 2nd tile in tileset B

"C4" would be the 4th tile in tileset C

An example usage would be

tile_swap("A9", "A1", 0)Which will swap all "A9" tiles on layer 0 with "A1" tiles. As usual, because I did not pass in a map ID, it is assumed to be the current map. Please check the new script call format for details.

2. It is very easy to look up the appropriate ID: just look at your tileset and number the top-left tile as 1. Then, numbering left-to-right, top-to-bottom, you would get something like this



For tileset A, it is a little different. This is assuming you have all 5 parts in tileset A.

You will need to skip over any missing pieces appropriately if you do not have all 5 parts.

A1 starts at 0 and goes to 15

A2 starts at 16 and goes to 47

A3 starts at 48 and goes to 79

A4 starts at 80 and goes to 119

A5 starts at 120 and goes down to the last number

To avoid all this unnecessary math, simply fill up the empty slots with dummy tilesets to make things easier.
 
Last edited by a moderator:

ShinGamix

DS Style 4Ever!
Veteran
Joined
Mar 18, 2012
Messages
3,905
Reaction score
451
First Language
April Fools
Primarily Uses
N/A
I wish there was a demo for this.


-How to make a bridge


-How to water flow out.


-Hole in walls


-Secrets like Zelda:aLttP
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,030
Reaction score
13,669
First Language
English
Primarily Uses
RMMV
I LOVE this script!


It looks like the changes are not retained when you leave the map, and are lost on exiting the game. I suppose both could be managed with a parallel process event controlled by a switch to do all the setup on loading, which is fine.


I'm not sure I understand about the flowing water (and I assume waterfalls, or in general, anything on the A1 tile). Perhaps you could make an example for that one as well?


What are your terms for commercial use?
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
The changes should be preserved since the script is designed so that you have your original map, and then you have your custom tile data stored in $game_system. Whenever the map loads, it will see if there are any custom tiles to draw and then go ahead and draw them, so the custom stuff is stored in the savefile and handled automatically.

I have added the terms to the script. Free for commercial use.

There may be some script compatibility issues at the moment which may have resulted in the new tiles not being preserved.

I have updated the script just now to address some compatibility issues.

By flowing water, I'm assuming it's like you start with an empty canal, and then water pours in and starts filling it up from say left to right. Given that each tile is 32x32 I don't think it would be possible to make it look like water is gradually filling up the canal without some extra stuff...
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,030
Reaction score
13,669
First Language
English
Primarily Uses
RMMV
Ah, I looked through the script, but missed any reference to $game_system.

My reference to flowing water is in response to this:

For flowing water, you would use position swapping in your event with wait events in between.
Oh - I just realized that's probably exactly what you're talking about. You could probably also do it with regions. Initially I thought you meant changing a non-water area into a water area that requires animation, but it just clicked that that's exactly what you did in your tutorial.
 

ShinGamix

DS Style 4Ever!
Veteran
Joined
Mar 18, 2012
Messages
3,905
Reaction score
451
First Language
April Fools
Primarily Uses
N/A
I guess i meant "water draining".

As for Zelda secrets would be like a bomb blast opening a wall

or picking up a stone and a staircase appearing under it

or pushing

but I guess these would be done more with events.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Here is something I am considering: Area swap.

When you're mapping, it is common to select tiles like this



Rather than just selecting a 32x32 tile, you select a group of them and then place them on your map.

This is useful for objects that are larger than 32x32, such as bridges or that stone thing.

The currently planned script call looks like

area_swap(x, y, tileID, width, height, layer, mapID)Where

(x,y) is the position where the rectangle will be drawn

tileID is the tile ID of the tile in the top-left corner of your rectangle

width is how many tiles across will be taken (1 to 8, default 1)

height is how many tiles down will be taken (1 to 32, default 1)

layer is the layer you want to draw it on, default 0

mapID is the map this applies to, default the current map ID

If anyone has any further suggestions or things I should taken into consideration now is a good time before I actually implement it.

I have only considered area position-swapping, but area region-swapping doesn't seem too bad either.

I don't know what to call it though. region_area_swap?
 
Last edited by a moderator:

GnlMarcus

Villager
Member
Joined
Feb 22, 2013
Messages
7
Reaction score
0
First Language
French
Primarily Uses
I don't know if this would fit, but i'm trying to swap region id's on specific tiles.

let's say in a conditional branch

if switch 2 is on

then region_swap (1)

else region_swap (0)

end

i'm not great at scripting at I thought this could maybe fit in.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
region_swap does not mean swapping regions. It means "swapping tiles by region ID".


Unless you were talking about your own region swapping idea.


I have thought about providing a way to swap region ID's, but I would leave that for a different script.
 
Last edited by a moderator:

Rycochet

Villager
Member
Joined
Sep 12, 2013
Messages
14
Reaction score
3
First Language
English
Primarily Uses
A small extension for this - Tile Swap From - lets you specify a from map reference, rather than a tile id specifically. There are added methods for the three swap functions simply passing a command suffix and replacing the tid with a from_x, from_y.

Written mainly fo better looking door open/close animations ;-)

Not writing full details for it (and I'm giving full permission to Tsukihime to fold it into Tile Swap and then be under whatever license that is under etc)

Code

#==============================================================================## ▼ Rycochet - Tile Swap From v1.0# -- Extension to Tile Swap by Tsukihime# -- -- Last Updated: 2015.09.16# -- License: CC BY-NC 3.0 - https://creativecommons.org/licenses/by-nc/3.0/##==============================================================================class Game_System  def add_tile_id_from(map_id, layer, old_tid, from_x, from_y)    initialize_tile_list(map_id, layer)    old_tid = convert_tid(old_tid)    new_tid = $game_map.tile_id(from_x, from_y, layer)    @swapped_tiles[map_id][layer][old_tid] = new_tid    $game_map.load_new_map_data  end    def add_region_tile_from(map_id, rid, layer, from_x, from_y)    initialize_region_list(map_id)    tid = $game_map.tile_id(from_x, from_y, layer)    @swapped_region_tiles[map_id][[rid, layer]] = tid    $game_map.load_new_map_data  end    def add_position_tile_from(map_id, x, y, layer, from_x, from_y)    initialize_pos_list(map_id, layer)    tid = $game_map.tile_id(from_x, from_y, layer)    @swapped_pos_tiles[map_id][layer][[x, y]] = tid    $game_map.load_new_map_data  endendclass Game_Interpreter  def tile_swap_from(old_tid, from_x, from_y, layer=0, map_id=$game_map.map_id)    $game_system.add_tile_id_from(map_id, layer, old_tid, from_x, from_y)  end    def pos_swap_from(x, y, from_x, from_y, layer=0, map_id=$game_map.map_id)    $game_system.add_position_tile_from(map_id, x, y, layer, from_x, from_y)  end    def region_swap_from(rid, from_x, from_y, layer=0, map_id=$game_map.map_id)    $game_system.add_region_tile_from(map_id, rid, layer, from_x, from_y)  end  end
Example - For a 2 tile high (indoor) event

Create the door event as usual, but replace the two tiles above it with a black tile and a top-of-wall tile like this: (the door event is sitting on top of a normal floor tile)



Then in game closed and open look like this:

 


And the completed script:



This only places the top of the door back if the player is below the door (otherwise they get trapped) - if you have npcs then you also need to use another script to push them up and out of the way of the door gap (stuck) and top-of-wall (yes, I had a cat escape up there and wander around... It was fun ;) )

It removes the black background first (as the door is slightly shorter than the doorway), then the ceiling goes when the door is fully open (makes the animation look a little more "natural" due to not having a top edge.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
I'm interested in how it looks. Can you put up a demo for it as well? (or a gif/video, whichever works)
 

Rycochet

Villager
Member
Joined
Sep 12, 2013
Messages
14
Reaction score
3
First Language
English
Primarily Uses
Here's a (very quick and dirty) project (video here: http://youtu.be/I5NFgzBfIjg) with the type of door I now use. Unlike the standard doors they can be closed as well, but by using the "pos_swap_from()" method it means I can just copy and paste the event, rather than having to edit each one for floortype etc.

I do have ideas about possibly the source being an optional bounds type, check if the argument is an array, otherwise treat it like a single position, you mentioned something along those lines earlier in the thread - I'd also like to be able to choose if the destination had the full autotile attributed to it (ie, hide/show a ceiling over a carpet - but without the carpet edges appearing)... Nothing important there, just interesting to play with ;-)

Tile Swap From.zip
 

Attachments

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
I can see the advantage of tile swapping using relative designation (let the game figure that out) rather than absolute designation (you figuring that out). It's a good feature.


Here is another use case: suppose I performed a tile swap during the game that changed all the wooden floor tiles to marble tiles (suppose your game involves upgrading your home or something). Then the marble tiles will be picked up, allowing you to re-use the same event without having to use conditional branches depending on any possible changes to the map at run-time.
 
Last edited by a moderator:

Rycochet

Villager
Member
Joined
Sep 12, 2013
Messages
14
Reaction score
3
First Language
English
Primarily Uses
Exactly - been thinking about how to do it for multiple positions, or a rectangle, and thought something like -

pos_swap(x, y, tid, layer, map_id)pos_swap([x, y, width, height], tid, layer, map_id)pos_swap([[x, y], [x, y], ...], tid, layer, map_id)It would pull all of the processing into the interpreter part. Would be pretty simple to parse out I think, and given the different formats it could be used for the source in the *_from too, so you can choose to do shaped replacements that don't rely on using region flags (which can easily be used by other scripts etc).
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
I am considering moving certain functions into a dll, such as the actual ID swapping which needs to be fast. For sufficient number of elements, you will find that there is some lag. I don't think it is the tilemap that is just slow at updating the tiles.

For the area swap, I would like to use a Rectangle object (not the built-in Rect class, but a custom Rectangle class). Perhaps generalize it to arbitrary Shape objects if someone writes such a library so you can have circles, triangles, etc easily without having to do any math yourself.

I would like to avoid working with arbitrary arrays and instead pass around different types of objects depending on what you need.

Also, with the idea of multiple points to trace out some weird shape, I would rather throw that in its own class as well.

Then again, it might become an issue for users because..well...saying things like

Code:
Triangle.new( ... )
is probably more daunting than just passing in an array of three points.
 
Last edited by a moderator:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

rux
Just 80% of my motivation on game making lmao, anyone got tips on how to not be unmotivated?
I've signed up for a job training program for people with Asperger's Syndrome. I went to a "test run" today so they could see how well I did with simple jobs, and I amazed them. Most new people do it in 30+ minutes, while I finished in a mere 15 minutes. Gives me time to work on a screenplay for Studio MDHR...
People,I have seen that Someone from China/Chile and London is doing a Vaccine Against COVID-19.
Doing anything that yield good result in the long run is like sowing seeds. With proper care, they will grow and bear fruits. I'm excited for tomorrow. :D

Forum statistics

Threads
105,455
Messages
1,013,841
Members
137,105
Latest member
twilightprincess
Top