Как уже говорил Хао-Шер Хонг: ваш randomFruit возвращает строку, а не объект Fruit.
Просматривая ваш код, я вижу, что вы повторяете себя много раз , Есть лучшие способы.
Могу ли я предложить какой-нибудь рефакторинг?
Например, в своем конструкторе вы добавляете к каждому свойству префикс fruit , но поскольку весь объект является фруктом , это не обязательно. Вот более чистый пример:
class Fruit {
constructor(x, y, type) {
this.x = x; //each fruit has a x
this.y = y; //each fruit has a y
this.width = 100; //each fruit has a width of 100
this.height = 50; //each fruit has a height of 50
this.isVisible = true; //fruit is visible
this.speed = 1; //fruit moves by 1
this.type = type; //fruit type
this.typeData = Fruit.typeNameToData[type]; // // Get data for fruit
if (!this.typeData) throw Error(`Unknown fruit: "${type}`); // Throw Error if unknown fruit
this.image = new Image(); //fruit image
this.image.src = this.typeData.image;
}
}
Вместо того, чтобы определять названия фруктов в нескольких местах в вашем коде, сделайте это один раз и используйте его повторно. В этом примере я поместил переменную непосредственно в объект Fruit. Это называется stati c. К сожалению, синтаксис для классов в настоящее время поддерживает только функции stati c, но можно определить переменные непосредственно следующим образом:
// Define fruit types
Fruit.types = [
{
name: "strawberry",
image: "Images/strawberry.png"
},
{
name: "banana",
image: "Images/banana.png"
},
{
name: "orange",
image: "Images/orange.png"
}
];
Fruit.typeNames = []; // List of typeNames
Fruid.typeNameToData = Object.create(null); // Create an empty object. Could also use a map, but I don't want to introduce too many new things at once.
Fruit.types.forEach(item => {
// here is some "magic": Reusing the data from *Fruit.types* to create a lookup
// for the name, and a list of names.
Fruit.typeNameToData[item.name] = item; // Map name to data
Fruit.typeNames.push(item.name); // add name to array
});
randomFruit можно сократить до этого:
function randomFruit() {
//function is to generate a random fruit
const fruitchoices = Fruit.typeNames; // Use list of fruits
const fruitId = Math.floor(Math.random() * fruitchoices.length);
const fruitX = Math.random() * (480 - 0);
const fruitY = 0;
return new Fruit(fruitX, fruitY, fruitchoices[fruitId]);
}
Я заметил, что вы пытаетесь использовать глобальную переменную i
здесь:
function moveFruit() {
fruits[i].Y += fruits[i].fruitSpeed; //the y value of the fruits in the array will be added by the fruit speed
}
Не используйте подобные глобальные переменные. Я обещаю вам, что вы будете создавать трудно найти ошибки, и вы случайно измените переменную в другой l oop. Добавьте аргумент в функцию и отправьте значение таким образом.