JavaFX - 如何在不扩大对象的命中框的情况下旋转可移动对象
Posted
技术标签:
【中文标题】JavaFX - 如何在不扩大对象的命中框的情况下旋转可移动对象【英文标题】:JavaFX - How to rotate a moveable object without enlarging the hitbox of the object 【发布时间】:2021-11-29 22:53:49 【问题描述】:所以我在 javafx 中制作了一个非常基本的 2D 停车游戏(比如 Parking Mania),但我的汽车旋转有问题。它可以很好地旋转,但是当汽车旋转时,汽车的碰撞箱不会旋转,而是会在汽车对象周围变成一个更大的非旋转矩形,因此我无法准确跟踪碰撞。我尝试到处寻找解决方案,但没有成功。 我真的是 java 新手,所以我会很感激任何简单的帮助。
代码如下:
Main.java
package sample;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class Main extends Application
private Pane root;
private List<GameObject> walls = new ArrayList<>();
private GameObject wall;
private GameObject player;
private GameObject park;
private GameObject ok;
private Parent createContent()
/*private GameObject wall;
private GameObject player;*/
root = new Pane();
root.setPrefSize(1380, 720);
BackgroundImage myBI= new BackgroundImage(new Image("parkovisko.png",1380,720,false,true),
BackgroundRepeat.REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
BackgroundSize.DEFAULT);
root.setBackground(new Background(myBI));
ImageView bg = new ImageView();
player = new Player();
wall = new Wall();
park = new Park();
ok = new Ok();
/*player.setVelocity(new Point2D(1, 0));*/
addGameObject(park, 385, 0);
addGameObject(player, 610, 245);
player.rotateStart();
//addGameObject(wall, 250, 330);
AnimationTimer timer = new AnimationTimer()
@Override
public void handle(long now)
onUpdate();
;
timer.start();
return root;
private void addGameObject(GameObject object, double x, double y)
object.getView().setTranslateX(x);
object.getView().setTranslateY(y);
root.getChildren().add(object.getView());
public int h = 0;
Rectangle rectangle = new Rectangle();
private void addWall(GameObject wall, double x, double y)
walls.add(wall);
addGameObject(wall, x, y);
private void onUpdate()
for (GameObject wall : walls)
if (player.isColliding(wall))
// player.setAlive(false);
//System.exit(1);
addGameObject(ok, 350, 175);
else if (park.isContaining(player) && h == 0)
addGameObject(ok, 350, 175);
h++;
player.update();
private static class Player extends GameObject
Player() super(new ImageView("caarr.png"));
//Player() super(new Polygon( ));
private static class Wall extends GameObject
Wall()
super(new Rectangle(150, 300));
private static class Park extends GameObject
Park()
super(new Rectangle(50, 100, Color.RED));
private static class Ok extends GameObject
Ok()
super(new ImageView("levelcomp.png"));
@Override
public void start(Stage stage) throws Exception
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 250);
stage.setScene(scene);
stage.setTitle("Parking :)");
stage.setScene(new Scene(createContent()));
ArrayList<String> input = new ArrayList<String>();
Wall car = new Wall();
/* Wall car1 = new Wall();
Wall car2 = new Wall();
*/
addWall( car, 800, 350);
/*
addWall( car1, 150, 150);
addWall(car2, 350, 350);
*/
stage.getScene().setOnKeyPressed(
new EventHandler<KeyEvent>()
@Override
public void handle(KeyEvent e)
String code = e.getCode().toString();
if ( !input.contains(code) )
input.add( code );
);
stage.getScene().setOnKeyReleased(
new EventHandler<KeyEvent>()
public void handle(KeyEvent e)
String code = e.getCode().toString();
input.remove( code );
if (e.getCode() == KeyCode.UP)
player.setVelocity(new Point2D(0, 0));
if (e.getCode() == KeyCode.DOWN)
player.setVelocity(new Point2D(0, 0));
);
new AnimationTimer()
public void handle(long currentNanoTime)
if (input.contains("UP"))
player.move();
if
(input.contains("LEFT") && input.contains("UP"))
player.rotateLeft();
if (input.contains("RIGHT") && input.contains("UP"))
player.rotateRight();
if (input.contains("DOWN"))
player.moveback();
if (input.contains("RIGHT") && input.contains("DOWN"))
player.rotateLeft();
if (input.contains("LEFT") && input.contains("DOWN"))
player.rotateRight();
.start();
stage.show();
public static void main(String[] args)
launch(args);
GameObject.java
package sample;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import java.util.ArrayList;
public class GameObject
private Node view;
private Point2D velocity = new Point2D(0, 0);
public GameObject(Node view)
this.view = view;
public void update()
view.setTranslateX(view.getTranslateX() + velocity.getX());
view.setTranslateY(view.getTranslateY() + velocity.getY());
public void setVelocity(Point2D velocity)
this.velocity = velocity;
public Point2D getVelocity()
return velocity;
public Node getView()
return view;
public double getRotate()
return view.getRotate();
public void rotateRight()
view.setRotate(view.getRotate() + 0.9);
public void rotateLeft()
view.setRotate(view.getRotate() - 0.9);
public void rotateStart()
view.setRotate(view.getRotate() - 90);
public void rotate()
view.setRotate(view.getRotate() - 90);
public boolean isColliding(GameObject other)
return getView().getBoundsInParent().intersects(other.getView().getBoundsInParent());
public boolean isContaining(GameObject other)
return getView().getBoundsInParent().contains(other.getView().getBoundsInParent());
public void move()
setVelocity(new Point2D(Math.cos(Math.toRadians(getRotate())), Math.sin(Math.toRadians(getRotate()))));
public void moveback()
setVelocity(new Point2D(0 - Math.cos(Math.toRadians(getRotate())), 0 - Math.sin(Math.toRadians(getRotate()))));
public void moves(GameObject obj, ArrayList<String> i)
if (i.contains("UP"))
setVelocity(new Point2D(Math.cos(Math.toRadians(getRotate())), Math.sin(Math.toRadians(getRotate()))));
【问题讨论】:
相关Checking Collision of Shapes 要使您的代码更像minimal reproducible example,请使用encrypted-tbn0.gstatic.com/… 等互联网图片或将您的图片上传到imgur.com 并使用它们。 【参考方案1】:您可以尝试将 pickOnBounds 属性设置为 false。见:https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#pickOnBoundsProperty
【讨论】:
我应该在哪里设置该属性?也不是属性的默认值 false 吗? 我的错。我认为默认情况下是这样的。以上是关于JavaFX - 如何在不扩大对象的命中框的情况下旋转可移动对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在不丢失setfocus的情况下将光标设置到文本框的末尾?