
I use no image but draws radial gradient into the canvas.
Try to click and drag the white ball after re-creates it.
Script in the html
This is the script I put in the html's footer (don't forget to add a canvas in the body and give id as "myCancas"):var game = new ICHOLE.Game(document.getElementById("myCanvas"));
game.canvas.onmousedown = function(e){ game.mouseDown(e); };
game.canvas.onmouseup = function(e){ game.mouseUp(e); };
window.setInterval( function(e){ game.updateAll(); }, 1000/game.FPS) ;
Script at js folder
... and this is the js/gchole.js:var ICHOLE = {author:"mi_kuncoro@yahoo.co.id", ver:"20130207"};
ICHOLE.Game = function(cvs)
{
this.canvas = cvs;
this.context = this.canvas.getContext("2d");
this.init();
};
ICHOLE.Game.prototype = {
costructor:ICHOLE.Game,
FRICTION:0.99,
PR:Math.PI * 2,
P180:Math.PI / 180,
I180:180 / Math.PI,
FPS:50,
mouseIsDown:false,
wall:{left:50, top:50, right:450, down:450},
players:[{id:0, playerName:"Player 1", score:0}, {id:1, playerName:"Player 2", score:0}],
hole:null,
gaco:null,
rBalls:[],
gBalls:[],
aBalls:[],
collides:[],
busy:false,
curLevel:0,
curPlayer:null,
canvas:null,
context:null,
createBall:function(xx, yy, rr, knd, clr){
return {x:xx, y:yy, vx:0, vy:0, radius:rr, kind:knd, color:clr, alive:true, collided:false};
},
collideA:function(a, firstTime){
if (a.length == 0) return;
for (var i = 0; i < a.length; i++){
this.collideBA(a[i], a, firstTime);
}
},
collideBA:function(b, a, firstTime){
var aCol = [];
var dMin = 100000;
var cObj;
for (var i = 0; i < a.length; i++){
cObj = this.collideBB(b, a[i]);
if (cObj.collide == true) {
if (firstTime) {
this.collides.push([b, a[i]]);
}
if (cObj.dist < dMin){
aCol.length = 0;
dMin = cObj.dist;
aCol.push(cObj);
}
else if (cObj.dist == dMin){
aCol.push(cObj);
}
}
}
this.resolveA(aCol);
},
collideBB:function(b1, b2){
if (b1 == b2) return {collide:false};
var o = {collide:false, ball1:b1, ball2:b2, dist:this.distance(b2.x, b2.y, b1.x, b1.y), dist2:0};
o.dist2 = b1.radius + b2.radius - o.dist;
if (o.dist2 > 0) o.collide = true;
return o;
},
collideBW:function(b, w){
if ((b.x - w.left) < b.radius){
b.x = b.x + b.x - w.left - b.radius + 1;
if (b.vx < 0) b.vx *= -1;
}
else if ((w.right - b.x) < b.radius){
b.x = b.x + b.x + b.radius - w.right - 1;
if (b.vx > 0) b.vx *= -1;
}
if ((b.y - w.top) < b.radius){
b.y = b.y + b.y - b.radius - w.top + 1;
if (b.vy < 0) b.vy *= -1;
}
else if ((w.down - b.y) < b.radius){
b.y = b.y + b.y + b.radius - w.down - 1;
if (b.vy > 0) b.vy *= -1;
}
},
resolveA:function(a){
if (a.length == 0) return;
var ab = [];
var ao;
while (a.length > 0){
ao = a.shift();
this.resolveO(ao);
this.collideBW(ao.ball1, this.wall);
this.collideBW(ao.ball2, this.wall);
ab.push(ao.ball1);
ab.push(ao.ball2);
}
this.collideA(ab);
},
resolveO:function(o){
var b1 = o.ball1;
var b2 = o.ball2;
var x1h = b1.vx / 2; var y1h = b1.vy / 2;
var x2h = b2.vx / 2; var y2h = b2.vy / 2;
var px = (b2.x - b1.x) / 2 + b1.x;
var py = (b2.y - b1.y) / 2 + b1.y;
var dx = b1.x - px;
var dy = b1.y - py;
var dd = Math.sqrt(dx * dx + dy * dy);
var dx2 = b2.x - px;
var dy2 = b2.y - py;
var dd2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
var pwr1 = Math.sqrt(b1.vx * b1.vx + b1.vy * b1.vy) / 2;
var pwr2 = Math.sqrt(b2.vx * b2.vx + b2.vy * b2.vy) / 2;
var pwr = (pwr1 + pwr2) / 2;
b1.vx = dx / dd * pwr + x1h;
b1.vy = dy / dd * pwr + y1h;
b2.vx = dx2 / dd2 * pwr + x2h;
b2.vy = dy2 / dd2 * pwr + y2h;
var ddd = o.dist2 + 1;
b1.x += b1.vx * ddd;
b1.y += b1.vy * ddd;
b2.x += b2.vx * ddd;
b2.y += b2.vy * ddd;
},
draw:function(ctx)
{
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
ctx.fillStyle = "#333333";
ctx.fillRect(this.wall.left, this.wall.top, this.wall.right - this.wall.left, this.wall.down - this.wall.top);
this.drawBall(ctx, this.hole);
for (var i = 0; i < this.aBalls.length; i++){
this.drawBall(ctx, this.aBalls[i]);
}
},
drawBall:function(ctx, b){
if (b.alive == false) return;
var curFill;
try {
curFill = ctx.createRadialGradient(b.x-b.radius, b.y - b.radius, 0, b.x + b.radius, b.y + b.radius, 50);
curFill.addColorStop(0, '#FFFFFF');
curFill.addColorStop(0.5, b.color);
curFill.addColorStop(1, '#000000');
ctx.fillStyle = curFill;
ctx.strokeStyle = "#553300";
ctx.beginPath();
ctx.arc(b.x, b.y, b.radius, 0, this.PR, true);
ctx.closePath();
ctx.fill();
ctx.stroke();
}catch(e){}
},
distance:function(x1, y1, x2, y2){
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt((dx * dx) + (dy * dy));
},
normalize:function(x1, y1){
var dd = Math.sqrt((x1 * x1) + (y1 * y1));
if (dd != 0 && dd != 1)
{
x1 /= dd;
y1 /= dd;
}
},
updateAll:function(e){
this.collides.length = 0;
var n = this.aBalls.length;
var b;
for (var i = 0; i < n; i++) {
b = this.aBalls[i];
if (b.vx != 0 || b.vy != 0){
b.x += b.vx;
b.y += b.vy;
b.vx *= this.FRICTION;
b.vy *= this.FRICTION;
if (Math.abs(b.vx * b.vy) < 0.01) b.vx = b.vy = 0;
this.collideBW(b, this.wall);
}
} this.collideA(this.aBalls, true);
this.draw(this.context);
},
mouseDown:function(e){
if (this.gaco == null) return;
var b = this.gaco; //console.log(b);
if (Math.abs(e.offsetX - b.x) < b.radius || Math.abs(e.offsetY - b.y) < b.radius) this.mouseIsDown = true;
},
mouseUp:function(e){
if (this.mouseIsDown) {
var b = this.gaco;
var dx = b.x - e.offsetX;
var dy = b.y - e.offsetY;
var dd = Math.sqrt(dx * dx + dy * dy);
var dn = (Math.abs(dd) < 10) ? dd : (9 * dd / Math.abs(dd));
if (dd != 0 && dd != 1)
{
b.vx = dx/dd * dn;
b.vy = dy/dd * dn;
}
}
this.mouseIsDown = false;
},
startLevel:function(v){
var a = - Math.PI / 2;
var aa = Math.PI * 2 / 7;
var b;
this.gaco.x = 250;
this.gaco.y = 400;
this.gaco.vx = 2;
this.gaco.vy = -3;
this.aBalls.push(this.gaco);
for (var i = 0; i < 7; i++){
b = this.rBalls[i];
b.x = Math.cos(a) * 100 + 250;
b.y = Math.sin(a) * 100 + 250;
b.alive = true;
this.aBalls.push(b);
b = this.gBalls[i];
b.x = Math.cos(a) * 150 + 250;
b.y = Math.sin(a) * 150 + 250;
b.alive = true;
this.aBalls.push(b);
a += aa;
}
this.draw(this.context, 500, 500);
this.curPlayer = this.players[0];
},
init:function(){
this.hole = this.createBall(250, 250, 16, -1, "#000000");
this.gaco = this.createBall(250, 400, 16, 0, "#cccccc");
for (var i = 0; i < 7; i++){
this.rBalls.push(this.createBall(0, 0, 16, 1, "#ff0000"));
this.gBalls.push(this.createBall(0, 0, 16, 2, "#00ff00"));
}
this.context.fillStyle = "#550033";
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.startLevel(1);
}
};
You also can copy and paste the script right into the html.
if (a.length == 0) return;
var ab = [];
var ao;
while (a.length > 0){
ao = a.shift();
this.resolveO(ao);
this.collideBW(ao.ball1, this.wall);
this.collideBW(ao.ball2, this.wall);
ab.push(ao.ball1);
ab.push(ao.ball2);
}
this.collideA(ab);
},
resolveO:function(o){
var b1 = o.ball1;
var b2 = o.ball2;
var x1h = b1.vx / 2; var y1h = b1.vy / 2;
var x2h = b2.vx / 2; var y2h = b2.vy / 2;
var px = (b2.x - b1.x) / 2 + b1.x;
var py = (b2.y - b1.y) / 2 + b1.y;
var dx = b1.x - px;
var dy = b1.y - py;
var dd = Math.sqrt(dx * dx + dy * dy);
var dx2 = b2.x - px;
var dy2 = b2.y - py;
var dd2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
var pwr1 = Math.sqrt(b1.vx * b1.vx + b1.vy * b1.vy) / 2;
var pwr2 = Math.sqrt(b2.vx * b2.vx + b2.vy * b2.vy) / 2;
var pwr = (pwr1 + pwr2) / 2;
b1.vx = dx / dd * pwr + x1h;
b1.vy = dy / dd * pwr + y1h;
b2.vx = dx2 / dd2 * pwr + x2h;
b2.vy = dy2 / dd2 * pwr + y2h;
var ddd = o.dist2 + 1;
b1.x += b1.vx * ddd;
b1.y += b1.vy * ddd;
b2.x += b2.vx * ddd;
b2.y += b2.vy * ddd;
},
draw:function(ctx)
{
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
ctx.fillStyle = "#333333";
ctx.fillRect(this.wall.left, this.wall.top, this.wall.right - this.wall.left, this.wall.down - this.wall.top);
this.drawBall(ctx, this.hole);
for (var i = 0; i < this.aBalls.length; i++){
this.drawBall(ctx, this.aBalls[i]);
}
},
drawBall:function(ctx, b){
if (b.alive == false) return;
var curFill;
try {
curFill = ctx.createRadialGradient(b.x-b.radius, b.y - b.radius, 0, b.x + b.radius, b.y + b.radius, 50);
curFill.addColorStop(0, '#FFFFFF');
curFill.addColorStop(0.5, b.color);
curFill.addColorStop(1, '#000000');
ctx.fillStyle = curFill;
ctx.strokeStyle = "#553300";
ctx.beginPath();
ctx.arc(b.x, b.y, b.radius, 0, this.PR, true);
ctx.closePath();
ctx.fill();
ctx.stroke();
}catch(e){}
},
distance:function(x1, y1, x2, y2){
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt((dx * dx) + (dy * dy));
},
normalize:function(x1, y1){
var dd = Math.sqrt((x1 * x1) + (y1 * y1));
if (dd != 0 && dd != 1)
{
x1 /= dd;
y1 /= dd;
}
},
updateAll:function(e){
this.collides.length = 0;
var n = this.aBalls.length;
var b;
for (var i = 0; i < n; i++) {
b = this.aBalls[i];
if (b.vx != 0 || b.vy != 0){
b.x += b.vx;
b.y += b.vy;
b.vx *= this.FRICTION;
b.vy *= this.FRICTION;
if (Math.abs(b.vx * b.vy) < 0.01) b.vx = b.vy = 0;
this.collideBW(b, this.wall);
}
} this.collideA(this.aBalls, true);
this.draw(this.context);
},
mouseDown:function(e){
if (this.gaco == null) return;
var b = this.gaco; //console.log(b);
if (Math.abs(e.offsetX - b.x) < b.radius || Math.abs(e.offsetY - b.y) < b.radius) this.mouseIsDown = true;
},
mouseUp:function(e){
if (this.mouseIsDown) {
var b = this.gaco;
var dx = b.x - e.offsetX;
var dy = b.y - e.offsetY;
var dd = Math.sqrt(dx * dx + dy * dy);
var dn = (Math.abs(dd) < 10) ? dd : (9 * dd / Math.abs(dd));
if (dd != 0 && dd != 1)
{
b.vx = dx/dd * dn;
b.vy = dy/dd * dn;
}
}
this.mouseIsDown = false;
},
startLevel:function(v){
var a = - Math.PI / 2;
var aa = Math.PI * 2 / 7;
var b;
this.gaco.x = 250;
this.gaco.y = 400;
this.gaco.vx = 2;
this.gaco.vy = -3;
this.aBalls.push(this.gaco);
for (var i = 0; i < 7; i++){
b = this.rBalls[i];
b.x = Math.cos(a) * 100 + 250;
b.y = Math.sin(a) * 100 + 250;
b.alive = true;
this.aBalls.push(b);
b = this.gBalls[i];
b.x = Math.cos(a) * 150 + 250;
b.y = Math.sin(a) * 150 + 250;
b.alive = true;
this.aBalls.push(b);
a += aa;
}
this.draw(this.context, 500, 500);
this.curPlayer = this.players[0];
},
init:function(){
this.hole = this.createBall(250, 250, 16, -1, "#000000");
this.gaco = this.createBall(250, 400, 16, 0, "#cccccc");
for (var i = 0; i < 7; i++){
this.rBalls.push(this.createBall(0, 0, 16, 1, "#ff0000"));
this.gBalls.push(this.createBall(0, 0, 16, 2, "#00ff00"));
}
this.context.fillStyle = "#550033";
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.startLevel(1);
}
};
You also can copy and paste the script right into the html.
Tidak ada komentar:
Posting Komentar