Home > Net >  Accessing elements inside a Graphic Context in JavaFX canvas
Accessing elements inside a Graphic Context in JavaFX canvas

Time:10-16

I'm implementing a simple hockey game following a MVC pattern. I'm having trouble refreshing the player's position which I created inside a canvas using the graphicContext.drawImage() method. I'm inside an AnimationTimer anonymous class, inside the handle method. The positions and boundaries are all reflected to the backend,so I don't really need to do any particular logic here, I just want to refresh the player's position on every frame, based on it's position calculated inside the model, but I can't access the image I've drawn before in any way. Here's the code:

DefaultController controller;

@FXML
public void initialize(){
    
    controller = new DefaultController(800,400);
    
    double playerX = controller.getField().getPlayer().getX();
    double playerY = controller.getField().getPlayer().getY();
    
    double enemyX = controller.getField().getEnemy().getX();
    double enemyY = controller.getField().getEnemy().getY();

    context.drawImage(new Image("player.png"),playerX,playerY);
    context.drawImage(new Image("enemy.png"),enemyX,enemyY);

    AnimationTimer timer = new AnimationTimer() {
        @Override
        public void handle(long now) {
            pane.getScene().addEventHandler(KeyEvent.KEY_PRESSED, (key) -> {
                if(key.getCode()== KeyCode.UP) {
                    controller.getField().getPlayer().setLocation(playerX,playerY-0.1)

                    //how I update the player image position inside the canvas?
                   
                }
            });
        }
    };
    timer.start();
}

CodePudding user response:

You are following a completely wrong approach. You cannot update anything in a Canvas once it is drawn. You can just erase it and redraw it again. For what you are trying to do the scene graph is much better suited.

CodePudding user response:

The following is an mre demonstrating how to move an image on a canvas using the UP key:

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.*;
import javafx.scene.image.Image;
import javafx.scene.input.*;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    private static final int SIZE = 200;
    private static final String FISH_IMAGE = "https://www.shareicon.net/data/128x128/2015/03/28/14104_animal_256x256.png";
    private Image image;
    private Canvas canvas;
    private final double xPos = 250;
    private double yPos = 150;
    private static final double MOVE = 0.8;
    @Override
    public void start(Stage primaryStage) {

        image = new Image(FISH_IMAGE,SIZE,SIZE,false,false);
        canvas = new Canvas(SIZE*3, SIZE*3);
        draw();
        Scene scene = new Scene(new StackPane(canvas));
        scene.addEventHandler(KeyEvent.KEY_PRESSED, (key) -> animate(key));
        primaryStage.setScene(scene);
        primaryStage.show();

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                //to avoid multiple handlers do not add handler here
                draw();
            }
        };
        timer.start();
    }
    
    private void animate(KeyEvent key){
          if(key.getCode()== KeyCode.UP) {
            yPos -= MOVE;
          }
          //todo add down , left , right 
    }

    private void draw(){
         GraphicsContext gc = canvas.getGraphicsContext2D();
         gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());//clear previous
         gc.drawImage(image, xPos, yPos);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
  • Related