Source code download: http://download.csdn.net/detail/y85171642/7209727
OpeningBefore getting started with the code, I would like to explain why I wrote this program. When I was a junior, I learned C # And came into contact with GDI +. I found that the original graphic interface program could be as simple as that. Then began to use GDI + to start animation, games, etc., which has a simulated multi-ball collision, In the CSDN have shared (http://pan.baidu.com/s/1qWjTkmS ), but now I think there are still many problems with that program. For example, I did not consider the question of non-center collision, or the question of sphere oblique collision, and the frame rate was low, collision detection accuracy is insufficient, leading to ball adhesion (using a sphere pixel integer ). Speaking of this, anyone who has used GDI + may have an idea that the efficiency of using GDI + to play games is indeed not good. So I switched to C ++, And I was just about to write a C ++ 2D game, so while I was writing a game project, it took one day to write the simulated sphere "elastic Oblique Collision" program. As for why it takes so long, most of the time I spent on this "oblique touch" problem, which is also the main reason why I want to write this blog, there are very few online apps about small ball elasticity. Believe it or not.
Code onSimulate Ball collision, so the Ball's entity class is required (Ball. h)
# Pragma once # include <math. h> # include "hge. h "class CBall {public: CBall (); CBall (float _ x, float _ y, float _ speedX, float _ speedY, float _ radius, DWORD _ color, float _ density = 1.0f );~ CBall () {}; public: bool IsCollision (CBall * ball, float dt); // collision detection void CollisionWith (CBall * ball ); // void CollisionWith2 (CBall * ball); // void SwapColor (CBall * ball); // Add an exchange color void MoveNext (float dt, float _ width, float _ height); // all public: float x; // the x axis coordinate float y; // y axis float speed_x; // speed float speed_y in the X axis direction; // speed float radius in the X axis direction; // sphere radius float density; // density float weight; // quality DWORD color; // mixed color };
It can be seen from the definition of the class members of the Ball that the approximate attributes of the sphere are comprehensive, but the attribute of Color is used to set the Color of the sphere, because the image material is a pure white solid circle, you can directly set the circle to obtain the color when using the color for vertex coloring. (1) constructor CBall (float_ X, float_ Y, float..., Float_ Density. 0f); for initialization of member variables, note that the default density is 1.0f, and the mass is calculated by the volume and density. [Sphere mass m = p * v, v = 4/3 * π * r ^ 3 ]. (2) collision detection. When the current object is returned, it will collide with the ball parameter. dt is the time of one frame.
Bool CBall: IsCollision (CBall * ball, float dt) {// calculates the position of the next moment, avoid adhesion float disX = (this-> x + this-> speed_x * dt)-(ball-> x + ball-> speed_x * dt ); float disY = (this-> y + this-> speed_y * dt)-(ball-> y + ball-> speed_y * dt ); float dis = sqrt (disX * disX + disY * disY); // checks whether a collision occurs at the next moment. if (dis <this-> radius + ball-> radius) return true; return false ;}
(3) automatically hitting voidCBallCollisionWith (CBall ball) formula obtained based on the kinetic energy theorem and the conservation of momentum law // formula of elastic positive collision // v1 '= [(M1-M2) * v1 + 2 * m2 * v2]/(m1 + m2) after the collision, the speed and direction of the two balls will change. , The main character of the article, because the computation is complex, we need to use Vector ).
Void CBall: CollisionWith2 (CBall * ball) {// reference: // http://www.cnblogs.com/kenkofox/archive/2011/09/06/2168944.html // http://tina0152.blog.163.com/blog/static/119447958200910229109326/ // Ballon point float x1 = this-> x; float y1 = this-> y; float x2 = ball-> x; float y2 = ball-> y; // Tangent Plane vector t at the collision, and its normal vector s hgeVector s (x2-x1, y2-y1); s. normalize (); // normalized vector hgeVector t (x2-x1, y2-y1); t. rotate (3.1415926f/2); t. normal Ize (); // speed vector hgeVector v1 (this-> speed_x, this-> speed_y); hgeVector v2 (ball-> speed_x, ball-> speed_y ); // calculate the projection values of v1 (v1x, v1y) on the s and t axes, and set them to v1s and v1t respectively. // then calculate v2 (v2x, v2y) the projection values on the s and t axes are set to v2s and v2t: float v1s = v1.Dot (& s); float v1t = v1.Dot (& t ); float v2s = v2.Dot (& s); float v2t = v2.Dot (& t); // an elastic positive collision on the s vector after conversion. Mass unequal // formula for Elastic positive collision // v1 '= [(M1-M2) * v1 + 2 * m2 * v2]/(m1 + m2) // v2' = [(m2-m1) * v2 + 2 * m1 * v1]/(m1 + m2) float m1 = this-> weight; float m2 = ball-> weight; float temp_v1s = (M1-M2) * v1s + 2 * m2 * v2s)/(m1 + m2); v2s = (m2-m1) * v2s + 2 * m1 * v1s) /(m1 + m2); v1s = temp_v1s; // first obtain the v1t and v2t vectors v1t' and v2t' on the t axis (convert the values into vectors) // obtain the vectors v1s and v2s' on the s axis (convert the values to vectors). hgeVector v1tVector = t * v1t; hgeVector v1sVector = s * v1s; hgeVector v2tVector = t * v2t; hgeVector v2sVector = s * v2s; // new speed vector hgeVector v1_new = medium + large; hgeVector v2_new = v2tVector + v2sVector; // divide it into x, y direction component speed this-> speed_x = v1_new.x; this-> speed_y = v1_new.y; ball-> speed_x = v2_new.x; ball-> speed_y = v2_new.y ;}
(5) color exchange: the two balls after the collision are used for color exchange, which is purely entertaining. VoidCBallSwapColor (CBall ball) (6) the ball moves. The parameter _ width and _ height indicate the width and height of the window, because this method contains the detection and rebound of the border collision.
Void CBall: MoveNext (float dt, float _ width, float _ height) {float moveX = speed_x * dt; float moveY = speed_y * dt; // if (x + moveX <radius | x + moveX> _ width-radius) in the x direction speed_x =-speed_x; // if (Y + moveY <radius | y + moveY> _ height-radius) speed_y =-speed_y; x + = speed_x * dt; y + = speed_y * dt ;}
Use the main function. Check the source file. (HGE is a small 2D Game Engine Based on DirectX8, learn more download: http://pan.baidu.com/s/1dDtdd2h)
ConclusionI have almost graduated from my senior year, and now I find that I have learned too little and played too much in College (DotAer haha). I feel a lot of emotion and have converted it into two words: "Time ". Recall that when I was just a freshman, I took a book and typed the C program code according to the above words. Until the program runs, I still cannot understand how the program works and how it is implemented, but fortunately, "Time" tells me. From freshman year to freshman year, the boring things can only be used for acm c/C ++, to the second year, I finally saw a graphical interface, but it was clumsy and not suitable for graphic interface development. Java makes graphic interface development extremely simple. however, the inefficiency cannot satisfy the game development C # And finally return to the original efficient and complicated crazy C ++, in this way, the University has been completed for four years. Many of my colleagues have gone out to work now, but I feel that everyone seems to be familiar with it. I keep learning with my salary, however, we hope that you can find a job that you are satisfied with and that your job will be smooth. I am still thinking about whether to participate in the blue bridge cup finals. After all, I am a senior, and there will be a lot of things recently. Sorry, the idea is a little broken. Http://pan.baidu.com/s/1ddebk4lthe program is expected to be released in poor conditions. Thank you! Program source code download: http://download.csdn.net/detail/y85171642/7209727