我创建了这个游戏,玩家在其中控制一个篮子来抓随机的水果。
我的代码告诉我.draw不是first.draw()函数。 (正在绘制数组中的第一个水果),并在为该水果创建一个类后创建了一个draw函数。所以我不太确定我该怎么做才能解决此问题。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var basket = new Image();
basket.src = "basket.png";
var basketHeight = 50;
var basketWidth = 100;
var basketX = 200;
var basketY = canvas.height-50;
var basketSpeed = 5; //vary with superpowers
var rightPressed = false;
var leftPressed = false;
var score = 10;
var strawberry = new Image();
strawberry.src = "strawberry.png";
var banana = new Image();
banana.src = "banana.png";
var orange = new Image();
orange.src = "orange.png";
class Fruit{
constructor(fruitX, fruitY, fruitType){
this.fruitX = fruitX;//each fruit has a x
this.fruitY = fruitY;//each fruit has a y
this.fruitWidth = 100;//each fruit has a width of 100
this.fruitHeight = 50;//each fruit has a height of 50
this.isVisible = true;//fruit is visible
this.fruitSpeed = 1;//fruit moves by 1
this.fruitType = fruitType;//fruit type
this.fruitImage = new Image();//fruit image
if(fruitType == strawberry){//if the fruittype (comparing it with funciton randomfruit) is a strawberry, then make the image a strawberry
fruitImage= 'Images/strawberry.png';
}
else if(fruitType == banana){
fruitImage = 'Images/banana.png';
}
else if(fruitType == orange){
fruitImage = 'Images/orange.png';
}
}
draw(){
ctx.drawImage(this.fruitImage, this.fruitX, this.fruitY, this.fruitWidth, this.fruitHeight);
}
}
function randomFruit(){//function is to generate a random fruit
var fruitchoices = ['strawberry', 'banana', 'orange'];
//array has strawberry, banana, orange
var fruit = fruitchoices[Math.floor(Math.random() * fruitchoices.length)]// choose random element from above
var fruitX = Math.random() * (480-0);//declaring the variables so that we don't have to copy and paste this each time into the fruitX value since it will be the same for every fruit initally
var fruitY = 0//set the y value of the fruit to 0
//compares the selected fruit with these statements
if(fruit == 'strawberry'){
new Fruit(fruitX,fruitY, 'strawberry');//if fruit is strawberry, make the fruit a strawberry
}
else if(fruit == 'banana'){
new Fruit(fruitX, fruitY, 'banana');
}
else if(fruit == 'orange'){
new Fruit(fruitX, fruitY, 'orange');
}
return fruit;//returns fruit value
}
//function for the fruits to move down the screen
function moveFruit(){
fruits[i].Y += fruits[i].fruitSpeed;//the y value of the fruits in the array will be added by the fruit speed
}
document.addEventListener("keydown", keyDownHandler, false); // arguments "keydown" is the event
document.addEventListener("keyup", keyUpHandler, false); // keyDownHandler is the function that gets called
// when the event occurs
function keyDownHandler(e){
if(e.key == "Right" || e.key == "ArrowRight") {
rightPressed = true;
}
else if(e.key == "Left" || e.key == "ArrowLeft") {
leftPressed = true;
}
}
function keyUpHandler(e){
if(e.key == "Right" || e.key == "ArrowRight") {
rightPressed = false;
}
else if(e.key == "Left" || e.key == "ArrowLeft") {
leftPressed = false;
}
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "#0095DD";
ctx.fillText("Score:" + score, canvas.width - 100, 20);
}
//drawing the game onto the screen
function drawGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // clears top left to bottom right
drawScore();
//update basket position/controlling basket movement
if(rightPressed) {
basketX += basketSpeed;
if(basketX + basketWidth > canvas.width){
basketX = canvas.width - basketWidth;
}
}
else if (leftPressed) {
basketX -= basketSpeed;
if(basketX < 0){
basketX = 0;
}
}
// loop thru each fruit
for(var i = 0; i < fruits.length; i++){
// check each fruit y value. if it is less than ?? draw new random fruit
}
moveFruit();
}
var first = randomFruit(); //variable first is set to a randomfruit from the function randomfruit
first.draw();//drawing the first fruit
fruits.add(first);//adding the first fruit to array so that we can keep track of it for the purpose of creating our second fruit image since we want a new fruit when the first fruit passes a certain y value
var interval = setInterval(drawGame, 10);//drawing whatever is in the function drawGame every 10 milliseconds
first.draw不起作用
var first = randomFruit(); //variable first is set to a randomfruit from the function randomfruit
first.draw();//drawing the first fruit
fruits.add(first);//adding the first fruit to array so that we can keep track of it for the purpose of creating our second fruit image since we want a new fruit when the first fruit passes a certain y value
答案 0 :(得分:1)
在您的randomFruit
函数中
function randomFruit(){//function is to generate a random fruit
var fruitchoices = ['strawberry', 'banana', 'orange'];
//array has strawberry, banana, orange
var fruit = fruitchoices[Math.floor(Math.random() * fruitchoices.length)]// choose random element from above
var fruitX = Math.random() * (480-0);//declaring the variables so that we don't have to copy and paste this each time into the fruitX value since it will be the same for every fruit initally
var fruitY = 0//set the y value of the fruit to 0
//compares the selected fruit with these statements
if(fruit == 'strawberry'){
new Fruit(fruitX,fruitY, 'strawberry');//if fruit is strawberry, make the fruit a strawberry
}
else if(fruit == 'banana'){
new Fruit(fruitX, fruitY, 'banana');
}
else if(fruit == 'orange'){
new Fruit(fruitX, fruitY, 'orange');
}
return fruit;//returns fruit value
}
您实例化了Fruit对象,但是返回了水果字符串(例如'orange')而不是实例化的对象。因此
var first = randomFruit();
first.draw();
first
是字符串,String.draw
不是函数。
尝试一下:
function randomFruit(){//function is to generate a random fruit
var fruitchoices = ['strawberry', 'banana', 'orange'];
//array has strawberry, banana, orange
var fruit = fruitchoices[Math.floor(Math.random() * fruitchoices.length)]// choose random element from above
var fruitX = Math.random() * (480-0);//declaring the variables so that we don't have to copy and paste this each time into the fruitX value since it will be the same for every fruit initally
var fruitY = 0//set the y value of the fruit to 0
//compares the selected fruit with these statements
if(fruit == 'strawberry'){
return new Fruit(fruitX,fruitY, 'strawberry');//if fruit is strawberry, make the fruit a strawberry
}
else if(fruit == 'banana'){
return new Fruit(fruitX, fruitY, 'banana');
}
else if(fruit == 'orange'){
return new Fruit(fruitX, fruitY, 'orange');
}
throw new Error('unexpected fruit');
}
答案 1 :(得分:0)
您在draw()
中定义了class Fruit
您需要使用Fruit.draw()
来调用函数。
类使用作用域,因此其中定义的任何函数都必须使用类名来访问该函数。
答案 2 :(得分:0)
Hong Hao-Cher Hong已经指出:您的 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对象上。它称为 static 。不幸的是,类的语法目前仅支持静态函数,但是可以像这样直接定义变量:
// 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
}
请勿使用此类全局变量。我向您保证,您将创建难以发现的错误,并且会在另一个循环中无意中更改变量。向函数添加参数,然后以这种方式发送值。