|
Aktibistang Positibo
Join Date: Sep 2009
Posts: 154
Thanks: 0
Thanked 16 Times in 14 Posts
Rep Power: 7 
|
Creative HTML5 and JavaScript Asteroid Game
Today in this post, jsB@nk want to present to you a simple JavaScript application made by HTML5; name of this web-based JavaScript g... detail at JavaScriptBank.com - 2.000+ free JavaScript codes
How to setup
Step 1: Place CSS below in your HEAD section
CSS
Code:
<style type="text/css">
/*
This script downloaded from www.JavaScriptBank.com
Come to view and download over 2000+ free javascript at www.JavaScriptBank.com
*/
* {
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
/* make transparent link selection, adjust last value opacity 0 to 1.0 */
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
body {
margin: 0px;
}
canvas {
display: block;
background-color: #113;
}
</style>
Step 2: Copy & Paste JavaScript code below in your HEAD section
JavaScript
Code:
<script type="text/javascript">
/*
This script downloaded from www.JavaScriptBank.com
Come to view and download over 2000+ free javascript at www.JavaScriptBank.com
*/
var Vector2 = function (x,y) {
this.x= x || 0;
this.y = y || 0;
};
Vector2.prototype = {
reset: function ( x, y ) {
this.x = x;
this.y = y;
return this;
},
toString : function (decPlaces) {
decPlaces = decPlaces || 3;
var scalar = Math.pow(10,decPlaces);
return "[" + Math.round (this.x * scalar) / scalar + ", " + Math.round (this.y * scalar) / scalar + "]";
},
clone : function () {
return new Vector2(this.x, this.y);
},
copyTo : function (v) {
v.x = this.x;
v.y = this.y;
},
copyFrom : function (v) {
this.x = v.x;
this.y = v.y;
},
magnitude : function () {
return Math.sqrt((this.x*this.x)+(this.y*this.y));
},
magnitudeSquared : function () {
return (this.x*this.x)+(this.y*this.y);
},
normalise : function () {
var m = this.magnitude();
this.x = this.x/m;
this.y = this.y/m;
return this;
},
reverse : function () {
this.x = -this.x;
this.y = -this.y;
return this;
},
plusEq : function (v) {
this.x+=v.x;
this.y+=v.y;
return this;
},
plusNew : function (v) {
return new Vector2(this.x+v.x, this.y+v.y);
},
minusEq : function (v) {
this.x-=v.x;
this.y-=v.y;
return this;
},
minusNew : function (v) {
return new Vector2(this.x-v.x, this.y-v.y);
},
multiplyEq : function (scalar) {
this.x*=scalar;
this.y*=scalar;
return this;
},
multiplyNew : function (scalar) {
var returnvec = this.clone();
return returnvec.multiplyEq(scalar);
},
divideEq : function (scalar) {
this.x/=scalar;
this.y/=scalar;
return this;
},
divideNew : function (scalar) {
var returnvec = this.clone();
return returnvec.divideEq(scalar);
},
dot : function (v) {
return (this.x * v.x) + (this.y * v.y) ;
},
angle : function (useRadians) {
return Math.atan2(this.y,this.x) * (useRadians ? 1 : Vector2Const.TO_DEGREES);
},
rotate : function (angle, useRadians) {
var cosRY = Math.cos(angle * (useRadians ? 1 : Vector2Const.TO_RADIANS));
var sinRY = Math.sin(angle * (useRadians ? 1 : Vector2Const.TO_RADIANS));
Vector2Const.temp.copyFrom(this);
this.x= (Vector2Const.temp.x*cosRY)-(Vector2Const.temp.y*sinRY);
this.y= (Vector2Const.temp.x*sinRY)+(Vector2Const.temp.y*cosRY);
return this;
},
equals : function (v) {
return((this.x==v.x)&&(this.y==v.x));
},
isCloseTo : function (v, tolerance) {
if(this.equals(v)) return true;
Vector2Const.temp.copyFrom(this);
Vector2Const.temp.minusEq(v);
return(Vector2Const.temp.magnitudeSquared() < tolerance*tolerance);
},
rotateAroundPoint : function (point, angle, useRadians) {
Vector2Const.temp.copyFrom(this);
//trace("rotate around point "+t+" "+point+" " +angle);
Vector2Const.temp.minusEq(point);
//trace("after subtract "+t);
Vector2Const.temp.rotate(angle, useRadians);
//trace("after rotate "+t);
Vector2Const.temp.plusEq(point);
//trace("after add "+t);
this.copyFrom(Vector2Const.temp);
},
isMagLessThan : function (distance) {
return(this.magnitudeSquared()<distance*distance);
},
isMagGreaterThan : function (distance) {
return(this.magnitudeSquared()>distance*distance);
}
// still AS3 to convert :
// public function projectOnto(v:Vector2) : Vector2
// {
// var dp:Number = dot(v);
//
// var f:Number = dp / ( v.x*v.x + v.y*v.y );
//
// return new Vector2( f*v.x , f*v.y);
// }
//
//
// public function convertToNormal():void
// {
// var tempx:Number = x;
// x = -y;
// y = tempx;
//
//
// }
// public function getNormal():Vector2
// {
//
// return new Vector2(-y,x);
//
// }
//
//
//
// public function getClosestPointOnLine ( vectorposition : Point, targetpoint : Point ) : Point
// {
// var m1 : Number = y / x ;
// var m2 : Number = x / -y ;
//
// var b1 : Number = vectorposition.y - ( m1 * vectorposition.x ) ;
// var b2 : Number = targetpoint.y - ( m2 * targetpoint.x ) ;
//
// var cx : Number = ( b2 - b1 ) / ( m1 - m2 ) ;
// var cy : Number = m1 * cx + b1 ;
//
// return new Point ( cx, cy ) ;
// }
//
};
Vector2Const = {
TO_DEGREES : 180 / Math.PI,
TO_RADIANS : Math.PI / 180,
temp : new Vector2()
};
(function () {
var spareBullets = [];
window.Bullet = function (ctx, x, y, angle) {
// this is rather nasty - so I'm not sure why I'm doing it...
if (this === window) {
if (spareBullets.length) {
var bullet = spareBullets.pop();
bullet.init(x, y, angle);
bullet.fresh = false;
return bullet;
} else {
return new Bullet(ctx, x, y, angle);
}
}
this.ctx = ctx;
// initialise
this.init(x, y, angle);
return this;
};
Bullet.prototype = {
init: function (x, y, angle) {
this.fresh = true;
this.pos = new Vector2(x,y);
this.vel = new Vector2(Bullet.speed,0);
this.vel.rotate(angle);
this.enabled = true;
// 15 is the length of the ship
this.pos.plusEq(this.vel.clone().normalise().multiplyEq(15));
},
checkEnabled: function () {
var ctx = this.ctx;
if (this.enabled == false) {
return;
}
if (this.pos.x < 0 || this.pos.x > ctx.canvas.width) this.enabled = false;
if (this.pos.y < 0 || this.pos.y > ctx.canvas.height) this.enabled = false;
if (this.enabled == false) {
spareBullets.push(this);
}
},
update: function () {
this.pos.plusEq(this.vel);
this.checkEnabled();
return this;
},
draw: function () {
var ctx = this.ctx,
pos = this.pos;
ctx.save();
ctx.lineWidth = 2;
ctx.strokeStyle = "#fff";
ctx.beginPath();
ctx.arc(pos.x, pos.y, 2, 0, Math.PI*2, true);
ctx.stroke();
ctx.restore();
return this;
}
};
// static
Bullet.speed = 5;
})();
Asteroid = function (x,y,radius)
{
this.pos = new Vector2(x,y);
this.vel = new Vector2(0,0);
this.points;
this.enabled = true;
// temp vector to calculate distance from circle in hitTest
this.diff = new Vector2(0,0);
this.reset = function (radius) {
this.points = [];
this.radius = radius;
var temp = new Vector2(radius, 0);
for (var angle = 0; angle<360; angle+= random(0, 45)) {
temp.reset(random(radius / 2, radius),0);
temp.rotate(angle);
this.points.push(temp.clone());
}
};
this.reset(radius);
this.update = function(canvas) {
this.pos.plusEq(this.vel);
if(this.pos.x+this.radius < 0) this.pos.x = canvas.width+this.radius;
else if (this.pos.x-this.radius > canvas.width) this.pos.x = -this.radius;
if(this.pos.y+this.radius < 0) this.pos.y = canvas.height+this.radius;
else if (this.pos.y-this.radius > canvas.height) this.pos.y = -this.radius;
};
this.draw = function(ctx) {
ctx.save();
ctx.translate(this.pos.x, this.pos.y);
ctx.strokeStyle = "#fff";
ctx.fillStyle = '#000';
ctx.lineWidth = 2;
ctx.beginPath();
for(var i = 0; i<this.points.length; i++) {
var p = this.points[i % this.points.length];
ctx.lineTo(p.x, p.y);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
};
this.hitTest = function(x,y) {
this.diff.copyFrom(this.pos);
this.diff.x-=x;
this.diff.y-=y;
var distanceSq = (this.diff.x * this.diff.x) + (this.diff.y*this.diff.y);
return distanceSq < (this.radius * this.radius);
};
};
ShipMoving = function(x,y) {
this.pos = new Vector2(x,y);
this.angle = 0;
this.vel = new Vector2(0,0);
this.temp = new Vector2(0,0);
this.thrustPower = 0.1;
this.rotateSpeed = 5;
this.thrusting = false;
this.invulnerable = false;
this.thrustAmount = 0;
this.dead = [];
this.update = function() {
this.pos.plusEq(this.vel);
};
this.thrust = function() {
this.temp.reset(this.thrustPower,0);
this.temp.rotate(this.angle);
this.vel.plusEq(this.temp);
};
this.rotateLeft = function() {
this.angle -= this.rotateSpeed;
};
this.rotateRight = function() {
this.angle += this.rotateSpeed;
};
this.hit = function () {
var n = 20;
while (n--) {
this.dead.push(new Vector2(random(3, 6), 0));
this.dead[this.dead.length - 1].rotate(Math.random() * Math.PI * 2, true);
}
};
this.isdead = function () {
return !!this.dead.length;
};
this.draw = function(c) {
c.save();
c.translate(this.pos.x, this.pos.y);
c.rotate(this.angle * Vector2Const.TO_RADIANS);
if (this.invulnerable == false && !this.isdead()) {
c.lineWidth = 4;
if (this.thrustAmount) {
c.beginPath();
c.moveTo(-11, -3);
c.lineTo(-11, 3);
c.lineTo(-12 -this.thrustAmount, 0);
c.closePath();
c.fillStyle = 'hsla(3, 100%, 50%, 0.9)';
c.fill();
c.strokeStyle = 'hsla(32, 100%, 50%, 0.7)';
c.stroke();
}
c.lineWidth = 2;
c.strokeStyle = "#fff";
c.beginPath();
c.moveTo(-10, -10);
c.lineTo(-10, 10);
c.lineTo(14, 0);
c.closePath();
c.stroke();
} else if (this.dead.length) {
var i = this.dead.length;
c.lineWidth = 2;
c.fillStyle = 'hsla(1, 100%, 50%, 0.75)';
while (i--) {
this.dead[i].multiplyEq(1.05);
c.beginPath();
c.arc(this.dead[i].x, this.dead[i].y, 2, 0, Math.PI * 2, true);
c.closePath();
c.fill();
}
}
if (this.thrusting && this.thrustAmount < 10) {
this.thrustAmount++;
} else if (this.thrustAmount > 0) {
this.thrustAmount--;
}
c.restore();
};
};
// canvas element and 2D context
var canvas = document.createElement('canvas'),
c = canvas.getContext('2d'),
touch = 'createTouch' in document;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
c.strokeStyle = "#ffffff";
var mouseX, mouseY,
halfWidth = canvas.width/2,
halfHeight = canvas.height/2,
bullets = [],
spareAsteroids = [],
ship = new ShipMoving(halfWidth, halfHeight),
thrusting = false,
rotateLeft = false,
rotateRight = false,
grad = c.createLinearGradient(0, 0, 0, canvas.height),
asteroids = [],
trail = 0.85;
grad.addColorStop(0, 'hsla(240,80%,2%,' + trail + ')');
grad.addColorStop(1, 'hsla(240,100%,15%,' + trail + ')');
timer = setInterval(draw, 1000/35);
for (var i = 0; i < (touch ? 5 : 10); i++) {
asteroids.push(new Asteroid(random(0, canvas.width), random(0, canvas.height), 50));
asteroids[i].vel.reset(1,0).rotate(random(0,360));
}
function draw() {
c.fillStyle = '#000'; //grad;
c.fillRect(0,0,canvas.width, canvas.height);
var bullet;
for (var i=0; i<bullets.length; i++) {
bullet = bullets[i];
if (bullet.enabled) {
bullet.update();
bullet.draw();
}
}
for (i = 0; i < asteroids.length; i++) {
var asteroid = asteroids[i],
hit = false;
if (!ship.invulnerable && !ship.isdead() && asteroid.hitTest(ship.pos.x, ship.pos.y)) {
// you lose!
ship.hit();
}
if(!asteroid.enabled) continue;
if (!ship.isdead()) {
for (var j = 0; j < bullets.length; j++) {
if (bullets[j].enabled) {
hit = asteroid.hitTest(bullets[j].pos.x, bullets[j].pos.y);
if (hit) {
bullets[j].enabled = false;
break;
}
}
}
}
if (hit) {
if (asteroid.radius < 15) {
asteroid.enabled = false;
} else {
asteroid.reset(asteroid.radius/2);
asteroid.vel.reset(random(-5,5),random(-5,5));
makeNewAsteroid(asteroid.pos.x, asteroid.pos.y, asteroid.radius).vel.reset(random(-5,5),random(-5,5));
makeNewAsteroid(asteroid.pos.x, asteroid.pos.y, asteroid.radius).vel.reset(random(-5,5),random(-5,5));
}
} else {
asteroid.update(canvas);
asteroid.draw(c);
}
}
if (ship.thrusting) ship.thrust();
if (rotateLeft) ship.rotateLeft();
if (rotateRight) ship.rotateRight();
ship.update();
if (ship.pos.x<0) ship.pos.x = canvas.width;
else if (ship.pos.x>canvas.width) ship.pos.x = 0;
if (ship.pos.y<0) ship.pos.y = canvas.height;
else if (ship.pos.y>canvas.height) ship.pos.y = 0;
ship.draw(c);
}
function makeNewAsteroid(x, y, radius) {
var newasteroid;
if (spareAsteroids.length > 0) {
newasteroid = spareAsteroids.pop();
newasteroid.pos.set(x, y);
newasteroid.radius = radius;
} else {
newasteroid = new Asteroid(x, y, radius);
asteroids.push(newasteroid);
}
return newasteroid;
}
function fire() {
if (ship.isdead()) {
return;
}
// only allow n bullets
var limit = 5,
i = bullets.length;
while (i--) {
if (bullets[i].enabled) {
limit--;
}
}
if (limit !== 0) {
var bullet = Bullet(c, ship.pos.x, ship.pos.y, ship.angle);
if (bullet.fresh) bullets.push(bullet);
}
}
canvas.addEventListener( 'mousemove', onMouseMove, false );
document.addEventListener( 'keydown', onKeyDown, false );
document.addEventListener( 'keyup', onKeyUp, false );
document.addEventListener( 'touchstart', onTouchStart, false );
document.addEventListener( 'touchmove', onTouchMove, false );
document.addEventListener( 'touchend', onTouchEnd, false );
var swipe = [];
if (touch) {
ship.thrustPower = 0.5;
}
function onTouchStart(e) {
swipe = [];
if (e.touches.length == 1) {
// rotate & fire
var v = new Vector2(e.touches[0].pageX-canvas.width/2, e.touches[0].pageY-canvas.height/2);
ship.angle = v.angle();
fire();
} else if (e.touches.length == 2) {
ship.thrusting = true;
ship.thrust();
} else if (e.touches.length == 3) {
ship.invulnerable = true;
}
}
function onTouchMove(e) {
e.preventDefault();
}
// window.addEventListener('devicemotion', function(event) {
// var v = new Vector2(event.accelerationIncludingGravity.x, event.accelerationIncludingGravity.y);
// ship.angle += v.angle() * 0.05;
// }, false);
function onTouchEnd(e) {
ship.thrusting = false;
ship.invulnerable = false;
}
function onKeyDown(e) {
if(e.keyCode == 38) ship.thrusting = true;
else if (e.keyCode == 40) ship.invulnerable = true;
else if(e.keyCode == 37) rotateLeft = true;
else if (e.keyCode == 39) rotateRight = true;
else if (e.which == 32) fire();
}
function onKeyUp(e) {
if (e.keyCode == 38) ship.thrusting = false;
else if (e.keyCode == 40) ship.invulnerable = false;
else if(e.keyCode == 37) rotateLeft = false;
else if (e.keyCode == 39) rotateRight = false;
}
function onMouseMove(event) {
mouseX = event.offsetX;
mouseY = event.offsetY;
}
function random(v1, v2){
return ((Math.random()*(v2-v1))+v1);
}
setTimeout(function () {
window.scrollTo(1, 0);
}, 1000);
</script>
Step 3: Copy & Paste HTML code below in your BODY section
HTML
Code:
<canvas height="609" width="1139"></canvas>
Step 4: Download files below
Files
demo.html
|