1. Pre-knowledge
(1) Implementation process of canvas rotation
Window.onload = function () {var ctx = document.getElementById (' canvas1 '). GetContext (' 2d ')//Rotate Ctx.save () ctx.translate (200,200)//(200,200) point as a temporary (0,0) point ctx.rotate (30*math.pi/180)//clockwise rotation 30 degrees corresponding to the Radian Ctx.fillrect (0,0,100,150) Ctx.restore ()}
(2) Simulation realization model of gravitational acceleration in parabolic motion
/* Parabolic motion This version has been modified to reduce the conversion between angles and radians (radians can be calculated directly by math.atan2), the angle in the construction parameter is changed to radians Deleted:angle = angle,//initial angle radians = angle* math.pi/180,//initial Radian Object parabolicmotion@velocity: Initial speed @radians: initial radian @gravity: initial acceleration {x:0,y:2}*/function Parabolicmotion (velocity,radians,gravity) {var velocity = velocity, radians = radians, gravity = gravity var OffsetX = Velo City*math.cos (radians), OffsetY =-velocity*math.sin (radians) function next (offset,gravity) {var offset1 = Offsetvar Offset2 = Offset+gravityreturn {offset:offset2,dv: (Offset1+offset2) *.5}}return {/* Gets the motion trajectory to the next point in time, the distance offset by the x, y axis */ Movenext:function () {var offsetxd = next (offsetx,gravity.x) var offsetyd = next (offsety,gravity.y) OffsetX = Offsetxd.offsetoffsety = Offsetyd.offset//console.log (offsetx+ ', ' +offsety) return {X:OFFSETXD.DV,Y:OFFSETYD.DV}}}}
2. The realization of the idea
involves the object, including Ball, Slingshot (Slingshot), Parabolic motion (parabolicmotion).
Operation process is, the mouse button to drag the ball, and the role of the slingshot point into a certain angle, the mouse button pressed, the small ball to do parabolic motion
3. Main code
/* Slingshot */function Slingshot () {var opts,ctx,crtball,ballselected = falsefunction Refresh () {Ctx.clearrect (0,0,opts.width , Opts.height) drawsling () Crtball.draw ()}function drawsling () {var point = Opts.actionPointctx.beginPath () Ctx.moveto ( POINT.X,POINT.Y) Ctx.lineto (point.x,opts.height) Ctx.closepath () Ctx.stroke () if (crtball!=null&& ballselected) {//Draw connection Ball and Slingshot "rubber Band" Ctx.beginpath () Ctx.moveto (POINT.X,POINT.Y) Ctx.lineto (CRTBALL.X,CRTBALL.Y) Ctx.closepath () Ctx.stroke ()}}function isballselected (offsetx,offsety) {var point = Opts.actionpointvar A = Math.abs ( POINT.X-OFFSETX) var B = Math.Abs (point.y-offsety)//var C = math.sqrt (a*a+b*b) return (A*A+B*B) <=crtball.radius* crtball.radius}//Add Pull Slingshot event function initevents () {var canvas = Opts.canvas/*addeventlistener function 3rd parameter, False indicates that an inner element event is triggered first, Ture indicates that the outer event first triggers alert (e.offsetx+ ', ' +e.offsety) must use the OFFSETX,OFFSETX is relative to the canvas canvas distance (but Firefox does not support) event parameter e does not consider browser compatibility issues */ Canvas.addeventlistener (' MouseDown ', function (e) {//Determines whether the ball is selected ballselected = isballselected (e.offsetx,e.offsety) if ( Ballselected) {crtball.locate (e.offsetx,e.offsety) Refresh ()}},false) canvas.addeventlistener (' MouseMove ', function (E {if (ballselected) {crtball.locate (e.offsetx,e.offsety) Refresh ()}},false) canvas.addeventlistener (' MouseUp ', Function (e) {if (ballselected) {ballselected = Falsecrtball.locate (e.offsetx,e.offsety) Refresh ()//Launch cannon fire (function (x, Y) {//todo)}},false)}function Fire (oncompleted) {//Get the current projectile launch speed and radians var velocity = ($.square ( OPTS.ACTIONPOINT.Y-CRTBALL.Y) +$.square (opts.actionpoint.x-crtball.x))/100var radians =-math.atan2 ( opts.actionpoint.y-crtball.y,opts.actionpoint.x-crtball.x)//30*math.pi/180var gravity = {X:0,y:2}var Parabolicmotion = new Parabolicmotion (velocity,radians,gravity) var completed = Falsevar Timer =setinterval (function () { In the current parabolic trajectory, gets the unit length of the x, Y axis that needs to be offset for the next unit of time in the shell var = parabolicmotion.movenext () crtball.move (OFFSET.X,OFFSET.Y) Refresh ()//check if the canvas boundary is exceeded completed = (crtball.x>=opts.width| | Crtball.y>=opts.height) if (completed) {clearinterval (timer) if (typeof oncompleted==' function ') {oncompleted (CRTBALL.X,CRTBALL.Y)}}},100)}return {init:function (options) {opts = $.extend (options,{ canvas:null,//Canvas width:1000,//canvas long height:300,//Canvas high actionpoint: {x:150,y:200}/* force point coordinates */}) CTX = Opts.canvas.getContext (' 2d ') drawsling ()//Add Pull Slingshot event initevents () return this},loadball:function (ball) {var point = Opts.actionpointcrtball = Ball.init ({ctx:ctx,x:point.x,y:point.y}). Draw () return this}}
Appwindow.onload = function () {var canvas = document.getElementById (' canvas1 ') var ball = new Ball (Ten) var slingshot = new Slingshot (). Init ({Canvas:canvas})//Load a Cannonball Slingshot.loadball (Ball)}
4. Optimization and improvement
(1) The target object should be rotated when the ball hits the target object.
(2) can be achieved at the same time a number of small ball launch, like the game fired bullets effect
"Finishing" HTML5 game Development Study notes (3)-Parabolic motion