Here is a link to the code pen
https://codepen.io/shahman28/pen/mdXraRE
This is a part of a larger project that I am working on. I am attempting to place circles when the mouse is clicked. As you can see in the codepen above the mouse follows well and places the circles at the correct locations, but when I try to do it in browser the cursor has an offset from the mouse and the circles are placed incorrectly. In firefox it is completely arbitrary, but in chrome it places them in the location of the cursor(which is in the incorrect location). I am recycling some code from previous projects so that is why there is the border in the html and css.
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
points = [];
class Mouse {
constructor(c) {
this.x = 0;
this.y = 0;
this.easing = 0.05;
let rect = canvas.getBoundingClientRect();
canvas.onmousemove = e => {
this.x = e.clientX - rect.left;
this.y = e.clientY - rect.top;
}
}
}
class Point {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, 5, 0, 2 * Math.PI);
ctx.stroke();
ctx.fill();
}
}
function random_hex_color_code() {
let n = (Math.random() * 0xfffff * 1000000).toString(16);
return '#' + n.slice(0, 6);
};
canvas.addEventListener('click', function(e) {
let rect = canvas.getBoundingClientRect();
x = e.clientX - rect.left
y = e.clientY - rect.top;
point = new Point(x, y, '#FF0000');
points.push(point);
})
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
mousePosition = new Mouse(canvas);
function animate() {
ctx.fillStyle = '#4A7DB9';
ctx.beginPath();
ctx.arc(mousePosition.x, mousePosition.y, 5, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
function handlePoints() {
for (let i = 0; i < points.length; i++) {
points[i].draw();
}
}
function render() {
ctx.clearRect(0, 0, w, h);
handlePoints();
animate();
window.requestAnimationFrame(render);
}
render();
body {
background: black;
}
#canvas1 {
border: 1px solid black;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 900px;
height: 600px;
background: white;
}
<!DOCTYPE html>
<html lang="en">
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]> <html class="no-js"> <!--<![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device.width, initial-scale=1.0">
<title>Tower Defense</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button onClick="start()">Start Combat</button>
<canvas id="canvas1"></canvas>
<script src="script.js"></script>
</body>
</html>
Does anyone know how to make it so that the the cursor and placed arcs are consistent?
The problem is that at one point the canvas is set to have fixed px dimensions and at another point it is set to have the dimensions of the viewport.
This snippet removes the settings in the stylesheet and just uses viewport dimensions. It seems to work fine (tested on Windows10 Edge/Chrome and Firefox).
You need to decide which setting you want and to stick with that rather than try to use both which leads to the inconsistency.
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
points = [];
class Mouse {
constructor(c) {
this.x = 0;
this.y = 0;
this.easing = 0.05;
let rect = canvas.getBoundingClientRect();
canvas.onmousemove = e => {
this.x = e.clientX - rect.left;
this.y = e.clientY - rect.top;
}
}
}
class Point {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, 5, 0, 2 * Math.PI);
ctx.stroke();
ctx.fill();
}
}
function random_hex_color_code() {
let n = (Math.random() * 0xfffff * 1000000).toString(16);
return '#' + n.slice(0, 6);
};
canvas.addEventListener('click', function(e) {
let rect = canvas.getBoundingClientRect();
x = e.clientX - rect.left
y = e.clientY - rect.top;
point = new Point(x, y, '#FF0000');
points.push(point);
})
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
mousePosition = new Mouse(canvas);
function animate() {
ctx.fillStyle = '#4A7DB9';
ctx.beginPath();
ctx.arc(mousePosition.x, mousePosition.y, 5, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
function handlePoints() {
for (let i = 0; i < points.length; i++) {
points[i].draw();
}
}
function render() {
ctx.clearRect(0, 0, w, h);
handlePoints();
animate();
window.requestAnimationFrame(render);
}
render();
body {
background: black;
}
#canvas1 {
border: 1px solid black;
position: absolute;
left 0;
top: 0;
/* removed
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 900px;
height: 600px;
*/
background: white;
}
<meta name="viewport" content="width=device.width, initial-scale=1.0">
<!--<button onClick = "start()">Start Combat</button>-->
<canvas id="canvas1"></canvas>
Related
I'm creating a canvas game and using Chrome profiler to find rendering and performance issues. But it shows lots of red block "Dropped Frame".
let canvas = document.querySelector('canvas')
let c = canvas.getContext('2d')
let dpr = window.devicePixelRatio || 1
let {width, height} = canvas.getBoundingClientRect()
canvas.width = width * dpr
canvas.height = height * dpr
c.scale(dpr, dpr)
let x = 100
let y = 100
document.body.addEventListener('mousemove', (event) => {
x = event.clientX
y = event.clientY
})
function render() {
c.fillStyle = '#9be2fe'
c.fillRect(0, 0, width, height)
c.fillStyle = '#e23521'
c.beginPath()
c.arc(x, y, 40, 0, 2 * Math.PI)
c.fill()
}
function main() {
requestAnimationFrame(main)
render()
}
main()
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
}
canvas {
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DEMO</title>
</head>
<body>
<canvas></canvas>
</body>
</html>
Even for most basic examples! What is wrong? And why are frames not the same size?
I am trying to move to translate the canvas to (100,100) but it is not moving.
And the canvas is not responsive, when I try to change the size of canvas using CSS the circles are shrinking.
How can I add a button to toggle the drawing on canvas by the circle (i.e.: when button pressed don't draw then the circle should not draw on canvas, when pressed draw it should draw)
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
ctx.translate(100,100);
canvas1.width = innerWidth;
canvas1.height = innerHeight;
const bgCan = copyCanvas(canvas1);
const redSize = 6, blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
var X = 50, Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', () => mouseButtonDown = true);
document.addEventListener('mouseup', () => mouseButtonDown = false);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width, height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx){
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI*2);
ctx.fill();
}
function direction(ctx){
const d = blueSize + redSize + 3;
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI*2);
ctx.fill();
}
function animate(){
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx);
X += Math.sin(angle) * drawSpeed;
Y += Math.cos(angle) * drawSpeed;
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
#canvas1{
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1"></canvas>
<input onclick="change()" type="button" value="Write" id="mybutton1"></input>
<script src="script.js"></script>
</body>
</html>
the translate(100, 100) gets reset by new width/height of the canvas. It just needs to be executed after width/height is set
The easiest way is to have a window resize listener and update canvas style width/height
I'm not sure why, but for some reason canvas has a higher z-index therefor button's onclick() never fired
In the code below I've added boundaries restriction, it's affected by translate(100, 100).
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
canvas1.width = innerWidth;
canvas1.height = innerHeight;
ctx.translate(100, 100);
const bgCan = copyCanvas(canvas1);
const redSize = 6,
blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
const drawButton = document.getElementById("mybutton1");
var draw = true;
var X = 50,
Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', onMouseEvent);
document.addEventListener('mouseup', onMouseEvent);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width,
height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx, mousedown) {
if (mousedown && !draw)
return;
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI * 2);
ctx.fill();
}
function direction(ctx) {
const d = blueSize + redSize + 3;
ctx.fillStyle = draw ? 'blue' : 'red';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI * 2);
ctx.fill();
}
function animate() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx, mouseButtonDown);
const x = X + Math.sin(angle) * drawSpeed,
y = Y + Math.cos(angle) * drawSpeed;
if (x > (blueSize + redSize) * 2 && x < canvas1.width - (blueSize + redSize) * 2 &&
y > (blueSize + redSize) * 2 && y < canvas1.height - (blueSize + redSize) * 2)
{
X = x;
Y = y;
}
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
function onMouseEvent(e) {
if (e.target === drawButton) {
if (e.type == "mouseup")
{
draw = !draw;
document.getElementById("mybutton1").value = draw ? "Write" : "Move";
}
return;
}
mouseButtonDown = e.type == "mousedown";
}
window.addEventListener("resize", handleResize)
function handleResize ()
{
const ratio = canvas1.width / canvas1.height;
let h = window.innerHeight,
w = h * ratio;
if (w > window.innerWidth) {
w = window.innerWidth;
h = w / ratio;
}
canvas1.style.width = w + 'px';
canvas1.style.height = h + 'px';
};
handleResize(); // First draw
#canvas1 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
z-index: -1; /* let other elements receive events */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1" scaleMode='fill'></canvas>
<input type="button" value="Write" id="mybutton1" />
<script src="script.js"></script>
</body>
</html>
So, I'm creating some drawing maker thing, but when I move the mouse it doesn't draw circles in a line. I don't know how to say it well, but I want it to draw a line from point A (last position of mouse) to point B (present position of mouse).
Start drawing here and you will understand:
const c = document.getElementById('c')
const ctx = c.getContext('2d')
c.height = window.innerHeight
c.width = window.innerWidth
function pen(e, colorHEX) {
let mouseX = e.clientX
let mouseY = e.clientY
ctx.fillStyle = colorHEX
ctx.beginPath()
ctx.arc(mouseX, mouseY, 2, 0, Math.PI * 2)
ctx.fill()
ctx.closePath()
}
$('body').mousedown(function(eObj){
$('body').mousemove(function(e) {
pen(e, '#000000')
})
})
$('body').mouseup(function(eObj) {
$('body').unbind('mousemove')
})
body {
margin: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>
I think you're trying to draw a contiguous line (you don't need to do that by painting circles). You'll need to store the last mouse position, and then draw a line from there to the current mouse position.
const c = document.getElementById('c')
const ctx = c.getContext('2d')
c.height = window.innerHeight
c.width = window.innerWidth
let lastPos // state variable
function pen(e, colorHEX) {
const pos = {x:e.clientX, y: e.clientY}
lastPos = (lastPos || pos) // Default to current pos
ctx.beginPath()
ctx.strokeStyle = colorHEX
ctx.lineWidth = 1
ctx.moveTo(lastPos.x, lastPos.y)
ctx.lineTo(pos.x, pos.y)
ctx.stroke()
ctx.closePath()
// Update the state variable
lastPos = pos
}
$('body').mousedown(function(eObj){
$('body').mousemove(function(e) {
pen(e, '#000000')
})
})
$('body').mouseup(function(eObj) {
$('body').unbind('mousemove')
lastPos = undefined
})
body {
margin: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>
You can use the lineTo method
To make it move while you are dragging the line will take an extra script that includes angles and math.
const c = document.getElementById('c')
const ctx = c.getContext('2d')
c.height = window.innerHeight
c.width = window.innerWidth
let startX;
let startY;
function pen(e, colorHEX) {
let endX = e.clientX
let endY = e.clientY
ctx.fillStyle = colorHEX
ctx.beginPath()
ctx.moveTo(startX, startY)
ctx.lineTo(endX, endY)
ctx.fill()
ctx.closePath()
ctx.stroke()
}
$('body').mousedown(function(e){
startX = e.clientX;
startY = e.clientY;
})
$('body').mouseup(function(e) {
pen(e, "#000000");
})
body {
margin: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>
Drawing with mouse
You have two options.
Draw a line segment from A to B setting the line width to match the circles diameter and the line cap to round.
Interpolate the points from A to B drawing a circle (or any shape) at points 1px apart.
I said two but there are a zillion ways to do this type of thing, but that would put this answer in the TLDR category.
Which method you use will depend on the finer details of your needs. The two example below drawing using the most basic solid line look identical.
What I think you may be having a problem with is because you are turning the event listeners on and off, the last mouse position you have is the last mouse up.
I have added two examples. One for each of the drawing options, and the top one uses an always on mouse listeners and a second turns on and of the mouse listeners as needed.
Examples
The mouse has its state put into an object called mouse.
Each time the mouse changes position the last position is put into mouse.lastX, mouse.lastY.
If the mouse event.type is mousedown the mouse.button is set to true and to false if mouseup
Mouse up and down are also used to turn on and off things like cursor, add and remove events (second example)
At the bottom of the listener it checks if the mouse is down (mouse.button is true) and draws a line from the last position to the current position.
Using line segments
Draws by using 2D API's stroke function.
Use always on mouse listeners.
const ctx = c.getContext('2d');
const BORDER = 1; // I added a 1px border to canvas.
c.height = innerHeight - BORDER * 2;
c.width = innerWidth - BORDER * 2;
const mouse = {x: 0, y: 0, lastX: 0, lastY: 0, button: false};
function drawLine(xA, yA, xB, yB, col, width) {
ctx.strokeStyle = col;
ctx.lineCap = "round";
ctx.lineWidth = width;
ctx.beginPath()
ctx.lineTo(xA, yA);
ctx.lineTo(xB, yB);
ctx.stroke();
}
function mouseEvent(e) {
if (e.type === "mousedown") {
mouse.button = true;
c.classList.add("hideMouse");
} else if (e.type === "mouseup") {
mouse.button = false;
c.classList.remove("hideMouse");
}
mouse.lastX = mouse.x;
mouse.lastY = mouse.y;
mouse.x = e.clientX - BORDER;
mouse.y = e.clientY - BORDER;
if (mouse.button) {
drawLine(mouse.lastX, mouse.lastY, mouse.x, mouse.y, "#000", 4);
}
}
addEventListener("mousedown", mouseEvent);
addEventListener("mouseup", mouseEvent);
addEventListener("mousemove", mouseEvent);
body {
margin: 0;
overflow: hidden;
font-family: arial;
}
canvas {
border: 1px solid black;
cursor: crosshair;
}
.hideMouse {
cursor: none;
}
div {
background: #FFF8;
position: absolute;
top: 4px;
left: 4px;
}
<canvas id="c"></canvas>
<div>Click and drag mouse to draw</div>
Interpolate line
Replaces drawLine function body with interpolation algorithum.
Adds mouse listeners mousemove and mouseup, on mousedown. Note that the up listener has the option {once:true} when added so does not need to be manually removed.
const ctx = c.getContext('2d');
const BORDER = 1; // I added a 1px border to canvas.
c.height = innerHeight - BORDER * 2;
c.width = innerWidth - BORDER * 2;
const mouse = {x: 0, y: 0, lastX: 0, lastY: 0, button: false};
function drawLine(xA, yA, xB, yB, col, width) {
var i = 0;
const dx = xB - xA;
const dy = yB - yA;
const length = Math.hypot(dx, dy);
const stepX = length > 0 ? dx / length : 0;
const stepY = length > 0 ? dy / length : 0;
ctx.beginPath();
ctx.fillStyle = col;
while (i <= length) {
ctx.moveTo(xA + width / 2, yA);
ctx.arc(xA, yA, width / 2, 0, Math.PI * 2);
xA += stepX;
yA += stepY;
i ++;
}
ctx.fill();
}
function mouseEvent(e) {
if (e.type === "mousedown") {
mouse.button = true;
c.classList.add("hideMouse");
addEventListener("mouseup", mouseEvent, {once: true});
addEventListener("mousemove", mouseEvent);
// Set mouse pos so last pos is not where the last mouse up was
mouse.x = e.clientX - BORDER;
mouse.y = e.clientY - BORDER;
} else if (e.type === "mouseup") {
mouse.button = false;
c.classList.remove("hideMouse");
removeEventListener("mousemove", mouseEvent);
}
mouse.lastX = mouse.x;
mouse.lastY = mouse.y;
mouse.x = e.clientX - BORDER;
mouse.y = e.clientY - BORDER;
if (mouse.button) {
drawLine(mouse.lastX, mouse.lastY, mouse.x, mouse.y, "#000", 4);
}
}
addEventListener("mousedown", mouseEvent);
body {
margin: 0;
overflow: hidden;
font-family: arial;
}
canvas {
border: 1px solid black;
cursor: crosshair;
}
.hideMouse {
cursor: none;
}
div {
background: #FFF8;
position: absolute;
top: 4px;
left: 4px;
}
<canvas id="c"></canvas>
<div>Click and drag mouse to draw</div>
Side note...
jQuery is dead
BTW jQuery is not needed, it became irrelevant about 5 years ago.
Using it puts you many years behind modern front end development.
In the past 5 years the demand for jQuery experience coders has dropped a significant amount. A trend that will continue as jQuery has painted its self into a corner from which the only way out is via re branding and re targeting its purpose.
Every time you use jQuery you are investing your most valuable asset, time. Time spent learning and gaining experience. Be wise and direct that time learning what is applicable and growing in the future, and not into what started dying over a decade ago.
For more details Should you use or learn jQuery in 2020?
I'm trying to move two circles separately, but I can't seem to make the two circles move despite searching over w3school or youtube, I know how to move one circle but when I try to move two circle by creating a constructor it fails.
I'm sure this is a dumb question but I just can't help but ask.
let canvas = document.querySelector("#canvas");
let ctx = canvas.getContext("2d");
let ball = new drawCircle(50, 50, 20);
let ballTwo = new drawCircle(100, 100, 20);
function drawCircle(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
this.draw = function() {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI *2);
ctx.fillStyle = "lightskyblue";
ctx.fill();
}
}
function draw() {
ball.x += 1;
ball.draw();
ballTwo.x += 1;
ballTwo.draw();
if (x + r > canvas.width || x < r) {
dx = -dx;
}
if (y + r > canvas.width || y < r) {
dy = -dy;
}
requestAnimationFrame(draw)
}
draw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CĂrculo</title>
<style>
body {
margin: 0;
display: flex;
justify-content: center;
}
#canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="300" height="300"></canvas>
</body>
<script src="/js/canvasTwo.js"></script>
</html>
I am trying to develop a game and i am starting to dip my toes into the HTML <canvas> tag and using it with javascript. My program here is my work in progress clone of PONG. I have managed to add the two paddles with no error but as i have added the Ball function it simply refuses to draw anything on the screen and thus i am given a page covered in black.
Could it be because i am using classes?
Here is the code:
// ctx.fillStyle = 'rgba(red, green, blue, alpha)';
// ctx.fillRect(x, y, width, height);
var canvas;
var ctx;
var dx = 5;
var dy = 5;
//Class Definitions
function Game(width, height, colour) {
this.width = width;
this.height = height;
this.colour = colour;
}
function Player(width, height, colour, x, y, up, down) {
this.width = width;
this.height = height;
this.colour = colour;
this.x = x;
this.y = y;
this.up = up;
this.down = down;
this.move = function(ny) {
this.y = this.y + ny;
ctx.fillStyle = this.colour;
ctx.fillRect(this.x, this.y, this.width, this.height);
};
}
function Ball(width, height, colour, x , y, isTouched, isInGoal) {
this.width = width;
this.height = height;
this.colour = colour;
this.x = x;
this.y = y;
this.isTouched = isTouched;
this.isInGoal = isInGoal;
this.move = function() {
clear();
this.x = this.x + 1;
ctx.fillStyle = this.colour;
ctx.fillRect(this.x, this.y, this.width, this.height);
};
}
//Creating new Classes
var gameStage = new Game((window.innerWidth), (window.innerHeight), 'rgb(0,0,0)');
var paddleOne = new Player(10, 150, 'rgb(255,255,255)', (gameStage.width/10), (gameStage.height/2), 38, 40);
var paddleTwo = new Player(10, 150, 'rgb(255,255,255)', (gameStage.width/1.1), (gameStage.height/2), 87, 83);
var ball = new Ball(20, 20, 'rgb(255,255,255)', (gameStage.width/2), (gameStage.height/2), 0, 0);
//Initialisation
function init(){
canvas = document.getElementById('game');
canvas.setAttribute('width', gameStage.width);
canvas.setAttribute('height', gameStage.height);
canvas.setAttribute('tabindex', 0);
if (game.getContext){
ctx = canvas.getContext('2d');
return setInterval(ball.move, 10);
return setInterval(draw, 10);
}
}
//Canvas Functions
function clear(){
ctx.clearRect(0, 0, gameStage.width, gameStage.height);
}
function draw() {
clear();
ctx.fillStyle = gameStage.colour;
ctx.fillRect(0, 0, gameStage.width, gameStage.height);
ctx.fillStyle = paddleOne.colour;
ctx.fillRect(paddleOne.x, paddleOne.y, paddleOne.width, paddleOne.height);
ctx.fillStyle = paddleTwo.colour;
ctx.fillRect(paddleTwo.x, paddleTwo.y, paddleTwo.width, paddleTwo.height);
console.log("PlayerOne Y Coordinate: " + paddleOne.y + "\n");
console.log("PlayerTwo Y Coordinate: " + paddleTwo.y + "\n");
}
//Player Control
function doKeyDown(e) {
if (e.keyCode == paddleOne.up){
paddleOne.move(-5);
} else if (e.keyCode == paddleOne.down) {
paddleOne.move(5);
} else if (e.keyCode == paddleTwo.up) {
paddleTwo.move(-5);
} else if (e.keyCode == paddleTwo.down) {
paddleTwo.move(5);
}
}
//For HTML
function beginStuff(){
init();
window.addEventListener('keydown', doKeyDown, true);
}
* { margin: 0; padding: 0;}
body, html {height: 100%;}
#game {
position: absolute;
width:100%;
height:100%;
background-color: #000000;
}
<!DOCTYPE HTML>
<htmL>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>A game</title>
<script type="text/javascript" src="game.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body onload="beginStuff();" >
<canvas id="game">
Please upgrade your browser to support HTML5. <br/>
</canvas>
</body>
</htmL>
This looks wrong to me:
return setInterval(ball.move, 10);
return setInterval(draw, 10);
Firstly, you've got 2 returns. Secondly, you've lost the binding on the move method:
return setInterval(ball.move.bind(ball), 10);
If that doesn't fix it I suggest stepping through in a debugger, line-by-line, making sure that everything is doing exactly what you expect it to.
With help from #skirtle, i moved the ball.move(); to the draw() function and removed the clear() call from the ball.move() function.