Hi you all, welcome back after what's been hopefully a lovely easter with much chocolate for everyone! I've got a few new clips for you guys to show some progress, this time it's the very beginnings of a battle system, starting at the very bottom with ... just spawning the enemy encounters! Yaaay?
The old classical way of just random encounters to start a battle would have probably been the easiest way (just have a random chance to generate an encounter on each step or something), but I'm personally not too fond of the constant invisible encounters. They do sometimes become a bit annoying, especially if they can't be avoided.
So I've decided to go the other common route: to spawn in some sort of blob/vague enemy avatar on the map and initiate the battle scene if you run into it, giving you a chance to avoid battle if you want to. A bit extra work, but not too much to not make it worth it. The first step was to figure out how to spawn things randomly but uniformly distributed inside an irregularly shaped area:
Which turned out to be way trickier than I thought! My first idea was "hmm, maybe if the script picks two random coordinates on the outline of an area, and then picks a random spot on the line between those two spots, that'd be fairly random and uniform?" Of course I quickly figured out that with that method the random spot picks would start clustering in any narrow, winding portions of the spawn areas, since those would have way bigger outline to surface ratio compared to any large, open areas. No good! After much pondering I concluded this is a way to do it:
1: Get a list of all the triangles that make up the spawn area shape (apparently pretty much all shapes are represented as a bunch of triangles, that's something I didn't know before.) 2: Calculate the area of each triangle and assign every triangle a value based on its area compared to the total area. Use this value to determine how probable it is to pick each of the triangles with a random value. (Eg. a triangle with twice the area than a smaller one should have twice the probability of being picked.) 3: Then pick a random point inside the chosen triangle (Easier said than done!)
Unfortunately I seem to have forgotten every single thing about math that I have ever learned since graduating 11th grade, frankly I haven't needed to use any of it in the last 10 years. Uuuuunitl now, suddenly. It's a little silly that in this whole process the functions for CalculateTriangeArea() and PickRandomPointInsideTriangle() were the ones that gave me the most trouble, and they stayed completely empty until the very end when I finally went trawling the internet for algorithms to put in there. :P
Anyway, as you're able to see from the clip above, things worked out and the spawning script is working quite nicely!
The second part of enemy spawns was much easier. Just a little script that makes the blobs move around lazily, detect if the player gets too close, starts chasing the player(red color means chasing mode is activated) and then either collides with the player and launches a battle (well that's the plan, right now it just destroys itself) or eventually loses interest and goes back to aimlessly moving around:
And oh, don't worry, there won't be that many enemies at a time for real in the game, that's way too many! It's just for easier testing. I'll tweak the spawn frequency and behaviour and test it out with you guys later once everything's a bit further along.
Then one last thing, completely unrelated to enemy spawns: light and shadows on the character:
Yaaay! My first shader in work! It's a simple one but does help provide a faux light and shadow effect. The "shadow" areas are defined with a collider object on the ground that holds information of a color (dark violet in this case). The player character is constantly doing a raycast on its position as it moves around, and if that raycast hits a collider which holds such a color information, it'll tell the shader on the player sprite to gradually shift towards that color. And if it hits no such collider it will shift towards/stay at the default color for a scene, a pale yellow in this case.
And it works in the inverse too. So instead of "shadow" areas there can be light spots or just general color shift areas marked out. As long as the color found with the raycast is different than the current color of the shader it'll start changing towards it. Medium grey is the baseline, which will show the sprite in its neutral, normal colors.
That's that for today, a fairly good amount of progress made. Next time ... maybe I'll fix up the inventory and item usage. See you then~