用javafx实现农夫过河游戏动画的代码
时间: 2024-03-06 18:51:24 浏览: 123
好的,以下是一个简单的用 JavaFX 实现农夫过河游戏动画的代码示例。该示例包含游戏界面和游戏逻辑的实现,可以让农夫和物品在界面上移动,并实现了游戏结束的判断。
```java
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FarmerGame extends Application {
// 游戏界面的宽度和高度
private static final int WIDTH = 600;
private static final int HEIGHT = 400;
// 游戏元素的位置和大小
private static final int RIVER_Y = 200;
private static final int BOAT_SIZE = 50;
private static final int FARMER_SIZE = 30;
private static final int ANIMAL_SIZE = 40;
private static final int CARROT_SIZE = 20;
// 游戏元素的状态
private boolean farmerOnBoat = false;
private boolean wolfOnBoat = false;
private boolean sheepOnBoat = false;
private boolean carrotOnBoat = false;
// 游戏结束条件
private boolean gameOver = false;
@Override
public void start(Stage primaryStage) throws Exception {
// 创建游戏界面
Canvas canvas = new Canvas(WIDTH, HEIGHT);
GraphicsContext gc = canvas.getGraphicsContext2D();
drawRiver(gc);
drawBoat(gc);
drawFarmer(gc);
drawAnimal(gc, "wolf", 100);
drawAnimal(gc, "sheep", 160);
drawAnimal(gc, "carrot", 220);
// 将游戏界面添加到场景中
Pane root = new Pane();
root.getChildren().add(canvas);
Scene scene = new Scene(root);
// 添加船只和动物的点击事件
Rectangle boat = new Rectangle(WIDTH / 2 - BOAT_SIZE / 2, RIVER_Y - ANIMAL_SIZE - BOAT_SIZE, BOAT_SIZE, BOAT_SIZE);
boat.setFill(Color.TRANSPARENT);
root.getChildren().add(boat);
boat.setOnMouseClicked(event -> {
if (!gameOver) {
moveBoat();
}
});
Rectangle wolf = new Rectangle(100, RIVER_Y - ANIMAL_SIZE, ANIMAL_SIZE, ANIMAL_SIZE);
wolf.setFill(Color.TRANSPARENT);
root.getChildren().add(wolf);
wolf.setOnMouseClicked(event -> {
if (!gameOver && !farmerOnBoat && !sheepOnBoat && !carrotOnBoat) {
moveAnimal(wolf);
wolfOnBoat = true;
}
});
Rectangle sheep = new Rectangle(160, RIVER_Y - ANIMAL_SIZE, ANIMAL_SIZE, ANIMAL_SIZE);
sheep.setFill(Color.TRANSPARENT);
root.getChildren().add(sheep);
sheep.setOnMouseClicked(event -> {
if (!gameOver && !farmerOnBoat && !wolfOnBoat && !carrotOnBoat) {
moveAnimal(sheep);
sheepOnBoat = true;
}
});
Rectangle carrot = new Rectangle(220, RIVER_Y - ANIMAL_SIZE, ANIMAL_SIZE, ANIMAL_SIZE);
carrot.setFill(Color.TRANSPARENT);
root.getChildren().add(carrot);
carrot.setOnMouseClicked(event -> {
if (!gameOver && !farmerOnBoat && !wolfOnBoat && !sheepOnBoat) {
moveAnimal(carrot);
carrotOnBoat = true;
}
});
primaryStage.setScene(scene);
primaryStage.setTitle("农夫过河游戏");
primaryStage.show();
}
// 绘制河流
private void drawRiver(GraphicsContext gc) {
gc.setStroke(Color.BLUE);
gc.setLineWidth(10);
gc.strokeLine(0, RIVER_Y, WIDTH, RIVER_Y);
}
// 绘制船只
private void drawBoat(GraphicsContext gc) {
gc.setFill(Color.BROWN);
gc.fillRect(WIDTH / 2 - BOAT_SIZE / 2, RIVER_Y - ANIMAL_SIZE - BOAT_SIZE, BOAT_SIZE, BOAT_SIZE);
}
// 绘制农夫
private void drawFarmer(GraphicsContext gc) {
gc.setFill(Color.GREEN);
gc.fillRect(WIDTH / 2 - FARMER_SIZE / 2, RIVER_Y - ANIMAL_SIZE - BOAT_SIZE - FARMER_SIZE, FARMER_SIZE, FARMER_SIZE);
}
// 绘制动物或菜
private void drawAnimal(GraphicsContext gc, String type, int x) {
gc.setFill(getColorByType(type));
gc.fillOval(x, RIVER_Y - ANIMAL_SIZE, ANIMAL_SIZE, ANIMAL_SIZE);
}
// 根据类型获取颜色
private Color getColorByType(String type) {
switch (type) {
case "wolf":
return Color.GRAY;
case "sheep":
return Color.WHITE;
case "carrot":
return Color.ORANGE;
default:
return Color.BLACK;
}
}
// 移动船只
private void moveBoat() {
if (farmerOnBoat) {
// 农夫在船上,移动船到对岸
TranslateTransition tt = new TranslateTransition(Duration.seconds(1), boat);
tt.setToX(WIDTH - BOAT_SIZE - BOAT_SIZE / 2);
tt.play();
farmerOnBoat = false;
checkGameOver();
} else if (wolfOnBoat || sheepOnBoat || carrotOnBoat) {
// 动物或菜在船上,移动船到这岸
TranslateTransition tt = new TranslateTransition(Duration.seconds(1), boat);
tt.setToX(WIDTH / 2 - BOAT_SIZE / 2);
tt.play();
if (wolfOnBoat) {
wolfOnBoat = false;
}
if (sheepOnBoat) {
sheepOnBoat = false;
}
if (carrotOnBoat) {
carrotOnBoat = false;
}
checkGameOver();
} else {
// 空船不能移动
}
}
// 移动动物或菜
private void moveAnimal(Rectangle animal) {
TranslateTransition tt = new TranslateTransition(Duration.seconds(1), animal);
if (animal.getX() < WIDTH / 2) {
// 动物或菜在这岸,移动到船上
tt.setToX(WIDTH / 2 - ANIMAL_SIZE / 2);
} else {
// 动物或菜在船上,移动到这岸
tt.setToX(animal.getX() - WIDTH / 2 + BOAT_SIZE / 2);
}
tt.play();
}
// 检查游戏结束条件
private void checkGameOver() {
if (wolfOnBoat && sheepOnBoat && !farmerOnBoat) {
// 狼吃羊,游戏失败
gameOver = true;
System.out.println("游戏失败!");
} else if (sheepOnBoat && carrotOnBoat && !farmerOnBoat) {
// 羊吃菜,游戏失败
gameOver = true;
System.out.println("游戏失败!");
} else if (!wolfOnBoat && !sheepOnBoat && !carrotOnBoat) {
// 所有物品都到达对岸,游戏胜利
gameOver = true;
System.out.println("游戏胜利!");
}
}
public static void main(String[] args) {
launch(args);
}
}
```
上述代码中,我们使用了 JavaFX 的动画 API 来实现农夫和物品在界面上的移动。在 `start` 方法中,我们创建了船只和动物的矩形对象,并为它们添加了点击事件。当玩家点击船只时,我们调用 `moveBoat` 方法来移动船只。当玩家点击动物或菜时,我们调用 `moveAnimal` 方法来移动它们。在移动船只和动物或菜时,我们使用了 `TranslateTransition` 类来实现平移动画,并在动画结束后更新游戏元素的状态。
需要注意的是,在移动船只和动物或菜时,我们需要检查游戏结束条件。当狼吃羊或羊吃菜时,游戏失败;当所有物品都到达对岸时,游戏胜利。在检查游戏结束条件时,我们设置了 `gameOver` 标志位,防止玩家重复点击游戏元素。
阅读全文