Setting a correct angular velocity to a canvas object - html

I am building a space shooter game and would like the ship to fire rockets at the direction of the cursor. Therefore, I grab the radian value of the angle it should fire at, multiply it by the ship's speed and set it's x and y velocities respectively.
I have this as a Bullet class:
function Bullet(x, y) {
this.x = x;
this.y = y;
this.rotation = 0;
this.width = 6;
this.height = 3;
this.color = utils.getRandomColor();
this.speed = 80;
}
And here is the function which updates the movement of all instances of the bullet class:
function drawBullet(bullet) {
var dx = mouse.x - bullet.x,
dy = mouse.y - bullet.y,
angle = Math.atan2(dy, dx);
bullet.vx = Math.cos(angle) * bullet.speed;
bullet.vy = Math.sin(angle) * bullet.speed;
bullet.x += bullet.vx;
bullet.y += bullet.vy;
bullet.draw(ctx);
}
It starts okay, going in the right direction and velocity and stuff. But as soon as it reaches the mouse, it stops dead there and starts flickering. NOW, I realise that this is because of the way I am getting the angle, using the mouse position as a value - the problem is that I can't figure out a way to use just the angle for the velocity, not the distance to the mouse position. So it doesn't slow down.
All suggestions are welcome, thanks in advance!

If you don't need homing missile type behavior just pass the mouse coordinates when you create the bullet.
Example:
new Bullet(shooterX, shooterY, mouseX, mouseY)
I included an over engineered stack snippet but the relevant part is below.
var Bullet = function(x,y,tx,ty){
this.speed = 15;
this.x = x;
this.y = y;
var radians = Math.atan2(ty-y, tx-x);
// we now have our velX and velY we can just refer to
this.velX = Math.cos(radians) * this.speed;
this.velY = Math.sin(radians) * this.speed;
}
Bullet.prototype.update = function(){
// just update by our previous calculated velX and velY.
this.x += this.velX;
this.y += this.velY;
};
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 250,
height = 250,
output = document.getElementById("radians"),
output2 = document.getElementById("degrees"),
cX = 0,
cY = 0,
mX = 0,
mY = 0,
bullets = [];
canvas.width = width;
canvas.height = height;
canvas.addEventListener("mousemove", function (e) {
mX = e.pageX;
mY = e.pageY;
});
var Ball = function (x, y, radius, color) {
this.x = x || 0;
this.y = y || 0;
this.radius = radius || 10;
// makes our x and y the center of the circle.
this.x = (this.x-this.radius/2);
this.y = (this.y-this.radius/2);
// how far out do we want the point
this.pointLength = 50;
this.px = 0;
this.py = 0;
this.color = color || "rgb(255,0,0)";
}
Ball.prototype.shoot = function(tx, ty){
bullets.push(new Bullet(this.x, this.y, tx, ty));
}
Ball.prototype.update = function (x, y) {
// get the target x and y
this.targetX = x;
this.targetY = y;
var x = this.x - this.targetX,
y = this.y - this.targetY,
radians = Math.atan2(y,x);
this.px = this.x - this.pointLength * Math.cos(radians);
this.py = this.y - this.pointLength * Math.sin(radians);
// -y will make 0 the top, y will 0 us at the bottom.
output.textContent = radians;
output2.textContent = radians/Math.PI * 180
};
Ball.prototype.render = function () {
ctx.fillStyle = this.color;
ctx.beginPath();
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();
};
var Bullet = function(x,y,tx,ty){
this.speed = 15;
this.x = x;
this.y = y;
var radians = Math.atan2(ty-y, tx-x);
this.velX = Math.cos(radians) * this.speed;
this.velY = Math.sin(radians) * this.speed;
}
Bullet.prototype.update = function(){
this.x += this.velX;
this.y += this.velY;
};
Bullet.prototype.render = function(){
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
};
var ball1 = new Ball(width/2, height/2, 10);
canvas.addEventListener("click", function (e) {
ball1.shoot(e.pageX, e.pageY);
});
function render() {
ctx.clearRect(0, 0, width, height);
ball1.update(mX, mY);
ball1.render();
bullets.forEach(function(b){
b.update();
b.render();
});
requestAnimationFrame(render);
}
render();
ol{list-style:none;}
<canvas id="canvas"></canvas>
<div>
<ol>
<li>
<span>Radians : </span><span id="radians"></span>
</li>
<li>
<span>Degrees : </span><span id="degrees"></span>
</li>
</ol>
</div>

Add a new property on bullet that stores the angle of motion, initialize it to -1. Then, on the very first drawBullet call, check if it has been initialized first. If not, set the angle...
function Bullet(x, y) {
this.x = x;
this.y = y;
this.rotation = 0;
this.width = 6;
this.height = 3;
this.color = utils.getRandomColor();
this.speed = 80;
this.angle = -1; // New, angle property initialized to -1
}
function drawBullet(bullet) {
if (bullet.angle === -1) { // Only pull the mouse cursor and get an angle
var dx = mouse.x - bullet.x, // If it hasn't already done so.
dy = mouse.y - bullet.y,
angle = Math.atan2(dy, dx);
bullet.angle = angle;
}
bullet.vx = Math.cos(bullet.angle) * bullet.speed; // Re-use the angle value.
bullet.vy = Math.sin(bullet.angle) * bullet.speed;
bullet.x += bullet.vx;
bullet.y += bullet.vy;
bullet.draw(ctx);
}

Related

Draw Line Arrowhead Without Rotating in Canvas

Most code to drawing arrowheads in html canvas involves rotating the canvas context and drawing the lines.
My use case is to draw them using trigonometry without rotating the canvas. or is that vector algorithm you call it? Help is appreciated.
This is what I have (forgot where I got most of the code). Draws 2 arrowheads on start and end based on the last 2 parameters arrowStart and arrowEnd which are boolean.
drawLineArrowhead: function(context, arrowStart, arrowEnd) {
// Place start end points here.
var x1 = 0;
var y1 = 0;
var x2 = 0;
var y2 = 0;
var distanceFromLine = 6;
var arrowLength = 9;
var dx = x2 - x1;
var dy = y2 - y1;
var angle = Math.atan2(dy, dx);
var length = Math.sqrt(dx * dx + dy * dy);
context.translate(x1, y1);
context.rotate(angle);
context.beginPath();
context.moveTo(0, 0);
context.lineTo(length, 0);
if (arrowStart) {
context.moveTo(arrowLength, -distanceFromLine);
context.lineTo(0, 0);
context.lineTo(arrowLength, distanceFromLine);
}
if (arrowEnd) {
context.moveTo(length - arrowLength, -distanceFromLine);
context.lineTo(length, 0);
context.lineTo(length - arrowLength, distanceFromLine);
}
context.stroke();
context.setTransform(1, 0, 0, 1, 0, 0);
},
See the code below, just a bit of trigonometry.
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.lineCap = "round";
ctx.lineWidth = 5;
function drawLineArrowhead(p1, p2, startSize, endSize) {
ctx.beginPath()
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
if (startSize > 0) {
lineAngle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
delta = Math.PI/6
for (i=0; i<2; i++) {
ctx.moveTo(p1.x, p1.y);
x = p1.x + startSize * Math.cos(lineAngle + delta)
y = p1.y + startSize * Math.sin(lineAngle + delta)
ctx.lineTo(x, y);
delta *= -1
}
}
if (endSize > 0) {
lineAngle = Math.atan2(p1.y - p2.y, p1.x - p2.x);
delta = Math.PI/6
for (i=0; i<2; i++) {
ctx.moveTo(p2.x, p2.y);
x = p2.x + endSize * Math.cos(lineAngle + delta)
y = p2.y + endSize * Math.sin(lineAngle + delta)
ctx.lineTo(x, y);
delta *= -1
}
}
ctx.stroke();
}
drawLineArrowhead({x:10, y:10}, {x:100, y:20}, 0, 30)
drawLineArrowhead({x:20, y:25}, {x:140, y:120}, 20, 20)
drawLineArrowhead({x:140, y:20}, {x:80, y:50} , 20, 0)
drawLineArrowhead({x:150, y:20}, {x:150, y:90}, 20, 5)
drawLineArrowhead({x:180, y:90}, {x:180, y:20}, 20, 5)
drawLineArrowhead({x:200, y:10}, {x:200, y:140}, 10, 10)
drawLineArrowhead({x:220, y:140}, {x:220, y:10}, 10, 20)
<canvas id="canvas">
If you run it you should see a few samples.
The drawLineArrowhead has 4 parameters (p1, p2, startSize, endSize)
the first two are the starting-point and end-point of the line, the last two are arrow size, just to give some control to the final user over how big are those arrows at the end, if we want to remove them we set to 0.

Canvas Spinning Cube

I have an HTML5 Canvas Spinning Cube on this codePen:
http://codepen.io/celli/pen/xwvnb
Can someone help to show how to remove the black background ? It looks like the ctx.fillStyle="#000000"; property in the JS is needed (try changing or removing it in the CodePen), but I'd like to have a transparent background, and can't seem to find a way to make that happen.
window.onload = startDemo;
function Point3D(x,y,z) {
this.x = x;
this.y = y;
this.z = z;
this.rotateX = function(angle) {
var rad, cosa, sina, y, z
rad = angle * Math.PI / 180
cosa = Math.cos(rad)
sina = Math.sin(rad)
y = this.y * cosa - this.z * sina
z = this.y * sina + this.z * cosa
return new Point3D(this.x, y, z)
}
this.rotateY = function(angle) {
var rad, cosa, sina, x, z
rad = angle * Math.PI / 180
cosa = Math.cos(rad)
sina = Math.sin(rad)
z = this.z * cosa - this.x * sina
x = this.z * sina + this.x * cosa
return new Point3D(x,this.y, z)
}
this.rotateZ = function(angle) {
var rad, cosa, sina, x, y
rad = angle * Math.PI / 180
cosa = Math.cos(rad)
sina = Math.sin(rad)
x = this.x * cosa - this.y * sina
y = this.x * sina + this.y * cosa
return new Point3D(x, y, this.z)
}
this.project = function(viewWidth, viewHeight, fov, viewDistance) {
var factor, x, y
factor = fov / (viewDistance + this.z)
x = this.x * factor + viewWidth / 2
y = this.y * factor + viewHeight / 2
return new Point3D(x, y, this.z)
}
}
var vertices = [
new Point3D(-1,1,-1),
new Point3D(1,1,-1),
new Point3D(1,-1,-1),
new Point3D(-1,-1,-1),
new Point3D(-1,1,1),
new Point3D(1,1,1),
new Point3D(1,-1,1),
new Point3D(-1,-1,1)
];
// Define the vertices that compose each of the 6 faces. These numbers are
// indices to the vertex list defined above.
var faces = [[0,1,2,3],[1,5,6,2],[5,4,7,6],[4,0,3,7],[0,4,5,1],[3,2,6,7]]
var angle = 0;
function startDemo() {
canvas = document.getElementById("cubeSpin");
if( canvas && canvas.getContext ) {
ctx = canvas.getContext("2d");
setInterval(loop,33);
}
}
function loop() {
var t = new Array();
ctx.fillStyle="#000000";
ctx.fillRect(0,0,320,200);
for( var i = 0; i < vertices.length; i++ ) {
var v = vertices[i];
var r = v.rotateX(angle).rotateY(angle).rotateZ(angle);
var p = r.project(320,200,128,3.5);
t.push(p)
}
ctx.strokeStyle = "rgb(255,255,255)"
for( var i = 0; i < faces.length; i++ ) {
var f = faces[i]
ctx.beginPath()
ctx.moveTo(t[f[0]].x,t[f[0]].y)
ctx.lineTo(t[f[1]].x,t[f[1]].y)
ctx.lineTo(t[f[2]].x,t[f[2]].y)
ctx.lineTo(t[f[3]].x,t[f[3]].y)
ctx.closePath()
ctx.stroke()
}
angle += 2
}
Change:
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,320,200);
To:
ctx.clearRect(0,0,320,200);

drawing a smooth line on html5 canvas for mobile app using jquery mobile

I am trying to draw on canvas, like drawing using pencil tool in the paint using jquery mobile.
I searched for many links and most of them were for the desktop, i tried to implement the same logic for the mobile app, i am able to obtain only the click events but not able to draw the line on the canvas.
This is what i was trying to implement on the mobile http://jsfiddle.net/loktar/dQppK/23/
This is my code
$(document).on(
'pageshow',
'#canvaspage',
function() {
var painting = false;
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// ctx.fillStyle="#FF0000";
// ctx.fillRect(0,0,150,75);
// ctx.drawImage(icons-18-black.png)
ctx.canvas.width = window.innerWidth * 0.8;
ctx.canvas.height = window.innerHeight * 0.8;
var imageObj = new Image();
imageObj.onload = function() {
ctx.drawImage(imageObj, 0, 0, ctx.canvas.width * 0.8,
ctx.canvas.height * 0.7);
};
imageObj.src = 'Image.png';
// c.addEventListener('touchstart', function(e) {
$("#myCanvas").on("touchstart",function(e){
painting = true;
e.preventDefault();
ctx.fillStyle = "#FF0000";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
});
// c.addEventListener('touchend', function(e) {
$("#myCanvas").on("touchend",function(e){
painting = false;
});
// c.addEventListener('touchmove', function(e) {
$("#myCanvas").on("touchmove",function(e){
if (painting) {
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep){
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
if(lineThickness < 1){
lineThickness = 1;
}
alert(painting +" " +x1 +" "+x2);
for (var x = x1; x < x2; x++) {
// alert(x +" "+ y +" "+ lineThickness);
if (steep) {
ctx.fillRect(y, x, lineThickness , lineThickness );
} else {
ctx.fillRect(x, y, lineThickness , lineThickness );
}
alert(steep);
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
}
lastX = mouseX;
lastY = mouseY;
}
// ctx.fillRect(0, 0, 150, 75);
e.preventDefault();
}, false);
});
In the above code i am able to obtain all the touch events but the unable to draw the line.
How can i draw the lines on the canvas??..
Thanks:)
You can use sketch.js (http://intridea.github.io/sketch.js/) with a small modification to make it work on mobile. The modification is given in the comment by leonth here: https://github.com/intridea/sketch.js/issues/1; you basically add 3 lines to the plugin on the mousedown/touchstart event:
switch (e.type) {
case 'mousedown':
case 'touchstart':
if (this.painting) { //add
this.stopPainting(); //add
} //add
this.startPainting();
break;
...
Here is a DEMO FIDDLE, try it from mobile device.

html5 canvas animation. leaving a trail and reset button

I'm pretty new to this and I got the animation working by watching a youtube tutorial.
Here is a canvas animation of a keyboard controlled car.
http://jsfiddle.net/unn9P/
canvas = document.getElementById('canvas');
c = canvas.getContext('2d');
c.clear = function() {
this.clearRect(0,0,1500,1500) };
function wait(fn) {
window.setTimeout(fn, 250) }
function repeat(fn) {
if (requestAnimationFrame) {
var advance = function() {fn(); requestAnimationFrame(advance);};
requestAnimationFrame(advance);
} else window.setInterval(fn, 50);
}
var dx = 0, dy = 0, mousex = 0, mousey=0, mouseclicks = 0;
document.onkeydown = function(e) {
var key = e.keyCode;
if (key == 37) dx=-1;
else if (key == 38) dy=-1;
else if (key == 39) dx=1;
else if (key == 40) dy=1;
else return true;
return false;
};
document.onkeyup = function(e) {
var key = e.keyCode;
if (key == 37 || key == 39) dx=0;
else if (key == 38 || key == 40) dy=0;
else return true;
return false;
};
canvas.onmousemove = function(e) {
var rect = canvas.getBoundingClientRect();
mousex = e.clientX - rect.left;
mousey = e.clientY - rect.top;
};
canvas.onmousedown = function(e) {mouseclicks++;};
a = new Image();
a.src = 'http://o.ooli.ca/car_top.png';
wait(function(){
x = 50;
y = 50;
angle = 0;
repeat(function() {
angle = angle + dx;
x = x - dy * Math.cos(angle * Math.PI / 180);
y = y - dy * Math.sin(angle * Math.PI / 180);
c.clear();
c.translate(x, y);
c.rotate(angle * Math.PI / 180);
c.translate(-37, -19);
c.drawImage(a, 0, 0);
c.setTransform(1, 0, 0, 1, 0, 0); //reset
});
});
Now I would like to add trail behind the car as it moves along and create a reset button inside the canvas which can help me clear the trail, and bring the car to its initial position.
I have read some tutorials but i can't seem to find what I want.
Is there any idea/suggestion on how I should do this?
Simply record your points when moving:
Modified fiddle here
repeat(function () {
angle = angle + dx;
x = x - dy * Math.cos(angle * Math.PI / 180);
y = y - dy * Math.sin(angle * Math.PI / 180);
/// record point
pts.push([x, y]);
c.clear();
/// render points (see below)
renderTrail(pts, c);
c.translate(x, y);
...
Then have a function to render the recorded points:
function renderTrail(pts, c) {
if (pts.length > 1) {
c.beginPath();
c.moveTo(pts[0][0], pts[0][1]);
for(var i = 1, pt; pt = pts[i]; i++) {
c.lineTo(pt[0], pt[1]);
}
c.stroke();
}
}
To reset just clear the point array:
pts = [];
You can do this on a mouse-click event on the canvas where you chose to draw your button or just put a html button on top of canvas (above it, literally on top will reduce the performance of canvas).

Ball movement path in canvas, and other ideas you may have?

I've created this animation for my project that had to use any form of physics.
I am a total beginner, too :) Anyway, this is my project now :
Bouncing Balls
You can setup gravity and force, then click play, and just drag and drop to shoot the balls. You can change the values and hit update too see an effect.
My question is, how can I create an effect that when I press ratio button (for example) I can see the path that ball makes? Is it complicated? As I was saying I am a beginner, so no complex code for me :)
Also, doyou have any ideas to make the project better? Any additional "physics" effects? Or maybe you know a website that shows tutorials for simile (please) effects made in HTML5/js so I can add additional effects to my project.
One possibility (as you're clearing the canvas each frame) would be to draw ball paths onto a secondary canvas, which would not be cleared each frame. Then, when you come to clear the first frame, render the second frame after clearing, and before rendering the balls.
The second canvas would of course have to be the same dimensions as the first, so that all of the ball points line up correctly. The second canvas should also have a z-index lower than the first, so that it is only shown when you specifically render it to the first canvas (i.e. when the radio button is checked).
To decrease any lag while the radio is not checked, you could skip drawing the ball paths to the second canvas, although I don't think you would see any great increase in performance.
On each frame update, you would mark the position of each ball with a pixel, or line (from the previous position to the current) on the second canvas.
Looking at your code, you seem pretty competent, so I've skipped writing an example as I think this would be good experience for you :)
Modified 'script.js' source demonstrating solution
window.onload = function(){
$("#canvas").hide();
var howManyPaths = 0;
var showPath=false;
// SLIDERS
var gravitySlider = document.getElementById('gravitySlider');
var gravityVal = document.getElementById('gravityValue');
gravitySlider.onchange = function(){
gravityVal.value = gravitySlider.value;
}
gravityVal.onkeyup = function(){
gravitySlider.value = gravityVal.value;
}
var forceSlider = document.getElementById('forceSlider');
var forceValue = document.getElementById('forceValue');
forceSlider.onchange = function(){
forceValue.value = forceSlider.value;
}
forceValue.onkeyup = function(){
forceSlider.value = forceValue.value;
}
// GLOBAL VARIABLES
var test = false;
var gravityCount = $("#gravity").val();
var forceCount = $("#rectangles").val();
// CSS :
var playCSS = document.getElementById("play");
var restartCSS = document.getElementById("restart");
var clickableCSS = document.getElementById("setup");
var clickableBG = document.getElementById("img");
//restartCSS.style.visibility="hidden";
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var canvas2 = document.getElementById("canvas2");
var ctx2 = canvas2.getContext("2d");
//var ctx;
var gravity = 9.86;
var forceFactor = 0.5;
var mouseDown = false;
var balls = new Array();
var mousePos = new Array();
// EVENT HANDLER
function onMouseDown(evt){
mouseDown = true;
mousePos['downX'] = evt.pageX;
mousePos['downY'] = evt.pageY;
}
function onMouseUp(evt){
mouseDown = false;
setup.style.visibility="visible";
if(test == true && !( mousePos['downX'] < 200 && mousePos['downY'] < 150) ){
restartCSS.style.visibility="visible";
forceFactor = forceCount;
balls.push(new ball(mousePos["downX"],
mousePos["downY"],
(evt.pageX - mousePos["downX"]) * forceFactor,
(evt.pageY - mousePos["downY"]) * forceFactor,
10 + (Math.random() * 10),
0.8,
randomColor()
));
}
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
}
function onMouseMove(evt){
mousePos['currentX'] = evt.pageX;
mousePos['currentY'] = evt.pageY;
}
function resizeWindow(evt){
//canvas.height = 960;
//canvas.width = 720;
canvas.height = $(window).height()-6;
canvas.width = $(window).width();
canvas2.height = $(window).height()-6;
canvas2.width = $(window).width();
}
$(document).mousedown(onMouseDown);
$(document).mouseup(onMouseUp);
$(document).mousemove(onMouseMove);
$(window).bind("resize", resizeWindow);
// GRAPHICS CODE
function circle(x, y, r, col){
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.closePath;
// fill
ctx.fillStyle = col;
ctx.fill();
// stroke
ctx.lineWidth = r * 0.1;
ctx.strokeStyle = "#000000";
ctx.stroke();
}
function circlePath(x, y)
{
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
ctx2.fillStyle = '#3f4043';
ctx2.fillRect(x, y, 5, 5);
ctx2.strokeStyle = "black";
ctx2.strokeRect(x, y, 5, 5);
}
function randomColor(){
var letter = "0123456789ABCDEF".split("");
var color = "#";
for(var i=0; i<6; i++){
color += letter[Math.round(Math.random()*15)];
}
return color;
}
function arrow(fromX, fromY, toX, toY, color){
// path
ctx.beginPath();
var headLen = 10;
var angle = Math.atan2(toY - fromY, toX - fromX);
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
ctx.lineTo(toX - headLen * Math.cos(angle - Math.PI/6), toY - headLen * Math.sin(angle - Math.PI/6));
ctx.moveTo(toX, toY);
ctx.lineTo(toX - headLen * Math.cos(angle + Math.PI/6), toY - headLen * Math.sin(angle + Math.PI/6));
// style
ctx.lineWith = 1;
ctx.strokeStyle = color;
ctx.lineCap = "butt";
ctx.stroke();
}
function drawBall(){
// Gravity
gravity = gravityCount;
this.speedY += gravity * 0.5; // v = a * t
this.x += this.speedX * 0.05; // s = v * t
this.y += this.speedY * 0.05;
// prawa ściana
if(this.x + this.r > canvas.width){
this.x = canvas.width - this.r;
this.speedX *= -1 * this.bounce;
}
// lewa ściana
if(this.x - this.r < 0){
this.x = this.r;
this.speedX *= -1 * this.bounce;
}
// dolna ściana
if(this.y + this.r > canvas.height){
this.y = canvas.height - this.r;
this.speedY *= -1 * this.bounce;
}
// górna ściana
if(this.y - this.r < 0){
this.y = this.r;
this.speedY *= -1 * this.bounce;
}
// zwalnianie na ziemi
if (this.speedX > 0.25){
this.speedX -= 0.25;
if (this.speedY > 0.25)
this.speedY -= 0.25;
}
if (this.speedX < -0.25){
this.speedX += 0.25;
//if (this.speedY < -0.25)
// this.speedY += 0.25;
}
circle(this.x, this.y, this.r, this.col);;
}
// OBJECTS
function ball(positionX, positionY, sX, sY, radius, b, color){
this.x = positionX;
this.y = positionY;
this.speedX = sX;
this.speedY = sY;
this.r = radius;
this.bounce = b;
this.col = color;
this.draw = drawBall;
}
//GAME LOOP
function gameLoop(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
//grab the context from your destination canvas
//if path drawing is enabled, first draw the path canvas to the display canvas
if (showPath) ctx.drawImage(canvas2,0,0);
if(mouseDown == true){
// ctx.clearRect(0, 0, canvas.width, canvas.height); /* !important !!!!!!!!!!!!!!! */
arrow(mousePos['downX'], mousePos['downY'], mousePos['currentX'], mousePos['currentY'], "red");
}
for(var i=0; i<balls.length; i++){
balls[i].draw();
if (i==balls.length-1) {
//draw path
ctx2.fillStyle = '#3f4043';
ctx2.fillRect(balls[i].x, balls[i].y, 5, 5);
ctx2.strokeStyle = "black";
ctx2.strokeRect(balls[i].x, balls[i].y, 5, 5);
}
}
ctx.fillStyle = "#000000";
ctx.font = "15px Arial";
ctx.fillText("Balls: " + balls.length + " " + gravityCount + " " + forceCount + " " + howManyPaths, 10, canvas.height -10);
}
// START THE GAME
function init(){
//$("#setup").hide();
$("#canvas").show();
$("#canvas2").hide();
ctx = $('canvas')[0].getContext("2d");
canvas.height = $(window).height()-6;
canvas.width = $(window).width();
//canvas.width = 960;
//canvas.height = 720;
canvas2.height = $(window).height()-6;
canvas2.width = $(window).width();
return setInterval(gameLoop, 10);
}
$("#play").click(function() {
test = true;
playCSS.style.visibility="hidden";
gravityCount = $("#gravitySlider").val();
forceCount = $("#forceSlider").val();
init();
});
$("#restart").click(function() {
window.location.href="index.html";
});
$("#refresh").click(function() {
gravityCount = $("#gravitySlider").val();
forceCount = $("#forceSlider").val();
});
$("#showPath").click(function() {
showPath=true;
});
$("#hidePath").click(function() {
showPath=false;
});
}