On website https://omegalords.ga/world/test.html, I have a code that calculates 1 unit towards a target. In the code the slope is 1. so the x and y of the next spot to jump to should be the same. Why does it at some point change and the 2 coordinates. I have ran the numbers, but it doesn't work properly. Could someone explain hwy?
</canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var findDis = function(x1,y1,x2,y2){
//Finds distance rounded to the nearest 1000th
return Math.trunc(((Math.sqrt((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2)))*1000))/1000
}
var findIntersections = function(b,a,m,r){
var Fraction = algebra.Fraction;
var Expression = algebra.Expression;
var Equation = algebra.Equation;
var coords = {
l:[],
g:[]
}
//b^2 - 2bx + x^2 - 2bm^2x + b^2m^2 - r^2
var sl = algebra.parse(Math.pow(b,2)+" - "+2*b+"x + x^2 + "+Math.pow(m,2)+"x^2 -" + 2 * b * Math.pow(m,2) + "* x + " + Math.pow(b,2) * Math.pow(m,2) + " - " + Math.pow(r,2));
var sr = algebra.parse("0")
var eq = new Equation(sl, sr);
//Solves for x rounded to the nearest 1000
coords.l.push(Math.trunc((eq.solveFor("x")[0]*1000))/1000);
coords.g.push(Math.trunc((eq.solveFor("x")[1]*1000))/1000);
//Solves for y
coords.l.push(Math.trunc((coords.l[0] * m + a - (b * m))*1000)/1000);
coords.g.push(Math.trunc((coords.g[0] * m + a - (b * m))*1000)/1000);
return JSON.stringify(coords);
}
var findSlope = function(x1,y1,x2,y2){
//Finds Slope rounded to the nearest 1000th
return Math.trunc(((y1-y2)/(x1-x2))*1000)/1000;
}
var getRandomInt = function(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var wolves = [];
var deers = [];
var deer = function(x,y){
this.x = x;
this.y = y;
this.hp = 100;
this.size = 10;
this.hunger = 0*%;
this.preyTypes = [grass];
this.predatorTypes = [wolves];
deers.push(this);
}
var wolf = function(x,y){
this.x = x;
this.y = y;
this.hp = 100;
this.size = 10;
this.hunger = 0 * %;
wolves.push(this);
this.preyTypes = [deers]
}
wolf.prototype.move = function(){
this.nearbyPredators = [];
this.nearbyPrey = [];
//finds all nearby prey
for(var j = 0;j<this.preyTypes.length;j++){
for(var i = 0;i < this.preyTypes[j].length;i++){
if(findDis(this.preyTypes[j][i].x,this.preyTypes[j][i].y,this.x,this.y) < 40){
this.nearbyPrey.push(this.preyTypes[j][i]);
}else{
console.log(findDis(this.preyTypes[j][i].x,this.preyTypes[j][i].y,this.x,this.y))
}
}
}
//If there are no nearby prey, move randomly
if(this.nearbyPrey.length === 0){
wolf.x += getRandomInt(-8,9)
wolf.y -= getRandomInt(-9,8);
//If there is only one nearby prey, move towards it
}else if(this.nearbyPrey.length === 1){
this.nearestPrey = this.nearbyPrey[0]
var slope = findSlope(this.nearestPrey.x,this.nearestPrey.y,this.x,this.y);
console.log(slope);
var coords = JSON.parse(findIntersections(this.x,this.y,slope,1));
console.log(coords);
var ldis = findDis(this.x,this.y,coords.l[0],coords.l[1]);
var gdis = findDis(this.x,this.y,coords.g[0],coords.g[1]);
console.log(ldis,gdis)
if(ldis > gdis){
this.x = coords.l[0]
this.y = coords.l[1]
console.log(this.x,this.y)
}else {
this.x = coords.g[0]
this.y = coords.g[1]
console.log(this.x,this.y)
}
//If there is more than 1, find the nearest prey and move towards it
}else {
for(var i = 0; i < this.nearbyPrey.length; i++){
this.tempDis = getDis(this.x,this.y,this.nearbyPrey[i].x,this.nearbyPrey[i].y)
if(typeof this.nearestPrey == 'undefined'){
this.nearestPrey = {
prey:this.nearbyPrey[i],
distance:this.tempDis
}
this.tempDis = undefined
}else {
if(this.tempDis > this.nearestPrey.distance){
this.nearestPrey = {
prey:this.nearbyPrey[i],
distance:this.tempDis
}
}
}
}
var slope = findSlope(this.nearestPrey.x,this.nearestPrey.y,this.x,this.y)
var coords = JSON.parse(findIntersections(this.nearestPrey.x,this.nearestPrey.y,slope,1));
var ldis = findDis(this.nearestPrey.x,this.nearestPrey.y,coords.l[0],coords.l[1]);
var gdis = findDis(this.nearestPrey.x,this.nearestPrey.y,coords.g[0],coords.g[1]);
if(ldis > gdis){
this.x = coords.l[0]
this.y = coords.l[1]
}else {
this.x = coords.g[0]
this.y = coords.g[1]
}
}
}
wolf.prototype.bite = function(prey){
prey.hp -= this.strength;
this.hunger += 40 * %
console.log(this.hunger);
console.log(this.nearestPrey.hp)
}
new wolf(100,100)
new deer(80,80);
var init = function(){
ctx.translate(0.5, 0.5);
ctx.lineWidth = .5
window.setInterval(draw,1000);
}
var draw = function(){
ctx.clearRect(0,0,canvas.width,canvas.height)
wolves[0].move();
for(var i=0;i<wolves.length;i++){
ctx.beginPath();
ctx.arc(deers[0].x,deers[0].y,10,0,2*Math.PI);
ctx.stroke();
ctx.beginPath()
ctx.arc(wolves[i].x,wolves[i].y,10,0,2*Math.PI);
ctx.stroke();
}
}
init()
</script>
Related
Using certain methods, I drew a 3D cube.
My task is to rotate it around the z axis. I also need to rotate the cube relative to the coordinates (0,0,0) (on my canvas, these will be the coordinates (150,150,0)). Now it rotates correctly, but only changes its angle relative to the 'top left corner of my canvas'.
I think the solution to my problem is as follows:
To rotate the cube relative to the given coordinates, the cube must first be translated to the negative coordinates of this point, and by changing the angle, it must be translated back, but only to the positive coordinates of this point.
In my case the pseudo code would be like this:
// if I want to flip the cube around the coordinates (150,150,0) (this is the center of my canvas), then I need to do the following
translate(-150,-150,0);
rotate();
translate(150,150,0);
In the commented parts of the code, I tried to do this, but when I translate the cube, it gets stuck somewhere in the corner and I don't know how to fix it.
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) ) + min;
}
function randomColor() {
return "rgb(" + randInt(0,255) + "," + randInt(0,255) + "," + randInt(0,255) + ")";
}
function ctg(x) {
return 1 / Math.tan(x);
}
function draw() {
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
let canvasWidth = 300;
canvas.width = canvas.height = canvasWidth;
function drawUW() {
context.lineWidth = 0.1;
context.beginPath();
context.moveTo(0,canvas.height/2);
context.lineTo(canvas.width,canvas.height/2);
context.moveTo(canvas.width/2,0);
context.lineTo(canvas.width/2,canvas.height);
context.stroke();
}
function updateCanvas() {
context.clearRect(0,0,canvas.width,canvas.height);
drawUW();
}
let x = 50, y = 50, z = 50;
let d = 100;
let x0 = canvas.width/2;
let y0 = canvas.height/2;
let x1 = x0+x;
let y1 = y0;
let x2 = x0;
let y2 = y0-y;
let x3 = x0+x;
let y3 = y0-y;
// x' = xd/(z+d)
// y' = yd/(z+d)
let x0p=x0*d/(z+d);
let y0p=y0*d/(z+d);
let x1p=x1*d/(z+d);
let y1p=y1*d/(z+d);
let x2p=x2*d/(z+d);
let y2p=y2*d/(z+d);
let x3p=x3*d/(z+d);
let y3p=y3*d/(z+d);
function getWalls() {
wall01 = [[x0,x2,x3,x1],[y0,y2,y3,y1]];
wall02 = [[x0p,x2p,x2,x0],[y0p,y2p,y2,y0]];
wall03 = [[x0p,x2p,x3p,x1p],[y0p,y2p,y3p,y1p]];
wall04 = [[x1p,x3p,x3,x1],[y1p,y3p,y3,y1]];
wall05 = [[x2,x2p,x3p,x3],[y2,y2p,y3p,y3]];
wall06 = [[x0,x0p,x1p,x1],[y0,y0p,y1p,y1]];
}
function drawWall(wall) {
context.fillStyle = randomColor();
context.strokeStyle = "black";
context.lineWidth = 0.5;
context.beginPath();
context.moveTo(wall[0][0],wall[1][0]);
context.lineTo(wall[0][1],wall[1][1]);
context.lineTo(wall[0][2],wall[1][2]);
context.lineTo(wall[0][3],wall[1][3]);
context.lineTo(wall[0][0],wall[1][0]);
context.fill();
context.stroke();
}
function rotatePoint(x,y,z,fi) {
fi*=Math.PI/180;
arr = [x,y,z,1];
newX = 0;
newY = 0;
newZ = 0;
tx = -150, ty = -150, tz = -150;
arrTranslate = [
[1,0,0,tx],
[0,1,0,ty],
[0,0,1,tz],
[0,0,0,1]
];
// z
arrRotate = [
[Math.cos(fi),-Math.sin(fi),0,0],
[Math.sin(fi),Math.cos(fi),0,0],
[0,0,1,0],
[0,0,0,1]
];
// translate
// for (let i = 0; i < arr.length; i++) {
// newX += arr[i] * arrTranslate[0][i];
// newY += arr[i] * arrTranslate[1][i];
// newZ += arr[i] * arrTranslate[2][i];
// }
//rotate
for (let i = 0; i < arr.length; i++) {
newX += arr[i] * arrRotate[0][i];
newY += arr[i] * arrRotate[1][i];
newZ += arr[i] * arrRotate[2][i];
}
tx = 150, ty = 150, tz = 150;
// translate
// for (let i = 0; i < arr.length; i++) {
// newX += arr[i] * arrTranslate[0][i];
// newY += arr[i] * arrTranslate[1][i];
// newZ += arr[i] * arrTranslate[2][i];
// }
x = newX;
y = newY;
z = newZ;
return [newX,newY,newZ];
}
function rotatePoints(fi) {
x0 = rotatePoint(x0,y0,z,fi)[0];
y0 = rotatePoint(x0,y0,z,fi)[1];
x1 = rotatePoint(x1,y1,z,fi)[0];
y1 = rotatePoint(x1,y1,z,fi)[1];
x2 = rotatePoint(x2,y2,z,fi)[0];
y2 = rotatePoint(x2,y2,z,fi)[1];
x3 = rotatePoint(x3,y3,z,fi)[0];
y3 = rotatePoint(x3,y3,z,fi)[1];
x0p = rotatePoint(x0p,y0p,z,fi)[0];
y0p = rotatePoint(x0p,y0p,z,fi)[1];
x1p = rotatePoint(x1p,y1p,z,fi)[0];
y1p = rotatePoint(x1p,y1p,z,fi)[1];
x2p = rotatePoint(x2p,y2p,z,fi)[0];
y2p = rotatePoint(x2p,y2p,z,fi)[1];
x3p = rotatePoint(x3p,y3p,z,fi)[0];
y3p = rotatePoint(x3p,y3p,z,fi)[1];
}
let inFi = document.getElementById("fi");
inFi.addEventListener("change", updateImage);
function updateImage() {
rotatePoints(inFi.value);
getWalls();
updateCanvas();
drawWall(wall06);
drawWall(wall04);
drawWall(wall03);
drawWall(wall02);
drawWall(wall05);
drawWall(wall01);
}
updateImage();
}
<body onload="draw();">
<canvas id="canvas"></canvas>
<div><input type="number" id="fi" value="0"></div>
</body>
Im making a small game where I move a ball onDeviceOrientation into holes. I generate holes(circles) in canvas and push them into an array called holes. When I'm trying to check for collision, the declared value let currentHole = this.holes[i]; shows this error. Can you tell me why the property of 0 is undefined? I couldn't understand checking other people's problems.
this is my JS code:
const canvas = document.querySelector('.canvas');
const hole = canvas.getContext('2d');
let scoreCount = 0;
let holes = [];
var hx = Math.random() * canvas.width;
var hy = Math.random() * canvas.height;
var radius = 25;
var sAngle = 0;
var eAngle = 2 * Math.PI;
let speedX = 0;
let speedY = 0;
let x = 200;
let y = 200;
window.addEventListener('deviceorientation', onDeviceOrientationChange);
const restart = document.querySelector('.restart');
document.querySelector('.start').addEventListener('click', onStartClick);
function onStartClick() {
const btn = document.querySelector('.start');
btn.classList.add('remove');
restart.classList.remove('remove');
const score = document.createElement('span');
score.classList.add('score');
score.innerHTML = 'SCORE: ' + scoreCount;
document.body.appendChild(score);
let ball = document.createElement('div');
ball.classList.add('ball');
document.body.appendChild(ball);
makeHoles();
onDeviceOrientationChange(event);
checkForCollision();
}
function onDeviceOrientationChange(event) {
let ball = document.querySelector('.ball');
speedX = event.alpha / 60; //alpha nie
speedY = event.beta / 60;
if ((innerWidth > speedX + x > 0)) {
x += speedX;
ball.style.left = x + 'px';
}
if (window.innerHeight > speedY + y > 0) {
y += speedY;
ball.style.top = y + 'px';
}
}
function makeHoles() {
for (let i = 1; i < canvas.width / 100; i++) {
hole.beginPath();
hole.arc(
hx,
hy,
radius,
sAngle,
eAngle,
);
hole.fillStyle = 'rgb(84, 93, 139)';
hole.fill();
hole.stroke();
hole.closePath();
holes.push(hole);
}
console.log(holes);
}
function checkForCollision() {
for (let i = 0; i < holes.length; i++) {
let currentHole = this.holes[i];
let ball = document.querySelector('.ball');
currentHole = {
radius: radius,
x: hx,
y: hy
};
ball = {
radius: 15,
x: x,
y: y
};
var dx = currentHole.x - ball.x;
var dy = currentHole.y - ball.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < currentHole.radius + ball.radius) {
scoreCount++;
}
}
}
You should use 'holes[i]', not 'this.holes[i]'.
I've found this codepen that I'm integrating on a small website I have for a project. I don't want to put too much time into it, so I'll just be using a codepen I found. I'll do some adjustments to it, like the shape.
I managed to implement it, but now I'm having trouble to change the colors and the shape of the confetti.
The colors are completely random and I'd love for this to just be simple.
Also, I can't seem to be able to change the shape. I can only adjust the size.
If anyone here feels like giving me a nudge in the right direction, that'd be great!
'use strict';
// If set to true, the user must press
// UP UP DOWN ODWN LEFT RIGHT LEFT RIGHT A B
// to trigger the confetti with a random color theme.
// Otherwise the confetti constantly falls.
var onlyOnKonami = false;
$(function() {
// Globals
var $window = $(window)
, random = Math.random
, cos = Math.cos
, sin = Math.sin
, PI = Math.PI
, PI2 = PI * 2
, timer = undefined
, frame = undefined
, confetti = [];
// Settings
var konami = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]
, pointer = 0;
var particles = 150
, spread = 40
, sizeMin = 3
, sizeMax = 12 - sizeMin
, eccentricity = 10
, deviation = 100
, dxThetaMin = -.1
, dxThetaMax = -dxThetaMin - dxThetaMin
, dyMin = .13
, dyMax = .18
, dThetaMin = .4
, dThetaMax = .7 - dThetaMin;
var colorThemes = [
function() {
return color(200 * random()|0, 200 * random()|0, 200 * random()|0);
}, function() {
var black = 200 * random()|0; return color(200, black, black);
}, function() {
var black = 200 * random()|0; return color(black, 200, black);
}, function() {
var black = 200 * random()|0; return color(black, black, 200);
}, function() {
return color(200, 100, 200 * random()|0);
}, function() {
return color(200 * random()|0, 200, 200);
}, function() {
var black = 256 * random()|0; return color(black, black, black);
}, function() {
return colorThemes[random() < .5 ? 1 : 2]();
}, function() {
return colorThemes[random() < .5 ? 3 : 5]();
}, function() {
return colorThemes[random() < .5 ? 2 : 4]();
}
];
function color(r, g, b) {
return 'rgb(' + r + ',' + g + ',' + b + ')';
}
// Cosine interpolation
function interpolation(a, b, t) {
return (1-cos(PI*t))/2 * (b-a) + a;
}
// Create a 1D Maximal Poisson Disc over [0, 1]
var radius = 1/eccentricity, radius2 = radius+radius;
function createPoisson() {
// domain is the set of points which are still available to pick from
// D = union{ [d_i, d_i+1] | i is even }
var domain = [radius, 1-radius], measure = 1-radius2, spline = [0, 1];
while (measure) {
var dart = measure * random(), i, l, interval, a, b, c, d;
// Find where dart lies
for (i = 0, l = domain.length, measure = 0; i < l; i += 2) {
a = domain[i], b = domain[i+1], interval = b-a;
if (dart < measure+interval) {
spline.push(dart += a-measure);
break;
}
measure += interval;
}
c = dart-radius, d = dart+radius;
// Update the domain
for (i = domain.length-1; i > 0; i -= 2) {
l = i-1, a = domain[l], b = domain[i];
// c---d c---d Do nothing
// c-----d c-----d Move interior
// c--------------d Delete interval
// c--d Split interval
// a------b
if (a >= c && a < d)
if (b > d) domain[l] = d; // Move interior (Left case)
else domain.splice(l, 2); // Delete interval
else if (a < c && b > c)
if (b <= d) domain[i] = c; // Move interior (Right case)
else domain.splice(i, 0, c, d); // Split interval
}
// Re-measure the domain
for (i = 0, l = domain.length, measure = 0; i < l; i += 2)
measure += domain[i+1]-domain[i];
}
return spline.sort();
}
// Create the overarching container
var container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '0';
container.style.left = '0';
container.style.width = '100%';
container.style.height = '0';
container.style.overflow = 'visible';
container.style.zIndex = '9999';
// Confetto constructor
function Confetto(theme) {
this.frame = 0;
this.outer = document.createElement('div');
this.inner = document.createElement('div');
this.outer.appendChild(this.inner);
var outerStyle = this.outer.style, innerStyle = this.inner.style;
outerStyle.position = 'absolute';
outerStyle.width = (sizeMin + sizeMax * random()) + 'px';
outerStyle.height = (sizeMin + sizeMax * random()) + 'px';
innerStyle.width = '100%';
innerStyle.height = '100%';
innerStyle.backgroundColor = theme();
outerStyle.perspective = '50px';
outerStyle.transform = 'rotate(' + (360 * random()) + 'deg)';
this.axis = 'rotate3D(' +
cos(360 * random()) + ',' +
cos(360 * random()) + ',0,';
this.theta = 360 * random();
this.dTheta = dThetaMin + dThetaMax * random();
innerStyle.transform = this.axis + this.theta + 'deg)';
this.x = $window.width() * random();
this.y = -deviation;
this.dx = sin(dxThetaMin + dxThetaMax * random());
this.dy = dyMin + dyMax * random();
outerStyle.left = this.x + 'px';
outerStyle.top = this.y + 'px';
// Create the periodic spline
this.splineX = createPoisson();
this.splineY = [];
for (var i = 1, l = this.splineX.length-1; i < l; ++i)
this.splineY[i] = deviation * random();
this.splineY[0] = this.splineY[l] = deviation * random();
this.update = function(height, delta) {
this.frame += delta;
this.x += this.dx * delta;
this.y += this.dy * delta;
this.theta += this.dTheta * delta;
// Compute spline and convert to polar
var phi = this.frame % 7777 / 7777, i = 0, j = 1;
while (phi >= this.splineX[j]) i = j++;
var rho = interpolation(
this.splineY[i],
this.splineY[j],
(phi-this.splineX[i]) / (this.splineX[j]-this.splineX[i])
);
phi *= PI2;
outerStyle.left = this.x + rho * cos(phi) + 'px';
outerStyle.top = this.y + rho * sin(phi) + 'px';
innerStyle.transform = this.axis + this.theta + 'deg)';
return this.y > height+deviation;
};
}
function poof() {
if (!frame) {
// Append the container
document.body.appendChild(container);
// Add confetti
var theme = colorThemes[onlyOnKonami ? colorThemes.length * random()|0 : 0]
, count = 0;
(function addConfetto() {
if (onlyOnKonami && ++count > particles)
return timer = undefined;
var confetto = new Confetto(theme);
confetti.push(confetto);
container.appendChild(confetto.outer);
timer = setTimeout(addConfetto, spread * random());
})(0);
// Start the loop
var prev = undefined;
requestAnimationFrame(function loop(timestamp) {
var delta = prev ? timestamp - prev : 0;
prev = timestamp;
var height = $window.height();
for (var i = confetti.length-1; i >= 0; --i) {
if (confetti[i].update(height, delta)) {
container.removeChild(confetti[i].outer);
confetti.splice(i, 1);
}
}
if (timer || confetti.length)
return frame = requestAnimationFrame(loop);
// Cleanup
document.body.removeChild(container);
frame = undefined;
});
}
}
$window.keydown(function(event) {
pointer = konami[pointer] === event.which
? pointer+1
: +(event.which === konami[0]);
if (pointer === konami.length) {
pointer = 0;
poof();
}
});
if (!onlyOnKonami) poof();
});
Look inside Confetto() it's just using a <div> inside another <div> and giving it random width, height, 3D rotation, etc., you should be able to manipulate innerStyle and/or outerStyle to your liking there.
Try adding something like this to make it rounded:
innerStyle.borderRadius = '100%';
Try something like this to make it squared:
innerStyle.borderRadius = '0';
Or a combination:
innerStyle.borderRadius = '100% 0 0 100%';
You should be able to set any style property you need, by camel-casing the css name (.border for border, .borderBottom for border-bottom, .borderBottomColor for border-bottom-color, etc.). Check this list for ideas
I have the code listed below. The code is on https://omegalords.ga/test.world.html. I want the item to not move beyond the canvas. How can I find how many units are in the canvas? I am aware of the other errors in the console. I specifically need the canvas's dimensions in reference to items placed on the canvas. The point of the code is to create a wolf and a deer that interact. The problem is that I need to ensure that the 2 don't leave the canvas.
<script src=../script/algebra-0.2.6.min.js></script>
<canvas id="myCanvas" style="width:100%; height:100%;">
</canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
console.log(document.body.style)
var findDis = function(x1,y1,x2,y2){
//Finds distance rounded to the nearest 1000th
return Math.trunc(((Math.sqrt((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2)))*1000))/1000
}
var findIntersections = function(b,a,m,r){
var Fraction = algebra.Fraction;
var Expression = algebra.Expression;
var Equation = algebra.Equation;
var coords = {
l:[],
g:[]
}
//b^2 - 2bx + x^2 - 2bm^2x + b^2m^2 - r^2
var sl = algebra.parse(Math.pow(b,2)+" - "+2*b+"x + x^2 + "+Math.pow(m,2)+"x^2 -" + 2 * b * Math.pow(m,2) + "* x + " + Math.pow(b,2) * Math.pow(m,2) + " - " + Math.pow(r,2));
var sr = algebra.parse("0")
var eq = new Equation(sl, sr);
//Solves for x rounded to the nearest 1000
coords.l.push(Math.trunc((eq.solveFor("x")[0]*1000))/1000);
coords.g.push(Math.trunc((eq.solveFor("x")[1]*1000))/1000);
//Solves for y
coords.l.push(Math.trunc((eq.solveFor("x")[0] * m + a - (b * m))*1000)/1000);
coords.g.push(Math.trunc((eq.solveFor("x")[1] * m + a - (b * m))*1000)/1000);
return JSON.stringify(coords);
}
var findSlope = function(x1,y1,x2,y2){
//Finds Slope rounded to the nearest 1000th
return Math.trunc(((y1-y2)/(x1-x2))*1000)/1000;
}
var getRandomInt = function(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var wolves = [];
var deers = [];
var animal = function(x,y){
this.age = 0
this.strength = 0;
this.x = x;
this.y = y;
this.hp = 100;
this.size = 10;
this.hunger = 0;
}
animal.prototype.move = function(){
this.nearbyPredators = [];
this.nearbyPrey = [];
for(var j = 0;j<this.predatorTypes.length;j++){
for(var i = 0;i < this.predatorTypes[j].length;i++){
if(findDis(this.predatorTypes[j][i].x,this.predatorTypes[j][i].y,this.x,this.y) < 40){
this.nearbyPredators.push(this.predatorTypes[j][i]);
}else{
console.log(findDis(this.predatorTypes[j][i].x,this.this.predatorTypes[j][i].y,this.x,this.y))
}
}
}
//finds all nearby prey
for(var j = 0;j<this.preyTypes.length;j++){
for(var i = 0;i < this.preyTypes[j].length;i++){
if(findDis(this.preyTypes[j][i].x,this.preyTypes[j][i].y,this.x,this.y) < 40){
this.nearbyPrey.push(this.preyTypes[j][i]);
}else{
console.log(findDis(this.preyTypes[j][i].x,this.preyTypes[j][i].y,this.x,this.y))
}
}
}
if(this.nearbyPredators.length == 0){
//If there are no nearby prey, move randomly
if(this.nearbyPrey.length === 0){
var tx = this.x + getRandomInt(-8,9);
var ty = this.y + getRandomInt(-9,8);
while(!(tx > (0 + this.size)) && !(ty > (0 + this.size)) && !(tx < (canvas.length - this.size)) && !(ty < (canvas.height - this.size))){
tx = this.x + getRandomInt(-8,9);
ty = this.y + getRandomInt(-9,8);
}
this.x = tx
this.y = ty
//If there is only one nearby prey, move towards it
}else if(this.nearbyPrey.length === 1){
this.nearestPrey = this.nearbyPrey[0]
var tempDis = findDis(this.x,this.y,this.nearestPrey.x,this.nearestPrey.y);
if(tempDis < 2*this.nearestPrey.size){
this.bite(this.nearestPrey)
}else {
var slope = findSlope(this.nearestPrey.x,this.nearestPrey.y,this.x,this.y);
var coords = JSON.parse(findIntersections(this.x,this.y,slope,0.125));
var ldis = findDis(this.x,this.y,coords.l[0],coords.l[1]);
var gdis = findDis(this.x,this.y,coords.g[0],coords.g[1]);
if(ldis > gdis){
this.x = coords.l[0]
this.y = coords.l[1]
}else {
this.x = coords.g[0]
this.y = coords.g[1]
}
}
//If there is more than 1, find the nearest prey and move towards it
}else {
for(var i = 0; i < this.nearbyPrey.length; i++){
this.tempDis = getDis(this.x,this.y,this.nearbyPrey[i].x,this.nearbyPrey[i].y)
if(typeof this.nearestPrey == 'undefined'){
this.nearestPrey = {
prey:this.nearbyPrey[i],
distance:this.tempDis
}
this.tempDis = undefined
}else {
if(this.tempDis > this.nearestPrey.distance){
this.nearestPrey = {
prey:this.nearbyPrey[i],
distance:this.tempDis
}
}
}
}
var slope = findSlope(this.nearestPrey.x,this.nearestPrey.y,this.x,this.y)
var coords = JSON.parse(findIntersections(this.nearestPrey.x,this.nearestPrey.y,slope,0.25));
var ldis = findDis(this.nearestPrey.x,this.nearestPrey.y,coords.l[0],coords.l[1]);
var gdis = findDis(this.nearestPrey.x,this.nearestPrey.y,coords.g[0],coords.g[1]);
if(ldis > gdis){
this.x = coords.l[0]
this.y = coords.l[1]
}else {
this.x = coords.g[0]
this.y = coords.g[1]
}
}
}else {
}
}
var grass = function(){
}
var deer = function(x,y){
animal.call(this,x,y)
deers.push(this);
this.preyTypes = [grass];
this.predatorTypes = [wolves];
}
var wolf = function(x,y){
animal.call(this,x,y)
wolves.push(this);
this.predatorTypes = [];
this.preyTypes = [deers]
}
deer.prototype = Object.create(animal.prototype);
wolf.prototype = Object.create(animal.prototype);
wolf.prototype.bite = function(prey){
prey.hp -= this.strength;
if(prey.hp < 0){
prey.die()
}
this.hunger += 40/100
console.log(this.hunger);
console.log(prey.hp)
}
new wolf(100,100)
new deer(50,50);
var init = function(){
ctx.translate(0.5, 0.5);
ctx.lineWidth = .5
window.setInterval(draw,250);
}
var draw = function(){
ctx.clearRect(0,0,canvas.width,canvas.height)
wolves[0].move();
for(var i=0;i<wolves.length;i++){
ctx.beginPath()
ctx.arc(wolves[i].x,wolves[i].y,10,0,2*Math.PI);
ctx.stroke();
}
for(var i=0; i<deers.length;i++){
ctx.beginPath();
ctx.arc(deers[i].x,deers[i].y,10,0,2*Math.PI);
ctx.stroke();
}
}
init()
</script>
var canvasHeight = canvas.clientHeight;
var canvasWidth = canvas.clientWidth;
Please note, this will also include any padding, but by default, the canvas has no padding.
Sources:
https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight
https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth
You can get the css properties:
var canvasWidth = canvas.style.width;
var canvasHeight = canvas.style.height;
function randomXToY(minVal,maxVal,floatVal)
{
var randVal = minVal+(Math.random()*(maxVal-minVal));
return typeof floatVal=='undefined'?Math.round(randVal):randVal.toFixed(floatVal);
}
Ball = (function() {
// constructor
function Ball(x,y,radius,color){
this.center = {x:x, y:y};
this.radius = radius;
this.color = color;
this.dx = 2;
this.dy = 2;
this.boundaryHeight = $('#ground').height();
this.boundaryWidth = $('#ground').width();
this.dom = $('<p class="circle"></p>').appendTo('#ground');
// the rectange div a circle
this.dom.width(radius*2);
this.dom.height(radius*2);
this.dom.css({'border-radius':radius,background:color});
this.placeAtCenter(x,y);
}
// Place the ball at center x, y
Ball.prototype.placeAtCenter = function(x,y){
this.dom.css({top: Math.round(y- this.radius), left: Math.round(x - this.radius)});
this.center.x = Math.round(x);
this.center.y = Math.round(y);
};
Ball.prototype.setColor = function(color) {
if(color) {
this.dom.css('background',color);
} else {
this.dom.css('background',this.color);
}
};
// move and bounce the ball
Ball.prototype.move = function(){
var diameter = this.radius * 2;
var radius = this.radius;
if (this.center.x - radius < 0 || this.center.x + radius > this.boundaryWidth ) {
this.dx = -this.dx;
}
if (this.center.y - radius < 0 || this.center.y + radius > this.boundaryHeight ) {
this.dy = -this.dy;
}
this.placeAtCenter(this.center.x + this.dx ,this.center.y +this.dy);
};
return Ball;
})();
var number_of_balls = 5;
var balls = [];
$('document').ready(function(){
for (i = 0; i < number_of_balls; i++) {
var boundaryHeight = $('#ground').height();
var boundaryWidth = $('#ground').width();
var y = randomXToY(30,boundaryHeight - 50);
var x = randomXToY(30,boundaryWidth - 50);
var radius = randomXToY(15,30);
balls.push(new Ball(x,y,radius, '#'+Math.floor(Math.random()*16777215).toString(16)));
}
loop();
});
loop = function(){
for (var i = 0; i < balls.length; i++){
balls[i].move();
}
setTimeout(loop, 8);
};
I have never used in oops concepts in javascript. How do I change the ball color when the balls touches each other?
This is the link : http://jsbin.com/imofat/1/edit
You currently don't have any interaction with the balls. What you can do is checking whether two balls are "inside" each other, and change colors in that case: http://jsbin.com/imofat/1491/.
// calculates distance between two balls
var d = function(a, b) {
var dx = b.center.x - a.center.x;
var dy = b.center.y - a.center.y;
return Math.sqrt(dx*dx + dy*dy);
};
and:
// for each ball
for(var i = 0; i < balls.length; i++) {
// check against rest of balls
for(var j = i + 1; j < balls.length; j++) {
var a = balls[i];
var b = balls[j];
// distance is smaller than their radii, so they are inside each other
if(d(a, b) < a.radius + b.radius) {
// set to some other color using your random color code
a.setColor('#'+Math.floor(Math.random()*16777215).toString(16));
b.setColor('#'+Math.floor(Math.random()*16777215).toString(16));
}
}
}
Still, there are things for improvement:
Balls are changing colors as long as they are inside each other, not just once.
If you want them to "touch", you might want to implement some kind of bouncing effect to make it more realistic.