Fireworks stress tests the MC Engine by throwing 1,000’s of Sprite objects about on the screen.
LEFT CLICK TO FIRE.
Code
// MaxCanvas Demo - Fireworks // by Max Bryans (March 2019) // // // Required to drag MC.js into Intellisense // thanks to https://visualstudiomagazine.com/blogs/tool-tracker/2018/07/use-javascript-code.aspx (Dec 2018) /// <reference path="MC.js" /> window.onload = (function() { // AQUIRE HTML DOM CANVAS REFERENCE // HTML has to have a HTML5 canvas element tagged as "canvas" var c=document.getElementById("canvas"); ////////////////////////// // INITIALISE MC Engine // ////////////////////////// // CHOOSE 1 // // CHOICE 1: Canvas Size fixed by HTML (in this case 900 x 700) MC.init(c); MC.game.setBounds(0, 1, 0, 1); // CHOICE 2: Full Window Option (Canvas will be resized to fit window) //MC.init(c,"fullWindow"); /////////////////////////// // END OF Initialisation // /////////////////////////// //----------------------------------------------------------------------------- ////////////////////////// // VARIABLE DECLARATION // ////////////////////////// // This simulation uses gravity MC.game.gravity.set(0,15); // Container for Game Objects var FW = { spd: 50, Particles: new MC.SpriteBin(), Trails: new MC.SpriteBin(), // 2 x ConBoxes as text holders. 1 for Reporting Sprite Count and fps, 2nd for Instructions Report: new MC.ConBox(), Instructions: new MC.ConBox() }; // Configure Text boxes FW.Report.pos.set(FW.Report.width/2,MC.canvas.bottom - FW.Report.height/2); FW.Instructions.pos.set(MC.canvas.right - FW.Report.width/2,MC.canvas.bottom - FW.Report.height/2); FW.Instructions.text = "Click for Fireworks !!"; // Player Input Event Handler ... Left Mouse click = make a firework MC.mouse.onClickL = function () { MakeBurst(); } // Control Function, sets parameters for a series of "Sparks" which make up an explosion function MakeBurst() { var angle = 0; var InitialVel = new MC.Point(FW.spd * MC.maths.randBetween(0.9,1.1),0); var pos = MC.mouse.pos.clone(); var color = MC.utils.randomColor(); var rocketVel = new MC.Point(0,-FW.spd * 1.2); rocketVel.rotate(MC.maths.randBetween(-30,30)); // a small random direction to add a bit of variety while (angle < 360) { // Set off a series of Sparks, with velocities radiating around (and away from) the burst centre MakeSpark(pos,InitialVel.clone().rotate(angle).add(rocketVel), color); angle += MC.maths.randBetween(5,25); // between 15-72 Sparks per Burst }; } // Sprite Factory function MakeSpark(position, velocity, color) { // Make standard Sprite object var s = new MC.Sprite({ type: "circ", size1: 3, pos: position.clone(), vel: velocity.clone(), wrapAround: false, fillColor: color.clone(), edgeColor: null, gravity: true, killAge: 4 }); // Customise behaviour via the Sprite.dev object s.dev.oldPos = s.pos.clone(); s.dev.update = function () { // Only need to add a "Trail" if the distance from the last one is > 1 pixel if (MC.maths.rangeSqr(s.pos,s.dev.oldPos) > 1) { MakeTrail(s.pos,s.fillColor); s.dev.oldPos = s.pos.clone(); } s.vel.times(0.995); // retard velocity slightly each frame to emulate drag }; // Store in SpriteBin FW.Particles.push(s); // Spritebin will handle all hereafter } // Sprite Factory. Trails do not move, but shrink over a 1 second lifespan, creating the illusion of movement function MakeTrail(position, color) { var t = new MC.Sprite({ type: "circ", size1: 3, pos: new MC.Point(position), vel: new MC.Point(0,0), wrapAround: false, fillColor: color, edgeColor: null, gravity: false }); t.dev.TrailTimer = 1; t.dev.update = function () { t.dev.TrailTimer -= MC.game.deltaTime; if (t.dev.TrailTimer < 0) { t.kill(); } else { t.scale = t.dev.TrailTimer; } }; FW.Trails.push(t); } ////////////////////////// // END OF declarations // ////////////////////////// //----------------------------------------------------------------------------- ////////////////////////// // GAME LOOP // ////////////////////////// // first call, request subsequently made within itself gameLoop(); function gameLoop() { requestAnimationFrame(gameLoop); // Essential to update MC.game to ensure MC.game.deltaTime is available MC.game.update(); update(); render(); } function update() { FW.Particles.update(); FW.Trails.update(); // Populate Report Text FW.Report.text = (~~((FW.Particles.bin.length + FW.Trails.bin.length)/100)*100) + "+ Sprites @ " + (~~(1/MC.game.deltaTime/10)*10) + " fps"; } function render() { MC.draw.clearInBounds("Black"); FW.Trails.render(); FW.Particles.render(); FW.Report.render(); FW.Instructions.render(); } }); // EoF