I'm working on a soccer webcam game in Canvas, still using headtrackr (https://github.com/auduno/headtrackr)
Here it is online; http://www.chrissnoek.com/ubicomp/webcam.html
so far I managed to check if my rectangle hits my ball, then the counter goes +1
The only thing is, I can't reposition my ball if the rectangle hits it.
I tried it this way, but the ball constantly redrawn, so as the rectangle.
bal.x = Math.floor(Math.random()* (640) + 20);
bal.y = Math.floor(Math.random()* (120) + 20);
But that doesn't work. Here is my full code;
Any suggestions to move the ball when it is hit?
<!doctype html>
<html lang="en">
<head>
<title>facetracking</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<meta charset="utf-8">
<script src="js/animate.js"></script>
<script src="js/delta.js"></script>
<script src="./js/headtrackr.js"></script>
</head>
<body>
<span id="counter">0</span>
<canvas id="compare" width="640" height="480" style="display:none"></canvas>
<video id="vid" autoplay loop width="640" height="480" style="width: 640px"></video>
<canvas id="overlay" width="640" height="480"></canvas>
<canvas id="Baloverlay" width="640" height="480"></canvas>
<canvas id="bal" width="640" height="480"></canvas>
<canvas id="debug" width="640" height="480"></canvas>
<p id='gUMMessage'></p>
<p>Status : <span id='headtrackerMessage'></span></p>
<p>
<input type="button" onclick="htracker.stop();htracker.start();" value="reinitiate facedetection"></input>
<br/><br/>
<input type="checkbox" onclick="showProbabilityCanvas()" value="asdfasd"></input>Show probability-map
</p>
<script>
// set up video and canvas elements needed
var videoInput = document.getElementById('vid');
var canvasInput = document.getElementById('compare');
var canvasOverlay = document.getElementById('overlay');
var balOverlay = document.getElementById('bal');
var debugOverlay = document.getElementById('debug');
var overlayContext = canvasOverlay.getContext('2d');
var balOverlay = document.getElementById('Baloverlay');
var balContext = balOverlay.getContext('2d');
var counter = document.getElementById('counter'),
count = 0;
canvasOverlay.style.position = "absolute";
canvasOverlay.style.top = '0px';
canvasOverlay.style.zIndex = '100001';
canvasOverlay.style.display = 'block';
balOverlay.style.position = "absolute";
balOverlay.style.top = '0px';
balOverlay.style.zIndex = '100002';
balOverlay.style.display = 'block';
debugOverlay.style.position = "absolute";
debugOverlay.style.top = '0px';
debugOverlay.style.zIndex = '100003';
debugOverlay.style.display = 'none';
// add some custom messaging
statusMessages = {
"whitebalance" : "checking for stability of camera whitebalance",
"detecting" : "Detecting face",
"hints" : "Hmm. Detecting the face is taking a long time",
"redetecting" : "Lost track of face, redetecting",
"lost" : "Lost track of face",
"found" : "Tracking face"
};
supportMessages = {
"no getUserMedia" : "Unfortunately, <a href='http://dev.w3.org/2011/webrtc/editor/getusermedia.html'>getUserMedia</a> is not supported in your browser. Try <a href='http://www.opera.com/browser/'>downloading Opera 12</a> or <a href='http://caniuse.com/stream'>another browser that supports getUserMedia</a>. Now using fallback video for facedetection.",
"no camera" : "No camera found. Using fallback video for facedetection."
};
document.addEventListener("headtrackrStatus", function(event) {
if (event.status in supportMessages) {
var messagep = document.getElementById('gUMMessage');
messagep.innerHTML = supportMessages[event.status];
} else if (event.status in statusMessages) {
var messagep = document.getElementById('headtrackerMessage');
messagep.innerHTML = statusMessages[event.status];
}
}, true);
// the face tracking setup
var htracker = new headtrackr.Tracker({altVideo : {ogv : "./media/capture5.ogv", mp4 : "./media/capture5.mp4"}, calcAngles : true, ui : false, headPosition : false, debug : debugOverlay});
htracker.init(videoInput, canvasInput);
htracker.start();
// for each facetracking event received draw rectangle around tracked face on canvas
document.addEventListener("facetrackingEvent", function( event ) {
// clear canvas
overlayContext.clearRect(0,0,640,480);
// once we have stable tracking, draw rectangle
if (event.detection == "CS") {
overlayContext.translate(event.x, event.y)
//overlayContext.rotate(event.angle-(Math.PI/2));
overlayContext.strokeStyle = "#00CC00";
overlayContext.strokeRect((-(event.width/2)) >> 0, (-(event.height/2)) >> 0, event.width, event.height);
//overlayContext.rotate((Math.PI/2)-event.angle);
overlayContext.translate(-event.x, -event.y);
var bal = new ball();
lookForBallInbound(event.x, event.y, event.width, event.height);
}
});
// turn off or on the canvas showing probability
function showProbabilityCanvas() {
var debugCanvas = document.getElementById('debug');
if (debugCanvas.style.display == 'none') {
debugCanvas.style.display = 'block';
} else {
debugCanvas.style.display = 'none';
}
}
/*==============================================
////////// KIJK OF BAL BINNEN VAK VALT ////////
==============================================*/
function lookForBallInbound(boxX,boxY,boxWidth,boxHeight) {
var rightCornerX = boxX - (boxWidth / 2),
topY = boxY - (boxHeight / 2);
if(rightCornerX <= xxx){
if((rightCornerX + boxWidth) <= xxx) {
return false;
} else {
// balls is in the box at the x axis
// Now check for Y
if (topY <= yyy) {
// Top is also inbound, => AWESOME <=
/*========================================
RECALCULATE BALL POSITION
========================================*/
bal.x = Math.floor(Math.random()* (640) + 20);
bal.y = Math.floor(Math.random()* (120) + 20);
/*========================================
INCREASE AND OUTPUT COUNTER
========================================*/
count++;
counter.innerHTML = '';
counter.innerHTML = count;
}
}
}
}
var xxx = Math.floor(Math.random()* (640) + 20);
var yyy = Math.floor(Math.random()* (120) + 20);
var ballRadius = 20;
function ball() {
console.log('Ball recalculating');
balContext.beginPath();
balContext.arc(xxx, yyy, ballRadius, 0, 2 * Math.PI, false);
balContext.fillStyle = 'green';
balContext.fill();
}
</script>
</body>
</html>
Something like this should work. Note that ball is defined as a global variable.
var videoInput = document.getElementById('vid');
var canvasInput = document.getElementById('compare');
var canvasOverlay = document.getElementById('overlay');
var debugOverlay = document.getElementById('debug');
var overlayContext = canvasOverlay.getContext('2d');
var balOverlay = document.getElementById('Baloverlay');
var balContext = balOverlay.getContext('2d');
var counter = document.getElementById('counter'),
count = 0,
ball,
statusMessages,
supportMessages,
htracker;
canvasOverlay.style.position = "absolute";
canvasOverlay.style.top = '0px';
canvasOverlay.style.zIndex = '100001';
canvasOverlay.style.display = 'block';
balOverlay.style.position = "absolute";
balOverlay.style.top = '0px';
balOverlay.style.zIndex = '100002';
balOverlay.style.display = 'block';
debugOverlay.style.position = "absolute";
debugOverlay.style.top = '0px';
debugOverlay.style.zIndex = '100003';
debugOverlay.style.display = 'none';
// add some custom messaging
statusMessages = {
"whitebalance": "checking for stability of camera whitebalance",
"detecting": "Detecting face",
"hints": "Hmm. Detecting the face is taking a long time",
"redetecting": "Lost track of face, redetecting",
"lost": "Lost track of face",
"found": "Tracking face"
};
supportMessages = {
"no getUserMedia": "Unfortunately, <a href='http://dev.w3.org/2011/webrtc/editor/getusermedia.html'>getUserMedia</a> is not supported in your browser. Try <a href='http://www.opera.com/browser/'>downloading Opera 12</a> or <a href='http://caniuse.com/stream'>another browser that supports getUserMedia</a>. Now using fallback video for facedetection.",
"no camera": "No camera found. Using fallback video for facedetection."
};
document.addEventListener("headtrackrStatus", function(event) {
var messagep;
if (event.status in supportMessages) {
messagep = document.getElementById('gUMMessage');
messagep.innerHTML = supportMessages[event.status];
} else if (event.status in statusMessages) {
messagep = document.getElementById('headtrackerMessage');
messagep.innerHTML = statusMessages[event.status];
}
}, true);
// the face tracking setup
htracker = new headtrackr.Tracker({
altVideo: {
ogv: "./media/capture5.ogv",
mp4: "./media/capture5.mp4"
},
calcAngles: true,
ui: false,
headPosition: false,
debug: debugOverlay
});
htracker.init(videoInput, canvasInput);
htracker.start();
// for each facetracking event received draw rectangle around tracked face on canvas
document.addEventListener("facetrackingEvent", function(event) {
// clear canvas
overlayContext.clearRect(0, 0, 640, 480);
// once we have stable tracking, draw rectangle
if (event.detection == "CS") {
overlayContext.translate(event.x, event.y);
//overlayContext.rotate(event.angle-(Math.PI/2));
overlayContext.strokeStyle = "#00CC00";
overlayContext.strokeRect((-(event.width / 2)) >> 0, (-(event.height / 2)) >> 0, event.width, event.height);
//overlayContext.rotate((Math.PI/2)-event.angle);
overlayContext.translate(-event.x, -event.y);
if (!ball) { // if there is no ball then make one
ball = new Ball();
}
lookForBallInbound(event.x, event.y, event.width, event.height);
}
});
// turn off or on the canvas showing probability
function showProbabilityCanvas() {
var debugCanvas = document.getElementById('debug');
if (debugCanvas.style.display == 'none') {
debugCanvas.style.display = 'block';
} else {
debugCanvas.style.display = 'none';
}
}
/*==============================================
////////// KIJK OF BAL BINNEN VAK VALT ////////
==============================================*/
function lookForBallInbound(boxX, boxY, boxWidth, boxHeight) {
var leftX = boxX - boxWidth / 2, rightX = leftX + boxWidth,
topY = boxY - boxHeight / 2, bottomY = topY + boxHeight;
if (!ball) return;
if (leftX <= ball.x && rightX >= ball.x &&
topY <= ball.y && bottomY >= ball.y) {
ball = new Ball();
// ^ replace the existing ball with a randomly positioned new one
count++;
counter.innerHTML = count;
}
}
function Ball() {
console.log('making new ball');
this.x = Math.floor(Math.random() * 640 + 20);
this.y = Math.floor(Math.random() * 120 + 20);
this.radius = 20;
this.draw = function() {
balContext.clearRect(0, 0, 640, 480);
balContext.beginPath();
balContext.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
balContext.fillStyle = 'green';
balContext.fill();
}
this.draw();
}
Related
Im trying to make the image of a trex jump when canavas is clicked
Here is my code
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<canvas onclick="canjump = true; renderer = requestAnimationFrame(loop); dinoy = 150;" height="250px" width="350px" style="border: 2px solid black" id="canvas"></canvas>
<img src="./dino.png" height="0px" width="0px" id="dinoimg">
<img src="./cacti.png" height="0px" width="0px" id="cactimg">
<script type="text/javascript" src="./main.js"></script>
</body>
</html>
main.js
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
var dinoimage = document.getElementById('dinoimg');
var dinoheight = 100;
var dinowidth = 50;
var dinox = 0;
var dinoy = 150;
var canjump = false;
var renderer;
var jmpv = 15;
function loop() {
if (canjump = true && dinoy <= 150) {
jumpdino();
} else {
dinoy = 151;
jmpv = 15;
canjump = false;
cancelAnimationFrame(renderer);
}
//setcacti();
//checkcollision();
renderer = requestAnimationFrame(loop);
}
function jumpdino() {
ctx.clearRect(0, 0, 350, 250);
ctx.drawImage(dinoimage, dinox, dinoy, dinowidth, dinoheight);
dinoy -= jmpv;
jmpv--;
}
The problem is that everything work as expected for first time but when canvas is clicked after then (second click and after), the image just go up and come down very fast and not smoothly with acceleration like first time.
Please help!!!
Those two fore function calls are commented because they arent implemented yet.
Just fixing the code you have I added a return in the else, the issue was even though you canceled the requestAnimationFrame after the else condition it still would continue and reassign renderer to the loop. So it was always running, each time you clicked it was just adding another instance making it go faster and faster.
function loop() {
if (canjump = true && dinoy <= 150) {
jumpdino();
} else {
dinoy = 151;
jmpv = 15;
canjump = false;
cancelAnimationFrame(renderer);
// You need to exit out.
return;
}
//setcacti();
//checkcollision();
renderer = requestAnimationFrame(loop);
}
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
var dinoheight = 100;
var dinowidth = 50;
var dinox = 0;
var dinoy = 150;
var canjump = false;
var renderer;
var jmpv = 15;
function loop() {
if (canjump = true && dinoy <= 150) {
jumpdino();
} else {
dinoy = 151;
jmpv = 15;
canjump = false;
cancelAnimationFrame(renderer);
return;
}
//setcacti();
//checkcollision();
renderer = requestAnimationFrame(loop);
}
function jumpdino() {
ctx.clearRect(0, 0, 350, 250);
ctx.fillRect(dinox, dinoy, dinowidth, dinoheight);
dinoy -= jmpv;
jmpv--;
}
<canvas onclick="canjump = true; requestAnimationFrame(loop); dinoy = 150;" height="250px" width="350px" style="border: 2px solid black" id="canvas"></canvas>
Personally I'd remove the inline event handler and do something like this in your code as well.
canvas.addEventListener('click', () => {
canjump = true;
dinoy = 150;
loop();
});
I've been working on a simple matching puzzle game for a little while now. Currently I have been able to have a countdown time and the number of matching tiles displayed as a text and I'm trying to create one for the best time completed (basically how fast the person completed the puzzle). However whenever I try to create it the text never displays.I noticed while writing the code that if I where to place the variable "txt" followed by a "." the autocomplete box will appear with .text as an available option so I would get "txt.text". I do not however get that option when writing the bestTimeTxt variable which is what I am using to display the time. I'm not sure what I have done wrong, here is my code.
<!DOCTYPE html>
<html>
<head>
<title>Recipe: Drawing a square</title>
<script src="easel.js"></script>
<script type="text/javascript">
var canvas;
var stage;
var squareSide = 70;
var squareOutline = 5;
var max_rgb_color_value = 255;
var gray = Graphics.getRGB(20, 20, 20);
var placementArray = [];
var tileClicked;
var timeAllowable;
var totalMatchesPossible;
var matchesFound;
var txt;
var bestTime;
var bestTimeTxt;
var matchesFoundText;
var squares;
function init() {
var rows = 5;
var columns = 6;
var squarePadding = 10;
canvas = document.getElementById('myCanvas');
stage = new Stage(canvas);
var numberOfTiles = rows*columns;
matchesFound = 0;
timeAllowable = 5;
bestTime = 0
txt = new Text(timeAllowable, "30px Monospace", "#000");
txt.textBaseline = "top"; // draw text relative to the top of the em box.
txt.x = 500;
txt.y = 0;
bestTimeTxt = new Text(bestTime, "30px Monospace", "#000");
bestTimeTxt.textBaseLine = "top";
bestTimeTxt.x = 300;
bestTimeTxt.y = 0;
stage.addChild(txt);
stage.addChild(bestTimeTxt);
squares = [];
totalMatchesPossible = numberOfTiles/2;
Ticker.init();
Ticker.addListener(window);
Ticker.setPaused(false);
matchesFoundText = new Text("Pairs Found: "+matchesFound+"/"+totalMatchesPossible, "30px Monospace", "#000");
matchesFoundText.textBaseline = "top"; // draw text relative to the top of the em box.
matchesFoundText.x = 500;
matchesFoundText.y = 40;
stage.addChild(matchesFoundText);
setPlacementArray(numberOfTiles);
for(var i=0;i<numberOfTiles;i++){
var placement = getRandomPlacement(placementArray);
if (i % 2 === 0){
var color = randomColor();
}
var square = drawSquare(gray);
square.color = color;
square.x = (squareSide+squarePadding) * (placement % columns);
square.y = (squareSide+squarePadding) * Math.floor(placement / columns);
squares.push(square);
stage.addChild(square);
square.cache(0, 0, squareSide + squarePadding, squareSide + squarePadding);
square.onPress = handleOnPress;
stage.update();
};
}
function drawSquare(color) {
var shape = new Shape();
var graphics = shape.graphics;
graphics.setStrokeStyle(squareOutline);
graphics.beginStroke(gray);
graphics.beginFill(color);
graphics.rect(squareOutline, squareOutline, squareSide, squareSide);
return shape;
}
function randomColor(){
var color = Math.floor(Math.random()*255);
var color2 = Math.floor(Math.random()*255);
var color3 = Math.floor(Math.random()*255);
return Graphics.getRGB(color, color2, color3)
}
function setPlacementArray(numberOfTiles){
for(var i = 0;i< numberOfTiles;i++){
placementArray.push(i);
}
}
function getRandomPlacement(placementArray){
randomNumber = Math.floor(Math.random()*placementArray.length);
return placementArray.splice(randomNumber, 1)[0];
}
function handleOnPress(event){
var tile = event.target;
tile.graphics.beginFill(tile.color).rect(squareOutline, squareOutline, squareSide, squareSide);
if(!!tileClicked === false || tileClicked === tile){
tileClicked = tile;
tileClicked.updateCache("source-overlay");
}else{
if(tileClicked.color === tile.color && tileClicked !== tile){
tileClicked.visible = false;
tile.visible = false;
matchesFound++;
matchesFoundText.text = "Pairs Found: "+matchesFound+"/"+totalMatchesPossible;
if (matchesFound===totalMatchesPossible){
gameOver(true);
}
}else{
tileClicked.graphics.beginFill(gray).rect(squareOutline, squareOutline, squareSide, squareSide);
}
tileClicked.updateCache("source-overlay");
tile.updateCache("source-overlay");
tileClicked = tile;
}
stage.update();
}
function tick() {
secondsLeft = Math.floor((timeAllowable-Ticker.getTime()/1000));
txt.text = secondsLeft;
bestTimeTxt.text = "test";
if (secondsLeft <= 0){
gameOver(false);
}
stage.update();
}
function gameOver(win){
Ticker.setPaused(true);
for(var i=0;i<squares.length;i++){
squares[i].graphics.beginFill(squares[i].color).rect(5, 5, 70, 70);
squares[i].onPress = null;
if (win === false){
squares[i].uncache();
}
}
var replayParagraph = document.getElementById("replay");
replayParagraph.innerHTML = "<a href='#' onClick='history.go(0);'>Play Again?</a>";
if (win === true){
matchesFoundText.text = "You win!"
}else{
txt.text = secondsLeft + "... Game Over";
}
}
function replay(){
init();
}
</script>
</head>
<body onload="init()">
<header id="header">
<p id="replay"></p>
</header>
<canvas id="myCanvas" width="960" height="400"></canvas>
</body>
</html>
Apparently the issue I was having was that the x and y position of the text was causing it to appear behind everything else.
I'm currently working on a small tile matching game and have made it so that each time you complete the game the variable "bestTime" will store the amount of time you took to complete the session. The variable "bestTimeTxt" will then take the value and display it in text. After you have completed a session a link will appear allowing you to start again. I have put the new text
bestTimeTxt = new Text("Best Time: " + bestTime , "30px Monospace", "#000");
bestTimeTxt.textBaseLine = "top";
bestTimeTxt.x = 500;
bestTimeTxt.y = 100;
outside of the init() function so it shouldn't keep resetting I'm not sure what I am supposed to do as every combination i could think of isn't working.
here is my full code.
I'm also using easeljs for this game
<!DOCTYPE html>
<html>
<head>
<title>Recipe: Drawing a square</title>
<script src="easel.js"></script>
<script type="text/javascript">
var canvas;
var stage;
var squareSide = 70;
var squareOutline = 5;
var max_rgb_color_value = 255;
var gray = Graphics.getRGB(20, 20, 20);
var placementArray = [];
var tileClicked;
var timeAllowable;
var totalMatchesPossible;
var matchesFound;
var txt;
var bestTime = 0;
var bestTimeTxt;
var matchesFoundText;
var squares;
var startingTime;
bestTimeTxt = new Text("Best Time: " + bestTime , "30px Monospace", "#000");
bestTimeTxt.textBaseLine = "top";
bestTimeTxt.x = 500;
bestTimeTxt.y = 100;
function init() {
var rows = 5;
var columns = 6;
var squarePadding = 10;
canvas = document.getElementById('myCanvas');
stage = new Stage(canvas);
var numberOfTiles = rows*columns;
matchesFound = 0;
timeAllowable = 500;
startingTime = timeAllowable;
txt = new Text(timeAllowable, "30px Monospace", "#000");
txt.textBaseline = "top"; // draw text relative to the top of the em box.
txt.x = 500;
txt.y = 0;
stage.addChild(bestTimeTxt);
stage.addChild(txt);
squares = [];
totalMatchesPossible = numberOfTiles/2;
Ticker.init();
Ticker.addListener(window);
Ticker.setPaused(false);
matchesFoundText = new Text("Pairs Found: "+matchesFound+"/"+totalMatchesPossible, "30px Monospace", "#000");
matchesFoundText.textBaseline = "top"; // draw text relative to the top of the em box.
matchesFoundText.x = 500;
matchesFoundText.y = 40;
stage.addChild(matchesFoundText);
setPlacementArray(numberOfTiles);
for(var i=0;i<numberOfTiles;i++){
var placement = getRandomPlacement(placementArray);
if (i % 2 === 0){
var color = randomColor();
}
var square = drawSquare(gray);
square.color = color;
square.x = (squareSide+squarePadding) * (placement % columns);
square.y = (squareSide+squarePadding) * Math.floor(placement / columns);
squares.push(square);
stage.addChild(square);
square.cache(0, 0, squareSide + squarePadding, squareSide + squarePadding);
square.onPress = handleOnPress;
stage.update();
};
}
function drawSquare(color) {
var shape = new Shape();
var graphics = shape.graphics;
graphics.setStrokeStyle(squareOutline);
graphics.beginStroke(gray);
graphics.beginFill(color);
graphics.rect(squareOutline, squareOutline, squareSide, squareSide);
return shape;
}
function randomColor(){
var color = Math.floor(Math.random()*255);
var color2 = Math.floor(Math.random()*255);
var color3 = Math.floor(Math.random()*255);
return Graphics.getRGB(color, color2, color3)
}
function setPlacementArray(numberOfTiles){
for(var i = 0;i< numberOfTiles;i++){
placementArray.push(i);
}
}
function getRandomPlacement(placementArray){
randomNumber = Math.floor(Math.random()*placementArray.length);
return placementArray.splice(randomNumber, 1)[0];
}
function handleOnPress(event){
var tile = event.target;
tile.graphics.beginFill(tile.color).rect(squareOutline, squareOutline, squareSide, squareSide);
if(!!tileClicked === false || tileClicked === tile){
tileClicked = tile;
tileClicked.updateCache("source-overlay");
}else{
if(tileClicked.color === tile.color && tileClicked !== tile){
tileClicked.visible = false;
tile.visible = false;
matchesFound++;
matchesFoundText.text = "Pairs Found: "+matchesFound+"/"+totalMatchesPossible;
if (matchesFound===totalMatchesPossible){
gameOver(true);
}
}else{
tileClicked.graphics.beginFill(gray).rect(squareOutline, squareOutline, squareSide, squareSide);
}
tileClicked.updateCache("source-overlay");
tile.updateCache("source-overlay");
tileClicked = tile;
}
stage.update();
}
function tick() {
secondsLeft = Math.floor((timeAllowable-Ticker.getTime()/1000));
txt.text = secondsLeft;
;
if (secondsLeft <= 0){
gameOver(false);
}
stage.update();
}
function gameOver(win){
Ticker.setPaused(true);
for(var i=0;i<squares.length;i++){
squares[i].graphics.beginFill(squares[i].color).rect(5, 5, 70, 70);
squares[i].onPress = null;
if (win === false){
squares[i].uncache();
}
}
var replayParagraph = document.getElementById("replay");
replayParagraph.innerHTML = "<a href='#' onClick='history.go(0);'>Play Again?</a>";
if (win === true){
matchesFoundText.text = "You win!"
if((startingTime - secondsLeft) > bestTime)
{
bestTime = startingTime - secondsLeft;
bestTimeTxt.text = "Best Time: " + bestTime;
}
}
else
{
txt.text = secondsLeft + "... Game Over";
}
}
function replay(){
init();
}
</script>
</head>
<body onload="init()">
<header id="header">
<p id="replay"></p>
</header>
<canvas id="myCanvas" width="960" height="400"></canvas>
</body>
</html>
In your code, inside gameover method, I see you are using history.go(0) on play again link.
Technically, history.go(0) means to refresh the page and all your variables no matter the scope are set to the initial values.
If you want to retain the best score for the session and continue, use the replay method instead of history.
Updated Code :
replayParagraph.innerHTML = "<a href='#' onClick='replay();'>Play Again?</a>";
In my code SVG is parse and drawn on Canvas and also orange1.png and green1.png images are plotted on SVg file. In this I am able to zoom and Pan canvas and also able to drag images which are plotted on it through JSON.
Now I want to add tooltip on the images (orange1.png and green1.png) When I click on those images or mouseover on those images.
showTooltip function is for showing the tooltip on those images(orange1.png , green1.png).
clearTooltip function is for clearing the tooltip.
Where and how should I add showTooltip and clearTooltip function in my updated code?
And which option will be better mouse click or mosehover for showing tooltip?
I tried some possibilities but I am missing something.
function showTooltip(x, y, index) {
var editedValue = [];
if (tooltip === null) {
tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.style.left = (x) + 'px';
tooltip.style.top = (y) + 'px';
tooltip.innerHTML = "<input type='text' id='generic_txt' value='"+dataJSON[index].tooltiptxt[0]+"' /> <input type='submit' id='generic_edit' value='Edit'>"
document.getElementsByTagName('body')[0].appendChild(tooltip);
}
document.getElementById('generic_txt').setAttribute('disabled', 'disabled');
$("#generic_edit").click(function(){
if(document.getElementById('generic_edit').value == "Edit"){
document.getElementById('generic_txt').removeAttribute('disabled');
document.getElementById('generic_txt').focus();
document.getElementById('generic_edit').value = "Change";
} else {
document.getElementById('generic_txt').setAttribute('disabled', 'disabled');
document.getElementById('generic_edit').value = "Edit";
editedValue = $('#generic_txt').val();
dataJSON[index].tooltiptxt[0] = editedValue; // important line
}
return false;
});
}
function clearTooltip(doFade) {
if (tooltip !== null) {
var fade = 1;
function fadeOut() {
tooltip.style.opacity = fade;
fade -= 0.1;
if (fade > 0) {
setTimeout(fadeOut, 16);
} else {
remove();
}
}
function remove() {
document.getElementsByTagName('body')[0].removeChild(tooltip);
tooltip = null;
}
if (doFade === true) {
fadeOut();
//$('.first_cancel').click(fadeOut());
} else {
remove();
}
}
}
Following is my updated source code.
HTML Code :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<style>
canvas {
border:1px solid #000
}
.tooltip{
*position:fixed;
position:absolute;
*background:#ff7;
background:green;
border:1px solid #000;
padding:7px;
font-family:sans-serif;
font-size:12px;
}
.tooltip2 {
*position:fixed;
position:absolute;
background:pink;
border:1px solid #000;
padding:7px;
font-family:sans-serif;
font-size:12px;
}
</style>
</head>
<body>
<script src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
<script src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
<canvas id="myCanvas" width="800" height="700" style="border: 1px solid;margin-top: 10px;"></canvas>
<div id="buttonWrapper">
<input type="button" id="plus" value="+">
<input type="button" id="minus" value="-">
<input type="button" id="original_size" value="100%">
</div>
<script src="/static/js/markers.js"></script>
<script src="/static/js/draw.js"></script>
</body>
</html>
draw.js:
var dataJSON = data || [];
var dataJSON2 = data2 || [];
window.onload = function(){
//$(function(){
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
var canvasOffset=$("#myCanvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var lastX=0;
var lastY=0;
var panX=0;
var panY=0;
var dragging=[];
var dragging2=[];
var isDown=false;
function loadImages(sources, callback){
var images = {};
var loadImages = 0;
var numImages = 0;
//get num of sources
for(var i in sources){
numImages++;
}
for(var i in sources){
images[i] = new Image();
images[i].onload = function(){
if(++loadImages >= numImages){
callback(images);
}
};
images[i].src = sources[i];
}
}
var sources = {orange : '/static/images/orange1.png', green : '/static/images/green1.png'};
// load the tiger image
var svgfiles = ["/static/images/awesome_tiger.svg"];
/*var tiger=new Image();
tiger.onload=function(){
draw();
}
tiger.src="tiger.png";*/
function draw(scaleValue){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.drawSvg(svgfiles[0],panX,panY,400*scaleValue, 400*scaleValue);
//ctx.drawImage(tiger,panX,panY,tiger.width,tiger.height);
//ctx.scale(scaleValue, scaleValue);
loadImages(sources, function(images){
ctx.scale(scaleValue, scaleValue);
for(var i = 0, pos; pos = dataJSON[i]; i++) {
ctx.drawImage(images.orange, parseInt(parseInt(pos.x) + parseInt(panX / scaleValue)), parseInt(parseInt(pos.y) + parseInt(panY / scaleValue)), 20/scaleValue, 20/scaleValue);
}
for(var i = 0, pos; pos = dataJSON2[i]; i++) {
ctx.drawImage(images.green, parseInt(parseInt(pos.x) + parseInt(panX / scaleValue)), parseInt(parseInt(pos.y) + parseInt(panY / scaleValue)), 20/scaleValue, 20/scaleValue);
}
ctx.restore();
});
};
var scaleValue = 1;
var scaleMultiplier = 0.8;
draw(scaleValue);
var startDragOffset = {};
var mouseDown = false;
// add button event listeners
document.getElementById("plus").addEventListener("click", function(){
scaleValue /= scaleMultiplier;
//checkboxZoomPan();
draw(scaleValue);
}, false);
document.getElementById("minus").addEventListener("click", function(){
scaleValue *= scaleMultiplier;
//checkboxZoomPan();
draw(scaleValue);
}, false);
document.getElementById("original_size").addEventListener("click", function(){
scaleValue = 1;
//checkboxZoomPan();
draw(scaleValue);
}, false);
// create an array of any "hit" colored-images
function imagesHitTests(x,y){
// adjust for panning
x-=panX;
y-=panY;
// create var to hold any hits
var hits=[];
// hit-test each image
// add hits to hits[]
loadImages(sources, function(images){
for(var i = 0, pos; pos = dataJSON[i]; i++) {
if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){
hits.push(i);
}
}
});
return(hits);
}
function imagesHitTests2(x,y){
// adjust for panning
//x-=panX;
//x = parseInt(x) - parseInt(panX);
// y-=panY;
x-=panX;
y-=panY;
// create var to hold any hits
var hits2=[];
// hit-test each image
// add hits to hits[]
loadImages(sources, function(images){
for(var i = 0, pos; pos = dataJSON2[i]; i++) {
//if(x > pos.x && x < parseInt(parseInt(pos.x) + parseInt(20)) && y > pos.y && y < parseInt(parseInt(pos.y) + parseInt(20))){
if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){
hits2.push(i);
}
}
});
return(hits2);
}
function handleMouseDown(e){
// get mouse coordinates
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// set the starting drag position
lastX=mouseX;
lastY=mouseY;
// test if we're over any of the images
dragging=imagesHitTests(mouseX,mouseY);
dragging2=imagesHitTests2(mouseX,mouseY);
// set the dragging flag
isDown=true;
}
function handleMouseUp(e){
// clear the dragging flag
isDown=false;
}
function handleMouseMove(e){
// if we're not dragging, exit
if(!isDown){
return;
}
//get mouse coordinates
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// calc how much the mouse has moved since we were last here
var dx=mouseX-lastX;
var dy=mouseY-lastY;
// set the lastXY for next time we're here
lastX=mouseX;
lastY=mouseY;
// handle drags/pans
if(dragging.length>0){
// we're dragging images
// move all affected images by how much the mouse has moved
for(var i = 0, pos; pos = dataJSON[dragging[i]]; i++) {
pos.x = parseInt(pos.x) + parseInt(dx);
pos.y = parseInt(pos.y) + parseInt(dy);
}
}
else if(dragging2.length>0){
for(var i = 0, pos1; pos1 = dataJSON2[dragging2[i]]; i++) {
pos1.x = parseInt(pos1.x) + parseInt(dx);
pos1.y = parseInt(pos1.y) + parseInt(dy);
}
}
else{
// we're panning the tiger
// set the panXY by how much the mouse has moved
panX+=dx;
panY+=dy;
}
draw(scaleValue);
}
// use jQuery to handle mouse events
$("#myCanvas").mousedown(function(e){handleMouseDown(e);});
$("#myCanvas").mousemove(function(e){handleMouseMove(e);});
$("#myCanvas").mouseup(function(e){handleMouseUp(e);});
// }); // end $(function(){});
}
markers.js:
data = [
{ "id" :["first"],
"x": ["195"],
"y": ["150"],
"tooltiptxt": ["Region 1"]
},
{
"id" :["second"],
"x": ["255"],
"y": ["180"],
"tooltiptxt": ["Region 2"]
},
{
"id" :["third"],
"x": ["200"],
"y": ["240"],
"tooltiptxt": ["Region 3"]
}
];
data2 = [
{ "id" :["first2"],
"x": ["225"],
"y": ["150"],
"tooltiptxt": ["Region 21"]
},
{
"id" :["second2"],
"x": ["275"],
"y": ["180"],
"tooltiptxt": ["Region 22"]
},
{
"id" :["third3"],
"x": ["300"],
"y": ["240"],
"tooltiptxt": ["Region 23"]
}
];
I think you can try out this :
<!DOCTYPE html>
<html>
<head>
<title>Canvas Links Example</title>
<script>
function OnLoad(){
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.translate(0.5, 0.5);
ctx.strokeStyle = "#5F7FA2";
ctx.strokeRect(50, 50, 25, 25);
var img = new Image();
img.src = "http://www.cs.washington.edu/education/courses/csep576/05wi/projects/project4/web/artifact/liebling/average_face.gif";
var img1 = new Image();
img1.src = "E:\Very IMP Projects\WinService\SourceCode\MVC\BpmPresentation\Images\loading.gif";
img.onload = function(){
ctx.drawImage(img, 50, 50);
canvas.addEventListener("mousemove", on_mousemove, false);
canvas.addEventListener("click", on_click, false);
Links.push(50 + ";" + 50 + ";" + 25 + ";" + 25 + ";" + "http://plus.google.com/");
}
var Links = new Array();
var hoverLink = "";
var canvas1 = document.getElementById("myCanvas1");
var ctx1 = canvas1.getContext("2d");
function on_mousemove (ev) {
var x, y;
if (ev.layerX || ev.layerX == 0) { // For Firefox
x = ev.layerX;
y = ev.layerY;
}
for (var i = Links.length - 1; i >= 0; i--) {
var params = new Array();
params = Links[i].split(";");
var linkX = parseInt(params[0]),
linkY = parseInt(params[1]),
linkWidth = parseInt(params[2]),
linkHeight = parseInt(params[3]),
linkHref = params[4];
if (x >= linkX && x <= (linkX + linkWidth) && y >= linkY && y <= (linkY + linkHeight)){
document.body.style.cursor = "pointer";
hoverLink = linkHref;
ctx1.translate(0.5, 0.5);
ctx1.strokeStyle = "#5F7FA2";
canvas1.style.left = x + "px";
canvas1.style.top = (y+40) + "px";
ctx1.clearRect(0, 0, canvas1.width, canvas1.height);
var img1 = new Image();
img1.src = "E:\Very IMP Projects\WinService\SourceCode\MVC\BpmPresentation\Images\loading.gif";
img1.onload = function () {
ctx1.drawImage(img1, 50, 50);
}
break;
}
else {
document.body.style.cursor = "";
hoverLink = "";
canvas1.style.left = "-200px";
}
};
}
function on_click(e) {
if (hoverLink) {
window.open(hoverLink);
//window.location = hoverLink;
}
}
}
</script>
</head>
<body onload="OnLoad();">
<canvas id="myCanvas" width="450" height="250" style="border:1px solid #eee;">
Canvas is not supported in your browser ! :(
</canvas>
<canvas id="myCanvas1" width="50" height="50" style="background-color:white;border:1px solid blue;position:absolute;left:-200px;top:100px;">
</canvas>
</body>
</html>
I am reading and trying to do this tutorial:
http://www.sitepoint.com/creating-a-simple-windows-8-game-with-javascript-input-and-sound/
Yesterday, I wrote in this forum with one error, and solved it, but today, I'm in the final one and getting another error.
My default.html file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CatapultGame</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<!-- CatapultGame references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
<script src="js/CreateJS/easeljs-0.6.0.min.js"></script>
<script src="js/CreateJS/preloadjs-0.2.0.min.js"></script>
</head>
<body>
<canvas id="gameCanvas"></canvas>
</body>
</html>
and default.js file :
// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
WinJS.strictProcessing();
var canvas, context, stage;
var bgImage, p1Image, p2Image, ammoImage, p1Lives, p2Lives, title, endGameImage;
var bgBitmap, p1Bitmap, p2Bitmap, ammoBitmap;
var preload;
// calculate display scale factor - original game assets assume 800x480
var SCALE_X = window.innerWidth / 800;
var SCALE_Y = window.innerHeight / 480;
var MARGIN = 25;
var GROUND_Y = 390 * SCALE_Y;
var LIVES_PER_PLAYER = 3;
var player1Lives = LIVES_PER_PLAYER;
var player2Lives = LIVES_PER_PLAYER;
var isShotFlying = false;
var playerTurn = 1;
var playerFire = false;
var shotVelocity;
var MAX_SHOT_POWER = 10;
var GRAVITY = 0.07;
var isAiming = false;
var aimPower = 1;
var aimStart, aimVector;
var FIRE_SOUND_FILE = "/sounds/CatapultFire.wav";
var HIT_SOUND_FILE = "/sounds/BoulderHit.wav";
var EXPLODE_SOUND_FILE = "/sounds/CatapultExplosion.wav";
var LOSE_SOUND_FILE = "/sounds/Lose.wav";
var AIM_SOUND_FILE = "/sounds/RopeStretch.wav";
var WIN_SOUND_FILE = "/sounds/Win.wav";
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
}
args.setPromise(WinJS.UI.processAll());
}
};
function initialize() {
canvas = document.getElementById("gameCanvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
context = canvas.getContext("2d");
canvas.addEventListener("MSPointerUp", endAim, false);
canvas.addEventListener("MSPointerMove", adjustAim, false);
canvas.addEventListener("MSPointerDown", beginAim, false)
**var stage = new createjs.Stage(canvas);** <<========== HERE IS THE ERROR LINE !!!!
// use preloadJS to get sounds and images loaded before starting
preload = new createjs.PreloadJS();
preload.onComplete = prepareGame;
var manifest = [
{ id: "screenImage", src: "images/Backgrounds/gameplay_screen.png" },
{ id: "redImage", src: "images/Catapults/Red/redIdle/redIdle.png" },
{ id: "blueImage", src: "images/Catapults/Blue/blueIdle/blueIdle.png" },
{ id: "ammoImage", src: "images/Ammo/rock_ammo.png" },
{ id: "winImage", src: "images/Backgrounds/victory.png" },
{ id: "loseImage", src: "images/Backgrounds/defeat.png" },
{ id: "blueFire", src: "images/Catapults/Blue/blueFire/blueCatapultFire.png" },
{ id: "redFire", src: "images/Catapults/Red/redFire/redCatapultFire.png" },
{ id: "hitSound", src: HIT_SOUND_FILE },
{ id: "explodeSound", src: EXPLODE_SOUND_FILE },
{ id: "fireSound", src: FIRE_SOUND_FILE },
{ id: "loseSound", src: LOSE_SOUND_FILE },
{ id: "aimSound", src: AIM_SOUND_FILE },
{ id: "winSound", src: WIN_SOUND_FILE }
];
preload.loadManifest(manifest);
}
function prepareGame()
{
// draw Bg first, others appear on top
bgImage = preload.getResult("screenImage").result;
bgBitmap = new createjs.Bitmap(bgImage);
bgBitmap.scaleX = SCALE_X;
bgBitmap.scaleY = SCALE_Y;
stage.addChild(bgBitmap);
// draw p1 catapult
p1Image = preload.getResult("redImage").result;
p1Bitmap = new createjs.Bitmap(p1Image);
p1Bitmap.scaleX = SCALE_X;
p1Bitmap.scaleY = SCALE_Y;
p1Bitmap.x = MARGIN;
p1Bitmap.y = GROUND_Y - p1Image.height * SCALE_Y;
stage.addChild(p1Bitmap);
// draw p2 catapult and flip
p2Image = preload.getResult("blueImage").result;
p2Bitmap = new createjs.Bitmap(p2Image);
p2Bitmap.regX = p2Image.width;
p2Bitmap.scaleX = -SCALE_X; // flip from right edge
p2Bitmap.scaleY = SCALE_Y;
p2Bitmap.x = canvas.width - MARGIN - (p2Image.width * SCALE_X);
p2Bitmap.y = GROUND_Y - (p2Image.height * SCALE_Y);
stage.addChild(p2Bitmap);
// draw the boulder, and hide for the moment
ammoImage = preload.getResult("ammoImage").result;
ammoBitmap = new createjs.Bitmap(ammoImage);
ammoBitmap.scaleX = SCALE_X;
ammoBitmap.scaleY = SCALE_Y;
ammoBitmap.visible = false; // hide until fired
stage.addChild(ammoBitmap);
// player 1 lives
p1Lives = new createjs.Text("Lives Left : " + player1Lives, "20px sans-serif", "red");
p1Lives.scaleX = SCALE_X;
p1Lives.scaleY = SCALE_Y;
p1Lives.x = MARGIN;
p1Lives.y = MARGIN * SCALE_Y;
stage.addChild(p1Lives);
//player 2 lives
p2Lives = new createjs.Text("Lives Left : " + player2Lives, "20px sans-serif", "red");
p2Lives.scaleX = SCALE_X;
p2Lives.scaleY = SCALE_Y;
p2Lives.x = canvas.width - p2Lives.getMeasuredWidth() * SCALE_X - MARGIN;
p2Lives.y = MARGIN * SCALE_Y;
stage.addChild(p2Lives);
// game title
title = new createjs.Text("Catapult Wars", "30px sans-serif", "black");
title.scaleX = SCALE_X;
title.scaleY = SCALE_Y;
title.x = canvas.width / 2 - (title.getMeasuredWidth() * SCALE_X) / 2
title.y = 30 * SCALE_Y;
stage.addChild(title);
stage.update();
startGame();
}
function startGame()
{
Ticker.setInterval(window.requestAnimationFrame);
Ticker.addListener(gameLoop);
}
function gameLoop()
{
update();
draw();
}
function update() {
if (isShotFlying)
{
// shot in the air
ammoBitmap.x += shotVelocity.x;
ammoBitmap.y += shotVelocity.y;
shotVelocity.y += GRAVITY; //apply gravity to the y(height) values only, obviously
if (ammoBitmap.y + ammoBitmap.image.height >= GROUND_Y ||
ammoBitmap.x <= 0 ||
ammoBitmap.x + ammoBitmap.image.width >= canvas.width)
{
// missed
isShotFlying = false; //stop shot
ammoBitmap.visible = false;
playerTurn = playerTurn % 2 + 1; // invert player ( switch between 1 and 2)
}
else if (playerTurn == 1)
{
if (checkHit(p2Bitmap)) {
// Hit
p2Lives.text = "Lives Left : " + --player2Lives;
processHit();
}
}
else if (playerTurn == 2)
{
if (checkHit(p1Bitmap))
{
// Hit
p1Lives.text = "Lives Left : " + --player1Lives;
processHit();
}
}
}
// No current shot, should either player fire ?
else if (playerTurn == 1)
{
// does the player want to fire ?
if (playerFire)
{
playerFire = false;
ammoBitmap.x = p1Bitmap.x + (p1Bitmap.image.width * SCALE_X / 2);
ammoBitmap.y = p1Bitmap.y;
shotVelocity = aimVector;
fireShot();
}
}
else if (playerTurn == 2)
{
// AI automatically fires (randomly on it's turn)
ammoBitmap.x = p2Bitmap.x + (p2Bitmap.image.width * SCALE_X / 2);
ammoBitmap.y = p2Bitmap.y;
shotVelocity = new createjs.Point(
Math.random() * (-4 * SCALE_X) - 3,
Math.random() * (-3 * SCALE_Y) - 1);
fireShot();
}
}
// triggered by MSPointerDown event
function beginAim(event)
{
if (playerTurn == 1)
{
if (!isAiming)
{
aimStart = new createjs.Point(event.x, event.y);
isAiming = true;
}
}
}
// triggered by MSPointerMove event
function adjustAim(event)
{
if (isAiming)
{
var aimCurrent = new createjs.Point(event.x, event.y);
aimVector = calculateAim(aimStart, aimCurrent);
// TODO write text and/or show aiming arrow on screen
Debug.writeln("Aiming..." + aimVector.x + "/" + aimVector.y);
}
}
// triggered by MSPointerUp event
function endAim(event)
{
if (isAiming) {
isAiming = false;
var aimCurrent = new createjs.Point(event.x, event.y);
aimVector = calculateAim(aimStart, aimCurrent);
playerFire = true;
}
}
function calculateAim(start, end)
{
// this only works for player 1
var aim = new createjs.Point(
(end.x - start.x) / 80,
(end.y - start.y) / 80);
aim.x = Math.min(MAX_SHOT_POWER, aim.x); // cap velocity
aim.x = Math.max(0, aim.x); // fire forward only
aim.y = Math.max(-MAX_SHOT_POWER, aim.y);/// cap velocity
aim.y = Math.min(0, aim.y); // fire up only
return aim;
}
function checkHit(target)
{
// EaselJS hit test doesn't factor in scaling
// so use simple bounding box vs center of rock
// get centre of rock
var shotX = ammoBitmap.x + ammoBitmap.image.width / 2;
var shotY = ammoBitmap.y + ammoBitmap.image.height / 2;
// return wether center of rock is in rectangle bounding target player
return (((shotX > target.x) &&
(shotX <= target.x + (target.image.width * SCALE_X)))
&&
((shotY >= target.y) &&
(shotY <= target.y + (target.image.height * SCALE_Y))));
}
function fireShot()
{
playSound(FIRE_SOUND_FILE);
ammoBitmap.visible = true;
isShotFlying = true;
}
function processHit()
{
playSound(EXPLODE_SOUND_FILE);
isShotFlying = false; // stop shot
ammoBitmap.visible = false; // hide shot
playerTurn = playerTurn % 2 + 1; // change player
if ((player1Lives <= 0) || (player2Lives <= 0)) {
endGame();
}
}
function endGame()
{
Ticker.setPaused(true); // stop game loop
// show win/lose graphic
var endGameImage;
if (player1Lives <= 0)
{
playSound(LOSE_SOUND_FILE);
endGameImage = preload.getResult("loseImage").result;
}
else if (player2Lives <= 0)
{
endGameImage = preload.getResult("winImage").result;
playSound(WIN_SOUND_FILE);
}
var endGameBitmap = new createjs.Bitmap(endGameImage);
stage.addChild(endGameBitmap);
endGameBitmap.x = (canvas.width / 2) - (endGameImage.width * SCALE_X / 2);
endGameBitmap.y = (canvas.height / 2) - (endGameImage.height * SCALE_Y / 2);
endGameBitmap.scaleX = SCALE_X;
endGameBitmap.scaleY = SCALE_Y;
stage.update();
}
function draw() {
// EaselJS allows for easy updates
stage.update();
}
function playSound(path)
{
var sound = document.createElement("audio");
sound.src = path;
sound.autoplay = true;
}
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state
// that needs to persist across suspensions here. You might use the
// WinJS.Application.sessionState object, which is automatically
// saved and restored across suspension. If you need to complete an
// asynchronous operation before your application is suspended, call
// args.setPromise().
};
document.addEventListener("DOMContentLoaded", initialize, false);
app.start();
})();
And there is the problem: when I'm trying to build this game, I'm getting error like this:
0x800a01bd - JavaScript runtime error: Object doesn't support this action
in the marked place in my code
Thanks for any help :)
Three problems, I report them from previous comments:
easeljs not present in the correct folder
mages/Catapults/Red/redFire/redCatapultFire.png missing
change var stage = new createjs.Stage(canvas); to stage = new createjs.Stage(canvas); you don't have to instantiate that variable as reported in the tutorial (http://www.sitepoint.com/creating-a-simple-windows-8-game-with-javascript-game-basics-createjseaseljs/)
And close this other related question (https://stackoverflow.com/a/16101960/975520), I think is solved by posting your solution as answer.