Use HTML5 to create a simple elastic ball game, html5 elastic ball
This article mainly introduces how to use HTML5 to create a simple elastic ball game. It mainly uses the Canvas API of HTML5. For more information, see
After learning canvas for more than a week, I think canvas is really fun. The idea of canvas is probably similar to that of me. I want to learn canvas with the attitude of writing games. So what are the basics of kinematics, collision detection, and some simple algorithms. I have never done any games before. It's really hard to learn. Today, I will write a simple elastic ball game using canvas, which uses the simplest gravity function and collision detection.
First go to the DEMO: elastic ball DEMO (clicking the blank area in the canvas will give the ball a new speed)
[Create a ball object]
The first step is to create a ball object and write the constructor of the ball:
The Code is as follows:
Var Ball = function (x, y, r, color ){
This. x = x;
This. y = y;
This. oldx = x;
This. oldy = y;
This. vx = 0;
This. vy = 0; this. radius = r;
This. color = color;
}
The attribute of the ball is very simple. xy is the coordinate of the ball, and vx and vy are the initial horizontal velocity and Initial vertical velocity of the ball. Radius is the radius of the ball, and color is the color of the ball (to distinguish different balls). oldx and oldy are the positions of the last frame of the ball, after the collision between the ball and the ball in the later stage, it is used for Position Correction (in fact, the latter is useless, and the position correction is directly calculated. If the oldx is used for configuration is not rigorous, but the record will inevitably be used ).
After the ball attribute is written, write the ball action in the ball prototype:
The Code is as follows:
Ball. prototype = {
Paint: function (){
Ctx. save ();
Ctx. beginPath ();
Ctx. arc (this. x, this. y, this. radius, 0, Math. PI * 2 );
Ctx. fillStyle = this. color;
Ctx. fill ();
Ctx. restore ();
This. moving = false;
},
Run: function (t ){
If (! This. candrod ){
This. paint ();
Return };
This. oldx = this. x;
This. oldy = this. y; </p> <p>
If (Math. abs (this. vx) <0.01 ){
This. vx = 0;
}
Else this. vx + = this. vx> 0? -Mocali * t: mocali * t; </p> <p> this. vy = this. vy + g * t;
This. x + = t * this. vx * pxpm;
This. y + = t * this. vy * pxpm; </p> <p> if (this. y> canvas. height-ballRadius | this. y <ballRadius ){
This. y = this. y <ballRadius? BallRadius: (canvas. height-ballRadius );
This. vy =-this. vy * collarg
}
If (this. x> canvas. width-ballRadius | this. x <ballRadius ){
This. x = this. x <ballRadius? BallRadius: (canvas. width-ballRadius );
This. derectionX =! This. derectionX;
This. vx =-this. vx * collarg;
}
This. paint ();
},</P> <p>}
The ball action method is also very simple. There are two methods. The first method is to draw the ball, and the second method is to control the ball movement. T is the time difference between the current frame and the previous frame. It is used to calculate the increment of the velocity of the ball to get the increment of the displacement of the ball, so as to calculate the new position of the ball and redraw the ball. Determine whether the new position of the ball exceeded the wall at the same time. If the new position is exceeded, modify the speed to make the ball rebound.
Some constants ballRadius = 30, g = 9.8, mocali = 0.5, bils = [], collarg = 0.8, pxpm = canvas in the second method. width/20; it means obviously: ballradius is the ball radius, g is the gravity acceleration, mocali is the horizontal reduction speed caused by air resistance, bils is an array used to store the ball object, collarg is the elasticity coefficient. Pxpm is the ing between pixels and meters, and regards the canvas as a 20-meter-wide area.
[Collision detection]
After the ball object is created, it starts to write a collision. The collision between the ball and the ball:
The Code is as follows:
Function collision (){
For (var I = 0; I <bils. length; I ++ ){
For (var j = 0; j <bils. length; j ++ ){
Var b1 = bils [I], b2 = bils [j];
If (b1! = B2 ){
Var rc = Math. sqrt (Math. pow (b1.x-b2.x, 2) + Math. pow (b1.y-b2.y, 2 ));
If (Math. ceil (rc) <(b1.radius + b2.radius) {</p> <p> // obtains the increment of the collision speed.
Var ax = (b1.vx-b2.vx) * Math. pow (b1.x-b2.x), 2) + (b1.vy-b2.vy) * (b1.x-b2.x) * (b1.y-b2.y)/Math. pow (rc, 2)
Var ay = (b1.vy-b2.vy) * Math. pow (b1.y-b2.y), 2) + (b1.vx-b2.vx) * (b1.x-b2.x) + (b1.y-b2.y)/Math. pow (rc, 2) </p> <p> // give the ball a new speed
B1.vx = (b1.vx-ax) * collarg;
B1.vy = (b1.vy-ay) * collarg;
B2.vx = (b2.vx + ax) * collarg;
B2.vy = (b2.vy + ay) * collarg; </p> <p> // obtain the oblique position of the two balls and forcibly reverse them.
Var clength = (b1.radius + b2.radius)-rc)/2;
Var cx = clength * (b1.x-b2.x)/rc;
Var cy = clength * (b1.y-b2.y)/rc;
B1.x = b1.x + cx;
B1.y = b1.y + cy;
B2.x = b2.x-cx;
B2.y = b2.y-cy;
}
}
}
}
} </P> <p>
The collision between balls is determined for each frame. if the distance between the two balls is smaller than the sum of the two ball radius, the two balls are collided. Then calculate the amount of speed changes after the collision between the two balls. Ax and ay are the amount of speed changes.
The following long formula is used:
I will not talk about the specific principle. If I want to know the principle, I will directly design the algorithm for the collision of small balls. The following section prevents repeated Collision Detection of the ball from causing normal rebound. Therefore, calculate the distance between the two balls, calculate the oblique positions of the two balls, and correct the positions of the two balls.
[Motion Animation]
Last step:
The Code is as follows: </p> <p> canvas. onclick = function (event ){
Event = event | window. event;
Var x = event. clientX + document. body. scrollLeft + document.doc umentElement. scrollLeft-canvas. offsetLeft;
Var y = event. clientY + document. body. scrollTop + document.doc umentElement. scrollTop-canvas. offsetTop; </p> <p> bils. forEach (function (){
This. vx = (x-this. x)/20; // initial speed m/s
This. vy = (y-this. y)/20;
});
} </P> <p> function animate (){
Ctx. save ();
Ctx. fillStyle = "rgba (255,255,255, 0.2 )";
Ctx. fillRect (0, 0, canvas. width, canvas. height)
Ctx. restore ();
// Ctx. clearRect (0, 0, canvas. width, canvas. height) </p> <p> var t1 = new Date ();
Var t = (t1-t0)/1000;
Collision ();
Bils. forEach (function (){
This. run (t );
});
T0 = t1; </p> <p> if ("requestAnimationFrame" in window ){
RequestAnimationFrame (animate );
}
Else if ("webkitRequestAnimationFrame" in window ){
WebkitRequestAnimationFrame (animate );
}
Else if ("msRequestAnimationFrame" in window ){
MsRequestAnimationFrame (animate );
}
Else if ("Your requestanimationframe" in window ){
Required requestanimationframe (animate );
}
}
} </P> <p>
Click the position of the canvas to give the ball the initial speed. Then, animate is the method for running each frame of the animation. The ctx above. fillStyle = "rgba (255,255,255, 0.2)"; ctx. fillRect (0, 0, canvas. width, canvas. height) is to add a virtual shadow to the ball. I think this will be better. If you don't like it, simply clear it with clearRect. Then, the time difference between each frame is calculated, and then the small ball array in the small ball array is traversed and re-painted. Then add the collision method for collision detection. The animation is complete.
Now, the source code address is:
Https://github.com/whxaxes/canvas-test/blob/gh-pages/src/Other-demo/shotBall.html