Creating a fancy weapon slot system for my game

Started by
12 comments, last by Alberth 8 years, 7 months ago

Your Atan2 can't be right.

'direction' is a difference in position (something you'd expect as Atan2 argument), but 'tempanswer' is a result from Asin, ie an angle.
Adding those things together is not likely to give a good result.

Maybe you intended to add "tempanswer" to the result of Atan2? (Also, I'd recommend to rename it to somethingAngle, to avoid such confusion.)


I find it hard to understand the meaning of all the variables, a picture would be great, or a simple stand-alone program that can be run?



These kind of problems are very closely related to the math. In figuring out how to do the computation exactly, I often find it useful to take out such a function into a separate program, and make everything an input parameter of the function, so you can just call it with known input data.
ie something like computeGun(shoulderPosition, gunOffset, mousePosition). Add "print" statements after each step, and run the computation in math as well (or even draw it on paper, and eg measure the angles and line lengths etc).

In this way, you can do a side-by-side comparison of the answers under fully controlled conditions. After each step, the math answer and the program answer should be the same.

Start with a really simple case, horizontal gun (compute mousePosition.y from shoulderPosition.y and gunOffset.y)
(check that different mousePosition.x have no effect)

Other options are to use math, with an example of 45 degrees down gun. Compute a mousePosition with math, then feed that into the program, and check with the print output whether it does the same calculation.
I'd also try 30 or 60 degrees up, or 90 degrees up and/or down.


As for flipping, I'd first get the non-flipping side work correctly for 100%, or you're fighting two problems at the same time.

What I am missing in the flipping code is inverting the gunOffset.x . Not sure that you need it, but I'd expect it to be there somewhere.
I'd treat the flipped case as fully separate from the non-flipped case, and start from scratch first. New function computeFlippedGun(), with horizontal gun, 45 degrees, 30 or 60 degrees, etc.
Once you have the flipped side working too, you can try to merge both functions into one, and paste stuff back into the real program.

Advertisement

Sorry about that. I didn't exactly explain it too well! I'm essentially working from that diagram that you posted up. I'm

trying to compute the angle between dd and the gun's position, and then add that position to the final rotation of the weapon.

I shall re-post the code in a more compartmentalized fashion :)

After trying and trying and trying, I just simply can NOT figure this one out! It should surely be pretty simple. The more I look at it,

the more infuriating it becomes! It's teasing me with its simplicity.

I tried to follow your method, but I just can't get it working. I've had a though, though:

Surely the x component of the deviation doesn't matter? I have have a gun as long or short as I want, and the cross-hair

will always be smack-bang in the center of the gun. It's the Y offset that I need to be taking into account, right?

So if I have this, for example:

demo_zpszta6ruav.png


            //All this method does is cause the gun's nozzle to aim at the direct centre of the cross-hair.
            Vector2 gunPosition = position + gunOrigin;

            //THESE SHOULD BE PARAMETERISED and comprises the muzzle of the gun:
            deviation = new Vector2(36, -2);
            int muzzleWidth = 8, muzzleHeight = 6;

            float yOffsetThatGunAimShouldAccountFor = deviation.Y + (muzzleHeight / 2);

            //something needs to then be done to convert that into something that influences the direction (my pythag is pretty rusty)


            direction = new Vector2(mouseVector.X - (crosshair.Width / 2), mouseVector.Y - (crosshair.Height / 2)) - gunPosition;
            direction.Normalize();

            if (spriteEffect == SpriteEffects.FlipHorizontally)
            {
                gunRotation = (float)Math.Atan2(-(double)direction.Y, -(double)direction.X);
            }
            else
            {
                gunRotation = (float)Math.Atan2((double)direction.Y, (double)direction.X);
            }

            //Shouldn't be able to touch this manually - parameters should accept deviation changes at start
            muzzleRect = new Rectangle((int)worldRect.X, (int)worldRect.Y, muzzleWidth, muzzleHeight);

Does what I'm saying make any sense? This is driving me to my wit's end!

The more I look at it, the more infuriating it becomes! It's teasing me with its simplicity.

Ha, I had a puzzle like that, and it took me 10 years to decide it was too complicated tongue.png

Since my C#-skills are non-existent, and I want to play interactively with the program, I decided to go for python 2 + pygame.

Attached are 7 versions of the program, I recommend incremental reading, preferably with a "dif" program nearby, so you can see what I changed between versions.

I ripped an existing program, and created aiming1.py: Some initialization, create a 400x300 window, shoulder position at hard-coded (200, 100), an event loop at the bottom that draws the scene, and a mouse-move event handler calling "update_crosshair" with a copy/paste of the post I made here, and some code to compute dx, dy, dd, and alpha.

This seemed to work (as you will see it didn't, some versions further down), and made aiming2.py: Added a 'gun' class to store gun variables.

I realized I would need to draw some lines as well to see what I was doing, so add a LINES colour, and some lines that get drawn as well.

The aiming3.py draws the orthogonal line from the shoulder, and orthogonal from there a line touching the circle. First glimpse of how it actually works!

Of course it didn't smile.png

[attachment=29208:aiming3_images.png]

The line touching the circle is supposed to point to the crosshair, but it doesn't. In positive x, it points down, in positive y it points to the right. It also rotates opposite to my mouse, so x and y seem swapped in some way. I use two angles to compute the line, which one is wrong? aiming4.py is the debug version, replacing the line to the cross-hair with a line computed from the shoulder at 'pi/2 - alpha' angle (which should thus point back to the cross-hair). It doesn't:

[attachment=29209:aiming4_image.png]

So the alpha angle is wrong. On the other hand, the distance between the crossing point of both lines, and the distance between the shoulder and cross-hair seem to be quite close, so that's promising. After some looking, my atan2 computation was wrong, fixed in aiming5.py

Next I wanted to draw a gun. I don't have a sprite, so instead I add some points in the gun class, and rotate those.

I disable the orthogonal line stuff, and draw the gun_angle instead. For fun, I added the path of the bullet.

[attachment=29210:aiming6_image.png]

The aiming_final.py basically cleans up, removing all development comments.

I hope this helps.

[attachment=29207:aiming.zip]

This topic is closed to new replies.

Advertisement