360 Mouse Rotation

Yesterday was quite fun (not).

As I previously mentioned, my current control scheme is to move the mouse left/right and the ship moves left/right (from the perspective of the pilot).  Being that it’s an overhead view AND a radial motion (360 degrees) it leads to an inversion.  When the ship is on the top half of the screen (i.e. North of the black hole/circle) it moves isomorphically to the mouse motion, as a player expects.  If a player is expecting the mouse to move in a rotational manner instead, this means that when the ship hits the bottom half of the screen (i.e. South side of the blackhole/circle), it’s inverse to the expectation of the player.  They would expect a leftward movement to move the ship left on the screen, whereas from the pilot’s view, it’s still a rightward movement.  I wanted to implement a 360 control due to some complaints of the control scheme as it currently is.

So yesterday I began that.  The first code I found was specifically for rotating an object around it’s own pivot point/center, to follow the mouse’s rotation.  This will actually come in handy later for another game I think I’d like to make (if I ever get to it.  Let’s focus on having one game created before I kick the bucket).  It was easily implemented and worked really nice (after I got the kinks worked out).  I then attempted to implement the function to rotate around the black hole using this information.

It didn’t work so easily.  I finally hit upon some solutions that are very close, but not quite what I need.

See, when I started this project there was no Unity2D.  All the stuff is 3D.  This is actually kind of cool, because it’s actually a really easy to use and well documented system that I have already seen some cool effects happen via “happy accidents”, even though I am not currently using any of them.  Unfortunately, this means that certain things require an extra bit of work to mesh with the 3D world (I believe that the newer versions of unity that now have proper 2d support built-in don’t have such issues, or at least reduce them).

So, for instance, if I have a point in 3d space on the screen and I want to work the angle in two dimensions, and also with the mouse’s position on the screen, there is a function that I have to use to map the 3d position of the object onto the screen in pixels/coordinates, and then manipulate that (in particular, I need to compare my Mouse_X and Mouse_Y coordinates to the object’s location in 3d space then mapped onto the screen coordinates and figure out the angle).

Doing this was fine and it allowed me to rotate the object around its own axis.  When I tried the rotataround function I had a few issues:

1) The object never fully settled when it approached the angle of the mouse.  Sometimes it did, but sometimes it would bounce a little left or right and never settle on it.  This is due to the code I had to check for whether the object angle was equal to the object angle.  I was rounding the values of the angles before moving the object.

My solution to this was to check if it was within a given range of that angle, and then slowly reduce the motion speed so that it would eventually go to a movement of 1 degree to move.  The reason I don’t do this initially is because then it means that the motion is reaaaaaaaaaaaaaaaaaaallllly slow.  So I set the movement speed to something like 1000, which gives it a fairly nice quick rotation, but it also means that it is difficult to get it to narrow in on the correct angle, and if you’re only within a couple degrees, you might be hopping over that point without ever landing on it.  Slowing it down once I get close means that I can narrow in on that angle.

That seemed to solve the problem as far as I can tell.

2) Another curious issue that was occurring, and still is, was that I’d have duplicate objects flickering as if the object was moving so fast across the screen and jumping between two locations.  Now that I got issue one solved, it seemed to be reduced, but not fully gone.  I notice that if I retain my mouse distance from the object it works properly, but after a certain level of proximity to the rotating object, it does this “split” effect.  It’s kind of cool looking, but definitely NOT what I want to be going on.

I realized that this is probably due to the fact that, currently my mouse is still set to detect its angle of rotation via the object, not the center of the screen which is where I am actually trying to get the angle from.  I believe that as I move closer to the object itself, something is happening there, possibly with the fact that the angles are counted in floats (and that I am rounding to nearest integer value), so, perhaps I am getting closer and closer, and the accuracy of my angle goes up in relation to the object (I have much less wiggle room – literally)  The larger the circle I move around, the more I can move without bumping out of a degree of motion.

This might be corrected if I round the value of the angle in a different location than where I am rounding it currently.

However, that’s a fudge.  I think I need to link the mouse’s pivot location to the center of the screen.  In fact, I tried doing that…

In the original rotation code (not the rotatearound() function which rotates around an external object; but the code that has the object rotate around its own pivot point), you subtract the object’s X and Y positions from the mouse’s X and Y positions in order to get the difference and calculate the angle.  I can’t give you the math off the top of my head.  However, the point being, is that I did something like this:

rotation_X = Mouse_X - Object_X
rotation_Y = Mouse_Y - Object_Y

Then did some stuff with the ATAN2 function that calculates stuff and returns the angle I need.

Well, I think to myself, clearly if I’m subtracting the object’s positions, and the blackhole object/center I’m actually trying to rotate around is located at <0,0,0>, I should be able to remove the subtraction and I should be fine, just use the Mouse_X and Mouse_Y values by themselves.  But it wasn’t working.  I gave up for the night.

Today, as I sat upon my philosophers throne (yeah, you know… the toilet), I pondered the issue and realized where I was going wrong.

Remember that bit about translating from 3D to 2D for the screen coordinates?  Well I wasn’t doing that with the center/black hole object (in my test project, I don’t have a black hole object, but that doesn’t matter, it’s just as I said above <0,0,0>).
Since I wasn’t mapping that to the screen coordinates, the coordinates were all wrong, and thus weren’t allowing the rotation to work properly.

What I need to do is use that projection of the 3D to screen coordinates function applied to the position vector of the center of the game world around which my ship is rotating, and THAT should be subtracted from my MOUSE_X and MOUSE_Y coordinates in order to give me a proper pivot point for the mouse, and from there, hopefully everything should work well.

I hate feeling so stupid, and when I can’t work something out, it feels as though it’s my own idiocy because I never had anything beyond 2 algebra classes and geometry – never had Trigonometry or anything beyond that, and you know… It’s not like that stuff is fresh in my head being some 20+ years ago as is…

So it gets frustrating and I feel defeatist at times, but then when I find a solution I feel so proud, especially if I was able to arrive at it on my own without an external input.

Of course, tonight is the real test when I attempt to implement this and see if my theory holds up.

If it does, I think I’ll let the user select the mode of input they prefer. I think this also will now let me add in gamepad/controller input (using the PC-360 controller) since it’s essentially the same thing. But at least I can let the user try left-right or rotational modes of play. The left/right can actually work well with a spinner control as well (my friend wants to try it with a spinner control for his arcade cabinet, I think that’d be pretty fun).

CROSSING MY FINGERS!

Game “Review”: Dishonored

Dishonored: 9/10

Last night I didn’t do any coding.  Instead I beat Dishonored.  I really like that game.  I went on, I think, the “normal” setting of difficulty (or it might have been easy – it wasn’t that hard, but a few spots were).  It’s not perfect, the controls sometimes seem a bit clunky/cludgy (compared to Deus Ex, for example).  I’m not sure why – but sometimes it felt like I was supposed to be able to do all these acrobatic cool things, but stuck in this first person mode, I felt like I was just a cylinder floating through space.  It’s hard to describe.  A lack of embodiment in some way.  That said, it’s a minor critique, because in terms of actual gameplay and control, I felt it was fairly tight and for the most part I could do what I wanted to do.  If I actually focused and spent more time mastering the controls, I probably could have done better.  But I was going pretty casually, not going for all the runes/charmes.

The story was interesting and had a couple surprises in store.  I also didn’t expect playstyle to affect the storyline, and I’m not sure how much it affects it, but I know there’s a couple places where it does, at least.  It’s funny, too.  I forgot the name of one character and I told someone I would kill this person, then I saw who they were and I’m like – Oh, YOU!  Man, we tight.  I won’t kill you!  Because of the earlier mission where they helped me.  It was this little reciprocality that was interesting to see how I played out.  It’s not like some big major thing that was “IN YOUR FACE MORAL CHOICE” of Bioware, but it was still this interesting moral choice.

Is it immoral to kill a person who’s going to die of the plague?  I mean, they’re suffering and it’s not like they have a cure.

Also – who is “The Outsider”?  I think I would actually love to read a book or at least see a graphic novel or some animated videos of this world.  It really does have a lot of interesting things for it.  Probably more than Bioshock Infinite (which I haven’t played yet, but have heard it’s still more bro-shooter than deep-story despite the attempts at deep story)…  I definitely felt that there was a much larger world waiting to be explored out there.  The steampunk motif was nice.  The art style was great, I like that cartoony look.  The characters really did have personality.  I really want to go find the stories posted around the world and read them as I only glanced at some because I wanted to get on with the killing and shit.  But I still want to go back and experience what was there to build the world.  The fact they mention these other locations/continents/islands or whatever just opened up more.  There’s clearly a lot of potential history.

The audio was great.  Not overbearing, everything sounded satisfying when you shot at someone.  The magic effects were nice.  I never felt too underpowered, and it was a nice wave of “difficult” “easy” … a good game design has that sort of structure.  You can’t continually make everything uber-hard.  Well, I shouldn’t say that.  Some games are MADE to be hard: Mega Man.  Super Meat Boy, etc…  But for a narrative game, you need those ebb and flows.  This did those flows well.  Sneaking, killing, large fights against a group of people.  More sneaking.  Getting lost.  Finding your way.  Various betrayals.  Etc…

So yeah – I’d put this up with Bioshock 1 in terms of being a great game from the past half a decade or so.

Laser Upgrades Part 2

One of the ideas I had when I first played with the laser shot way back was a “pulse cannon” which was visualized as a large “wavefront” type pulse going out.  It was much faster than the regular laser shot, but due to it’s width was pretty devastating.  My friend said it was overpowered when trying it so I thought to remove it.

Upon reflection of how I could upgrade, and the laser-chain shot concept, I thought of another use for this type of pulse cannon shot.

It would work on multiple asteroids, similar to the idea of a chain shot.  The difference is that it doesn’t seek out nearby asteroids, but rather ends up as a large wavefront (as visualized before), that gets split when it hits an asteroid, and each new, smaller wavefront is bounced off the asteroid, reflected/refracted.

So, here, you now have 2 smaller wavefronts flying out back from the asteroid it just destroyed…  These can continue forward until they hit other asteroids (or fly off the screen – which may be an issue.  It seems it would make sense to have a weapon like this showing up near the later stages of the game in order to make sure there’s a large enough population of asteroids to really have a nice WOW effect of the wavefront continuing to split and reflect for a given number of splits).  Continue doing this splitting and reflecting for a certain amount of time.  I like this idea.

My friend is also like “HOMING MISSILES!”

The problem I have with that is that everything on the screen is too “tight”.  If I just have one homing missile flying out, it’s probably not much better than a bullet (except that I don’t have to be quite as accurate with a shot).  Now if I had a couple missiles (which I could mount on the ship wings), that would be better.  If I did a barrage so I could hold down the buttons and just fire a whole crapton then that would be best.  So maybe I’ll do it that way.  And I do have Homing Missiles already planned as I’ve got that in my powerup icon set ready to deploy at some point.  Maybe I’ll do like a triple shot of homing missiles on the first set.  (3 missiles x 2 missiles each spawn, one for each wing): 6 homing missiles.  Then up it to 8 and 10 or something.

First things first, though.  Getting that damn rotation of the ship to work.