I want to move a object on a slanting line. I have given my code. In my code in my 3rd div as I move the slider I am drawing a slanting line on this line I want to move an object. Similar thing I am doing in my 1st div. Where I am moving an object on curve. I am looking for some function in which I will provide the points and the object will follow the points. Here is my code. This code works only in chrome as I am trying to make this only for safari and chrome browsers.
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
.wrapper {
margin: 0 auto;
width: 1000px;
}
.canHdr {
float: left;
width: 450px;
height: 400px;
border: 1px solid red;
}
</style>
</head>
<body>
<form>
<!-- wrapper -->
<div class="wrapper">
<!-- canHdr -->
<div id="canHdr" class="canHdr" >
<p>
This is my 1st div with bezier curve the curve is getting drawn as slider moves and also a ball in moving on that .
</p>
<div class="canOuterHdr" >
<canvas id="myCanvas1" width="300" height="195" style="position: relative;">
[No canvas support]
</canvas>
</div>
<div id="slider1" class="newBg">
<input id="slide1" type="range" min="0" max="100" step="1" value="0" onchange="counterSlider('slide1');" />
</div>
</div>
<!--/ canHdr -->
<!-- canHdr2 -->
<div id="canHdr2" class="canHdr" >
<p>
This is my 2nd div
</p>
<div class="canOuterHdr" >
<canvas id="myCanvas2" width="300" height="195" style="position: relative;">
[No canvas support]
</canvas>
</div>
<div id="slider2" class="newBg">
<input id="slide2" type="range" min="0" max="100" step="1" value="0" onchange="counterSlider('slide2');" />
</div>
</div>
<!-- canHdr2 -->
<!-- canHdr3 -->
<div id="canHdr3" class="canHdr" >
<p>
This is my 3rd div with slanting line. I want to move a ball on this line when I move the slider. So as the line increases ball will also move on the line.
</p>
<div class="canOuterHdr" >
<canvas id="myCanvas3" width="300" height="195" style="position: relative;">
[No canvas support]
</canvas>
</div>
<div id="slider3" class="newBg">
<input id="slide3" type="range" min="0" max="100" step="1" value="0" onchange=" drawSlopeCurve2('slide3','100'); " />
</div>
</div>
<!--/ canHdr3 -->
<!-- canHdr4 -->
<div id="canHdr4" class="canHdr" >
<p>
This is my 4th div with slanting line. I want to move a ball on this line when I move the slider. So as the line increases ball will also move on the line.
</p>
<div class="canOuterHdr" >
<canvas id="myCanvas4" width="300" height="195" style="position: relative;">
[No canvas support]
</canvas>
</div>
<div id="slider4" class="newBg">
<input id="slide4" type="range" min="0" max="100" step="1" value="0" onchange=" drawSlopeCurve1('slide4','100'); " />
</div>
</div>
<!--/ canHdr4 -->
</div>
<!-- /wrapper -->
<script type="text/javascript">
function counterSlider(sID) {
var slideVal = document.getElementById(sID).value;
/*if (maxValue ==100){
slideVal=slideVal/100;
}*/
slideVal = slideVal / 100;
var position = slideVal;
var startPt = {
x : 18.8,
y : 45
};
var controlPt = {
x : 28,
y : 160
};
var endPt = {
x : 228,
y : 165
};
var startPt2 = {
x : 20,
y : 75
};
var controlPt2 = {
x : 28,
y : 160
};
var endPt2 = {
x : 228,
y : 165
};
if (slideVal == 0) {
erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');
//newSprite('myCanvas1b', 18.8, 45);
drawBezier2('myCanvas1', new Array({
x : 18.8,
y : 45
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
drawBezier2('myCanvas2', new Array({
x : 20,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
} else if (slideVal > 0 && slideVal <= 34) {
erase('myCanvas1');
//erase('myCanvas1b');
erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');
drawBezier2('myCanvas1', new Array({
x : 18.8,
y : 45
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
drawBezier2('myCanvas2', new Array({
x : 20,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
drawNextPoint('myCanvas1', startPt, controlPt, endPt, position);
drawNextPoint('myCanvas2', startPt2, controlPt2, endPt2, position);
} else if (slideVal > 34 && slideVal <= 67) {
erase('myCanvas1');
erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');
drawBezier2('myCanvas1', new Array({
x : 18.8,
y : 45
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
drawBezier2('myCanvas2', new Array({
x : 20,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
drawNextPoint('myCanvas1', startPt, controlPt, endPt, position);
drawNextPoint('myCanvas2', startPt2, controlPt2, endPt2, position);
} else if (slideVal > 67 && slideVal <= 100) {
erase('myCanvas1');
erase('myCanvas2');
erase('myCanvas3');
erase('myCanvas4');
drawBezier2('myCanvas1', new Array({
x : 18.8,
y : 45
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
drawBezier2('myCanvas2', new Array({
x : 20,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
drawNextPoint('myCanvas1', startPt, controlPt, endPt, position);
drawNextPoint('myCanvas2', startPt2, controlPt2, endPt2, position);
}
}
function erase(canvasId) {
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.beginPath();
context.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = canvas.width;
}
/**********for backgroundImage********************/
function _getQBezierValue(t, p1, p2, p3) {
var iT = 1 - t;
return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;
}
function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {
return {
x : _getQBezierValue(position, startX, cpX, endX),
y : _getQBezierValue(position, startY, cpY, endY)
};
}
function drawNextPoint(canId, startPt, controlPt, endPt, position) {
var pt = getQuadraticCurvePoint(startPt.x, startPt.y, controlPt.x, controlPt.y, endPt.x, endPt.y, position);
position = (position + 0.006) % 1.0;
var canvas = document.getElementById(canId);
var ctx = canvas.getContext('2d');
//ctx.globalCompositeOperation = 'source-atop';
//ctx.globalCompositeOperation = "destination-over";
ctx.beginPath();
ctx.fillStyle = "#0077c1";
ctx.arc(pt.x, pt.y, 6, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}
function newSprite(canId, mvx, mvy) {
var canvas = document.getElementById(canId);
var ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = 'source-atop';
//ctx.globalCompositeOperation = "destination-over";
ctx.beginPath();
ctx.fillStyle = "#0077c1";
ctx.arc(mvx, mvy, 6, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}
function drawBezier2(canId, points, slideVal) {
var canvas = document.getElementById(canId);
var context = canvas.getContext("2d");
//context.globalCompositeOperation = 'source-atop';
//context.strokeStyle = "rgb(113, 113, 213)";
context.strokeStyle = "#000";
context.lineWidth = 0.6;
context.beginPath();
// Label end points
//context.fillStyle = "rgb(0, 0, 0)";
// Draw spline segemnts
context.moveTo(points[0].x, points[0].y);
for (var t = 0; t <= slideVal; t += 0.1) {
context.lineTo(Math.pow(1 - t, 2) * points[0].x + 2 * (1 - t) * t * points[1].x + Math.pow(t, 2) * points[2].x, Math.pow(1 - t, 2) * points[0].y + 2 * (1 - t) * t * points[1].y + Math.pow(t, 2) * points[2].y);
}
// Stroke path
context.stroke();
}
function drawSlopeCurve1(sID, maxValue) {
// erase('canvasTwo');
var canId = 'myCanvas4';
var slideVal = parseInt(document.getElementById(sID).value);
var canvas = document.getElementById(canId);
var context = canvas.getContext('2d');
canvas.width = canvas.width;
//line end points
x1 = 16;
y1 = 170;
x2 = 200;
y2 = 80;
//get slope (rise over run)
var m = (y2 - y1) / (x2 - x1);
//get y-intercept
var b = y1 - (m * x1);
//get distance between the two points
var distance = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
//get new x and y values
var x = x1 + parseInt(distance / maxValue * slideVal);
var y = parseInt(m * x + b);
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x, y);
context.lineWidth = 0.6;
context.stroke();
}
function drawSlopeCurve2(sID, maxValue) {
// erase('canvasTwo');
var canId = 'myCanvas3';
var slideVal = parseInt(document.getElementById(sID).value);
var canvas = document.getElementById(canId);
var context = canvas.getContext('2d');
canvas.width = canvas.width;
//line end points
x1 = 16;
y1 = 170;
x2 = 160;
y2 = 72;
//get slope (rise over run)
var m = (y2 - y1) / (x2 - x1);
//get y-intercept
var b = y1 - (m * x1);
//get distance between the two points
var distance = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
//get new x and y values
var x = x1 + parseInt(distance / maxValue * slideVal);
var y = parseInt(m * x + b);
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x, y);
context.lineWidth = 0.6;
context.stroke();
}
</script>
</form>
</body>
</html>
Thanks in Advance. my jsfiddle link: http://jsfiddle.net/g7hWD/1/
You need to add the drawing code at the very end of functions drawSlopeCurve1() and drawSlopeCurve2(). The simplest way is to fix function newSprite() first and then use it (to avoid copying identical code-blocks over and over).
In function newSprite():
// Change that:
ctx.globalCompositeOperation = 'source-atop';
// To this:
ctx.globalCompositeOperation = "source-over";
(For more details on globalCompositeOperation see here.)
At the end of functions drawSlopeCurve1/2():
// Append this:
newSprite(canId, x, y);
See, also, this modified demo.
Related
I need to draw a dashed polygon using corner coordinates of the polygon. For this I will be iterating over the corners and keep drawing dashed line between the two corners(corner[i] and corner[i+1]) in all iterations. I found some code over the net to do so so I am currently doing this:
offSetCorners.forEach((point, i) => {
let endPoint = i < offSetCorners.length - 1 ? offSetCorners[i + 1] : offSetCorners[0];
zoneGraphic.drawDash(point.x, point.y, endPoint.x, endPoint.y);
});
drawDash(x1: number, y1: number, x2: number, y2: number, dashLength = 5, spaceLength = 5) {
let x = x2 - x1;
let y = y2 - y1;
let hyp = Math.sqrt(x * x + y * y);
let units = hyp / (dashLength + spaceLength);
let dashSpaceRatio = dashLength / (dashLength + spaceLength);
let dashX = (x / units) * dashSpaceRatio;
let spaceX = x / units - dashX;
let dashY = (y / units) * dashSpaceRatio;
let spaceY = y / units - dashY;
zoneGraphic.moveTo(x1, y1);
while (hyp > 0) {
x1 += dashX;
y1 += dashY;
hyp -= dashLength;
if (hyp < 0) {
x1 = x2;
y1 = y2;
}
zoneGraphic.lineTo(x1, y1);
x1 += spaceX;
y1 += spaceY;
zoneGraphic.moveTo(x1, y1);
hyp -= spaceLength;
}
zoneGraphic.moveTo(x2, y2);
}
But this draws the dashed line like this
What I want is
You can do that with setLineDash:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash
Here is a code sample:
var ctx = document.getElementById("c").getContext("2d");
ctx.font = "60px Arial";
ctx.setLineDash([5, 5]);
ctx.strokeText("ABC", 50, 60);
ctx.rect(5, 5, 190, 90);
ctx.lineTo(40,80);
ctx.stroke();
<canvas id="c" width=200 height=100></canvas>
That is just pure JS no Pixi involved, I imagine the same is available in that library, if not you should be able to do it directly with JS on the canvas
Try "PixiJS Smooth Graphics" package - for example like described here: https://github.com/pixijs/pixijs/issues/7897#issuecomment-948493891
I want to move a character along a specific path. How can I achieve this?
Example visualization
It is necessary for the hero to get to a point on the map, but stop at each point and, when you press the button "to the university", continues on his way. That is, when the button was pressed, it made a move.
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const hero = new Image();
hero.src = '../img/hero.png';
let x = 430;
let y = 425;
hero.onload = function() {
ctx.drawImage(hero,x,y,31,86)
}
const go = document.querySelector('.go_university');
let tur = 0;
let timer;
let direction = 0;
go.addEventListener('click',()=>{
tur += 1;
turn();
})
function turn(){
ctx.clearRect(0,0,960,630);
direction+=1;
if(direction<=15){
x-=2;
y=(y-2/3);
}else if(direction >= 15 && direction <= 28){
x-=2;
y=(y-2);
}else if(direction >=28 && direction <=48){
x-=2;
y=(y+3/6);
}else if(direction >= 48 && direction <=70){
x-=2;
y=(y+3/6);
}
timer = setTimeout(turn,60);
ctx.drawImage(hero,x,y,31,86)
}
This is the code I wrote. I can't figure it out any further. How can I restore animation on click? And in general, am I doing the calculations correctly?
I wrote a blog post on this a while back while the JS isn't the newest the concepts are all the same. I assume you have a collection of waypoints you want to move your character towards which I define in this code under targets.
The main thing really is the pointing at a target and moving towards it
Ball.prototype.update = function () {
// get the target x and y
this.targetX = targets[this.target].x;
this.targetY = targets[this.target].y;
// We need to get the distance this time around
var tx = this.targetX - this.x,
ty = this.targetY - this.y,
dist = Math.sqrt(tx * tx + ty * ty);
/*
* we calculate a velocity for our object
* divide the target x and y by the distance and multiply it by our speed
* this gives us a constant movement speed.
*/
this.velX = (tx / dist) * this.speed;
this.velY = (ty / dist) * this.speed;
/*
* Get the direction we are facing
* I just use -tx and -ty here because we already calculated tx and ty
* To get the proper x and y you need to subtract the targets x and y from
* our objects x and y
*/
var radians = Math.atan2(-ty,-tx);
this.px = this.x - this.pointLength * Math.cos(radians);
this.py = this.y - this.pointLength * Math.sin(radians);
// Once we hit our target move on to the next.
if (dist > this.radius/2) {
// add our velocities
this.x += this.velX;
this.y += this.velY;
}else{
this.target++;
if(this.target == targets.length){
this.target = 0;
}
}
};
If you want to pause and wait for a click you would do that when the player reaches the target instead of automatically selecting the next target you'd do it onclick.
Full snippet included below.
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 500,
height = 600,
balls = [],
targets = [
{x : 450, y : 20},
{x : 450, y : 150},
{x : 20, y : 150},
{x : 20, y : 250},
{x : 450, y : 250},
{x : 450, y : 350},
{x : 20, y : 350},
{x : 20, y : 450},
{x : 450, y : 450},
{x : 450, y : 550},
{x : 20, y : 550},
{x : 20, y : 20}
],
started = false;
canvas.width = width;
canvas.height = height;
canvas.addEventListener("mouseenter", function (e) {
if(!started){
started = true;
render();
}
});
canvas.addEventListener("mouseleave", function (e) {
started = false;
});
var Ball = function (x, y, radius, color) {
this.x = x || 0;
this.y = y || 0;
this.radius = radius || 10;
this.speed = 3;
this.color = color || "rgb(255,0,0)";
this.pointLength = 20;
this.px = 0;
this.py = 0;
this.target = 0;
this.targetX = 0;
this.targetY = 0;
this.velX = 0;
this.velY = 0;
}
Ball.prototype.update = function () {
// get the target x and y
this.targetX = targets[this.target].x;
this.targetY = targets[this.target].y;
// We need to get the distance this time around
var tx = this.targetX - this.x,
ty = this.targetY - this.y,
dist = Math.sqrt(tx * tx + ty * ty);
/*
* we calculate a velocity for our object this time around
* divide the target x and y by the distance and multiply it by our speed
* this gives us a constant movement speed.
*/
this.velX = (tx / dist) * this.speed;
this.velY = (ty / dist) * this.speed;
/*
* Get the direction we are facing
* I just use -tx and -ty here because we already calculated tx and ty
* To get the proper x and y you need to subtract the targets x and y from
* our objects x and y
*/
var radians = Math.atan2(-ty,-tx);
this.px = this.x - this.pointLength * Math.cos(radians);
this.py = this.y - this.pointLength * Math.sin(radians);
// Once we hit our target move on to the next.
if (dist > this.radius/2) {
// add our velocities
this.x += this.velX;
this.y += this.velY;
}else{
this.target++;
if(this.target == targets.length){
this.target = 0;
}
}
};
Ball.prototype.render = function () {
ctx.fillStyle = this.color;
ctx.beginPath();
// draw our circle with x and y being the center
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.strokeStyle = "rgb(0,0,255)";
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.px, this.py);
ctx.closePath();
ctx.stroke();
};
for(var i = 0; i < 20; i++){
balls.push(new Ball(20 - i * 30, 20, 10));
}
function render() {
ctx.clearRect(0, 0, width, height);
balls.forEach(function(el){
el.update();
el.render();
});
if(started){
requestAnimationFrame(render);
}
}
render();
canvas {
border:1px solid black;
}
<canvas id="canvas"></canvas>
I'm trying to make a rectangle follow the angle between it and the mouse. Basically if the angle between the mouse and the current angle of the rectangle is higher than the current angle of the rectangle, it adds 1 and will continue until condition is false. The opposite happens when the angle between the two is lower than the current angle of the rectangle. My problem here is the angle between the mouse and rectangle, after 180 degrees it goes becomes -180. This causes the rectangle to go around again instead of going to 181 degrees. I've tried figuring out a way around this but I somehow always ended up in the same problem.
Thanks in advance, here is my code:
<body>
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
</body>
<script>
var canvas = document.getElementById("ctx"),
ctx = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
mouse,
angle = 0;
function test() {
"use strict";
var dX = mouse.X - 200,
dY = mouse.Y - 200,
rad = (Math.atan2(dY, dX)),
deg = (rad * (180 / Math.PI)),
player = {
x : 200,
y : 200,
width : 40,
height : 10,
angle : 0,
dAngle : 0
};
//Test
if (deg > angle) {
angle += 1;
} else if (deg) {
angle -= 1;
}
ctx.clearRect(0, 0, width, height);
ctx.translate(player.x, player.y);
ctx.rotate((angle * Math.PI / 180));
ctx.fillRect(0, -player.height / 2, player.width, player.height);
//console.log("deg :" + deg + "angle : " + angle);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
window.onmousemove = function (mm) {
"use strict";
mouse = {
X : mm.clientX - document.getElementById('ctx').getBoundingClientRect().left,
Y : mm.clientY - document.getElementById('ctx').getBoundingClientRect().top
};
};
setInterval(test, 40);
</script>
The Math.atan2() method returns a numeric value between -π and π representing the angle theta of an (x, y) point as mentioned in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
So you need just a convert value from [-180;180] to [0;360]. You can do it, let say, in this manner degrees = (degrees + 360) % 360;
<body>
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
</body>
<script>
var canvas = document.getElementById("ctx"),
ctx = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
//Initialize with dummy values
mouse={X:0,Y:0},
angle = 0;
function test() {
"use strict";
var dX = mouse.X - 200,
dY = mouse.Y - 200,
rad = (Math.atan2(dY, dX)),
deg = (rad * (180 / Math.PI)),
player = {
x : 200,
y : 200,
width : 40,
height : 10,
angle : 0,
dAngle : 0
};
//Test
if (deg > angle) {
angle += 1;
} else if (deg) {
angle -= 1;
}
ctx.clearRect(0, 0, width, height);
ctx.translate(player.x, player.y);
ctx.rotate((angle * Math.PI / 180));
ctx.fillRect(0, -player.height / 2, player.width, player.height);
//console.log("deg :" + deg + "angle : " + angle);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
window.onmousemove = function (mm) {
"use strict";
mouse = {
X : mm.clientX - document.getElementById('ctx').getBoundingClientRect().left,
Y : mm.clientY - document.getElementById('ctx').getBoundingClientRect().top
};
};
setInterval(test, 40);
</script>
you can notice that angle flip flops within 1.0 of deg by printing (deg-angle). Just make it stop if it's in that range. (and dont use plain > or == when dealing with floats)
Of course there's nothing special about 1.0, here I replaced it with spd:
<body>
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
</body>
<script>
var canvas = document.getElementById("ctx"),
ctx = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
mouse = {X:0.0, Y:0.0},
angle = 0;
function test() {
"use strict";
var dX = mouse.X - 200,
dY = mouse.Y - 200,
rad = (Math.atan2(dY, dX)),
deg = (rad * (180 / Math.PI)),
player = {
x : 200,
y : 200,
width : 40,
height : 10,
angle : 0,
dAngle : 0
};
//Test
var spd = 5.0;
if (Math.abs(deg - angle) - spd > 0.0000001)
angle += Math.sign(deg - angle)*spd;
ctx.clearRect(0, 0, width, height);
ctx.translate(player.x, player.y);
ctx.rotate((angle * Math.PI / 180));
ctx.fillRect(0, -player.height / 2, player.width, player.height);
//console.log("deg :" + deg + "angle : " + angle);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
window.onmousemove = function (mm) {
"use strict";
mouse = {
X : mm.clientX - document.getElementById('ctx').getBoundingClientRect().left,
Y : mm.clientY - document.getElementById('ctx').getBoundingClientRect().top
};
};
setInterval(test, 40);
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Pong Game by Zach</title>
<style>
canvas {
display: block;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<script>
function playGame(form) {
var canvas;
var ctx;
var keystate;
var canvasWidth = form.cWidth.value;
var canvasHeight = form.cHeight.value;
var ballSpeed = form.bSpeed.value;
var playerSpeed = form.pSpeed.value;
var playerWidth = form.pWidth.value;
var playerHeight = form.pHeight.value;
var movePlayer1Up = form.movePlayer1Up.value.charCodeAt(0) - 32;
var movePlayer1Down = form.movePlayer1Down.value.charCodeAt(0) - 32;
if (form.movePlayer2Up.value == "UpArrow") {
var movePlayer2Up = 38;
} else {
var movePlayer2Up = form.movePlayer2Up.value.charCodeAt(0) - 32;
}
if (form.movePlayer2Down.value == "DownArrow") {
var movePlayer2Down = 40;
} else {
var movePlayer2Down = form.movePlayer2Down.value.charCodeAt(0) - 32;
}
var player1 = {
x: null,
y: null,
score: null,
width: playerWidth,
height: playerHeight,
update: function() {
if (keystate[movePlayer1Up]) this.y -= playerSpeed;
if (keystate[movePlayer1Down]) this.y -= -playerSpeed;
this.y = Math.max(Math.min(this.y, canvasHeight - this.height), 0);
},
draw: function() {
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
var player2 = {
x: null,
y: null,
score: null,
width: playerWidth,
height: playerHeight,
update: function() {
if (keystate[movePlayer2Up]) this.y -= 7;
if (keystate[movePlayer2Down]) this.y += 7;
this.y = Math.max(Math.min(this.y, canvasHeight - this.height), 0);
},
draw: function() {
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
var ball = {
x: null,
y: null,
vel: null,
side: 20,
serve: function(side) {
var r = Math.random();
this.x = canvasWidth / 2;
this.y = (canvasHeight - this.side) * r;
var phi = 0.1 * Math.PI * (1 - 2 * r);
this.vel = {
x: side * ballSpeed * Math.cos(phi),
y: ballSpeed * Math.sin(phi)
}
},
update: function() {
this.x += this.vel.x;
this.y += this.vel.y;
if (0 > this.y || this.y + this.side > canvasHeight) {
var offset = this.vel.y < 0 ? 0 - this.y : canvasHeight - (this.y + this.side);
this.y += 2 * offset;
this.vel.y *= -1;
}
var AABBIntersect = function(ax, ay, aw, ah, bx, by, bw, bh) {
return ax < bx + bw && ay < by + bh && bx < ax + aw && by < ay + ah;
};
var pdle = this.vel.x < 0 ? player1 : player2;
if (AABBIntersect(pdle.x, pdle.y, pdle.width, pdle.height,
this.x, this.y, this.side, this.side)) {
this.x = pdle === player1 ? player1.x + player1.width : player2.x - this.side;
var n = (this.y + this.side - pdle.y) / (pdle.height + this.side);
var phi = 0.25 * Math.PI * (2 * n - 1);
var smash = Math.abs(phi) > 0.2 * Math.PI ? 1.5 : 1;
this.vel.x = smash * (pdle === player1 ? 1 : -1) * ballSpeed * Math.cos(phi);
this.vel.y = smash * ballSpeed * Math.sin(phi);
}
if (0 > this.x + this.side || this.x > canvasWidth) {
ballSpeed = 12;
var isplayer1 = pdle === player1;
player1.score += isplayer1 ? 0 : 1;
player2.score += isplayer1 ? 1 : 0;
this.serve(pdle === player1 ? 1 : -1);
}
},
draw: function() {
ctx.fillRect(this.x, this.y, this.side, this.side);
}
};
function mplayer2n() {
canvas = document.createElement("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
keystate = {};
document.addEventListener("keydown", function(evt) {
keystate[evt.keyCode] = true;
});
document.addEventListener("keyup", function(evt) {
delete keystate[evt.keyCode];
});
init();
var loop = function() {
update();
draw();
window.requestAnimationFrame(loop, canvas);
};
window.requestAnimationFrame(loop, canvas);
}
function init() {
player1.x = player1.width;
player1.y = (canvasHeight - player1.height) / 2;
player2.x = canvasWidth - (player1.width + player2.width);
player2.y = (canvasHeight - player2.height) / 2;
player1.score = 0;
player2.score = 0;
ball.serve(1);
}
function update() {
if (player1.score < 10 && player2.score < 10) {
ball.update();
player1.update();
player2.update();
}
}
function draw() {
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.save();
ctx.fillStyle = "red";
player1.draw();
ctx.fillStyle = "blue";
player2.draw();
ctx.fillStyle = "white";
ball.draw();
var w = 4;
var x = (canvasWidth - w) * 0.5;
var y = 0;
var step = canvasHeight / 20;
while (y < canvasHeight) {
ctx.fillStyle = "white"
ctx.fillRect(x, y + step * 0.25, w, step * 0.5);
y += step;
}
ctx.font = "150px Georgia"
var t = player1.score
var v = player2.score
ctx.fillText(t, canvas.width / 2 - ctx.measureText(t).width - 20, 100);
ctx.fillText(v, canvas.width / 2 + 20, 100)
if (player1.score > 9) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = "Black"
ctx.font = "100px Georgia"
var u = t + " - " + v
var w = "Player 1 wins"
ctx.fillText(w, canvas.width / 2 - ctx.measureText(w).width / 2, 130);
ctx.font = "150px Georgia"
ctx.fillText(u, canvas.width / 2 - ctx.measureText(u).width / 2, 300);
} else if (player2.score > 9) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = "Black"
ctx.font = "100px Georgia"
var u = t + " - " + v
var w = "Player 2 wins"
ctx.fillText(w, canvas.width / 2 - ctx.measureText(w).width / 2, 130);
ctx.font = "150px Georgia"
ctx.fillText(u, canvas.width / 2 - ctx.measureText(u).width / 2, 300);
}
ctx.restore();
}
mplayer2n();
}
</script>
<form action="">
Settings:
<br>Canvas Width:
<br>
<input type="text" name="cWidth" value="1200">
<br>Canvas Height:
<br>
<input type="text" name="cHeight" value="600">
<br>Ball Speed:
<br>
<input type="text" name="bSpeed" value="12">
<br>Player Speed:
<br>
<input type="text" name="pSpeed" value="8">
<br>Player Width:
<br>
<input type="text" name="pWidth" value="20">
<br>Player Height:
<br>
<input type="text" name="pHeight" value="100">
<br>Move Player 1 Up:
<br>
<input type="text" name="movePlayer1Up" value="w">
<br>Move Player 1 Down:
<br>
<input type="text" name="movePlayer1Down" value="s">
<br>Move Player 2 Up:
<br>
<input type="text" name="movePlayer2Up" value="UpArrow">
<br>Move Player 2 Down:
<br>
<input type="text" name="movePlayer2Down" value="DownArrow">
<br>Save Settings and start game:
<br>
<input type="button" name="Start" value="Start" onClick="playGame(this.form)">
<br>
</form>
</body>
</html>
Above is the code that I have so far.
The part in question is the bottom part with the form and the part near the top where I am defining the variables for the settings.
I was making a pong game and it was working as expected until I tried to add a <form> so the player could customise the settings and controls.
I then set the variables I had used before to the values from this form. The problem was that when I when I added in the "player width" and "player height" variables. The game glitched out. Eg. The ball would bounce early, a paddle was missing etc.
Any ideas why this would occur when the data entered into the form was the same as the constants I had had before which worked perfectly fine.
You are reading the player width and player height in as text. You need to convert to integers. Do the same for player2.
var player1 = {
x: null,
y: null,
score: null,
width: parseInt(playerWidth),
height: parseInt(playerHeight),
As I move my slider I am drawing an arc. I have made it dynamic. If I change the points of arc then the line drawn will also change. Same thing I want to do with a line. If I move my slider the line should get drawn. Also I want to make it dynamic means If i change the line points the line should also change.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH5EX10: Moving In A Simple Geometric Spiral </title>
<style>
.wrapper {
margin: 0 auto;
width: 1000px;
}
.uppleft {
float: left;
width: 1000px;
position: relative;
margin: 0 0 500px 10px;
}
.dnleft {
float: left;
width: 1000px;
}
.clear {
clear: both;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="uppleft">
<canvas id="canvasOne" width="300" height="300"width="500" height="500" style="position:absolute; left:5px; top:10px; border:1px solid red;">
Your browser does not support HTML5 Canvas.
</canvas>
<canvas id="canvasTwo" width="300" height="300" style="position:absolute; left:250px; top:30px; border:1px solid red;">
Your browser does not support HTML5 Canvas.
</canvas>
</div>
<div class="clear"></div>
<div class="dnleft">
<input id="slide1" type="range" min="0" max="100" step="1" value="0" onchange="counterSliderNew('slide1', '100');"/>
</div>
</div>
</body>
<script type="text/javascript">
drawSlopeCurve2('canvasTwo', 16, 170, 200, 80)
function counterSliderNew(sID, maxValue) {
var slideVal = document.getElementById(sID).value;
//alert(slideVal);
if (maxValue == 100) {
slideVal = slideVal / 100;
}
if (slideVal == 0) {
} else if (slideVal > 0 && slideVal <= 34) {
erase('canvasOne');
drawBezier2('canvasOne', new Array({
x : 18.8,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
} else if (slideVal > 34 && slideVal <= 67) {
//alert(slideVal);
erase('canvasOne');
drawBezier2('canvasOne', new Array({
x : 18.8,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
staticGraph5('canvasTwo');
} else if (slideVal > 67 && slideVal <= 100) {
erase('canvasOne');
drawBezier2('canvasOne', new Array({
x : 18.8,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
}
}
function drawBezier2(canId, points, slideVal) {
var canvas = document.getElementById(canId);
var context = canvas.getContext("2d");
// Draw guides
context.lineWidth = 2;
context.strokeStyle = "rgb(113, 113, 213)";
context.beginPath();
// Label end points
context.fillStyle = "rgb(0, 0, 0)";
// Draw spline segemnts
context.moveTo(points[0].x, points[0].y);
for (var t = 0; t <= slideVal; t += 0.1) {
context.lineTo(Math.pow(1 - t, 2) * points[0].x + 2 * (1 - t) * t * points[1].x + Math.pow(t, 2) * points[2].x, Math.pow(1 - t, 2) * points[0].y + 2 * (1 - t) * t * points[1].y + Math.pow(t, 2) * points[2].y);
}
// Stroke path
context.stroke();
}
function erase(canvasId) {
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.beginPath();
context.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = canvas.width;
}
function drawSlopeCurve2(canId, mvx, mvy, lnx, lny) {
var canvas = document.getElementById(canId);
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(mvx, mvy);
context.lineTo(lnx, lny);
context.lineWidth = 0.6;
context.stroke();
}
</script>
</html>
This will work only in chrome. I want to use drawSlopeCurve2('canvasTwo', 16, 170, 200, 80); this function to draw a line on movement of slider. I am looking for some formula as I have used for moving an arc on slider movement.
You can use this function to get an array of points that interpolate a line between any 2 points:
function linePoints(x1, y1, x2, y2, frames) {
var dx = x2 - x1;
var dy = y2 - y1;
var length = Math.sqrt(dx * dx + dy * dy);
var incrementX = dx / frames;
var incrementY = dy / frames;
var a = new Array();
a.push({ x: x1, y: y1 });
for (var frame = 0; frame < frames - 1; frame++) {
a.push({
x: x1 + (incrementX * frame),
y: y1 + (incrementY * frame)
});
}
a.push({ x: x2, y: y2 });
return (a);
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/qhzJv/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH5EX10: Moving In A Simple Geometric Spiral </title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<style>
.wrapper {
width: 700px;
height:350px;
border:2px solid green;
padding:15px;
}
.uppleft{
display: inline;
margin-left: 30px;
}
canvas{
border:1px solid red;
}
#sliderwrapper{
display: inline-block;
position:relative;
width:37px; height:300px;
border:1px solid blue;
}
#amount{
position:absolute;
left:5px; top:5px;
margin-bottom:15px;
width:23px;
border:0; color:#f6931f;
font-weight:bold;
}
#slider-vertical{
position:absolute;
left:10px; top:40px;
width:15px; height:225px;
border:0px; color:#f6931f;
font-weight:bold;
}
</style>
</head>
<body>
<div class="wrapper">
<div id="sliderwrapper">
<input type="text" id="amount" />
<div id="slider-vertical"></div>
</div>
<div class="uppleft">
<canvas id="canvasOne" width="300" height="300">
Your browser does not support HTML5 Canvas.
</canvas>
<canvas id="canvasTwo" width="300" height="300">
Your browser does not support HTML5 Canvas.
</canvas>
</div>
</div>
</body>
<script type="text/javascript">
var startingValue=20;
// handles user moving the slider
$( "#slider-vertical" ).slider({
orientation: "vertical",
range: "min",
min: 0,
max: 100,
value: startingValue,
slide: function( event, ui ) {
$( "#amount" ).val( ui.value );
counterSliderNew('slide1', '100', ui.value);
}
});
// get an array of 100 points between start and end of line
var points=linePoints(16, 170, 200, 80,100);
// draw the initial point based on the beginning slider value
counterSliderNew('slide1', '100', startingValue);
function counterSliderNew(sID, maxValue,theSliderValue) {
var slideVal = theSliderValue; // document.getElementById(sID).value;
// get the slider value and get the point at points[slideVal]
var point=points[slideVal];
erase('canvasTwo');
drawSlopeCurve2('canvasTwo',16,170,point.x,point.y);
if (maxValue == 100) {
slideVal = slideVal / 100;
}
if (slideVal == 0) {
} else if (slideVal > 0 && slideVal <= 34) {
erase('canvasOne');
drawBezier2('canvasOne', new Array({
x : 18.8,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
} else if (slideVal > 34 && slideVal <= 67) {
//alert(slideVal);
erase('canvasOne');
drawBezier2('canvasOne', new Array({
x : 18.8,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
staticGraph5('canvasTwo');
} else if (slideVal > 67 && slideVal <= 100) {
erase('canvasOne');
drawBezier2('canvasOne', new Array({
x : 18.8,
y : 75
}, {
x : 28,
y : 160
}, {
x : 228,
y : 165
}), slideVal);
}
}
function drawBezier2(canId, points, slideVal) {
var canvas = document.getElementById(canId);
var context = canvas.getContext("2d");
// Draw guides
context.lineWidth = 2;
context.strokeStyle = "rgb(113, 113, 213)";
context.beginPath();
// Label end points
context.fillStyle = "rgb(0, 0, 0)";
// Draw spline segemnts
context.moveTo(points[0].x, points[0].y);
for (var t = 0; t <= slideVal; t += 0.1) {
context.lineTo(Math.pow(1 - t, 2) * points[0].x + 2 * (1 - t) * t * points[1].x + Math.pow(t, 2) * points[2].x, Math.pow(1 - t, 2) * points[0].y + 2 * (1 - t) * t * points[1].y + Math.pow(t, 2) * points[2].y);
}
// Stroke path
context.stroke();
}
function erase(canvasId) {
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.beginPath();
context.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = canvas.width;
}
function drawSlopeCurve2(canId, mvx, mvy, lnx, lny) {
var canvas = document.getElementById(canId);
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(mvx, mvy);
context.lineTo(lnx, lny);
context.lineWidth = 0.6;
context.stroke();
}
function linePoints(x1, y1, x2, y2, frames) {
var dx = x2 - x1;
var dy = y2 - y1;
var length = Math.sqrt(dx * dx + dy * dy);
var incrementX = dx / frames;
var incrementY = dy / frames;
var a = new Array();
a.push({ x: x1, y: y1 });
for (var frame = 0; frame < frames - 1; frame++) {
a.push({
x: x1 + (incrementX * frame),
y: y1 + (incrementY * frame)
});
}
a.push({ x: x2, y: y2 });
return (a);
}
</script>
</html>