After a lengthy absence, I'm returning to making a bump-attack Ys engine. I made a discovery about the system from Ys I&II, and it seems that you take damage if you bump an enemy head-on, but you DON'T take damage if you bump an enemy off-center (basically clipping it form the side).
So, I did some brainstorming and the Bump() proc seems obvious. Now, to bump off-center, I feel I need to use step size 8 so that offset clashes are even possible, but my question is:
What do I call during the Bump proc to make the user bump another mob off-center?
Jan 17 2016, 12:18 am
|
|
Bump is able to handle pixel movement collisions just fine.
|
I opted out of pixel movement because it frightens me lol. I decided to just use step size 8 with the classic movement system instead. My troubles come from getting Bump() to differentiate from colliding head-on with an enemy (taking damage), and me bumping the enemy halfway (dealing damage). I'm not sure which variable determines whether I bumped it fully or clipped its side.
|
If you're using a step size less than or greater than, but not divisible by, world.icon_size you're using pixel movement. Bump() doesn't treat either form differently.
|
You will need to know the absolute x or y coordinates of the lesser and greater points of the enemy bounding box to determine this.
To calculate the absolute coordinates: left: (x-1)*TILE_WIDTH + step_x + bound_x + 1 Let's make some shortcuts for this: #define left_x(ref) ((ref:x-1)*TILE_WIDTH + ref:step_x + ref:bound_x + 1) What we're going to need to do is get the axis that the bump occurs on. If you are allowing diagonal movement, there are three possibilities. If you are not allowing diagonal movement, there are only two. Let's assume that you are are allowing diagonal movement. In order to correctly determine the axis of the bump, we're going to need to check for the three cases. The only way we can check these three cases is by getting the X and Y deltas of the opposing edges. //let's just set up a Bump() analogue to make our life easier. mob What we're doing in the above bit of code is determining what direction the bump is coming from. Because the mob's facing direction isn't entirely reliable for detecting on what part of the bounding box the collision occurred, we have to do this manually. It's fairly ugly. Using trig could result in a much cleaner code structure, but is going to be more computationally expensive than a simple if-else chain. Now that we've got the collision info, we need to know what to do with it. Now we're going to compare axial overlap. If the collision is happening on a diagonal case, that's CASE 1. If it's happening on an EAST or WEST case, it's CASE 2. If it's happening on a NORTH or SOUTH case, that's case 3. Diagonal case, I'm not sure what to do with it, so I'll leave that up to you. In order to calculate case 2 and case 3, we need to know how much of the player's hitbox should not cross into the enemy's hitbox in order to determine damage. Let's set this up: mob CASE 2 (from EAST/WEST) math: this_y2 = this_y1 + hitbox_y + hitbox_height - 1 CASE 3 (from NORTH/SOUTH) math: this_x2 = this_x1 + hitbox_x + hitbox_width - 1 Now that we know how to set all of this up for each case, let's just put it all together. #define left_x(ref) ((ref:x-1)*TILE_WIDTH + ref:step_x + ref:bound_x + 1) This is not a simple problem to solve. BYOND, unfortunately gives you very little information about collision events. Some of this information is actually fairly difficult to suss out without an extensive knowledge of the underlying structure of how things work. There are probably better ways of going about this, but this is what I managed to come up with in the moment. There are also significant optimizations to this approach available, and there are also more than likely a few things in this approach that will have to be adapted to your specific game's structure. |
In response to Chaoder
|
|
Chaoder wrote:
I opted out of pixel movement because it frightens me lol. I decided to just use step size 8 with the classic movement system instead. My troubles come from getting Bump() to differentiate from colliding head-on with an enemy (taking damage), and me bumping the enemy halfway (dealing damage). I'm not sure which variable determines whether I bumped it fully or clipped its side. Ys's combat system will not work with tile-based movement. I'm sorry, but you can't opt out of this one if you want to do what you are trying to do. The pixel movement system does make come things more difficult (like intelligent AI pathfinding), but it's really something you should probably get used to from the start. |
Okay, I see. Thank you for that very elaborate response! I don't even have a game to add it to, luckily. I was hoping to at least get the collision differences down and go from there. I kept playing around with the step size 8 thing and came up with this. It seems to return the appropriate messages depending on whether I hit on-center or not but what do you think?
mob Of course, pixel movement would be way cooler, I should delve into it. Is pixel movement too demanding for multiplayer? |
Again, you're using pixel movement already unless your world.icon_size is 8, which I doubt.
|
Sorry, I keep forgetting that, haha. icon's are 32, step size isn't. I'm so used to the mobs moving entire tiles. ^^;
|
Is pixel movement too demanding for multiplayer? No. Of course, pixel movement would be way cooler, I should delve into it. You cannot implement the combat system you are attempting to implement without pixel movement. It seems to return the appropriate messages depending on whether I hit on-center or not but what do you think? Your method most definitely does not work. The response I gave you may not be the very best solution to the problem, but if there was a simpler solution that I was aware of that would work, I would have offered it. The problem with your solution is that step_x and step_y are values between 0 and tile size - 1 on each axis respectively. Checking if step_x and step_y are both equal doesn't actually test to see if the bounding boxes are lined up properly, because you aren't accounting for the actual location. There are a large number of cases using this code that will fail, even if it appears to work correctly in some cases. |
Okay, thank you. I now understand that I've been using pixel_movement all along in this project, haha. I'll study the code you posted earlier. I'm aware you definitely would've offered something shorter if it were possible, but I'm glad I posted what I tried because I learned why it isn't efficient :D. I forgot to mention, I plan to have the character (and hopefully all non-player mobs) only walk north, south, east and west a la the NES version of Ys I. Does the absence of diagonal movement change anything for better or worse?
|
Does the absence of diagonal movement change anything for better or worse? In my code? No. It's safe to use the version that allows diagonal movement even if you don't use it. It would be unsafe the other way, though. For your game's user experience, though? I'd talk more in depth about Ys I & II and the issues they have, but I think that it would discourage you and I'd like to see you churn out something cool and keep bringing me interesting problems like this one. Keep on chugging, guy. |