this is the code I tried below I wanted to run this animation project full screen of the window. when run the project it not run as an full screen please any one help me to run this application as full window thanks
window.onload = init();
function init() {
c = document.getElementById("canvas10");
ctx = c.getContext("2d");
ctx.fillStyle = "white";
//ctx.rect(0,0,1366,768);
// ctx.fill();
// Coordinates and speed of player
var x1 = 200 ;
var y1 = 420 ;
var SPEED = 4 ;
//tree creaion
var x3 = 600;
var y3 = 350;
//mouse1 creations
var x4 = 570;
vr y4 = 500;
var SPEED1 = 1;
//mouse2 creations
var x5 = 640;
var y5 = 560;
var SPEED2 = 1;
//mouse3 creations
var x6 = 700;
var y6 = 580;
var SPEED3 = 1;
//mouse4 creations
var x7 = 600;
var y7 = 540;
//roof creations
var x8 = 130;
var y8 = 500;
//fence creations
var x9 = 30;
var y9 = 500;
//leavies creations
var x10 = 380;
var y10 = 550;
//bee creation
var x11 = 680;
var y11 = 350;
// programming begins
// commands
stop = false;
var textImage = new Image(); // make image object
textImage.src = "text1.jpg"; // set the image path
var textImage2 = new Image(); // make image object
textImage2.src = "text2.jpg"; // set the image path
agentCanFeel = false;
agentCOLOR = "lightblue";
// Handle keyboard controls
var keyPress = {} ; // initialize the list that stores key presses
addEventListener ("keydown", function (e) {
keyPress[e.keyCode] = true; } , false);
addEventListener ("keyup", function (e) {
delete keyPress[e.keyCode]; } , false);
function Player(x1, y1) {
var playerImage = new Image(); // make image object
playerImage.src = "tom.png"; // set the image path
ctx.drawImage(playerImage, x1, y1, 80,70);
}
function Agent() {
ctx.beginPath();
ctx.arc (x2,y2, 50, 0 , 2 * Math.PI, false);
ctx.fillStyle = agentCOLOR;
ctx.fill();
var wingImage = new Image();
wingImage.src = "wings.jpg";
ctx.drawImage(wingImage, x2-40, y2-120 , 90 , 70);
}
//tree creation function
function tree()
{
ctx.beginPath();
ctx.fill();
var tree = new Image();
tree.src = "tree.png";
ctx.drawImage(tree, x3- 60, y3- 120 , 250 , 230);
}
//mouse creation function
function mouse()
{
ctx.beginPath();
ctx.fill();
var mouse = new Image();
mouse.src = "mouse.gif";
ctx.drawImage(mouse, x4- 60, y4- 120 , 40 , 30);
}
function mouse2()
{
ctx.beginPath();
ctx.fill();
var mouse1 = new Image();
mouse1.src = "mouse.gif";
ctx.drawImage(mouse1, x5- 60, y5- 120 , 40 , 30);
}
function mouse3()
{
ctx.beginPath();
ctx.fill();
var mouse2 = new Image();
mouse2.src = "mouse.gif";
ctx.drawImage(mouse2, x6- 60, y6- 120 , 40 , 30);
}
function mouse4()
{
ctx.beginPath();
ctx.fill();
var mouse4 = new Image();
mouse4.src = "mouse.gif";
ctx.drawImage(mouse4, x7- 60, y7- 120 , 40 , 30);
}
//cat roof creation function
function roof()
{
ctx.beginPath();
ctx.fill();
var roof = new Image();
roof.src = "roof.png";
ctx.drawImage(roof, x8- 60, y8- 120 , 150 , 130);
}
// fence behind cat
function fence()
{
ctx.beginPath();
ctx.fill();
var roof = new Image();
roof.src = "fence.png";
ctx.drawImage(roof, x9- 60, y9- 120 , 150 , 130);
}
// leavies creation
function leaves()
{
ctx.beginPath();
ctx.fill();
var roof = new Image();
roof.src = "leaves.png";
ctx.drawImage(roof, x10- 60, y10- 120 , 80 , 70);
}
// bee creation
function bee()
{
ctx.beginPath();
ctx.fill();
var bee = new Image();
bee.src = "bee.gif";
ctx.drawImage(bee, x11- 60, y11- 120 , 80 , 70);
}
function clear() {
ctx.rect(0,0,1000,600);
ctx.fill();
}
//mouse programming
function updatemouse()
{
x5 = x5 + SPEED1;
if (x5>650)
SPEED1 = SPEED1 * -1;
if (x5<600)
SPEED1 = SPEED1 * -1;
}
//end updateStuff
function updatemouse1()
{
x6 = x6 + SPEED2;
if (x6>800)
SPEED2 = SPEED2 * -1;
if (x6<600)
SPEED2 = SPEED2 * -1;
}
//end updateStuff
function updatemouse2()
{
x7 = x7 + SPEED3;
if (x7>800)
SPEED3 = SPEED3 * -1;
if (x7<600)
SPEED3 = SPEED3 * -1;
}
//end updateStuff
if (stopok == true)
{
ctx.drawImage(textImage, 100, 250); //STOP COMMAND
ctx.drawImage(textImage2, x5, y5-50); // OK RESPONSE
}//end if
function updateStuff() {
if (37 in keyPress && x1>0) // left arrorw
x1 = x1 - SPEED;
if (39 in keyPress && x1<1000) // right arrow
x1 = x1 + SPEED;
if (38 in keyPress && y1 > 20) // arrow up
y1 = y1 - SPEED;
if (50 in keyPress && y1 < 500) // arrow down
y1 = y1 + SPEED;
if (agentCanFeel == true ) {
agentCOLOR = "Red";
x4 = x4 + 2;
}
else
{
agentCOLOR = "Lightblue";
x4=x4 - 1;
}
} //end updateStuff
function drawStuff() {
Player(x1,y1);
// Agent();
// mouse();
mouse2();
mouse3();
mouse4();
roof();
tree();
fence();
leaves();
bee();
} //end drawStuff
function gameLoop() {
clear();
updateStuff();
drawStuff();
updatemouse();
updatemouse1();
updatemouse2();
setTimeout(gameLoop, 20); //call game loop every 20 mili sec
} //end gameloop
gameLoop();
} //end init function
Related
So I'm making a game with canvas and my object for one of the characters aren't showing up. My console didn't show any errors so I just decided to check my asteroidList object. I checked it and saw that the first character in the object's height was undefined, but I already defined it. Can someone tell me what the problem is? Here is my code:
var c = document.getElementById("game");
var ctx = c.getContext("2d");
//variables
pX = 1;
pY = 40;
pW = 54.6;
pH = 52.6;
hw = 100;
hh = 10;
asteroidSpeed = 0.05;
//load image sprites
var player = new Image();
var aster = new Image();
var enemy = new Image();
var max = new Image();
var animatedPlayer = new Image();
player.src = "player.png";
aster.src = "aster.png";
enemy.src = "enemy.png";
max.src = "max.png";
animatedPlayer.src = "animatedPlayer.png";
//keys
document.addEventListener("keydown",function (e) {
if (e.keyCode === 83) {
moveDown();
}
else if(e.keyCode === 87) {
moveUp();
}
})
function moveDown() {
pY += 2;
}
function moveUp() {
pY -= 2;
}
//asteroid constructor
asteroidList = {};
function asteroid(id,x,y,img,width,height) {
var asteroid = {
x:x,
y:y,
width:width,
height:height,
id:id
};
asteroidList['A1'] = asteroid;
}
function updateAsteroid(asteroid) {
asteroid.x -= asteroidSpeed;
ctx.drawImage(aster, asteroid.x, asteroid.y, asteroid.width, asteroid.height);
}
function draw() {
ctx.clearRect(0,0,c.width,c.height);
//characters
asteroid('A1', 250, 40, 29.6, 29.3);
ctx.drawImage(player,pX,pY,pW,pH);
setInterval(update, 40);
function update() {
//map collision
if(pY < 0) {
pY = 0;
}
if(pY > 100) {
pY = 100;
}
//enemy loop
for(var key in asteroidList) {
updateAsteroid(asteroidList[key]);
}
}
//hp
ctx.fillStyle = 'green';
ctx.strokeStyle = 'black';
ctx.beginPath();
ctx.fillRect(199,139,hw,hh);
ctx.strokeRect(199,139,100,10);
//animation call
requestAnimationFrame(draw);
}
</script>
You have an extra param called img in your asteroid function definition:
function asteroid(id, x, y, img, width, height) {
var asteroid = {
x:x,
y:y,
width:width,
height:height,
id:id
};
asteroidList['A1'] = asteroid;
}
So when you call it like:
asteroid('A1', 250, 40, 29.6, 29.3);
// asteroid(id, x, y, img, width);
you are missing to set up the height value and thus getting undefined.
I'm trying to use Javascript to create a Canvas Game which is similar to Bug Smasher or Ant Smasher game. It means the obj will move randomly, and when u click on it, the score will increase. ( I'm not allowed to use JQuery )
I almost finished all the work. But there's an error I cannot figure out: Everytime I click on the object, the score increases but it overwrites the number "0" like this:
And this is my code:
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var timer = 0;
var caught = false;
var fps = 10;
document.body.appendChild(canvas);
canvas.width = 800;
canvas.height = 544;
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "images/background.png";
// nar image
var narReady = false;
var narImage = new Image();
narImage.onload = function () {
narReady = true;
};
narImage.src = "images/nar.png";
var nar = {};
var narCaught = 0;
// When nar is caught, reset
var reset = function () {
nar.x = 40 + (Math.random() * (canvas.width - 70));
do {
nar.y = 40 + (Math.random() * (canvas.height - 70));
}
while (nar.y < 100)
};
//mousedown event
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(e) {
if (e.button != 0) return;
mouseXinCanvas = e.clientX;
mouseYinCanvas = e.clientY;
if (narBody(nar, mouseXinCanvas, mouseYinCanvas)) {
caught = true;
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
}
if (ResetScore(mouseXinCanvas, mouseYinCanvas)) {
location.reload();
}
if (ResetSpeed(mouseXinCanvas, mouseYinCanvas)) {
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
render();
}
};
//nar's body define
function narBody(nar, x, y) {
if (x <= (nar.x + 80)
&& nar.x <= (x + 80)
&& y <= (nar.y + 80)
&& nar.y <= (y + 80)
) {
fps = fps + 5;
narCaught++;
return true;
}
return false;
};
//Reset Score box
function ResetScore(x, y) {
if (x > (305)
&& x < (545)
&& y > (15)
&& y < (85)
) {
return true;
}
return false;
};
//Reset speed box
function ResetSpeed(x, y) {
if (x > (605)
&& x < (845)
&& y > (15)
&& y < (85)
) {
fps = 10;
return true;
}
return false;
};
// Draw everything
var render = function () {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
if (narReady) {
ctx.drawImage(narImage, nar.x, nar.y);
}
if (caught == true) {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
caught = false;
}
// Score, Title
ctx.fillStyle = "rgb(65, 226, 24)";
ctx.font = "34px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Catch Naruto!!!", 5, 40);
ctx.font = "20px Helvetica";
ctx.fillText("Score: " + narCaught, 10, 10);
// Reset Score, Speed button
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(250, 10, 250, 80);
ctx.fillRect(520, 10, 250, 80);
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(255, 15, 240, 70);
ctx.fillRect(525, 15, 240, 70);
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.font = "34px Arial";
ctx.fillText("Reset Score", 275, 30);
ctx.fillText("Reset Speed", 545, 30);
};
// The main game loop
var main = function () {
render();
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
//var then = Date.now();
reset();
main();
<html lang="en">
<head>
<meta charset="utf-8">
<title>Assignment 5</title>
</head>
<body>
<script src="game.js"></script>
</body>
</html>
Please help ! :(
The problem is simple to solve. You just need to clear all the previous frame's rendering before you render the new frame.
Just add the following line to the render function
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
You will notice that the quality of the text also improves. This is because you are no long drawing over the top of the old text,
I dont know what the background image is so I clear the whole canvas. But if the background image is not transparent you only need to clear what it does not cover.
See change below
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var timer = 0;
var caught = false;
var fps = 10;
document.body.appendChild(canvas);
canvas.width = 800;
canvas.height = 544;
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "images/background.png";
// nar image
var narReady = false;
var narImage = new Image();
narImage.onload = function () {
narReady = true;
};
narImage.src = "images/nar.png";
var nar = {};
var narCaught = 0;
// When nar is caught, reset
var reset = function () {
nar.x = 40 + (Math.random() * (canvas.width - 70));
do {
nar.y = 40 + (Math.random() * (canvas.height - 70));
}
while (nar.y < 100)
};
//mousedown event
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(e) {
if (e.button != 0) return;
mouseXinCanvas = e.clientX;
mouseYinCanvas = e.clientY;
if (narBody(nar, mouseXinCanvas, mouseYinCanvas)) {
caught = true;
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
}
if (ResetScore(mouseXinCanvas, mouseYinCanvas)) {
location.reload();
}
if (ResetSpeed(mouseXinCanvas, mouseYinCanvas)) {
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
render();
}
};
//nar's body define
function narBody(nar, x, y) {
if (x <= (nar.x + 80)
&& nar.x <= (x + 80)
&& y <= (nar.y + 80)
&& nar.y <= (y + 80)
) {
fps = fps + 5;
narCaught++;
return true;
}
return false;
};
//Reset Score box
function ResetScore(x, y) {
if (x > (305)
&& x < (545)
&& y > (15)
&& y < (85)
) {
return true;
}
return false;
};
//Reset speed box
function ResetSpeed(x, y) {
if (x > (605)
&& x < (845)
&& y > (15)
&& y < (85)
) {
fps = 10;
return true;
}
return false;
};
// Draw everything
var render = function () {
//===========================================================
// add the following line to clear the display.
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
if (narReady) {
ctx.drawImage(narImage, nar.x, nar.y);
}
if (caught == true) {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
caught = false;
}
// Score, Title
ctx.fillStyle = "rgb(65, 226, 24)";
ctx.font = "34px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Catch Naruto!!!", 5, 40);
ctx.font = "20px Helvetica";
ctx.fillText("Score: " + narCaught, 10, 10);
// Reset Score, Speed button
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(250, 10, 250, 80);
ctx.fillRect(520, 10, 250, 80);
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(255, 15, 240, 70);
ctx.fillRect(525, 15, 240, 70);
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.font = "34px Arial";
ctx.fillText("Reset Score", 275, 30);
ctx.fillText("Reset Speed", 545, 30);
};
// The main game loop
var main = function () {
render();
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
//var then = Date.now();
reset();
main();
I am using this code to draw an arrow on a canvas:
var arrowCanvas = document.getElementById("arrowCanvas");
var ctx = arrowCanvas.getContext("2d");
drawArrow(ctx, 30, 10, 30, 100);
function drawArrow(ctx, fromx, fromy, tox, toy){
//variables to be used when creating the arrow
var headlen = 10;
ctx.strokeStyle = "#cc0000";
ctx.fillStyle = "#cc0000";
ctx.lineWidth = 10;
var angle = Math.atan2(toy-fromy,tox-fromx);
//starting path of the arrow from the start square to the end square and drawing the stroke
ctx.beginPath();
ctx.moveTo(fromx, fromy);
ctx.lineTo(tox, toy);
ctx.stroke();
//starting a new path from the head of the arrow to one of the sides of the point
ctx.beginPath();
ctx.moveTo(tox, toy);
ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
//path from the side point of the arrow, to the other side point
ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7));
//path from the side point back to the tip of the arrow, and then again to the opposite side point
ctx.lineTo(tox, toy);
ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
//draws the paths created above
ctx.stroke();
ctx.fill();
}
(Code is found in this answer: Draw arrow on canvas tag).
My problem with this code is that because of ctx.lineWidth the arrowHead points over the specified coordinates (tox, toy). In the provided example the arrowhead points onto the canvas y-position 110, due to lineWidth = 10px. I want it to point exactly on the tox, toy-coordinates, independent of the arrows angle.
My solution would be to reduce the initial length of the arrow by the amount of lineWidth, but I failed at considering the arrow angle for it.
A little trig is all that is needed. Bellow is a snippet that solves the 3 types of line joins. Bevel, Miter, and round.
The function drawArrow draw a line from x,y,xx,yy with options setting the various dimensions for the arrow head.
The function reads the ctx.lineWidth and ctx.lineJoin values to work out how to move the end point to ensure it does not pass the point.
For "round" joins the distance to move in is half the line width
For "miter" the distance is half line width divide the sin of half the arrowhead pointy angle
For "Bevel" the distance is cos of half the angle of the pointy end times the half line width
const PI = Math.PI;
const PI2 = PI * 2;
function drawArrow(ctx,x,y,xx,yy,options){
function getDef(name,def){return options[name] !== undefined ? options[name] : def;}
var w = getDef("width",5); // get settings
var hs = getDef("headSize",15); //
var hw = getDef("headWidth",15); //
var dx = xx-x;
var dy = yy-y;
var dir = Math.atan2(dy,dx);
var dist = Math.sqrt(dx*dx+dy*dy);
var lineWidth = Number(ctx.lineWidth)
var endMove = ctx.lineWidth/2; // assume round joins
if(ctx.lineJoin === "miter"){
endMove = Math.min(ctx.miterLimit,endMove / (hw / Math.sqrt(hs*hs+hw*hw)));
}else if(ctx.lineJoin === "bevel"){
endMove = endMove * Math.cos(Math.asin(hs / Math.sqrt(hs*hs+hw*hw)));
}
// move canvas coordinates so that the arrow starts at 0,0,
ctx.setTransform(1,0,0,1,x,y);
ctx.rotate(dir); // and is aligned to x
dist -= endMove; // shorten for line width
ctx.beginPath();
ctx.moveTo(0,-w);
ctx.lineTo(dist - hs,-w);
ctx.lineTo(dist - hs,-hw);
ctx.lineTo(dist ,0);
ctx.lineTo(dist - hs,hw);
ctx.lineTo(dist - hs,w);
ctx.lineTo(0,w);
ctx.stroke();
ctx.fill();
}
var arrows = [
{width : 5, headWidth : 10, headSize : 20, lineWidth : 5,line : "red", fill : "blue",join : "bevel", limit : 100},
{width : 10, headWidth : 20, headSize : 20, lineWidth : 5,line : "Orange", fill : "blue",join : "miter", limit : 5},
{width : 10, headWidth : 20, headSize : 20, lineWidth : 5,line : "Green", fill : "blue",join : "round", limit : 0},
]
var tempArrow = {width : 10, headWidth : 20, headSize : 20};
const numArrows = 3;
const mouseClear = 30;
// main update function
function display(){
ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.globalAlpha = 1; // reset alpha
ctx.clearRect(0,0,w,h);
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.arc(mouse.x,mouse.y,mouseClear,0,PI2);
ctx.miterLimit = 1000;
ctx.stroke();
for(var i = 0; i < numArrows; i ++){
var x = cw + Math.cos((i/numArrows)*PI2) * cw *1.8;
var y = ch + Math.sin((i/numArrows)*PI2) * ch *1.8;
var dir = Math.atan2(y-mouse.y,x-mouse.x);
var xx = mouse.x + Math.cos(dir) * mouseClear;
var yy = mouse.y + Math.sin(dir) * mouseClear;
var scaleLine = (Math.sin(globalTime/1000)+1.1) * 2;
var style = arrows[i%arrows.length];
var arrowHead = (Math.sin(globalTime/770)+1.1) * 2;
var arrowSize = (Math.sin(globalTime/1370)+1.1) * 2;
ctx.lineWidth = style.lineWidth * scaleLine;
ctx.strokeStyle = style.line;
ctx.fillStyle = style.fill;
ctx.lineJoin = style.join;
tempArrow.headWidth = style.headSize * arrowHead;
tempArrow.headSize = style.headSize * arrowSize;
drawArrow(ctx,x,y,xx,yy,tempArrow);
}
}
//==============================================================================
// From here down part of answer just boiler room stuff
// can be ignored.
/** SimpleFullCanvasMouse.js begin **/
var w, h, cw, ch, canvas, ctx, mouse, globalTime = 0, firstRun = true;
;(function(){
const RESIZE_DEBOUNCE_TIME = 100;
var createCanvas, resizeCanvas, setGlobals, resizeCount = 0;
createCanvas = function () {
var c,
cs;
cs = (c = document.createElement("canvas")).style;
cs.position = "absolute";
cs.top = cs.left = "0px";
cs.zIndex = 1000;
document.body.appendChild(c);
return c;
}
resizeCanvas = function () {
if (canvas === undefined) {
canvas = createCanvas();
}
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx = canvas.getContext("2d");
if (typeof setGlobals === "function") {
setGlobals();
}
if (typeof onResize === "function") {
if(firstRun){
onResize();
firstRun = false;
}else{
resizeCount += 1;
setTimeout(debounceResize, RESIZE_DEBOUNCE_TIME);
}
}
}
function debounceResize() {
resizeCount -= 1;
if (resizeCount <= 0) {
onResize();
}
}
setGlobals = function () {
cw = (w = canvas.width) / 2;
ch = (h = canvas.height) / 2;
}
mouse = (function () {
function preventDefault(e) {
e.preventDefault();
}
var mouse = {
x : 0,
y : 0,
w : 0,
alt : false,
shift : false,
ctrl : false,
buttonRaw : 0,
over : false,
bm : [1, 2, 4, 6, 5, 3],
active : false,
bounds : null,
crashRecover : null,
mouseEvents : "mousemove,mousedown,mouseup,mouseout,mouseover,mousewheel,DOMMouseScroll".split(",")
};
var m = mouse;
function mouseMove(e) {
var t = e.type;
m.bounds = m.element.getBoundingClientRect();
m.x = e.pageX - m.bounds.left;
m.y = e.pageY - m.bounds.top;
m.alt = e.altKey;
m.shift = e.shiftKey;
m.ctrl = e.ctrlKey;
if (t === "mousedown") {
m.buttonRaw |= m.bm[e.which - 1];
} else if (t === "mouseup") {
m.buttonRaw &= m.bm[e.which + 2];
} else if (t === "mouseout") {
m.buttonRaw = 0;
m.over = false;
} else if (t === "mouseover") {
m.over = true;
} else if (t === "mousewheel") {
m.w = e.wheelDelta;
} else if (t === "DOMMouseScroll") {
m.w = -e.detail;
}
if (m.callbacks) {
m.callbacks.forEach(c => c(e));
}
e.preventDefault();
}
m.addCallback = function (callback) {
if (typeof callback === "function") {
if (m.callbacks === undefined) {
m.callbacks = [callback];
} else {
m.callbacks.push(callback);
}
}
}
m.start = function (element) {
if (m.element !== undefined) {
m.removeMouse();
}
m.element = element === undefined ? document : element;
m.mouseEvents.forEach(n => {
m.element.addEventListener(n, mouseMove);
});
m.element.addEventListener("contextmenu", preventDefault, false);
m.active = true;
}
m.remove = function () {
if (m.element !== undefined) {
m.mouseEvents.forEach(n => {
m.element.removeEventListener(n, mouseMove);
});
m.element.removeEventListener("contextmenu", preventDefault);
m.element = m.callbacks = undefined;
m.active = false;
}
}
return mouse;
})();
function update(timer) { // Main update loop
if(ctx === undefined){
return;
}
globalTime = timer;
display(); // call demo code
requestAnimationFrame(update);
}
setTimeout(function(){
resizeCanvas();
mouse.start(canvas, true);
window.addEventListener("resize", resizeCanvas);
requestAnimationFrame(update);
},0);
})();
The Problem
I am creating a game where you have to move away from or dodge projectiles coming towards you, I have enabled the user to move the image they are controlling but at the moment the user can place the image anywhere on the canvas.
The Question
How can I only allow the user to move along designated part of the canvas and only along the X axis? for example:
Here is my game, "working progress":
The user is in control of the ship, they should only be able to move left or right like this for example:
The Code
<script>
var game = create_game();
game.init();
//music
var snd = new Audio("menu.mp3");
snd.play();
document.getElementById('mute').addEventListener('click', function (evt) {
if ( snd.muted ) {
snd.muted = false
evt.target.innerHTML = 'mute'
}
else {
snd.muted = true
evt.target.innerHTML = 'unmute'
}
})
function create_game() {
debugger;
var level = 1;
var projectiles_per_level = 1;
var min_speed_per_level = 1;
var max_speed_per_level = 2;
var last_projectile_time = 0;
var next_projectile_time = 0;
var width = 600;
var height = 500;
var delay = 1000;
var item_width = 30;
var item_height = 30;
var total_projectiles = 0;
var projectile_img = new Image();
var projectile_w = 30;
var projectile_h = 30;
var player_img = new Image();
var c, ctx;
var projectiles = [];
var player = {
x: 200,
y: 400,
score: 0
};
function init() {
projectile_img.src = "apple.png";
player_img.src = "basket.png";
level = 1;
total_projectiles = 0;
projectiles = [];
c = document.getElementById("c");
ctx = c.getContext("2d");
ctx.fillStyle = "#ff6600";
ctx.fillRect(0, 0, 500, 600);
c.addEventListener("mousemove", function (e) {
//moving over the canvas.
var bounding_box = c.getBoundingClientRect();
player.x = (e.clientX - bounding_box.left) * (c.width / bounding_box.width) - player_img.width / 2;
player.y = (e.clientY - bounding_box.top) * (c.height / bounding_box.height) - player_img.height / 2;
}, false);
setupProjectiles();
requestAnimationFrame(tick);
}
function setupProjectiles() {
var max_projectiles = level * projectiles_per_level;
while (projectiles.length < max_projectiles) {
initProjectile(projectiles.length);
}
}
function initProjectile(index) {
var max_speed = max_speed_per_level * level;
var min_speed = min_speed_per_level * level;
projectiles[index] = {
x: Math.round(Math.random() * (width - 2 * projectile_w)) + projectile_w,
y: -projectile_h,
v: Math.round(Math.random() * (max_speed - min_speed)) + min_speed,
delay: Date.now() + Math.random() * delay
}
total_projectiles++;
}
function collision(projectile) {
if (projectile.y + projectile_img.height < player.y + 74) {
return false;
}
if (projectile.y > player.y + 74) {
return false;
}
if (projectile.x + projectile_img.width < player.x + 177) {
return false;
}
if (projectile.x > player.x + 177) {
return false;
}
return true;
}
function maybeIncreaseDifficulty() {
level = Math.max(1, Math.ceil(player.score / 10));
setupProjectiles();
}
function tick() {
var i;
var projectile;
var dateNow = Date.now();
c.width = c.width;
for (i = 0; i < projectiles.length; i++) {
projectile = projectiles[i];
if (dateNow > projectile.delay) {
projectile.y += projectile.v;
if (collision(projectile)) {
initProjectile(i);
player.score++;
} else if (projectile.y > height) {
initProjectile(i);
} else {
ctx.drawImage(projectile_img, projectile.x, projectile.y);
}
}
}
ctx.font = "bold 24px sans-serif";
ctx.fillStyle = "#ff6600";
ctx.fillText(player.score, c.width - 50, 50);
ctx.fillText("Level: " + level, 20, 50);
ctx.drawImage(player_img, player.x, player.y);
maybeIncreaseDifficulty();
requestAnimationFrame(tick);
}
return {
init: init
};
}
</script>
JSFiddle (Broken)
https://jsfiddle.net/3oc4jsf6/10/
If your ship is tied to mouse movement, and you want to only allow movement across the X-axis you can simply avoid changing its .y property in your mousemove listener.
Remove this line:
player.y = (e.clientY - bounding_box.top) * (c.height / bounding_box.height) - player_img.height / 2;
I'm using this jsfiddle for the animation and the final value is
wheel.segments[i]
http://jsfiddle.net/bramp/94jP6/
And I would like to retrieve that value after animation has stopped so I can use it in PHP. I tried something like:
function retrivewinner() {
var winner = wheel.segments[i];
window.location.href = "index.php?tag=" + winner;
}
But it would freeze the browser or reload each time
i have edit your code, try:
// Helpers
shuffle = function(o) {
for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
String.prototype.hashCode = function() {
// See http://www.cse.yorku.ca/~oz/hash.html
var hash = 5381;
for (i = 0; i < this.length; i++) {
char = this.charCodeAt(i);
hash = ((hash << 5) + hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
Number.prototype.mod = function(n) {
return ((this % n) + n) % n;
}
// List of venues. These are foursquare IDs, with the idea that eventually it'll tie in
venues = {
"116208": "Jerry's Subs and Pizza",
"66271": "Starbucks",
"5518": "Ireland's Four Courts",
"392360": "Five Guys",
"2210952": "Uptown Cafe",
"207306": "Corner Bakery Courthouse",
"41457": "Delhi Dhaba",
"101161": "TNR Cafe",
"257424": "Afghan Kabob House",
"512060": "The Perfect Pita",
"66244": "California Tortilla",
"352867": "Pho 75 - Rosslyn",
"22493": "Ragtime",
"268052": "Subway",
"5665": "Summers Restaurant & Sports Bar",
"129724": "Cosi",
"42599": "Ray's Hell Burger"
};
$(function() {
var venueContainer = $('#venues ul'),
e_winner = null;
$.each(venues, function(key, item) {
venueContainer.append(
$(document.createElement("li")).append(
$(document.createElement("input")).attr({
id: 'venue-' + key,
name: item,
value: item,
type: 'checkbox',
checked: true
}).change(function() {
var cbox = $(this)[0];
var segments = wheel.segments;
var i = segments.indexOf(cbox.value);
if (cbox.checked && i == -1) {
segments.push(cbox.value);
} else if (!cbox.checked && i != -1) {
segments.splice(i, 1);
}
segments.sort();
wheel.update();
})
).append(
$(document.createElement('label')).attr({
'for': 'venue-' + key
}).text(item)))
});
$('#venues ul>li').tsort("input", {
attr: "value"
});
});
// WHEEL!
var wheel = {
timerHandle: 0,
timerDelay: 33,
angleCurrent: 0,
angleDelta: 0,
size: 290,
canvasContext: null,
colors: ['#ffff00', '#ffc700', '#ff9100', '#ff6301', '#ff0000', '#c6037e',
'#713697', '#444ea1', '#2772b2', '#0297ba', '#008e5b', '#8ac819'],
segments: [],
seg_colors: [],
// Cache of segments to colors
maxSpeed: Math.PI / 16,
upTime: 1000,
// How long to spin up for (in ms)
downTime: 17000,
// How long to slow down for (in ms)
spinStart: 0,
frames: 0,
centerX: 300,
centerY: 300,
spin: function() {
// Start the wheel only if it's not already spinning
if (wheel.timerHandle == 0) {
wheel.spinStart = new Date().getTime();
wheel.maxSpeed = Math.PI / (16 + Math.random()); // Randomly vary how hard the spin is
wheel.frames = 0;
wheel.sound.play();
wheel.timerHandle = setInterval(wheel.onTimerTick, wheel.timerDelay);
}
},
onTimerTick: function() {
wheel.frames++;
wheel.draw();
var duration = (new Date().getTime() - wheel.spinStart);
var progress = 0;
var finished = false;
if (duration < wheel.upTime) {
progress = duration / wheel.upTime;
wheel.angleDelta = wheel.maxSpeed * Math.sin(progress * Math.PI / 2);
} else {
progress = duration / wheel.downTime;
wheel.angleDelta = wheel.maxSpeed * Math.sin(progress * Math.PI / 2 + Math.PI / 2);
if (progress >= 1) finished = true;
}
wheel.angleCurrent += wheel.angleDelta;
while (wheel.angleCurrent >= Math.PI * 2)
// Keep the angle in a reasonable range
wheel.angleCurrent -= Math.PI * 2;
if (finished) {
clearInterval(wheel.timerHandle);
wheel.timerHandle = 0;
wheel.angleDelta = 0;
$("#counter").html((wheel.frames / duration * 1000) + " FPS");alert(e_winner);
// here you build a post or get request $.post('save.php',{value:e_winner});
}
/*
// Display RPM
var rpm = (wheel.angleDelta * (1000 / wheel.timerDelay) * 60) / (Math.PI * 2);
$("#counter").html( Math.round(rpm) + " RPM" );
*/
},
init: function(optionList) {
try {
wheel.initWheel();
wheel.initAudio();
wheel.initCanvas();
wheel.draw();
$.extend(wheel, optionList);
} catch (exceptionData) {
alert('Wheel is not loaded ' + exceptionData);
}
},
initAudio: function() {
var sound = document.createElement('audio');
sound.setAttribute('src', 'http://bramp.net/javascript/wheel.mp3');
wheel.sound = sound;
},
initCanvas: function() {
var canvas = $('#wheel #canvas').get(0);
if ($.browser.msie) {
canvas = document.createElement('canvas');
$(canvas).attr('width', 1000).attr('height', 600).attr('id', 'canvas').appendTo('.wheel');
canvas = G_vmlCanvasManager.initElement(canvas);
}
canvas.addEventListener("click", wheel.spin, false);
wheel.canvasContext = canvas.getContext("2d");
},
initWheel: function() {
shuffle(wheel.colors);
},
// Called when segments have changed
update: function() {
// Ensure we start mid way on a item
//var r = Math.floor(Math.random() * wheel.segments.length);
var r = 0;
wheel.angleCurrent = ((r + 0.5) / wheel.segments.length) * Math.PI * 2;
var segments = wheel.segments;
var len = segments.length;
var colors = wheel.colors;
var colorLen = colors.length;
// Generate a color cache (so we have consistant coloring)
var seg_color = new Array();
for (var i = 0; i < len; i++)
seg_color.push(colors[segments[i].hashCode().mod(colorLen)]);
wheel.seg_color = seg_color;
wheel.draw();
},
draw: function() {
wheel.clear();
wheel.drawWheel();
wheel.drawNeedle();
},
clear: function() {
var ctx = wheel.canvasContext;
ctx.clearRect(0, 0, 1000, 800);
},
drawNeedle: function() {
var ctx = wheel.canvasContext;
var centerX = wheel.centerX;
var centerY = wheel.centerY;
var size = wheel.size;
ctx.lineWidth = 1;
ctx.strokeStyle = '#000000';
ctx.fileStyle = '#ffffff';
ctx.beginPath();
ctx.moveTo(centerX + size - 40, centerY);
ctx.lineTo(centerX + size + 20, centerY - 10);
ctx.lineTo(centerX + size + 20, centerY + 10);
ctx.closePath();
ctx.stroke();
ctx.fill();
// Which segment is being pointed to?
var i = wheel.segments.length - Math.floor((wheel.angleCurrent / (Math.PI * 2)) * wheel.segments.length) - 1;
// Now draw the winning name
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillStyle = '#000000';
ctx.font = "2em Arial";
ctx.fillText(wheel.segments[i], centerX + size + 25, centerY);e_winner= wheel.segments[i];
},
drawSegment: function(key, lastAngle, angle) {
var ctx = wheel.canvasContext;
var centerX = wheel.centerX;
var centerY = wheel.centerY;
var size = wheel.size;
var segments = wheel.segments;
var len = wheel.segments.length;
var colors = wheel.seg_color;
var value = segments[key];
ctx.save();
ctx.beginPath();
// Start in the centre
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, size, lastAngle, angle, false); // Draw a arc around the edge
ctx.lineTo(centerX, centerY); // Now draw a line back to the centre
// Clip anything that follows to this area
//ctx.clip(); // It would be best to clip, but we can double performance without it
ctx.closePath();
ctx.fillStyle = colors[key];
ctx.fill();
ctx.stroke();
// Now draw the text
ctx.save(); // The save ensures this works on Android devices
ctx.translate(centerX, centerY);
ctx.rotate((lastAngle + angle) / 2);
ctx.fillStyle = '#000000';
ctx.fillText(value.substr(0, 20), size / 2 + 20, 0);
ctx.restore();
ctx.restore();
},
drawWheel: function() {
var ctx = wheel.canvasContext;
var angleCurrent = wheel.angleCurrent;
var lastAngle = angleCurrent;
var segments = wheel.segments;
var len = wheel.segments.length;
var colors = wheel.colors;
var colorsLen = wheel.colors.length;
var centerX = wheel.centerX;
var centerY = wheel.centerY;
var size = wheel.size;
var PI2 = Math.PI * 2;
ctx.lineWidth = 1;
ctx.strokeStyle = '#000000';
ctx.textBaseline = "middle";
ctx.textAlign = "center";
ctx.font = "1.4em Arial";
for (var i = 1; i <= len; i++) {
var angle = PI2 * (i / len) + angleCurrent;
wheel.drawSegment(i - 1, lastAngle, angle);
lastAngle = angle;
}
// Draw a center circle
ctx.beginPath();
ctx.arc(centerX, centerY, 20, 0, PI2, false);
ctx.closePath();
ctx.fillStyle = '#ffffff';
ctx.strokeStyle = '#000000';
ctx.fill();
ctx.stroke();
// Draw outer circle
ctx.beginPath();
ctx.arc(centerX, centerY, size, 0, PI2, false);
ctx.closePath();
ctx.lineWidth = 10;
ctx.strokeStyle = '#000000';
ctx.stroke();
},
}
window.onload = function() {
wheel.init();
var segments = new Array();
$.each($('#venues input:checked'), function(key, cbox) {
segments.push(cbox.value);
});
wheel.segments = segments;
wheel.update();
// Hide the address bar (for mobile devices)!
setTimeout(function() {
window.scrollTo(0, 1);
}, 0);
}