2014-10-16 2 views
0

저는 게임 에뮬레이터를 구축 중이며 디스플레이 픽셀을 나타내는 매트릭스를 가지고 있습니다. JavaFX 8을 사용하여 어떻게 표현할 수 있습니까 (스윙은 키 바인딩 및 사운드와 관련하여 많은 문제를 겪었습니다). 이미지를 자주 새로 고쳐야합니다. 고맙습니다!픽셀로 JavaFX 8에서 게임 매트릭스 표현

예 :

I 매트릭스가 [64] [32] 부울 값을 운반한다. 1은 흰색을 나타내고 0은 검은 색을 나타냅니다. 그리고 행렬의 값을 표시 픽셀로 나타내는 메서드 (paint())를 호출하려고합니다.

답변

1

아마도 가장 빠른 방법은 WritableImage을 사용하는 것입니다.

WritableImage.getPixelWriter().setPixels(...); 

으로 전화하면 일부 데이터의 이미지를 업데이트 할 수 있습니다. 이 작업을 수행하는 가장 편리한 방법은 데이터 ("행렬")을 일차원 바이트 배열로 표현하고 바이트 값을 색상 배열 (argb 값으로 표시)에 매핑하는 PixelFormat을 사용하는 것입니다. . setPixels(...) 메소드의 해당 버전을 호출 할 수 있습니다.

(그래서 paint() 메소드는 잠재적으로보고 계산하는 비트 하는 setPixels 메소드를 호출 정확하게하는 화상의 부분 갱신이 필요로한다.)

이 예 작은 (8 × 8 애니메이션이 기술을 사용하여) 직사각형.

import java.nio.ByteBuffer; 

import javafx.animation.Animation; 
import javafx.animation.KeyFrame; 
import javafx.animation.Timeline; 
import javafx.application.Application; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.scene.Scene; 
import javafx.scene.image.ImageView; 
import javafx.scene.image.PixelFormat; 
import javafx.scene.image.WritableImage; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

public class DirectImageFromArray extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     final int width = 64 ; 
     final int height = 32 ; 

     final int boxSize = 8 ; 

     final int blackArgb = 0xFF << 24 ; 
     final int whiteArgb = 0xFF << 24 | 0xFF << 16 | 0xFF << 8 | 0xFF ; 

     byte[] data = new byte[width*height]; 
     for (int y = 0 ; y < boxSize; y++) { 
      int scanLineStride = y * width ; 
      for (int x = 0 ; x < boxSize; x++) { 
       data[x+scanLineStride] = 1 ; 
      } 
     } 

     WritableImage img = new WritableImage(width, height); 

     // indexed colors 0 -> black, 1 -> white: 
     PixelFormat<ByteBuffer> pixelFormat = 
       PixelFormat.createByteIndexedInstance(new int[] {blackArgb, whiteArgb}); 

     // write entire image: 
     img.getPixelWriter().setPixels(0, 0, width, height, pixelFormat, data, 0, width); 

     // represents the first pixel that is white: 
     IntegerProperty firstLitPixel = new SimpleIntegerProperty(); 

     // update the data array and then the image when the property changes: 
     firstLitPixel.addListener((obs, oldValue, newValue) -> { 

      // track portion that changes: 
      int minChangedX = width ; 
      int minChangedY = height ; 
      int maxChangedX = 0 ; 
      int maxChangedY = 0 ; 

      // move box 
      for (int y = 0; y < boxSize; y++) { 

       // set left edge of box to black: 
       int oldIndex = (oldValue.intValue() + y * width) % (width * height) ; 
       data[oldIndex] = 0 ; 

       // set right edge of new box location to white: 
       int newIndex = (newValue.intValue() + y * width + boxSize - 1) % (width*height) ; 
       data[newIndex] = 1 ; 

       // update changed portion: 
       int oldX = oldIndex % width ; 
       int oldY = oldIndex/width ; 
       int newX = newIndex % width ; 
       int newY = newIndex/width ; 
       minChangedX = Math.min(minChangedX, Math.min(oldX, newX)); 
       maxChangedX = Math.max(maxChangedX, Math.max(oldX, newX)); 
       minChangedY = Math.min(minChangedY, Math.min(oldY, newY)); 
       maxChangedY = Math.max(maxChangedY, Math.max(oldY, newY)); 
      } 
      int minIndex = minChangedX + minChangedY * width ; 
      int changedWidth = maxChangedX - minChangedX + 1; 
      int changedHeight = maxChangedY - minChangedY + 1; 

      // update image 
      img.getPixelWriter().setPixels(minChangedX, minChangedY, 
        changedWidth, changedHeight, 
        pixelFormat, data, minIndex, width); 
     }); 

     // animate the property: 
     Timeline animation = new Timeline(new KeyFrame(Duration.millis(10), event -> 
      firstLitPixel.set((firstLitPixel.get() + 1) % (width * height)) 
     )); 

     animation.setCycleCount(Animation.INDEFINITE); 
     animation.play(); 

     ImageView imageView = new ImageView(img); 
     StackPane root = new StackPane(imageView); 
     Scene scene = new Scene(root, 400, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

    } 

} 
관련 문제