以下代码中有一些我无法理解的内容。经过谷歌挖掘一段时间后,我觉得最好问别人。 我在youtube上关注游戏编程教程,我觉得我(在某种程度上)理解了我写的所有内容,除了涉及程序渲染部分的一些行。
package com.thomas.game;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import com.thomas.game.graphics.Screen;
import com.thomas.game.input.Keyboard;
public class Game extends Canvas implements Runnable {
private static final int WIDTH = 300;
private static final int HEIGHT = (WIDTH / 16) * 9;
private static final int SCALE = 3;
private static final String TITLE = "Game";
private JFrame frame;
private Thread thread;
private Screen screen;
private BufferedImage image;
private Keyboard key;
private int[] pixels;
private boolean running = false;
private int x = 0, y = 0;
public Game() {
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
screen = new Screen(WIDTH, HEIGHT);
frame = new JFrame();
initializeFrame();
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
这是我不明白的。我得到了图像栅格,从中我获得了数据库。我将数据缓冲区转换为(DatabufferInt),这允许我通过int[]
方法检索getData()
。完成此操作后,pixel.length的值为48600,并且每个索引都包含int值0.使用此int[]
进行操作会使程序按照预期进行渲染。但是,如果我没有以上述方式进行类型转换并检索int[]
,而是说pixels = new int[48600]
,我最终会出现黑屏。
我想我想知道的是:这两个int[]
之间有什么区别,或者更确切地说,是什么使第一个工作?它是如何工作的?
key = new Keyboard();
addKeyListener(key);
setFocusable(true);
}
public void run() {
long lastTime = System.nanoTime();
double nsPerTick = 1E9/60;
double delta = 0;
long now;
int ticks = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while(running) {
now = System.nanoTime();
delta += (now - lastTime) / nsPerTick;
lastTime = now;
while(delta >= 1) {
tick();
ticks++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer >= 1000) {
timer += 1000;
frame.setTitle(TITLE + " | ups: " + ticks + " fps: " + frames);
ticks = 0;
frames = 0;
}
}
}
private void render() {
BufferStrategy bs = getBufferStrategy(); // retrieves the bufferstrategy from the current component (the instance of Game that calls this method)
if(bs == null) {
createBufferStrategy(3);
return;
}
screen.clear();
screen.render(x, y);
getPixels();
Graphics g = bs.getDrawGraphics(); // retrieves a graphics object from the next in line buffer in the bufferstrategy, this graphics object draws to that buffer
g.drawImage(image, 0, 0, getWidth(), getHeight(), null); // draws the bufferedimage to the available buffer
g.dispose();
bs.show(); // orders the next in line buffer (which the graphics object g is tied to) to show its contents on the canvas
}
private void tick() {
key.update();
if(key.up)
y--;
if(key.down)
y++;
if(key.left)
x--;
if(key.right)
x++;
}
public void initializeFrame() {
frame.setTitle(TITLE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(this);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public synchronized void start() {
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Game game = new Game();
game.start();
}
public void getPixels() {
for(int i = 0; i < pixels.length; i++)
pixels[i] = screen.pixels[i];
}
}
似乎bufferedimage从像素数组中获取值。但我不明白这两者是如何沟通的,或者它们是如何联系的。我没有明确告诉bufferedimage从像素数组中获取像素,所以它是如何知道的? 我还将附加Screen类,它负责更新像素阵列。
package com.thomas.game.graphics;
import java.util.Random;
public class Screen {
private int width, height;
public int[] pixels;
private final int MAP_SIZE = 64;
private final int MAP_SIZE_MASK = MAP_SIZE - 1;
private int[] tiles;
private int tileIndex;
private int xx, yy;
private Random r;
public Screen(int w, int h) {
width = w;
height = h;
pixels = new int[width * height];
tiles = new int[MAP_SIZE * MAP_SIZE];
r = new Random(0xffffff);
for(int i = 0; i < tiles.length; i++) {
tiles[i] = r.nextInt();
}
tiles[0] = 0;
}
public void clear() {
for(int i = 0; i < pixels.length; i++)
pixels[i] = 0;
}
public void render(int xOffset, int yOffset) {
for(int y = 0; y < height; y++) {
yy = y + yOffset;
for(int x = 0; x < width; x++) {
xx = x + xOffset;
tileIndex = (yy >> 4 & MAP_SIZE_MASK) * MAP_SIZE + (xx >> 4 & MAP_SIZE_MASK);
pixels[y * width + x] = tiles[tileIndex];
}
}
}
}
我真的希望有人可以向我解释一下,我们将不胜感激。该程序正在按照预期的方式工作,但在我掌握这一点之前,我不觉得继续学习本教程。
答案 0 :(得分:1)
short,int,long等基本类型不是Objects。
但是,int []是一个数组。数组是java中的对象。 Java通过引用操作对象,而不是值。
在此行中,您不是要创建新对象。您正在变量pixels
中存储对象int []的引用。您在pixels
中更改的任何内容都会在image
中的int []对象内更改:
pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
我创建了一个示例,尝试运行此代码:
public class Data {
private int[] values = {25,14};
public int[] getValues() {
return values;
}
public static void main(String[] args) {
Data d = new Data();
System.out.println(d.getValues()[0]);
int[] values = d.getValues();
values[0] = 15;
System.out.println(d.getValues()[0]);
}
}
输出:
25
15
答案 1 :(得分:0)
请注意,您有此代码......
pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
虽然它应该是这样的......
pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
将image
更改为img
。
希望它有效!