Trending
Opinion: How will Project 2025 impact game developers?
The Heritage Foundation's manifesto for the possible next administration could do great harm to many, including large portions of the game development community.
When it comes to canvas-based HTML5-Games the possibilities are limited, but I want to show you some amazing technics!
(Original Article: http://vempiregame.com/allgemein/this-is-just-html5js-are-you-kidding-me/)
This was one of the greatest compliments that we've received for VEmpire - The Kings of Darkness.
There are a lot of things that makes a game look polished.
But when it comes to canvas-based HTML5-Games the possibilities are limited, it is not Unity!
To cut a long story short, here is what makes VEmpire look as it does:
- Great art!
- Smart animations!
- A simple particle-engine!
- Neat effects!
I can't do the art for you and i want to talk about the particle engine in the next post, but today I want to focus on one particular effect, it is this one:
Cool isn't it?
So how is this made, you ask?
OK, here you have it.
It is primarily about these things:
A proper image, we'll focus on this below!
Scaling
Rotating
Moving
Using of canvas.globalCompositeOperation = 'lighter'
Using of canvas.globalAlpha for Fading in and out
So let's figure it out step by step.
The first thing you need is a proper image with transparency, a png.
Here you have it:
Consider using a typical HTML 5 game-engine you have an update and a draw method to overwrite for your objects!
Both are triggered every frame, the draw method after the update method.
In the update-method the position of our "dust" is calculated, we are moving it from the initial position towards a target-point and
are increasing the rotation-angle. Further we have a little "state-machine" for handling fading in and fading out.
In the draw-method our dust-image is drawn onto the canvas with the proper settings.
To strengthen the effect we are drawing the image twice while letting the second one rotate reverse!
We are using Impact/JS but it will be similar for any other engine out there.
isReady:false, gaSpeed:0.01, state:0, diffFric:0.001, angleSpeed:0.004, scaling:45, update:function(){ this.parent(); // Calculating the Position, where 'to' is the Target-Point, diffPosX & diffPosY are the distances if (this.pos.x!=this.to.x) { var ldiffX=this.diffPosX*(this.diffFric); if(Math.abs( ldiffX )<this.posTolX)ldiffX=ldiffX<0? this.posTolX*-1:this.posTolX; this.pos.x+=ldiffX;//this.diffPosX; if ((this.pos.x.round(1)==this.to.x.round(1)) || (this.diffPosX<0 && this.pos.x<this.to.x) || (this.diffPosX>0 && this.pos.x>this.to.x)) { this.pos.x=this.to.x; } } if (this.pos.y!=this.to.y) { var ldiffY=this.diffPosY*(this.diffFric); if(Math.abs( ldiffY )<this.posTolY)ldiffY=ldiffY<0? this.posTolY*-1:this.posTolY; this.pos.y+=ldiffY;//this.diffPosX; if ((this.pos.y.round(1)==this.to.y.round(1)) || (this.diffPosY<0 && this.pos.y<this.to.y) || (this.diffPosY>0 && this.pos.y>this.to.y)) { this.pos.y=this.to.y; } } // Rotating... this.currentAnim.angle+=this.angleSpeed; // Fading in and Fading out... if (this.state==0) { this.currentAnim.alpha+=this.gaSpeed; if (this.currentAnim.alpha>=this.switchAlpha) { this.currentAnim.alpha=this.switchAlpha; this.state=2; } }else if (this.state==1 && this.pos.x==this.to.x && this.pos.y==this.to.y) { this.state=2; }else if(this.state==2 && this.gaFadeOut){ this.currentAnim.alpha-=this.gaSpeed; if ( this.currentAnim.alpha<=0) { this.currentAnim.alpha=0; this.state=3; this.isReady=true; } } }, draw:function(){ ig.system.context.save(); if( this.currentAnim.alpha != 1) { ig.system.context.globalAlpha = this.currentAnim.alpha; } ig.system.context.globalCompositeOperation = "lighter"; ig.system.context.translate( ig.system.getDrawPos(this.pos.x + this.currentAnim.pivot.x), ig.system.getDrawPos(this.pos.y + this.currentAnim.pivot.y) ); this.pos.x/=this.scaling; this.pos.y/=this.scaling; this.size.x/=this.scaling; this.size.y/=this.scaling; ig.system.context.rotate(this.currentAnim.angle); ig.system.context.scale(this.scaling,this.scaling); ig.system.context.drawImage(this.currentAnim.sheet.image.data,ig.system.getDrawPos(-this.currentAnim.pivot.x),ig.system.getDrawPos(-this.currentAnim.pivot.y)); ig.system.context.rotate( -this.currentAnim.angle*2.5 ); // Drawing a second one to make the effect much more effective ig.system.context.drawImage(this.currentAnim.sheet.image.data,ig.system.getDrawPos(-this.currentAnim.pivot.x),ig.system.getDrawPos(-this.currentAnim.pivot.y)); ig.system.context.restore(); this.pos.x*=this.scaling; this.pos.y*=this.scaling; this.size.x*=this.scaling; this.size.y*=this.scaling; },
The effect is simple but truly effective, hopefully you can try it out and enjoy it.
If you have any question, just ask me below!
Wolfgang!
You May Also Like