|
// constant options |
|
const focalDepth = 80; |
|
const focalPoint = 256; |
|
|
|
|
|
// variables |
|
var centreX; |
|
var centreY; |
|
var mouseX=0; |
|
var mouseY=0; |
|
var frameCount=0; |
|
var gameStart; |
|
|
|
var context; |
|
var canvas; |
|
var fontsize = 20; |
|
|
|
// test multiple groups |
|
var boardPieces = []; |
|
var mapScale = {x:0, y:0}; |
|
var galaxyMapSize = {x:16, y:8}; |
|
var shipLocation = {x:0, y:0}; |
|
var shipPosition = {x:0, y:0}; |
|
var shipPing = {x:0, y:0}; |
|
var pingRadius = 100; |
|
var lastCycle = 0; |
|
var cycleScalar = 1; // 3 = 30 seconds. |
|
var targetBase = 0; |
|
|
|
var warpLocation = {x:0, y:0}; |
|
var warpAnim = 0; |
|
var warpLocked = false; |
|
|
|
|
|
// board pieces |
|
function GetBoardPiece(x, y, useKnown) |
|
{ |
|
if (useKnown) |
|
{ |
|
for (var i=0; i<boardPieces.length; i++) |
|
{ |
|
if (boardPieces[i].lastknown.x == x && boardPieces[i].lastknown.y==y) return i; |
|
} |
|
} |
|
else |
|
{ |
|
for (var i=0; i<boardPieces.length; i++) |
|
{ |
|
if (boardPieces[i].location.x == x && boardPieces[i].location.y==y) return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
function GetBoardPieceScreen(sx, sy, lastKnown) |
|
{ |
|
// convert sx and sy into board-coords |
|
var scaleX = canvas.width/(galaxyMapSize.x+2); |
|
var scaleY = canvas.height/(galaxyMapSize.y+2); |
|
|
|
x = Math.floor(sx/scaleX) - 1; |
|
y = Math.floor(sy/scaleY) - 1; |
|
|
|
return GetBoardPiece(x, y, lastKnown); |
|
} |
|
|
|
// creates a piece |
|
function BoardPiece(x, y, type) |
|
{ |
|
this.init(x, y, type); |
|
} |
|
|
|
// initializer |
|
BoardPiece.prototype.init = function(fx, fy, type) |
|
{ |
|
// type 0 = base |
|
// type 1 = patrol |
|
// type 2 = group |
|
// type 3 = fleet |
|
|
|
// status = 0 dead |
|
// status = 1 alive |
|
this.type = type; |
|
this.laststate = 0; |
|
this.lastknown = {x:fx, y:fy}; |
|
|
|
this.location = {x:fx, y:fy}; |
|
this.status = 2; |
|
|
|
this.moveRate = type==3 ? 8 : type; |
|
this.nextMove = this.moveRate; |
|
|
|
this.numTargets = type==0 ? 0 : type+1; |
|
} |
|
|
|
// render pieces |
|
BoardPiece.prototype.render = function(x, y, radius) |
|
{ |
|
var trailRad2 = radius*radius*0.25; |
|
var leadRad2 = radius*radius*4; |
|
|
|
var pos = this.screen(this.lastknown.x, this.lastknown.y); |
|
var dx = pos.x - x; |
|
var dy = pos.y - y; |
|
var distance2 = dx*dx+dy*dy; |
|
|
|
var fade=1; |
|
|
|
if (distance2<leadRad2) // update lastknow |
|
{ |
|
fade = (distance2 - trailRad2) / (leadRad2-trailRad2); |
|
if (fade>0 && this.laststate!=0) |
|
{ |
|
this.drawitem(pos, fade); |
|
} |
|
} |
|
else if (this.laststate!=0) |
|
{ |
|
this.drawitem(pos, 1); |
|
} |
|
|
|
var pos2 = this.screen(this.location.x, this.location.y); |
|
var dx2 = pos2.x-x; |
|
var dy2 = pos2.y-y; |
|
var distance22 = dx2*dx2+dy2*dy2; |
|
|
|
if (distance22<leadRad2 && this.status>0) // update lastkno |
|
{ |
|
fade = ((distance22 - trailRad2) / (leadRad2-trailRad2))+1.0; |
|
this.drawitem(pos2, fade); |
|
} |
|
else if (this.status == 1) |
|
{ |
|
this.drawitem(pos2, fade); |
|
} |
|
|
|
} |
|
|
|
|
|
// update to known location |
|
BoardPiece.prototype.updateKnowns = function() |
|
{ |
|
if(this.status==2) this.status=1; |
|
|
|
this.lastknown.x = this.location.x; |
|
this.lastknown.y = this.location.y; |
|
this.laststate = this.status; |
|
} |
|
|
|
// game piece movement logic - pretty rough randomizer |
|
|
|
BoardPiece.prototype.move = function(gameCycle) |
|
{ |
|
this.updateKnowns(); |
|
|
|
// scale game cycle time (radar beats every 10s) |
|
aiCycle = Math.floor(gameCycle/cycleScalar); |
|
|
|
if (this.nextMove<=aiCycle && this.type > 0) // new position except bases |
|
{ |
|
var x, y; |
|
var target = boardPieces[targetBase].location; |
|
// bee-line |
|
var dx = target.x - this.location.x; |
|
var dy = target.y - this.location.y; |
|
x = Math.max(Math.min(dx, 1), -1) + this.location.x; |
|
y = Math.max(Math.min(dy, 1), -1) + this.location.y; |
|
|
|
var p = GetBoardPiece(x, y); |
|
if ((p>=0 || x<0 || y<0 || x>=galaxyMapSize.x || y>=galaxyMapSize.y) && p.type!=0) |
|
{ |
|
if (dx==0) x = Math.floor(Math.random()*2)*2-1 + this.location.x; |
|
else y = Math.floor(Math.random()*2)*2-1 + this.location.y; |
|
p = GetBoardPiece(x, y); |
|
// off board or occupied |
|
if (p>=0 || x<0 || y<0 || x>=galaxyMapSize.x || y>=galaxyMapSize.y) return; |
|
} |
|
|
|
// update movement time |
|
this.nextMove += this.moveRate; |
|
|
|
this.location.x = x; |
|
this.location.y = y; |
|
this.status = 2; |
|
|
|
} |
|
|
|
|
|
} |
|
|
|
// help functoin to convert from map to screen space |
|
BoardPiece.prototype.screen = function(x, y) |
|
{ |
|
var scaleX = canvas.width/(galaxyMapSize.x+2); |
|
var scaleY = canvas.height/(galaxyMapSize.y+2); |
|
return {x:x*scaleX+scaleX*1.5, y:y*scaleY+scaleY*1.5}; |
|
} |
|
|
|
|
|
// DRAW Board piece item with label text |
|
BoardPiece.prototype.drawitem = function( pos, fading) |
|
{ |
|
var ascii = ["starbase", "patrol", "group", "fleet"]; |
|
|
|
var light = (fading-1)*255; |
|
light = Math.floor(Math.max(Math.min(light, 255), 0)); |
|
|
|
font = fontsize + (((fading-1.5)*40)); |
|
if (this.status < 2 || fading <=1.5) font = fontsize; |
|
font*=0.75; |
|
context.globalAlpha = fading>1 ? 1.0: fading; |
|
context.font = font + 'pt Calibri'; |
|
context.fillStyle = 'rgb('+light+',255,'+light+')'; |
|
context.textAlign = "center"; |
|
|
|
context.fillText(ascii[this.type], pos.x, pos.y+font*1.5); |
|
|
|
pos.y-=font; |
|
|
|
switch(this.type) |
|
{ |
|
case 0: // base |
|
context.beginPath(); |
|
context.arc(pos.x, pos.y, font, 0, Math.PI, true); |
|
context.moveTo(pos.x+font, pos.y); |
|
context.quadraticCurveTo(pos.x, pos.y+font*0.75, pos.x-font, pos.y); |
|
context.fill(); |
|
context.strokeStyle='#80ff80'; |
|
context.stroke(); |
|
break; |
|
case 1: // patrol fighter |
|
context.beginPath(); |
|
context.arc(pos.x, pos.y, font*0.75, 0, Math.PI*2, false); |
|
context.fill(); |
|
context.moveTo(pos.x-font, pos.y-font); |
|
context.lineTo(pos.x-font, pos.y+font); |
|
context.moveTo(pos.x+font, pos.y-font); |
|
context.lineTo(pos.x+font, pos.y+font); |
|
context.strokeStyle='#80ff80'; |
|
context.stroke(); |
|
break; |
|
case 2: // group cruiser |
|
context.beginPath(); |
|
context.moveTo(pos.x-font, pos.y); |
|
context.lineTo(pos.x-font/2, pos.y-font/2); |
|
context.lineTo(pos.x+font*2, pos.y); |
|
context.lineTo(pos.x-font/2, pos.y+font/2); |
|
context.closePath(); |
|
context.fill(); |
|
context.lineTo(pos.x+font*2, pos.y); |
|
context.strokeStyle='#80ff80'; |
|
context.stroke(); |
|
context.beginPath(); |
|
context.arc(pos.x-font*1.5, pos.y-font*0.9, font*0.25, 0, Math.PI*2, false); |
|
context.arc(pos.x-font*2, pos.y+font*0.75, font*0.25, 0, Math.PI*2, false); |
|
context.fill(); |
|
break; |
|
|
|
case 3: // fleet / basestar |
|
context.beginPath(); |
|
context.moveTo(pos.x-font, pos.y-font/2); |
|
context.quadraticCurveTo(pos.x, pos.y-font, pos.x+font, pos.y-font/2); |
|
context.lineTo(pos.x-font, pos.y+font/2); |
|
context.quadraticCurveTo(pos.x, pos.y+font, pos.x+font, pos.y+font/2); |
|
context.closePath(); |
|
context.fill(); |
|
context.strokeStyle='#80ff80'; |
|
context.stroke(); |
|
break; |
|
} |
|
|
|
} |
|
|
|
function CountHostiles(loc) |
|
{ |
|
var count = 0; |
|
for (var i=-1; i<2; i++) |
|
{ |
|
for (var j=-1; j<2; j++) |
|
{ |
|
var p = GetBoardPiece(loc.x+i, loc.y+j); |
|
if (p>=0 && p.type!=0) count++; |
|
} |
|
} |
|
|
|
return count; |
|
} |
|
|
|
|
|
function BoardSetup() |
|
{ |
|
// clear board |
|
targetBase = 0; |
|
boardPieces = []; |
|
|
|
var x, y, border = 1; |
|
for (var i =0; i<4; i++) // types |
|
{ |
|
for (var j=0; j<4; j++) // counts |
|
{ |
|
|
|
do |
|
{ |
|
x = Math.floor(Math.random() * (galaxyMapSize.x-border*2))+border; |
|
y = Math.floor(Math.random() * (galaxyMapSize.y-border*2))+border; |
|
|
|
var p = GetBoardPiece(x, y); |
|
} while(p>=0); |
|
|
|
boardPieces.push(new BoardPiece(x, y, i)); |
|
} |
|
border = 0; |
|
} |
|
} |
|
|
|
function SetShipLocation(x, y) |
|
{ |
|
shipLocation.x = Math.floor(x); |
|
shipLocation.y = Math.floor(y); |
|
shipPosition.x = x; |
|
shipPosition.y = y; |
|
} |
|
|
|
function SetWarpPoint(x, y, lock) |
|
{ |
|
if (warpLocked == true && lock == false) return; |
|
warpLocked = lock; |
|
warpLocation.x = x; |
|
warpLocation.y = y; |
|
warpAnim = 0; |
|
|
|
} |
|
|
|
function ClearWarpPoint() |
|
{ |
|
warpLocked = false; |
|
} |
|
|
|
// many thanks to http://www.sonic.net/~nbs/star-raiders/docs/v.html |
|
var distanceTable =[100,130,160,200,230,500,700,800,900,1200,1250,1300,1350,1400,1550,1700,1840,2000,2080,2160,2230,2320,2410, 2500,9999]; |
|
|
|
function ShipCalculateWarpEnergy(sx, sy) |
|
{ |
|
// convert sx and sy into board-coords |
|
var scaleX = canvas.width/(galaxyMapSize.x+2); |
|
var scaleY = canvas.height/(galaxyMapSize.y+2); |
|
|
|
var x = (sx/scaleX) - 1; |
|
var y = (sy/scaleY) - 1; |
|
|
|
var dx = shipPosition.x - x; |
|
var dy = shipPosition.y - y; |
|
|
|
// location |
|
var distance = Math.sqrt(dx*dx+dy*dy); |
|
|
|
var di = Math.floor(distance); |
|
if (di>23) di=23; |
|
|
|
var energy = distanceTable[di]; |
|
energy+= (distanceTable[di+1]-energy) * (distance-di); |
|
|
|
return Math.floor(energy); |
|
} |
|
|
|
// initialization |
|
|
|
function init() |
|
{ |
|
// setup canvas and context |
|
canvas = document.getElementById('test'); |
|
context = canvas.getContext('2d'); |
|
|
|
// set canvas to be window dimensions |
|
resize(); |
|
|
|
// create event listeners |
|
canvas.addEventListener('mousemove', mouseMove); |
|
canvas.addEventListener('click', mouseClick); |
|
window.addEventListener('resize', resize); |
|
|
|
// initialze variables |
|
SetShipLocation(galaxyMapSize.x*0.5, galaxyMapSize.y*0.5); |
|
|
|
// initial ping |
|
shipPing.x = shipPosition.x; |
|
shipPing.y = shipPosition.y; |
|
|
|
// populate map |
|
BoardSetup(); |
|
|
|
var d = new Date(); |
|
gameStart = d.getTime(); |
|
|
|
|
|
} |
|
|
|
// long range scan |
|
// galactic scan |
|
|
|
|
|
function renderGalacticScanner() |
|
{ |
|
var scaleX = canvas.width/(galaxyMapSize.x+2); |
|
var scaleY = canvas.height/(galaxyMapSize.y+2); |
|
|
|
context.beginPath(); |
|
|
|
for (var i=0; i<=galaxyMapSize.x; i++) |
|
{ |
|
context.moveTo(scaleX*(i+1), scaleY); |
|
context.lineTo(scaleX*(i+1), scaleY*(galaxyMapSize.y+1)); |
|
} |
|
context.strokeStyle = '#c0c0c0'; |
|
context.lineWidth = 4; |
|
context.stroke(); |
|
|
|
context.beginPath(); |
|
|
|
for (var j=0; j<=galaxyMapSize.y; j++) |
|
{ |
|
context.moveTo(scaleX, scaleY*(j+1)); |
|
context.lineTo(scaleX*(galaxyMapSize.x+1), scaleY*(j+1)); |
|
} |
|
|
|
context.strokeStyle = '#c0c0c0'; |
|
context.lineWidth = 4; |
|
context.stroke(); |
|
|
|
|
|
|
|
// ping every 5 seconds |
|
var d = new Date(); |
|
var currentTime = d.getTime(); |
|
var distance = ((currentTime - gameStart)%10000)/10000; |
|
pingRadius = distance * canvas.width/2; |
|
|
|
context.globalCompositeOperation='source-over'; |
|
var shipX = shipPing.x * scaleX + scaleX; |
|
var shipY = shipPing.y * scaleY + scaleY; |
|
// update map with locations of ships |
|
for (var b=0; b<boardPieces.length; b++) |
|
{ |
|
// fade in and out board pieces as the ping passes over them |
|
boardPieces[b].render(shipX, shipY, pingRadius); |
|
} |
|
|
|
context.globalCompositeOperation='lighter'; |
|
context.globalAlpha = 1; |
|
context.beginPath(); |
|
|
|
var gradient = context.createRadialGradient(shipX, shipY, pingRadius*0.5, shipX, shipY, pingRadius*2); |
|
gradient.addColorStop(0, 'rgba(128, 255, 128,0)'); |
|
gradient.addColorStop(1, 'rgba(128, 255, 128,'+(1-distance)+')'); |
|
|
|
context.fillStyle = gradient; |
|
context.arc(shipX, shipY, pingRadius*2, Math.PI*2, false); |
|
context.fill(); |
|
|
|
// render hyperspace location |
|
context.beginPath(); |
|
clampX = Math.max(Math.min(warpLocation.x, scaleX*(galaxyMapSize.x+1)), scaleX); |
|
clampY = Math.max(Math.min(warpLocation.y, scaleY*(galaxyMapSize.y+1)), scaleY); |
|
|
|
context.moveTo(clampX, scaleY) |
|
context.lineTo(clampX, scaleY*(galaxyMapSize.y+1)); |
|
context.moveTo(scaleX, clampY); |
|
context.lineTo(scaleX*(galaxyMapSize.x+1), clampY); |
|
|
|
if (warpLocked) |
|
{ |
|
warpAnim=(warpAnim+1)%(Math.sqrt(scaleX*scaleX+scaleY*scaleY)*0.5); |
|
context.arc(clampX, clampY, warpAnim, 0, Math.PI*2, false); |
|
} |
|
|
|
context.strokeStyle = '#c0ffc0'; |
|
context.lineWidth = 1; |
|
context.stroke(); |
|
|
|
|
|
} |
|
|
|
// input functions |
|
|
|
function mouseMove(event) |
|
{ |
|
var rect = canvas.getBoundingClientRect(); |
|
|
|
mouseX = event.clientX - rect.left; |
|
mouseY = event.clientY - rect.top; |
|
|
|
SetWarpPoint(mouseX, mouseY, false); |
|
} |
|
|
|
function mouseClick() |
|
{ |
|
var scaleX = canvas.width/(galaxyMapSize.x+2); |
|
var scaleY = canvas.height/(galaxyMapSize.y+2); |
|
|
|
var x = (mouseX/scaleX)-1; |
|
var y = (mouseY/scaleY)-1; |
|
|
|
//SetShipLocation(x, y); |
|
|
|
// lock in warp point |
|
if (!warpLocked) |
|
SetWarpPoint(mouseX, mouseY, true); |
|
else |
|
ClearWarpPoint(); |
|
} |
|
|
|
function resize() |
|
{ |
|
canvas.width = window.innerWidth; |
|
canvas.height = window.innerHeight; |
|
// compute centre of screen |
|
centreX = canvas.width/2; |
|
centreY = canvas.height/2; |
|
fontsize = 21; |
|
|
|
// resize font based on canvas size |
|
mapScale.x = canvas.width/(galaxyMapSize.x+2); |
|
mapScale.y = canvas.height/(galaxyMapSize.y+2); |
|
|
|
do |
|
{ |
|
fontsize-=0.1; |
|
context.font = fontsize + 'pt Calibri'; |
|
var fits = context.measureText('group'); |
|
}while((fits.width+20>mapScale.x || mapScale.y<fontsize*4) && fontsize >5); |
|
|
|
} |
|
|
|
function renderInformation() |
|
{ |
|
var scaleX = canvas.width/(galaxyMapSize.x+2); |
|
var scaleY = canvas.height/(galaxyMapSize.y+2); |
|
|
|
var i = GetBoardPieceScreen(mouseX, mouseY); |
|
var targets = 'empty'; |
|
if (i>0) |
|
{ |
|
targets = boardPieces[i].numTargets; |
|
if (targets == 0) targets = 'starbase'; |
|
} |
|
|
|
context.globalAlpha = 1.0; |
|
context.font = '20pt Calibri'; |
|
context.fillStyle = 'rgb(255,255,0)'; |
|
context.textAlign = "left"; |
|
context.fillText('Targets: ' + targets, mapScale.x, canvas.height-15); |
|
|
|
var fuel = ShipCalculateWarpEnergy(mouseX, mouseY); |
|
|
|
context.font = '20pt Calibri'; |
|
context.fillStyle = 'rgb(255,255,0)'; |
|
context.textAlign = "center"; |
|
context.fillText('Warp Energy: ' + fuel, canvas.width/2, canvas.height-15); |
|
|
|
if (warpLocked) |
|
{ |
|
var clampX = Math.max(Math.min(warpLocation.x, mapScale.x*(galaxyMapSize.x+1)), mapScale.x); |
|
var clampY = Math.max(Math.min(warpLocation.y, mapScale.y*(galaxyMapSize.y+1)), mapScale.y); |
|
var fuel = ShipCalculateWarpEnergy(clampX, clampY); |
|
|
|
context.textAlign = "centre"; |
|
context.font = '11pt Calibri'; |
|
context.fillText('Energy: ' + fuel, clampX, clampY-12); |
|
|
|
} |
|
|
|
// render our ship |
|
context.beginPath(); |
|
var x = shipPosition.x*scaleX+scaleX; |
|
var y = shipPosition.y*scaleY+scaleY; |
|
context.arc(x, y, fontsize*0.5, 0, Math.PI*2); |
|
context.fill(); |
|
context.moveTo(x, y-fontsize*1.5); |
|
context.lineTo(x-fontsize, y+fontsize*1.5); |
|
context.lineTo(x, y); |
|
context.lineTo(x+fontsize, y+fontsize*1.5); |
|
context.closePath(); |
|
|
|
context.fill(); |
|
} |
|
|
|
function renderStarDate() |
|
{ |
|
var d = new Date(); |
|
var currentTime = d.getTime(); |
|
|
|
var gameTime = currentTime - gameStart; |
|
var decimalTime = gameTime / 60000; |
|
context.font = '20pt Calibri'; |
|
context.fillStyle = 'rgb(255,255,0)'; |
|
context.textAlign = "right"; |
|
leadingzero = decimalTime<10 ? '0':''; |
|
context.fillText('StarDate: ' + leadingzero + decimalTime.toFixed(2), canvas.width-mapScale.x, canvas.height-15); |
|
} |
|
|
|
|
|
// rendering functions |
|
|
|
function render() |
|
{ |
|
|
|
context.fillStyle = 'black'; |
|
context.clearRect(0, 0, canvas.width, canvas.height); |
|
|
|
renderGalacticScanner(); |
|
|
|
renderInformation(); |
|
|
|
renderStarDate(); |
|
|
|
context.globalAlpha = 1.0; |
|
context.font = '20pt Calibri'; |
|
context.fillStyle = 'rgb(255,255,255)'; |
|
context.textAlign = "center"; |
|
context.fillText('Galactic Scanner', canvas.width/2, 30); |
|
|
|
} |
|
|
|
// movement functions |
|
|
|
function update() |
|
{ |
|
var d = new Date(); |
|
var currentTime = d.getTime(); |
|
var gameCycle = Math.floor((currentTime - gameStart)/10000); |
|
if (gameCycle!=lastCycle) |
|
{ |
|
for (var b=0; b<boardPieces.length; b++) |
|
{ |
|
boardPieces[b].move(gameCycle); |
|
} |
|
shipPing.x = shipPosition.x; |
|
shipPing.y = shipPosition.y; |
|
} |
|
lastCycle = gameCycle; |
|
|
|
// check starbase health and trigger destruction |
|
var base = boardPieces[targetBase]; |
|
var count = CountHostiles(base.location); |
|
if (count>=4) // trigger kaboom |
|
{ |
|
if (base.nextMove==0) base.nextMove = gameCycle + 2; |
|
if (base.nextMove<gameCycle) |
|
{ |
|
targetBase++; |
|
base.status = 0; |
|
boardPieces.push(new BoardPiece(base.location.x, base.location.y, 1)); |
|
} |
|
} |
|
else |
|
{ |
|
base.nextMove = 0; |
|
} |
|
|
|
if (targetBase == 4 ) // zylons win |
|
{ |
|
BoardSetup(); |
|
} |
|
|
|
CheckButtons(mouseX, mouseY); |
|
} |
|
|
|
// per frame tick functions |
|
|
|
function animate() |
|
{ |
|
frameCount++; |
|
// movement update |
|
update(); |
|
// render update |
|
render(); |
|
// trigger next frame |
|
requestAnimationFrame(animate); |
|
} |
|
|
|
// array to hold all buttons |
|
var buttons = []; |
|
|
|
// checks hits against the button list |
|
function CheckButtons(x, y) |
|
{ |
|
for (var i=0; i<buttons.length; i++) |
|
{ |
|
buttons[i].hit(x,y); |
|
} |
|
} |
|
|
|
// renders the buttons |
|
function RenderButtons() |
|
{ |
|
for (var i=0; i<buttons.length; i++) |
|
{ |
|
buttons[i].render(); |
|
} |
|
} |
|
|
|
function Button(x, y, w, h, name, callback) |
|
{ |
|
this.x = x; |
|
this.y = y; |
|
this.w = w; |
|
this.h = h; |
|
this.name = name; |
|
this.callback = callback; |
|
// add button to stack |
|
buttons.push(this); |
|
} |
|
|
|
Button.prototype.render = function() |
|
{ |
|
// fill a rect |
|
context.beginPath(); |
|
context.rect(this.x, this.y, this.w, this.h); |
|
context.fillStyle = 'rgba(0, 0, 0, 0.5)'; |
|
context.fill(); |
|
|
|
context.lineWidth = 2; |
|
context.strokeStyle = 'rgba(120, 120, 120, 0.5)'; |
|
context.stroke(); |
|
|
|
context.moveTo(this.x, this.y); |
|
context.font = '20pt Calibri'; |
|
context.fillStyle = 'rgba(255,255,255, 1)'; |
|
context.textAlign = "center"; |
|
context.fillText(this.name, this.x+this.w/2, this.y+this.h-9); |
|
} |
|
|
|
Button.prototype.hit = function(x, y) |
|
{ |
|
if (x>=this.x && x<this.x+this.w && y>this.y && y<this.y+this.h) |
|
{ |
|
// hit |
|
return this.callback(); |
|
} |
|
return false; |
|
} |
|
|
|
// entry point |
|
init(); |
|
animate(); |