проблема с рендерингом листа спрайтов (пиксели не отображаются и смещаются влево) - PullRequest
2 голосов
/ 20 июня 2020

я впервые задаю вопрос о переполнении стека. Я следил за этим руководством по созданию 2D-игры с java и столкнулся с проблемой ... Когда я запускаю свою программу, она очень странно отображает мой лист спрайтов:

My JFrame: enter image description here

his JFrame: введите описание изображения здесь

Я понятия не имею, что вызывает эту проблему, но вот мой код. извините, если он слишком длинный.

игра. java:

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
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.leekman.game.gfx.screen;
import com.leekman.game.gfx.spriteSheet;

public class Game extends Canvas implements Runnable{

    private static final long serialVersionUID = 1L;
    
    public boolean running = false;
    
    public static final int WIDTH = 160;
    public static final int HEIGHT = WIDTH / 12 * 9;
    public static final int SCALE = 3;
    public static final String NAME = "Game";
    
    private JFrame frame;
    
    public int tickCount = 0;
    
    private BufferedImage img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
    private int[] pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
    
    private screen scrn;
    
    public Game() {
        setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        
        frame = new JFrame(NAME);
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(this, BorderLayout.CENTER);
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    public void init() {
        scrn = new screen(WIDTH, HEIGHT, new spriteSheet("/Sprite_sheet.png"));
    }
    
    private synchronized void start() {
        running = true;
        new Thread(this).start();
    }
    
    private synchronized void stop() {
        running = false;
    }
    
    @Override
    public void run() {
        long lastTime = System.nanoTime();
        double NSpertick = 1000000000D / 60D;
        
        int ticks= 0;
        int frames = 0;
        
        long lastTimer = System.currentTimeMillis();
        double unproccesedTime = 0;
        
        init();
        
        while (running) {
            long now = System.nanoTime();
            unproccesedTime += (now - lastTime) / NSpertick;
            lastTime = now;
            boolean shouldRender = true;
            
            while (unproccesedTime >= 1) {
                ticks++;
                tick();
                unproccesedTime -= 1;
                shouldRender = true;
            }
            
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            if (shouldRender) {
                frames++;
                render();
            }
            
            if (System.currentTimeMillis() - lastTimer >= 1000) {
                lastTimer += 1000;
                System.out.println(frames+", "+ticks);
                frames = 0;
                ticks = 0;
            }
        }
    }
    
    public void tick() {
        tickCount++;
        
        for (int i = 0; i < pixels.length; i++) {
            pixels[i] = i + tickCount;
        }
    }
    
    public void render() {
        BufferStrategy bs = getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(3);
            return;
        }
        
        scrn.render(pixels, 0, WIDTH);
        
        Graphics g = bs.getDrawGraphics();
        g.setColor(Color.BLACK);
        g.drawRect(0, 0, getWidth(), getHeight());
        g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
        g.dispose();
        bs.show();
    }
    
    public static void main(String[] args) {
        new Game().start();
    }
}

spriteSheet. java:

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

public class spriteSheet {
    
    public String path;
    public int width;
    public int height;
    
    public int[] pixels;
    
    public spriteSheet(String path) {
        BufferedImage image = null;
        
        try {
            image = ImageIO.read(spriteSheet.class.getResourceAsStream(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        if (image == null) {
            return;
        }
        
        this.path = path;
        this.height = image.getHeight();
        this.width = image.getWidth();
        
        pixels = image.getRGB(0, 0, width, height, null, 0, width);
        
        for (int i = 0; i < pixels.length; i++) {
            pixels[i] = (pixels[i] & 0xff) / 64;
        }
        
        for (int i = 0; i < 8; i++) {
            System.out.println(pixels[i]);
        }
    }
}

экран. java:

public class screen {
    
    public static final int MAP_WIDTH = 64;
    public static final int MAP_WIDTH_MASK = MAP_WIDTH - 1;
    
    public int[] tiles = new int[MAP_WIDTH * MAP_WIDTH];
    public int[] colours = new int[MAP_WIDTH * MAP_WIDTH * 4];
    
    public int Xoffset = 0; 
    public int Yoffset = 0;
    
    public int height;
    public int width;
    
    public spriteSheet sheet;
    
    public screen(int width, int height , spriteSheet sheet) {
        this.height = height;
        this.width = width;
        this.sheet = sheet;
        
        for (int i = 0; i < MAP_WIDTH * MAP_WIDTH; i++) {
            colours[i * 4 + 0] = 0xff00ff;
            colours[i * 4 + 1] = 0x00ffff;
            colours[i * 4 + 2] = 0xffff00;
            colours[i * 4 + 3] = 0xffffff;
        }
    }
    
    public void render(int[] pixels, int offset, int row) {
        for (int yTile = Yoffset >> 3; yTile <= (Yoffset + height) >> 3; yTile++) {
            int yMin = yTile * 8 - Yoffset;
            int yMax = yMin + 8;
            
            if (yMin < 0) {
                yMin = 0;
            }
            
            if (yMax > height) {
                yMax = height;
            }
            
            for (int xTile = Xoffset >> 3; xTile <= (Xoffset + width) >> 3; xTile++) {
                int xMin = xTile * 8 - Xoffset;
                int xMax = xMin + 8;
                
                if (xMin < 0) {
                    xMin = 0;
                }
                
                if (xMax > width) {
                    xMax = width;
                }
                
                int tileIndex = (xTile & (MAP_WIDTH_MASK)) + (yTile & (MAP_WIDTH_MASK)) * MAP_WIDTH;
                
                for (int y = yMin; y < yMax; y++) {
                    int sheetpix = y + ((y + Yoffset) & 7) * sheet.width + ((xMin + Xoffset) & 7);
                    int tilepix = offset + xMin + y * row;
                    for (int x = xMin; x < xMax; x++) {
                        int colour = tileIndex * 4 + sheet.pixels[sheetpix++];
                        pixels[tilepix++] = colours[colour];
                    }
                }
            }
        }
    }
}

Любая помощь будет очень признательна, спасибо !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...