| 09-25-2011, 04:39 AM | #1 | |
So as anitarf knows, I like to try things that I have absolutely no idea how to do and then inevitably end up here asking someone to help fix what I (possibly) shouldn't have started in the first place. Well this time its not any different. Well its a little bit different, but not in a good way. This time I have absolutely no idea how to do (the majority) of this Mazes for people who've never played them (this is important if you don't know what a maze is but still want to help (<3s)) in mazes there's a path. In this example the path is ice. If you step off the path with your unit (you only have 1) your unit dies. In this example the death terrain is snow. ![]() on a sidenote, this is for a friend. I probably never would name a map about lettuce. so here's the idea this struct remembers the initial terrain types (on initialization) at every 128x128 space in the given terrain change rects this is an example of how the rects would be setup. I'll get to why there are 3 rects instead of 1 later. ![]() what happens is this entire path is replaced with snow and then every x seconds a row or column is revealed. But also only so many (variable) rows/columns are revealed at a time.
so I'll post the parts that I was able to do JASS:struct TerrainChangeRect integer TrailSize real TimeStep integer StartCorner //0 = bot left, 1 = bot right, 2 = top left, 3 = top right integer array TerrainTypes[0] //records the integer values for each terrain type in the rect boolean RectType //false = horizontally long, true = vertically long integer XDirection integer YDirection real XStart real YStart real XEnd real YEnd static method create takes rect area, integer trailSize, real timeStep, integer startCorner returns TerrainChangeRect local TerrainChangeRect new = TerrainChangeRect.allocate() local integer i = 0 local real x local real y local real AreaMinX = GetRectMinX(area) local real AreaMinY = GetRectMinY(area) local real AreaMaxX = GetRectMaxX(area) local real AreaMaxY = GetRectMaxY(area) set new.TrailSize = trailSize set new.TimeStep = timeStep set new.StartCorner = startCorner if startCorner = 0 then set x = AreaMinX set y = AreaMinY set new.XDirection = 1 set new.YDirection = 1 set new.XEnd = AreaMaxX set new.YEnd = AreaMaxY set new.XStart = AreaMinX set new.YStart = AreaMinY elseif startCorner = 1 then set x = AreaMaxX set y = AreaMinY set new.XDirection = -1 set new.YDirection = 1 set new.XEnd = AreaMinX set new.YEnd = AreaMaxY set new.XStart = AreaMaxX set new.YStart = AreaMinY elseif startCorner = 2 then set x = AreaMinX set y = AreaMaxY set new.XDirection = 1 set new.YDirection = -1 set new.XEnd = AreaMaxX set new.YEnd = AreaMinY set new.XStart = AreaMinX set new.YStart = AreaMaxY else set x = AreaMaxX set y = AreaMaxY set new.XDirection = -1 set new.YDirection = -1 set new.XEnd = AreaMinX set new.YEnd = AreaMinY set new.XStart = AreaMaxX set new.YStart = AreaMaxY endif if ((RAbsBJ(new.AreaMaxX) - RAbsBJ(new.AreaMinX)) > (RAbsBJ(new.AreaMaxY) - RAbsBJ(new.AreaMinY))) then //rectangle is horizontally long and should use vertical strips set new.RectType = false loop exitwhen x > new.XEnd loop exitwhen y > new.YEnd set new.TerrainTypes[i] = GetTerrainType(x, y) set i = i + 1 set y = y + (yDirection * TerrainYSize) endloop set y = new.YStart set x = x + (xDirection * TerrainXSize) endloop else //rectangle is vertically long and should use horizontal strips set new.RectType = true loop exitwhen y > new.YEnd loop exitwhen x > new.XEnd set new.TerrainTypes[i] = GetTerrainType(x, y) set i = i + 1 set x = x + (xDirection * TerrainXSize) endloop set x = new.XStart set y = y + (yDirection * TerrainYSize) endloop endif return new endmethod endstruct this records the terrain types in the TerrainTypes[] array. because its using an array (as opposed to a hashtable or (maybe) a table) their indices matter. Thus the (sorta) switch statement on the value of startCorner tells the loop what corner to start in. As is, it automatically chooses whether to add in horizontal or vertical bands by looking at the size of the rect horizontally vs. vertically. so here's a few features i want to incorporate integer TrailSize: this refers to how long of a trail is behind the "front" real TimeStep: this refers to how long between each update to the trail the first tricky part is that these (as i want them) are both specific to each rect. another thing is that all these TerrainChangeRects will be (unless I'm doing this completely wrong) inside another struct like this: JASS:struct TerrainChangeArea TerrainChangeRect array Rects[0] integer DefaultTerrainType real Period readonly integer rI public method start takes boolean returns nothing endmethod public method insertAt takes integer insertHere, rect area, integer trailSize, real timeStep, integer startCorner returns nothing endmethod public method insert takes rect area, integer trailSize, real timeStep, integer startCorner returns nothing endmethod public method removeAt takes integer deleteHere returns nothing endmethod public method remove takes nothing returns nothing endmethod static method create takes real period, integer ttype, rect area, integer trailSize, real timeStep, integer startCorner returns TerrainChangeArea local TerrainChangeArea new = TerrainChangeArea.allocate() set new.Period = period set new.DefaultTerrainType = ttype set new.Rects[0] = TerrainChangeRect.create(area, trailSize, timeStep, startCorner) //period is too small for the given trailsize and timestep if new.Period =< (trailSize * timeStep) then set new.Period = (trailSize * timeStep) + 4 endif set new.rI = 1 return new endmethod endstruct this is kinda an ordered conglomeration of all the different TerrainRects. but this also has its own timer (period). Ie every x seconds (where x is the period) this "snake" of terrain change starts and goes through (completely separate from all other "snakes"). This is hard to explain and I'm sure it shows, so I attached a map from a friend that shows this concept of mazing in action. use arrow keys to control the mazer. The way he did this level was a huge mass of individual terrain change calls (which this will do as well, just in a much, much lazier and easy way) anyways I'm literally taking anything offered for this project from actual code to death threats in the mail, everything is appreciated because I have absolutely no idea how to proceed from here. |
| 09-25-2011, 04:12 PM | #2 |
I think there are easier ways to approach this than the one you took. It seems like it would be easier to simply do manual data entry for each terrain tile than to make the path in the terrain editor and then read it with triggers, especially since that still requires data entry in the form of regions. Sure, you can still draw the thing in the terrain editor first to see how it works out. Then, what I'd do is take a piece of paper with square grid lines on it and copy the layout, adding numbers to all rows and columns covered by the maze. Once that is done, I'd take the CineScript library and write a module for it that changes terrain tiles, with a public API consisting of a single function: function ScriptTerrainTile takes CineScript s, real timestamp, integer tilex, integer tiley, integer tiletype returns nothing With this code and your sheet of paper, you could make a CineScript that gradually creates ice tiles along your maze. If you made the function that writes this CineScript take a terrain tile argument, you could then use it write both the script that creates ice tiles as well as the script that turns them back to snow. In game, you would just run these two scripts with a sufficient delay between them, at the ingame coordinates where the 0,0 tile on your paper is. The first script would be creating ice tiles and the second one, run later, would be turning those back into snow tiles. |
| 09-27-2011, 08:02 AM | #3 |
If you have a chance could you give me a bit more direction than that? I'm really bad at learning things from description. I pick things up really quickly from examples though. I think I'll take your advice and try hardcoding it first, but I'd like to create the module in a way that later on I can implement some sort of auto create. |
| 09-27-2011, 11:01 AM | #4 |
Well, this is what a terrain type CineScript library would look like: JASS:library TerrainCineScript requires CineScript private struct TerrainTypeAction extends ScriptAction private real x private real y private integer typ private integer var private integer size private integer brush static method create takes CineScript s, real timestamp, real x, real y, integer typ, integer var, integer size, integer brush returns TerrainTypeAction local TerrainTypeAction this=TerrainTypeAction.allocate(s, timestamp, 0.0) set .x=x set .y=y set .typ=typ set .var=var set .size=size set .brush=brush return this endmethod method run takes nothing returns nothing call SetTerrainType(.parent.globalX(.x,.y),.parent.globalY(.x,.y),.typ, .var, .size, .brush) endmethod endstruct function ScriptTerrainType takes CineScript s, real timestamp, integer tileX, integer tileY, integer terType, integer variation, integer size, integer brushType returns nothing call TerrainTypeAction.create(s, timestamp, tileX*128.0, tileY*128.0, terType, variation, size, brushType) endfunction endlibrary Then, you would use it like this: JASS:globals private CineScript mazeMaker private CineScript mazeEraser endglobals private function WriteMazeScript takes integer terrainTile returns CineScript local CineScript s=CineScript.create() set s.x = X_COORDINATE_OF_BOTTOM_RIGHT_TILE set s.y = Y_COORDINATE_OF_BOTTOM_RIGHT_TILE // I made the tile changes below happen once per second, // but you can easily change this by modifying the speed of the script. set s.speed=1.0 call ScriptTerrainType( s, 0, 0, 0, terrainTile,-1, 1,0) call ScriptTerrainType( s, 0, 0, 1, terrainTile,-1, 1,0) call ScriptTerrainType( s, 0, 0, 2, terrainTile,-1, 1,0) call ScriptTerrainType( s, 1, -1, 0, terrainTile,-1, 1,0) call ScriptTerrainType( s, 1, -1, 2, terrainTile,-1, 1,0) call ScriptTerrainType( s, 2, -2, 0, terrainTile,-1, 1,0) call ScriptTerrainType( s, 2, -2, 1, terrainTile,-1, 1,0) call ScriptTerrainType( s, 2, -2, 2, terrainTile,-1, 1,0) call ScriptTerrainType( s, 3, -3, 1, terrainTile,-1, 1,0) call ScriptTerrainType( s, 4, -4, 0, terrainTile,-1, 1,0) call ScriptTerrainType( s, 4, -4, 1, terrainTile,-1, 1,0) call ScriptTerrainType( s, 4, -4, 2, terrainTile,-1, 1,0) call ScriptTerrainType( s, 5, -5, 0, terrainTile,-1, 1,0) call ScriptTerrainType( s, 5, -5, 2, terrainTile,-1, 1,0) call ScriptTerrainType( s, 6, -6, 0, terrainTile,-1, 1,0) call ScriptTerrainType( s, 6, -6, 1, terrainTile,-1, 1,0) call ScriptTerrainType( s, 6, -6, 2, terrainTile,-1, 1,0) //...and so on. endfunction private function StartMaze takes nothing returns nothing call mazeMaker.run() // wait however long you like. call mazeEraser.run() endfunction private function Init takes nothing returns nothing set mazeMaker=WriteMazeScript( ICE_TILE ) set mazeEraser=WriteMazeScript( SNOW_TILE ) endfunction |
| 09-27-2011, 08:52 PM | #5 |
This. This is perfect Thank you so much Ani And wow, you can actually change the speed at any time too thats incredibly cool tytytyty |
