代码崩溃,因为对象的.rad属性变为未定义

时间:2019-04-09 19:20:45

标签: javascript function object canvas crash

我正在创建一个生态系统,其代码由植物,草食动物和食肉动物组成,并用圆圈表示。出于某种原因,我的代码在经过30秒到8分钟(但不超过此时间)的一定时间后一直崩溃。

进行了一些挖掘之后,我发现崩溃是由于我的对象的.rad属性由于某种原因而变得未定义的结果。可能是由于我不正确地设置函数而导致的,但是我找不到解决方法。

var plantSpawn = 5;
var herbSpawn = 3;
var carnSpawn = 2;

var myPlants = new Array();
var myCarns = new Array();
var myHerbs = new Array();

		//////////////PLANTS//////////////////
	
function createPlants() {
	
	reproducePlants();
	setInterval(reproducePlants, 5000);
	
}	
	
function reproducePlants() {
	
	for(var p=0; p<plantSpawn; p++){
		
		
		var rr = Math.round(Math.random() * 150);
		var gg = Math.round(Math.random() * 255);
		var bb = Math.round(Math.random() * 150);
	
		var plant = new Object();
			plant.x = Math.random() * canvas.width;
			plant.y = Math.random() * canvas.height;
			plant.rad = 2 + Math.random()*2;
			plant.skin = 'rgba('+rr+','+gg+','+bb+', 1)';
		
		myPlants.push(plant);
		
	}
}
	
function drawPlants(){
	var plantAmt = myPlants.length;
	
	for(var j=0; j<plantAmt; j++) {
		
		if (myPlants[j].x + myPlants[j].rad >= canvas.width) {
			myPlants[j].x -= 10;
		}
		
		if (myPlants[j].y + myPlants[j].rad >= canvas.height) {
			myPlants[j].y -= 10;
		}
		
		context.beginPath();
			context.arc(myPlants[j].x, myPlants[j].y, myPlants[j].rad, 0, Math.PI*2, false);
		context.closePath();
		
		context.fillStyle = myPlants[j].skin;
		context.fill();
	}
}
	
function killPlants() {
	plantDeath();
	setInterval(plantDeath, 30000); //play with inc
}
	
function plantDeath() {
	myPlants.splice(0,5);
}

		//////////////HERBS//////////////////

function herbsLife(){
	reproduceHerbs();
	setInterval(reproduceHerbs, 10000);
	
	herbsDeath();
	setInterval(herbsDeath, 90000); //1.5 minutes
	setInterval(herbsStarve, 10000); //10 seconds
}
	
function reproduceHerbs() {
	
	for (var h=0; h<herbSpawn; h++){
		
		var gg = Math.round(Math.random() * 100);
		var bb = Math.round(Math.random() * 255);
		
		var herbivore = new Object();
			herbivore.x = Math.random() * canvas.width;
			herbivore.y = Math.random() * canvas.height;
			herbivore.rad = 5 + Math.random()*3;
			herbivore.skin = 'rgba(0,'+gg+','+bb+', 1)';

			herbivore.speedH = -3 + Math.random()*1.2;
			herbivore.speedV = -3 + Math.random()*1.2;
			herbivore.dirH = 1;
			herbivore.dirV = 1;
		
		myHerbs.push(herbivore);
	}
	
}	
	
function drawHerbs() {
	var herbAmt = myHerbs.length;
	
	for(var j=0; j<herbAmt; j++) {
		var hX = myHerbs[j].x;
		var hY = myHerbs[j].y;
		
		//HERB MOVEMENT//
		
		myHerbs[j].x += myHerbs[j].dirH * myHerbs[j].speedH;
		
		if (myHerbs[j].x > canvas.width + myHerbs[j].rad || myHerbs[j].x < 0){

			myHerbs[j].dirH *= -1;

		}
		
		myHerbs[j].y += myHerbs[j].dirV * myHerbs[j].speedV; 
		
		
		if (myHerbs[j].y > canvas.height + myHerbs[j].rad || myHerbs[j].y < 0){

			myHerbs[j].dirV *= -1;

		}
 
		
		context.beginPath();
			context.arc(myHerbs[j].x, myHerbs[j].y, myHerbs[j].rad, 0, Math.PI*2, false);
		context.closePath();
		
		context.fillStyle = myHerbs[j].skin;
		context.fill();
	}
}	

	
function herbsDeath() {
	myHerbs.splice(0,3);
}	
	
function herbsEat() {
	for (var k=0; k<myPlants.length; k++){
		var pX = myPlants[k].x;
		var pY = myPlants[k].y;

	
	for (var h=0; h<myHerbs.length; h++){
		var hX = myHerbs[h].x;
		var hY = myHerbs[h].y;

	
		var eX = hX - pX;
		var eY = hY - pY;
		var dist = Math.sqrt(Math.pow(eX,2) + Math.pow(eY,2));
	
			if (dist < myPlants[k].rad*2) { 
				myPlants.splice(k,1);
				myHerbs[h].rad += 1;
			}	
		}	
	}
}
	
function herbsStarve() {
	for (var s=0; s<myPlants.length; s++){
		myHerbs[s].rad -= 1;
		if (myHerbs[s].rad <= 2) {
			myHerbs.splice(s,1);
		}
	}
}


//////////////CARNS//////////////////

function carnsLife() {
	
	reproduceCarns();
	setInterval(reproduceCarns, 20000); //20 seconds
	
	carnsDeath();
	setInterval(carnsDeath, 60000); //50 seconds
	setInterval(carnsStarve, 7500); //10 seconds
}	
	
	
function reproduceCarns() {
	for (var c=0; c<carnSpawn; c++){
		
		var rr = Math.round(Math.random() * 255);
		var gg = Math.round(Math.random() * 100);
		
		var carnivore = new Object();
			carnivore.x = Math.random() * canvas.width;
			carnivore.y = Math.random() * canvas.height;
			carnivore.rad = 7 + Math.random()*3;
			carnivore.skin = 'rgba('+rr+','+gg+',0, 1)';

				//bigger random = slower//
			carnivore.speedH = -3 + Math.random()*2; 
			carnivore.speedV = -3 + Math.random()*2;
			carnivore.dirH = 1;
			carnivore.dirV = 1;
		
		myCarns.push(carnivore);
	}
}

function drawCarns() {
	var carnAmt = myCarns.length;
	
	for(var j=0; j<carnAmt; j++) {
		
		//CARN MOVEMENT//
		
		myCarns[j].x += myCarns[j].dirH * myCarns[j].speedH;
		
		if (myCarns[j].x > canvas.width + myCarns[j].rad || myCarns[j].x < 0){

			myCarns[j].dirH *= -1;

		}
		
		myCarns[j].y += myCarns[j].dirV * myCarns[j].speedV; 
		
		
		if (myCarns[j].y > canvas.height + myCarns[j].rad || myCarns[j].y < 0){

			myCarns[j].dirV *= -1;

		}
		
		context.beginPath();
			context.arc(myCarns[j].x, myCarns[j].y, myCarns[j].rad, 0, Math.PI*2, false);
		context.closePath();
		
		context.fillStyle = myCarns[j].skin;
		context.fill();
	}
	
	}	
	
function carnsDeath() {
	myCarns.splice(0,2);
}
	
function carnsEat() {
	for (var k=0; k<myCarns.length; k++){
		var cX = myCarns[k].x;
		var cY = myCarns[k].y;

	
	for (var h=0; h<myHerbs.length; h++){
		var hX = myHerbs[h].x;
		var hY = myHerbs[h].y;

	
		var eX = cX - hX;
		var eY = cY - hY;
		var dist = Math.sqrt(Math.pow(eX,2) + Math.pow(eY,2));
	
		if (dist < myCarns[k].rad*1.2 && myCarns[k].rad > myHerbs[h].rad) { 
			myHerbs.splice(h,1);
			myCarns[k].rad += 1;
		}	
		}	
	}
}
	
function carnsStarve() {
	for (var q=0; q<myPlants.length; q++){
		myCarns[q].rad = myCarns[q].rad - 1;
		if (myCarns[q].rad <= 5) {
			myCarns.splice(q,1);
		}
	}
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">



<title> Ecosystem </title>



<!-- import external .js scripts here -->

<script type="text/javascript" src="Creatures.js" ></script>

<!-- modify CSS properties here -->

<style type="text/css">

  body,td,th {
  font-family: Monaco, "Courier New", "monospace";
  font-size: 14px;
  color: rgba(255,255,255,1);
  }

  body {
  background-color: rgba(0,0,0,1);
  }

  #container {
  position: relative;
  text-align: left;
  width: 95%;
  height: 800px;
  }

  #fmxCanvas {
  position: relative;
  background-color:rgba(255,255,255,1);
  border: rgba(255,255,255,1) thin dashed;
  cursor: crosshair;
  display: inline-block;
  }

</style>

</head>



<body>

<div id="container">
<!-- START HTML CODE HERE -->


<canvas id="fmxCanvas" width="800" height="800"></canvas>

<div id="display"></div>




<!-- FINISH HTML CODE HERE -->
</div>

<script>

///////////////////////////////////////////////////////////////////////
// DECLARE requestAnimFrame

var rAF = window.requestAnimFrame ||
window.mozRequestAnimFrame ||
window.webkitRequestAnimFrame ||
window.msRequestAnimFrame;

var fps = 30;

window.requestAnimFrame = (

function(callback) {

return rAF ||

function(callback) {
window.setTimeout(callback, 1000 / fps);
};

})();

///////////////////////////////////////////////////////////////////////
// DEFINE GLOBAL VARIABLES HERE

var canvas;
var context;
canvas = document.getElementById("fmxCanvas");
context = canvas.getContext("2d");

var canvas1;
var context1;
canvas1 = document.createElement("canvas");
context1 = canvas1.getContext("2d");

canvas1.width = canvas.width;
canvas1.height = canvas.height;

var display;
display = document.getElementById('display');

var counter;

///////////////////////////////////////////////////////////////////////
// DEFINE YOUR GLOBAL VARIABLES HERE
			

///////////////////////////////////////////////////////////////////////
// CALL THE EVENT LISTENERS

window.addEventListener("load", setup, false);


//////////////////////////////////////////////////////////////////////
// ADD EVENT LISTENERS

canvas.addEventListener("mousemove", mousePos, false);

//////////////////////////////////////////////////////////////////////
// MOUSE COORDINATES

var stage, mouseX, mouseY;

function mousePos(event) {
stage = canvas.getBoundingClientRect();
mouseX = event.clientX - stage.left;
mouseY = event.clientY - stage.top;
}

/////////////////////////////////////////////////////////////////////
// INITIALIZE THE STARTING FUNCTION

function setup() {

/////////////////////////////////////////////////////////////////////
// DECLARE STARTING VALUES OF GLOBAL VARIABLES

counter = 0;
mouseX = canvas.width/2;
mouseY = canvas.height/2;

/////////////////////////////////////////////////////////////////////
// CALL SUBSEQUENT FUNCTIONS, as many as you need
	
createPlants();
killPlants();
	
herbsLife();

carnsLife();

clear(); // COVER TRANSPARENT CANVAS OR CLEAR CANVAS

draw(); // THIS IS WHERE EVERYTHING HAPPENS

}

////////////////////////////////////////////////////////////////////
// CLEAR THE CANVAS FOR ANIMATION
// USE THIS AREA TO MODIFY BKGD

function clear() {

context.clearRect(0,0,canvas.width, canvas.height);
context1.clearRect(0,0,canvas.width, canvas.height);

// clear additional contexts here if you have more than canvas1

}

////////////////////////////////////////////////////////////////////
// THIS IS WHERE EVERYTHING HAPPENS

function draw() {

counter += 0.1; // EASIER FOR SINE COSINE FUNCTIONS

//if (counter > Math.PI*200) { counter = 0; } // RESET COUNTER

clear(); // USE THIS TO REFRESH THE FRAME AND CLEAR CANVAS

////////////////////////////////////////////////////////////////////
// >>>START HERE>>>START HERE>>>START HERE>>>START HERE>>>START HERE


drawPlants();
drawHerbs();
drawCarns();

herbsEat();
carnsEat();
	

// <<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE
///////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
// HTML DISPLAY FIELD FOR TESTING PURPOSES

display.innerHTML = 
//	mouseX + " || " + mouseY + 
	" || Minutes = " + Math.trunc(counter/180) + 
	" || Seconds = " + Math.round(counter/3) + 
	"<br><br>" + 
	"Plants = " + myPlants.length +
	"<br>" + 
	"Herbivores = " + myHerbs.length +
	"<br>" + 
	"Carnivores = " + myCarns.length;
	


/////////////////////////////////////////////////////////////////
// LAST LINE CREATES THE ANIMATION

requestAnimFrame(draw); // CALLS draw() every nth of a second

}

</script>

</body>
</html>

0 个答案:

没有答案