I got an agar.io clone from online and I am trying to remove the Quadtree in the corner (acts as a map) completely! I try to delete everything associating with the quadtree but i end up with a gray screen. Could someone please remove the map from the top right corner for me or tell me which lines to remove?
Here is my HTML:
<div id="viewport">
<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>
<canvas id="canvas3" width="250px" height="250px"></canvas>
</div>
Here is my javascript:
var MouseHandler = (function() {
var x = 0;
var y = 0;
var mouseIn = false;
var init = function(eventSrc) {
eventSrc.addEventListener('mousemove', onMouseMove);
eventSrc.addEventListener('mouseout', onMouseOut);
eventSrc.addEventListener('mouseover', onMouseOver);
};
var onMouseOut = function() {
mouseIn = false;
};
var onMouseOver = function() {
mouseIn = true;
};
var onMouseMove = function(e) {
x = e.clientX;
y = e.clientY;
};
var getPos = function() {
return {
x: x,
y: y
};
};
var isMouseIn = function() {
return mouseIn;
};
return {
init: init,
getPos: getPos,
isMouseIn: isMouseIn
};
}());
Quadtree.MAX_OBJECTS = 5;
Quadtree.MAX_LEVEL = 5;
function Quadtree(lvl, bnds) {
var level = lvl;
var bounds = bnds;
var objects = [];
var nodes = [];
var xMiddle = bounds.x + (bounds.width / 2);
var yMiddle = bounds.y + (bounds.height / 2);
var clear = function() {
objects = [];
nodes = [];
};
var split = function() {
nodes[0] = new Quadtree(level+1, {x: xMiddle, y: bounds.y , width: bounds.width/2, height: bounds.height/2});
nodes[1] = new Quadtree(level+1, {x: bounds.x, y: bounds.y, width: bounds.width/2, height: bounds.height/2});
nodes[2] = new Quadtree(level+1, {x: bounds.x, y: yMiddle, width: bounds.width/2, height: bounds.height/2});
nodes[3] = new Quadtree(level+1, {x: xMiddle, y: yMiddle, width: bounds.width/2, height: bounds.height/2});
};
var getIndex = function(rec) {
var top = (rec.y > bounds.y && (rec.y+rec.height) < yMiddle);
var bottom = (rec.y > yMiddle && (rec.y+rec.height) < (bounds.y+bounds.height));
if(rec.x > bounds.x && (rec.x+rec.width) < xMiddle) {
if(top) {
return 1;
} else if(bottom) {//LEFT
return 2;
}
} else if(rec.x > xMiddle && (rec.x+rec.width) < (bounds.x+bounds.width)) {
if(top) {
return 0;
} else if(bottom) {//RIGHT
return 3;
}
}
return -1;
};
var insert = function(ent) {
var rec = ent.getBounds();
var index = getIndex(rec);
var len = 0;
var i = 0;
if(nodes[0] && index !== -1) {
nodes[index].insert(ent);
return;
}
objects.push(ent);
if(objects.length > Quadtree.MAX_OBJECTS && level < Quadtree.MAX_LEVEL) {
if(!nodes[0]) {
split();
}
len = objects.length;
while(i < objects.length) {
index = getIndex(objects[i].getBounds());
if(index !== -1) {
nodes[index].insert(objects[i]);
objects.splice(i, 1);
} else {
i += 1;
}
}
}
};
var retrieve = function (list, ent) {
var rec1 = bounds;
var rec2 = ent.getBounds();
if(rec2.x < (rec1.x+rec1.width) && (rec2.x+rec2.width) > rec1.x &&
rec2.y < (rec1.y+rec1.height) && (rec2.y+rec2.height) > rec1.y) {
for(var o in objects) {
if(objects[o] !== ent) {
list.push(objects[o]);
}
}
if(nodes.length) {
nodes[0].retrieve(list, ent);
nodes[1].retrieve(list, ent);
nodes[2].retrieve(list, ent);
nodes[3].retrieve(list, ent);
}
}
return list;
};
var drawTree = function(ctx) {
draw(ctx);
if(nodes[0]) {
nodes[0].drawTree(ctx);
nodes[1].drawTree(ctx);
nodes[2].drawTree(ctx);
nodes[3].drawTree(ctx);
}
};
var draw = function(ctx) {
var entAttr = null
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.strokeRect(bounds.x/20, bounds.y/20, bounds.width/20, bounds.height/20);
ctx.fillStyle = 'gray';
for(o in objects) {
entAttr = objects[o].getAttr();
ctx.fillRect(entAttr.x/20, entAttr.y/20, 3, 3);
}
};
var toString = function() {
return '('+bounds.x+','+bounds.y+')'+'['+bounds.width+','+bounds.height+']';
};
return {
clear: clear,
insert: insert,
retrieve: retrieve,
drawTree: drawTree,
toString: toString,
};
}
function Circle(attr) {
attr = attr || {};
var x = attr.x || 0;
var y = attr.y || 0;
var mass = attr.mass || 500;
var color = attr.color || 'white';
var borderColor = attr.borderColor || 'black';
var velX = attr.velX || 0;
var velY = attr.velY || 0;
var droplet = attr.droplet || false;
var maxVel = 80 * (80 / Math.sqrt(mass));
var radius = Math.sqrt( mass / Math.PI ); //1 unit of area === 1 uni of mass
var getAttr = function() {
return {
x: x,
y: y,
mass: mass,
radius: radius,
color: color,
velX: velX,
velY: velY,
maxVel: maxVel
};
};
var setAttr = function(attr) {
x = (attr.x !== undefined)? attr.x: x;
y = (attr.y !== undefined)? attr.y: y;
mass = (attr.mass !== undefined)? attr.mass: mass;
color = (attr.color !== undefined)? attr.color: color;
velX = (attr.velX !== undefined)? attr.velX: velX;
velY = (attr.velY !== undefined)? attr.velY: velY;
};
var incMass = function(dMass) {
mass += dMass;
maxVel = 100 * (100 / Math.sqrt(mass));
radius = Math.sqrt( mass / Math.PI );
};
var intersects = function(ent2) {
var ent2Attr = ent2.getAttr();
var dX = Math.abs(ent2Attr.x - x);
var dY = Math.abs(ent2Attr.y - y);
var totalRadius = ent2Attr.radius + radius;
return (dX < totalRadius && dY < totalRadius);
};
var draw = function(ctx, cam) {
var camSize = cam.getSize();
var rPos = cam.getRelPos(getAttr());
//if outside Cam view
if((rPos.x + radius) < 0 || (rPos.y + radius) < 0 || (rPos.x - radius) > camSize.width || (rPos.y - radius) > camSize.height) {
return;
}
ctx.fillStyle = color;
ctx.strokeStyle = borderColor;
ctx.lineWidth = 5;
ctx.beginPath();
ctx.arc(rPos.x, rPos.y, radius, 0, 2 * Math.PI, false);
ctx.fill();
ctx.stroke();
};
var update = !droplet && function(dTime) {
x += velX * dTime;
y += velY * dTime;
};
var getBounds = function() {
return {
x: x-radius,
y: y-radius,
width: radius*2,
height: radius*2,
};
};
return {
getBounds: getBounds,
getAttr: getAttr,
setAttr: setAttr,
incMass: incMass,
intersects: intersects,
draw: draw,
update: update
};
}
var gameManager = (function() {
var canvasGrid = null;
var canvasEnt = null;
var canvasQuadtree = null;
var ctxGrid = null;
var ctxEnt = null;
var ctxQuadTree = null;
var dTime = 1 / 60;
var player = null;
var entityBag = [];
var qTree = null;
var drwQuad = 0;
var addEntity = function(ent) {
entityBag.push(ent);
};
var removeEntity = function(ent) {
var len = entityBag.length;
var i = 0;
for(i=0; i<len; i+=1) {
if(ent === entityBag[i]) {
entityBag.splice(i, 1);
return;
}
}
};
var init = function(cvsGridId, cvsEntId, cvsQuadtree) {
canvasGrid = document.getElementById(cvsGridId);
canvasEnt = document.getElementById(cvsEntId);
canvasQuadtree = document.getElementById(cvsQuadtree);
ctxGrid = canvasGrid.getContext('2d');
ctxEnt = canvasEnt.getContext('2d');
ctxQuadtree = canvasQuadtree.getContext('2d');
fitToContainer(canvasGrid);
fitToContainer(canvasEnt);
ctxGrid.fillStyle = '#F0FBFF';
ctxGrid.strokeStyle = '#BFBFBF';
ctxGrid.lineWidth = 1;
MouseHandler.init(document);
qTree = new Quadtree(0, {x:0, y:0, width:5000, height:5000});
player = new Circle({
x: 50,
y: 50,
color: 'red',
mass: 1000,
velX: 500,
velY:500
});
Camera.init(ctxEnt, player);
addEntity(player);
gameloop();
};
var handleInput = function() {
if(MouseHandler.isMouseIn() === false) {
player.setAttr({ velX: 0, velY: 0 });
return;
}
var pAttr = player.getAttr();
var rPlyrPos = Camera.getRelPos(player.getAttr());
var mPos = MouseHandler.getPos();
var dX = mPos.x - rPlyrPos.x;
var dY = mPos.y - rPlyrPos.y;
var vLength = Math.sqrt( (dX*dX) + (dY*dY) );
var normX = dX / vLength;
var normY = dY / vLength;
var newVelX = normX * (pAttr.maxVel * vLength / 50);
var newVelY = normY * (pAttr.maxVel * vLength / 50);
player.setAttr({
velX: newVelX,
velY: newVelY
});
};
var drawGrid = function() {
var camPos = Camera.getPos();
var camSize = Camera.getSize();
var start = Math.floor(camPos.x / 40);
var relX = Camera.getRelPos({x: (start*40), y: 0}).x;
var numLines = camSize.width / 40;
var i = 0;
ctxGrid.fillRect(0, 0, canvasGrid.width, canvasGrid.height);
for(i=0; i<numLines; i+=1) {
ctxGrid.beginPath();
ctxGrid.moveTo(relX + (40 * i), 0);
ctxGrid.lineTo(relX + (40 * i), camSize.height);
ctxGrid.stroke();
}
start = Math.floor(camPos.y / 40);
var relY = Camera.getRelPos({x: 0, y: (start * 40)}).y;
numLines = camSize.height / 40;
for(i=0; i<numLines; i+=1) {
ctxGrid.beginPath();
ctxGrid.moveTo(0, relY + (40 * i));
ctxGrid.lineTo(camSize.width, relY + (40 * i));
ctxGrid.stroke();
}
};
var handleCollisions = function() {
var possibleColl = [];
var collisions = [];
var coll = null;
var ent = null;
var plyMass = player.getAttr().mass
var entMass = 0;
qTree.clear();
for(ent in entityBag) {
qTree.insert(entityBag[ent]);
}
possibleColl = qTree.retrieve([], player);
while(ent = possibleColl.pop()) {
if(player.intersects(ent)) {
entMass = ent.getAttr().mass;
if(plyMass > (1.5 * entMass)) {
removeEntity(ent);
player.incMass(entMass);
}
}
var entAttr = ent.getAttr();
ctxQuadtree.fillStyle = 'red';
ctxQuadtree.fillRect(entAttr.x/20, entAttr.y/20, 3, 3);
}
};
var fitToContainer = function(canvas) {
canvas.style.width='100%';
canvas.style.height='100%';
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
};
var gameloop = function() {
var len = entityBag.length;
var i = 0;
var ent = null;
handleInput();
Camera.update();
drawGrid();
if(drwQuad === 5) {
ctxQuadtree.fillStyle = 'white';
ctxQuadtree.fillRect(0, 0, 250, 250);
qTree.drawTree(ctxQuadtree);
drwQuad = 0;
}
drwQuad += 1;
ctxEnt.clearRect(0, 0, canvasEnt.width, canvasEnt.height)
for(i=0; i<len; i+=1) {
ent = entityBag[i];
if(ent.update) {
ent.update(dTime);
}
if(ent.draw) {
ent.draw(ctxEnt, Camera);
}
}
handleCollisions();
setTimeout(gameloop, dTime * 1000);
};
return {
init: init,
addEntity: addEntity,
removeEntity: removeEntity
};
}());
var Camera = (function() {
var x = 0;
var y = 0;
var width = 0;
var height = 0;
var ctx = null;
var player = null;
var init = function(_ctx, plyr) {
ctx = _ctx;
player = plyr;
width = ctx.canvas.width;
height = ctx.canvas.height;
};
var update = function() {
width = ctx.canvas.width;
height = ctx.canvas.height;
var plyrAttr = player.getAttr();
x = (plyrAttr.x - width / 2);
y = (plyrAttr.y - height / 2);
};
var getRelPos = function(entAttr) {
var relX = entAttr.x - x;
var relY = entAttr.y - y;
return {
x: relX,
y: relY
};
};
var getPos = function() {
return {
x: x,
y: y
};
};
var getSize = function() {
return {
width: width,
height: height
};
};
return {
init: init,
update: update,
getRelPos: getRelPos,
getPos: getPos,
getSize: getSize
};
}());
var i = 0;
var space = 70;
for(i=0; i<400; i+=1) {
gameManager.addEntity(new Circle({
x: 100 + Math.random() * 4850,//(i%20) * space,
y: 100 + Math.random() * 4850,//Math.floor(i/20)*space,
color: ['red', 'blue', 'green', 'yellow', 'purple', 'brown', 'violet'][Math.floor(Math.random()*7)],
droplet: true
}));
}
gameManager.init('canvas1', 'canvas2', 'canvas3');
And last but not least, my css:
html, body {
background: gray;
width: 100%;
height: 100%;
margin: 0px;
}
#viewport {
position: relative;
width: 100%;
height: 100%;
}
#viewport canvas {
position: absolute;
}
canvas {
background-color: transparent;
}
Related
var sketcher = null;
var brush = null;
function Sketcher(canvasID, brushImage) {
this.renderFunction = (brushImage == null || brushImage == undefined) ? this.updateCanvasByLine : this.updateCanvasByBrush;
this.brush = brushImage;
this.touchSupported = Modernizr.touch;
this.canvasID = canvasID;
this.canvas = $("#" + canvasID);
this.context = this.canvas.get(0).getContext("2d");
this.context.strokeStyle = "#000000";
this.context.lineWidth = 3;
this.lastMousePoint = {
x: 0,
y: 0
};
if (this.touchSupported) {
this.mouseDownEvent = "touchstart";
this.mouseMoveEvent = "touchmove";
this.mouseUpEvent = "touchend";
} else {
this.mouseDownEvent = "mousedown";
this.mouseMoveEvent = "mousemove";
this.mouseUpEvent = "mouseup";
}
this.canvas.bind(this.mouseMoveEvent, this.onCanvasMouseMove());
}
Sketcher.prototype.onCanvasMouseMove = function() {
var self = this;
return function(event) {
self.mouseMoveHandler = self.onCanvasMouseMove()
self.mouseUpHandler = self.onCanvasMouseUp()
$(document).bind(self.mouseMoveEvent, self.mouseMoveHandler);
$(document).bind(self.mouseUpEvent, self.mouseUpHandler);
self.updateMousePosition(event);
self.renderFunction(event);
}
}
Sketcher.prototype.onCanvasMouseMove = function() {
var self = this;
return function(event) {
self.renderFunction(event);
event.preventDefault();
return false;
}
}
Sketcher.prototype.onCanvasMouseUp = function(event) {
var self = this;
return function(event) {
$(document).unbind(self.mouseMoveEvent, self.mouseMoveHandler);
$(document).unbind(self.mouseUpEvent, self.mouseUpHandler);
self.mouseMoveHandler = null;
self.mouseUpHandler = null;
}
}
Sketcher.prototype.updateMousePosition = function(event) {
var target;
if (this.touchSupported) {
target = event.originalEvent.touches[0]
} else {
target = event;
}
var offset = this.canvas.offset();
this.lastMousePoint.x = target.pageX - offset.left;
this.lastMousePoint.y = target.pageY - offset.top;
}
Sketcher.prototype.updateCanvasByLine = function(event) {
this.context.beginPath();
this.context.moveTo(this.lastMousePoint.x, this.lastMousePoint.y);
this.updateMousePosition(event);
this.context.lineTo(this.lastMousePoint.x, this.lastMousePoint.y);
this.context.stroke();
}
Sketcher.prototype.updateCanvasByBrush = function(event) {
var halfBrushW = this.brush.width / 2;
var halfBrushH = this.brush.height / 2;
var start = {
x: this.lastMousePoint.x,
y: this.lastMousePoint.y
};
this.updateMousePosition(event);
var end = {
x: this.lastMousePoint.x,
y: this.lastMousePoint.y
};
var distance = parseInt(Trig.distanceBetween2Points(start, end));
var angle = Trig.angleBetween2Points(start, end);
var x, y;
for (var z = 0;
(z <= distance || z == 0); z++) {
x = start.x + (Math.sin(angle) * z) - halfBrushW;
y = start.y + (Math.cos(angle) * z) - halfBrushH;
//console.log( x, y, angle, z );
this.context.drawImage(this.brush, x, y);
}
}
Sketcher.prototype.toString = function() {
var dataString = this.canvas.get(0).toDataURL("image/png");
var index = dataString.indexOf(",") + 1;
dataString = dataString.substring(index);
return dataString;
}
Sketcher.prototype.toDataURL = function() {
var dataString = this.canvas.get(0).toDataURL("image/png");
return dataString;
}
var Trig = {
distanceBetween2Points: function ( point1, point2 ) {
var dx = point2.x - point1.x;
var dy = point2.y - point1.y;
return Math.sqrt( Math.pow( dx, 2 ) + Math.pow( dy, 2 ) );
},
angleBetween2Points: function ( point1, point2 ) {
var dx = point2.x - point1.x;
var dy = point2.y - point1.y;
return Math.atan2( dx, dy );
}
}
var canvas = document.getElementById("sketch");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
brush = new Image();
brush.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Ash_Tree_-_geograph.org.uk_-_590710.jpg/440px-Ash_Tree_-_geograph.org.uk_-_590710.jpg";
brush.onload = function() {
sketcher = new Sketcher("sketch", brush);
};
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.sketch-container {
position: relative;
position: absolute;
height: 100vh;
width: 100%;
}
#sketch {
background: none yellow;
position: absolute;
height: 100vh;
width: 100%;
}
.button-container {
position: absolute;
left: 10px;
top: 10px;
opacity: .5;
background: none blue;
font-size: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<div class="sketch-container">
<canvas id="sketch"></canvas>
<button type="button" class="button-container">Can you draw below me?</button>
</div>
I am drawing an image using this javascript code:
var sketcher = null;
var brush = null;
function Sketcher(canvasID, brushImage) {
this.renderFunction = (brushImage == null || brushImage == undefined) ? this.updateCanvasByLine : this.updateCanvasByBrush;
this.brush = brushImage;
this.touchSupported = Modernizr.touch;
this.canvasID = canvasID;
this.canvas = $("#" + canvasID);
this.context = this.canvas.get(0).getContext("2d");
this.context.strokeStyle = "#000000";
this.context.lineWidth = 3;
this.lastMousePoint = {
x: 0,
y: 0
};
if (this.touchSupported) {
this.mouseDownEvent = "touchstart";
this.mouseMoveEvent = "touchmove";
this.mouseUpEvent = "touchend";
} else {
this.mouseDownEvent = "mousedown";
this.mouseMoveEvent = "mousemove";
this.mouseUpEvent = "mouseup";
}
this.canvas.bind(this.mouseMoveEvent, this.onCanvasMouseMove());
}
Sketcher.prototype.onCanvasMouseMove = function() {
var self = this;
return function(event) {
self.mouseMoveHandler = self.onCanvasMouseMove()
self.mouseUpHandler = self.onCanvasMouseUp()
$(document).bind(self.mouseMoveEvent, self.mouseMoveHandler);
$(document).bind(self.mouseUpEvent, self.mouseUpHandler);
self.updateMousePosition(event);
self.renderFunction(event);
}
}
Sketcher.prototype.onCanvasMouseMove = function() {
var self = this;
return function(event) {
self.renderFunction(event);
event.preventDefault();
return false;
}
}
Sketcher.prototype.onCanvasMouseUp = function(event) {
var self = this;
return function(event) {
$(document).unbind(self.mouseMoveEvent, self.mouseMoveHandler);
$(document).unbind(self.mouseUpEvent, self.mouseUpHandler);
self.mouseMoveHandler = null;
self.mouseUpHandler = null;
}
}
Sketcher.prototype.updateMousePosition = function(event) {
var target;
if (this.touchSupported) {
target = event.originalEvent.touches[0]
} else {
target = event;
}
var offset = this.canvas.offset();
this.lastMousePoint.x = target.pageX - offset.left;
this.lastMousePoint.y = target.pageY - offset.top;
}
Sketcher.prototype.updateCanvasByLine = function(event) {
this.context.beginPath();
this.context.moveTo(this.lastMousePoint.x, this.lastMousePoint.y);
this.updateMousePosition(event);
this.context.lineTo(this.lastMousePoint.x, this.lastMousePoint.y);
this.context.stroke();
}
Sketcher.prototype.updateCanvasByBrush = function(event) {
var halfBrushW = this.brush.width / 2;
var halfBrushH = this.brush.height / 2;
var start = {
x: this.lastMousePoint.x,
y: this.lastMousePoint.y
};
this.updateMousePosition(event);
var end = {
x: this.lastMousePoint.x,
y: this.lastMousePoint.y
};
var distance = parseInt(Trig.distanceBetween2Points(start, end));
var angle = Trig.angleBetween2Points(start, end);
var x, y;
for (var z = 0;
(z <= distance || z == 0); z++) {
x = start.x + (Math.sin(angle) * z) - halfBrushW;
y = start.y + (Math.cos(angle) * z) - halfBrushH;
//console.log( x, y, angle, z );
this.context.drawImage(this.brush, x, y);
}
}
Sketcher.prototype.toString = function() {
var dataString = this.canvas.get(0).toDataURL("image/png");
var index = dataString.indexOf(",") + 1;
dataString = dataString.substring(index);
return dataString;
}
Sketcher.prototype.toDataURL = function() {
var dataString = this.canvas.get(0).toDataURL("image/png");
return dataString;
}
var Trig = {
distanceBetween2Points: function ( point1, point2 ) {
var dx = point2.x - point1.x;
var dy = point2.y - point1.y;
return Math.sqrt( Math.pow( dx, 2 ) + Math.pow( dy, 2 ) );
},
angleBetween2Points: function ( point1, point2 ) {
var dx = point2.x - point1.x;
var dy = point2.y - point1.y;
return Math.atan2( dx, dy );
}
}
var canvas = document.getElementById("sketch");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
brush = new Image();
brush.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Ash_Tree_-_geograph.org.uk_-_590710.jpg/440px-Ash_Tree_-_geograph.org.uk_-_590710.jpg";
brush.onload = function() {
sketcher = new Sketcher("sketch", brush);
};
It works well and draws an image exactly as I would like. However, I have divs on top with text for which I have onclick functions on.
Picture of how the image is being drawn
The problem is the image is not being drawn underneath the divs because the canvas is under them. I understand I may need to add a listener to the window and draw according to that, but I have tried and tried and do not understand where something like that goes/what needs to be replaced.
Something that I've tried is to get rid of pointer events, which of course works to maintain the continuity of the image being dragged, but prevents me from clicking on the button.
Thanks
Hey i'm trying to make a super simple Galaxian Shooter game. I'm having a problem in making all the enemies in the enemy list shoot separately. Right now, only one shoots bullets. I know there are a lot of better ways to do things in this code, I just haven't made it efficient yet and I'm fixing it all so please don't say anything about that. Lines 193,86,72, and 42 all have something do with the enemyBulletList, if that helps.
var c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
keys = [];
width = 500;
height = 500;
bulletList = {};
enemyBulletList = {};
enemyList = {};
enemyAmount = 10;
var player = {
x:400,
y:450,
speedX:7,
speedY:7,
width:32,
height:32,
hp:3,
shootCdTimer:0,
shootCd:1,
};
tickShootCooldown = function(){
player.shootCdTimer--;
}
setInterval(tickShootCooldown,500);
onGameStart = function(){
generateEnemy();
generateBullet();
generateEnemyBullet();
setInterval(changeEnemyDirection,2000);
setInterval(changeEnemyDirection2,4000);
}
setTimeout(onGameStart,0);
Bullet = function(id,x,y,speedX,speedY,width,height) {
var asd = {
x:x,
y:y,
speedX:speedX,
speedY:speedY,
name:'B',
id:id,
width:width,
height:height,
color:'black',
};
bulletList[id] = asd;
}
generateBullet = function() {
var x = player.x;
var y = player.y;
var width = 5;
var height = 15;
var id = Math.random();
var speedX = 0;
var speedY = 15;
Bullet(id,x,y,speedX,speedY,width,height);
}
EnemyBullet = function(id,x,y,speedX,speedY,width,height) {
var asd = {
x:x,
y:y,
speedX:speedX,
speedY:speedY,
name:'B',
id:id,
width:width,
height:height,
color:'black',
};
enemyBulletList[id] = asd;
}
generateEnemyBullet = function() {
for(var key3 in enemyList){
var x = enemyList[key3].x;
var y = enemyList[key3].y;
}
var width = 5;
var height = 15;
var id = Math.random();
var speedX = 0;
var speedY = -15;
EnemyBullet(id,x,y,speedX,speedY,width,height);
}
Enemy = function(id,x,y,speedX,speedY,width,height) {
var asd = {
x:x,
y:y,
speedX:speedX,
speedY:speedY,
name:'B',
id:id,
width:width,
height:height,
color:'red',
};
enemyList[id] = asd;
}
generateEnemy = function() {
var x = 50;
var y = 50;
var width = 32;
var height = 32;
var id = 1;
var speedX = 2;
var speedY = 0;
Enemy(id,x,y,speedX,speedY,width,height);
Enemy(id*2,x*2,y,speedX,speedY,width,height);
Enemy(id*3,x*3,y,speedX,speedY,width,height);
Enemy(id*4,x*4,y,speedX,speedY,width,height);
Enemy(id*5,x*5,y,speedX,speedY,width,height);
Enemy(id*6,x,y*2,speedX,speedY,width,height);
Enemy(id*7,x*2,y*2,speedX,speedY,width,height);
Enemy(id*8,x*3,y*2,speedX,speedY,width,height);
Enemy(id*9,x*4,y*2,speedX,speedY,width,height);
Enemy(id*10,x*5,y*2,speedX,speedY,width,height);
}
changeEnemyDirection = function() {
for(var key in enemyList){
if(enemyList[key].speedX > 0){
enemyList[key].speedX *= -1;
}
}
}
changeEnemyDirection2 = function() {
for(var key in enemyList){
if(enemyList[key].speedX < 0){
enemyList[key].speedX *= -1;
}
}
}
function update() {
ctx.clearRect(0, 0, width, height);
ctx.fillRect(player.x,player.y,player.width,player.height);
if(enemyAmount < 1){
generateEnemy();
enemyAmount = 10;
}
if(player.x < player.width/2){
player.x = player.width/2;
}
if(player.x > width - player.width){
player.x = width - player.width;
}
if(player.y < height-150){
player.y = height-150;
}
if(player.y > height-32){
player.y = height-33;
}
if (keys[39]) { //right arrow
player.x+=player.speedX;
}
if (keys[37]) { //left arrow
player.x-=player.speedX;
}
if (keys[38]) { //up arrow
player.y-=player.speedY;
}
if (keys[40]) { //down arrow
player.y+=player.speedY;
}
if (keys[32]) { //space bar
if(player.shootCdTimer<=0){
generateBullet();
player.shootCdTimer = player.shootCd;
}
}
for(var key in bulletList) {
updateEntity(bulletList[key]);
}
for(var keyy in enemyBulletList) {
updateEntity(enemyBulletList[keyy]);
}
for(var key2 in enemyList) {
var isColliding = testCollisionEntity(bulletList[key],enemyList[key2]);
if(isColliding) {
delete enemyList[key2];
enemyAmount --;
delete bulletList[key];
break;
}
}
//for(var key3 in enemyList){
var timer = Math.random();
if(timer <= 0.01){
generateEnemyBullet(enemyList[key2]);
}
// }
for(var key in enemyList){ //change to collision with enemy bullet
updateEntity(enemyList[key]);
var isColliding = testCollisionEntity(player,enemyList[key]);
if(isColliding){
player.hp = player.hp - 1;
}
}
ctx.fillText(player.shootCdTimer,5,10);
}
setInterval(update,20);
testCollisionEntity = function (entity1,entity2){ //return if colliding (true/false)
var rect1 = {
x:entity1.x-entity1.width/2,
y:entity1.y-entity1.height/2,
width:entity1.width,
height:entity1.height,
}
var rect2 = {
x:entity2.x-entity2.width/2,
y:entity2.y-entity2.height/2,
width:entity2.width,
height:entity2.height,
}
return testCollisionRectRect(rect1,rect2);
}
testCollisionRectRect = function(rect1,rect2){
return rect1.x <= rect2.x+rect2.width
&& rect2.x <= rect1.x+rect1.width
&& rect1.y <= rect2.y + rect2.height
&& rect2.y <= rect1.y + rect1.height;
}
updateEntity = function(something){
updateEntityPosition(something);
drawEntity(something);
}
updateEntityPosition = function(something){
something.x += something.speedX;
something.y -= something.speedY;
}
drawEntity = function(something){
ctx.save();
ctx.fillStyle = something.color;
ctx.fillRect(something.x-something.width/2,something.y-something.height/2,something.width,something.height);
ctx.restore();
}
document.body.addEventListener("keydown", function (e) {
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
keys[e.keyCode] = false;
});
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
I try to use canvas as a clickable board for minesweeper. My problem is that i can clicked out of the canvas but i don't want to it. Here's my code:
var board;
var ctx;
var bombs = [];
var clickedX;
var clickedY;
function initBoard(w, h){
board = document.getElementById("board");
ctx = board.getContext('2d');
drawBoard(w,h);
placedBombs();
}
function drawBoard(w,h){
board.squareSize = {
w: board.width / w,
h: board.height / h
};
ctx.fillStyle = "#C0C0C0"
ctx.fillRect(0, 0, board.width, board.height)
board.drawGrid = function () {
ctx.beginPath();
for (var i = 0; i <= w; i++) {
ctx.moveTo(i * this.squareSize.w, 0);
ctx.lineTo(i * this.squareSize.w, this.height);
}
for (var i = 0; i <= h; i++) {
ctx.moveTo(0, i * this.squareSize.h);
ctx.lineTo(this.width, i * this.squareSize.h);
}
ctx.lineWidth = 0.3;
ctx.stroke();
ctx.closePath();
}
board.drawGrid();
}
function placedBombs(){
for(var n=0; n<10; n++){
bombs[n] = ([Math.floor(Math.random() * 10), Math.floor(Math.random() * 10)]);
}
}
board.onmouseup = function(e){
board.squareSize = {
w: board.width / 10,
h: board.height / 10
};
board.eventToGrid = function (e) {
return {
i: parseInt(e.offsetX / this.squareSize.w),
j: parseInt(e.offsetY / this.squareSize.h)
};
}
var pos = board.eventToGrid(e);
clickedX = pos.i;
clickedY = pos.j;
loc = document.getElementById("loc");
loc.innerHTML = "Position: " + pos.i + ", " + pos.j;
if(check(clickedX, clickedY) == false){
lose();
}
/*else{
clickPass();
}*/
}
function check(clickedX, clickedY){
console.log(clickedX);
console.log(clickedY);
for(var i=0; i<bombs.length; i++){
if((clickedX == bombs[i][0]) && (clickedY == bombs[i][1])){
return false;
}
}
return true;
}
/*function clickPass(){
}*/
function lose(){
alert("bomb");
}
<body onload="initBoard(10,10)">
<canvas id="board" width="350" height="350">
</canvas>
<div id="loc">
Mouse location: x, y
</div>
</body>
I try to use board as an object. But i failed.
Thanks for your helps.
Put the assignment to board.onmouseup inside initBoard(), so that it runs after you've assigned the variable.
function initBoard(w, h){
board = document.getElementById("board");
ctx = board.getContext('2d');
drawBoard(w,h);
placedBombs();
board.onmouseup = function(e){
board.squareSize = {
w: board.width / 10,
h: board.height / 10
};
board.eventToGrid = function (e) {
return {
i: parseInt(e.offsetX / this.squareSize.w),
j: parseInt(e.offsetY / this.squareSize.h)
};
}
var pos = board.eventToGrid(e);
clickedX = pos.i;
clickedY = pos.j;
loc = document.getElementById("loc");
loc.innerHTML = "Position: " + pos.i + ", " + pos.j;
if(check(clickedX, clickedY) == false){
lose();
}
/*else{
clickPass();
}*/
}
}
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 need some expert help. When I make canvas background transparent the line colors the whole canvas (shown in code below).
How do I stop/fix this? I want the line stay as a single line that doesn't color the canvas.
Math.clamp = function(x, min, max) {
return x < min ? min : (x > max ? max : x);
};
// canvas settings
var viewWidth = window.innerWidth,
viewHeight = window.innerHeight,
drawingCanvas = document.getElementById("drawing_canvas"),
ctx,
timeStep = (10 / 100),
time = 0;
var lineTension = 0.067,
lineDamping = 0.068,
waveSpreadFactor = 0.1;
var previousMousePosition = {
x: 0,
y: 0
},
currentMousePosition = {
x: 0,
y: 0
},
actualMousePosition = {
x: 0,
y: 0
};
var line,
lineSegmentCount = 64,
lineMaxForce = 32,
lineStrokeGradient;
var audioCtx,
nodeCount = 64,
oscillatorNodes = [],
gainNodes = [];
var segmentsPerNode = lineSegmentCount / nodeCount;
function initGui() {
}
function goBananas() {
lineTension = 0.2;
line.anchors[Math.floor(Math.random() * line.anchors.length)].
vel = lineMaxForce;
}
function resetLine() {
line.reset();
for (var i = 0; i < nodeCount; i++) {
oscillatorNodes[i].detune.value = 100;
gainNodes[i].gain.value = 0;
}
lineTension = 0.0025;
lineDamping = 0.05;
waveSpreadFactor = 0.1;
}
function initDrawingCanvas() {
drawingCanvas.width = viewWidth;
drawingCanvas.height = viewHeight;
window.addEventListener('resize', resizeHandler);
window.addEventListener('mousemove', mouseMoveHandler);
setInterval(updateMousePosition, (1000 / 30));
ctx = drawingCanvas.getContext('2d');
ctx.lineWidth = 5;
line = new Line(0, viewHeight * 0.5, viewWidth, lineSegmentCount);
// line.anchors[0].vel = viewHeight * 0.25;
lineStrokeGradient = ctx.createLinearGradient(0, 0, 0, viewHeight);
lineStrokeGradient.addColorStop(0, '#0ff');
}
function initWebAudio() {
audioCtx = new(window.AudioContext || window.webkitAudioContext)();
for (var i = 0; i < nodeCount; i++) {
var oscillatorNode = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();
oscillatorNode.connect(gainNode);
gainNode.connect(audioCtx.destination);
gainNode.gain.value = 0;
oscillatorNode.type = 'saw';
oscillatorNode.detune.value = 200;
oscillatorNode.frequency.value = 1200 * (i / 60);
oscillatorNode.start();
oscillatorNodes[i] = oscillatorNode;
gainNodes[i] = gainNode;
}
}
function resizeHandler() {
drawingCanvas.width = viewWidth = window.innerWidth;
drawingCanvas.height = viewHeight = window.innerHeight;
if (ctx) {
ctx.lineWidth = 4;
line.resize(viewWidth, viewHeight * 0.5);
}
}
function mouseMoveHandler(event) {
actualMousePosition.x = Math.floor(event.clientX);
actualMousePosition.y = Math.floor(event.clientY);
}
function updateMousePosition() {
previousMousePosition.x = currentMousePosition.x;
previousMousePosition.y = currentMousePosition.y;
currentMousePosition.x = actualMousePosition.x;
currentMousePosition.y = actualMousePosition.y;
}
function update() {
var px = Math.min(previousMousePosition.x, currentMousePosition.x),
py = Math.min(previousMousePosition.y, currentMousePosition.y),
pw = Math.max(1, Math.abs(previousMousePosition.x - currentMousePosition.x)),
ph = Math.max(1, Math.abs(previousMousePosition.y - currentMousePosition.y)),
force = Math.clamp(currentMousePosition.y -
previousMousePosition.y, -lineMaxForce, lineMaxForce);
var pixels = ctx.getImageData(px, py, pw, ph),
data = pixels.data;
for (var i = 0; i < data.length; i += 3) {
var r = data[i + 0],
g = data[i + 1],
b = data[i + 2],
x = (i % ph) + px;
if (r + g + b > 0) {
line.ripple(x, force);
}
}
line.update();
for (var j = 0; j < gainNodes.length; j++) {
var anchor = line.anchors[j * segmentsPerNode],
gain = Math.clamp(Math.abs(anchor.vel) / viewHeight * 0.5, 0, 3),
detune = Math.clamp(anchor.pos / viewHeight * 100, 0, 300);
gainNodes[j].gain.value = gain;
oscillatorNodes[j].detune.value = detune;
}
}
function draw() {
ctx.strokeStyle = lineStrokeGradient;
line.draw();
}
window.onload = function() {
initDrawingCanvas();
initWebAudio();
initGui();
requestAnimationFrame(loop);
};
function loop() {
update();
draw();
time += timeStep;
requestAnimationFrame(loop);
}
Line = function(x, y, length, segments) {
this.x = x;
this.y = y;
this.length = length;
this.segments = segments;
this.segmentLength = this.length / this.segments;
this.anchors = [];
for (var i = 0; i <= this.segments; i++) {
this.anchors[i] = {
target: this.y,
pos: this.y,
vel: 0,
update: function() {
var dy = this.pos - this.target,
acc = -lineTension * dy - lineDamping * this.vel;
this.pos += this.vel;
this.vel += acc;
},
reset: function() {
this.pos = this.target;
this.vel = 0;
}
};
}
};
Line.prototype = {
resize: function(length, targetY) {
this.length = length;
this.segmentLength = this.length / this.segments;
for (var i = 0; i <= this.segments; i++) {
this.anchors[i].target = targetY;
}
},
reset: function() {
for (var i = 0; i <= this.segments; i++) {
this.anchors[i].reset();
}
},
ripple: function(origin, amplitude) {
var i = Math.floor((origin - this.x) / this.segmentLength);
if (i >= 0 && i <= this.segments) {
this.anchors[i].vel = amplitude;
}
},
update: function() {
var lDeltas = [],
rDeltas = [],
i;
for (i = 0; i <= this.segments; i++) {
this.anchors[i].update();
}
for (i = 0; i <= this.segments; i++) {
if (i > 0) {
lDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i - 1].pos);
this.anchors[i - 1].vel += lDeltas[i];
}
if (i < this.segments) {
rDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i + 1].pos);
this.anchors[i + 1].vel += rDeltas[i];
}
}
for (i = 0; i <= this.segments; i++) {
if (i > 0) {
this.anchors[i - 1].pos += lDeltas[i];
}
if (i < this.segments) {
this.anchors[i + 1].pos += rDeltas[i];
}
}
},
draw: function() {
ctx.beginPath();
for (var i = 0; i <= this.segments; i++) {
ctx.lineTo(
this.x + this.segmentLength * i,
this.anchors[i].pos
);
}
ctx.stroke();
}
};
From the code you posted, the problem seems to be a missing
ctx.clearRect(0, 0, viewWidth, viewHeight)
at the beginning of your "draw" function.
See a working example here