This past weekend, I ended up engaging in what I think was a bit of folly while working on the game. I wasn’t in a coding mood, but decided I could manually place walls on the grid lines for Quadrophobia. The idea there was I could easily turn the walls on and off when designing a level. This is a good idea.
However, placing the walls took a loooooooong time. There are, IIRC, 81 walls on a 5×5 grid (this includes the exterior/perimeter walls).
I’m sure there was a quicker way to do it, but I was doing them individually. Now that I think about it, I could have setup a “container” for each column and row then I’d just have to copy that container and drag all of them across the proper amount to their new column/row position. Nope – I ended up doing it individually. Whatevs.
But my other concern right now is expansion/expandability.If I want to make more rows/columns in future levels I’d have to continue to add more walls manually, which sucks. Had I done an algorithmic method I would expand easily.But, that would mean that the walls would only exist when the game was running, not necessarily in the editor. I’m sure if I dicked around with Custom Editors and shit, I’d find a way to have my cake and eat it too, however, I’m trying to get a damn game out, and the more I dick around with all these tools that Unity provides (even as powerful as they are) the less I get on making the game itself. I can learn some of that more later, but right now – getting a game finished comes first.So – manual it is.I’ll just leave a 5×5 grid
The next bit is to figure out how to get the walls working. I was able to get the collision detection via raycasting from my piece (one of the great things about Unity is the wealth of code just laying on the net, simple examples you can mostly plug and play right into your code with minor modifications). I’m not talking a whole game, just a little algorithm here and there.So I got that working and was going to implement my code to alter the movement accordingly to whether a wall was obstructing it.However, in my initial design, I had architected the code for movement to basically return a value on keypress. I then have a separate move function that moves based upon that return value. I separated the concerns so I could have better modularity in design and implement touch screen input along side my keyboard input. Nice clean separation of concerns. However it means that I can’t just do a simple raycast when I move the piece (via swiping or key down) and then set its move-ability, as I first need to detect the move direction and then modify the move amount (and since I set the direction separately from the move amount, it means I’m going to have to set the move amount beforehand).My line of thinking right now is, when I place the piece on the board, it scans the rays out, determines if there is a wall, and if so, where it is located.In order to determine where to place the piece if it hits a wall, there are two potential options I’m thinking.The first is a bit silly when I think about it, but it’s one solution:A) Each wall has 2 values. Since a wall is either horizontal or vertical, these values represent each side of the wall which could be hit. If my player detects a wall when it is below/south of a wall, it would pull the information on that wall indicating it’s southern point (that is, the square in the grid on which the piece should be played). This requires hand-coding a value into all 81 walls, and not just one value, but two (a top/bottom or left/right)The second makes more sense. It’s another algorithmic method. B) Here I determine what the wall’s location is (if I’m travelling along the y-axis (i.e. up/down), it will be detecting the walls y position; conversely if I travel left/right, I would detect the wall’s x position).
I would have to check whether the wall sits between me and the target position. If it does, then it would I would have to alter the target position before I move the piece. The new target position would then be equal to the location of the wall plus an offset (which would be half the height of a square in the grid). The sign of the offset would be determined by the direction of travel. It would be an inverse of my direction. That is – if I am moving Downward, that means I’m moving negatively on the Y axis. This means if I cast a ray in that direction and hit a wall, I would be adding the inverse of my movement vector (which was negative), which means I’m adding a positive offset (i.e. it would be ABOVE the wall) whereas if I’m coming from below, it means I’m traveling in a positive vector on the Y axis, and thus, the inverse of that is negative, which means I would be subtracting the offset value (thus making it under the wall, not on top).Now that I have this written down, tonight I will have to compress this all into the sweet syntactic sugar we know as “C# code” 😉
But, Dave, you ask… Why don’t you just hit the wall and stop?Well, dear reader, the problem is that I’m using the iTween library. While this library allows you to do nice things like transition easily between locations across a specified amount of time (which is what I’m using it for in Quadrophobia — though I realize I’m having the movement always be the same amount of time now and to be more realistic, it might be best to create a fixed amount of time per square and multiply that by the move amount so it takes just a wee bit longer to travel 5 spaces vs 1, but that’s a derail)…To get back on the track, since iTween uses a manual positioning, it means you’re not using the physics engine (though I suppose it might be possible, but I’m not using it that way, as I want precise positioning of my unit). This means that detecting whether I hit a wall at the time I hit it and having the piece “bounce back” isn’t quite as feasible. I could be wrong on this. But I think this incurs more cost (in this way – learning the specific feature of iTween that might allow this possibility – I believe my cursory check showed that this isn’t possible at all, but it might just be difficult).. This means that it’s quicker just to come up with a quick and dirty algorithm to do this since I will know what I’m doing and how I’m doing it.