Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于平铺的游戏上的复制平铺_Java_Java 2d_Tile - Fatal编程技术网

Java 基于平铺的游戏上的复制平铺

Java 基于平铺的游戏上的复制平铺,java,java-2d,tile,Java,Java 2d,Tile,我目前正在用Java2D开发一个基于tile的Java游戏。然而,我认为我遗漏了一些非常愚蠢的东西,或者可能没有,问题是我检查了我的代码数千次,没有看到任何奇怪的东西。这就是我现在的游戏: 但它应该是这样的: 嗯,我知道,看起来不错,但是如果你看一下我的基于平铺的关卡的图像: (灰色瓷砖是砖,绿色瓷砖是草,棕色瓷砖是土) 所以砖瓦是以某种奇怪的方式复制的。这是我的级别代码: import java.awt.Graphics2D; import java.awt.Point; import

我目前正在用Java2D开发一个基于tile的Java游戏。然而,我认为我遗漏了一些非常愚蠢的东西,或者可能没有,问题是我检查了我的代码数千次,没有看到任何奇怪的东西。这就是我现在的游戏:

但它应该是这样的:

嗯,我知道,看起来不错,但是如果你看一下我的基于平铺的关卡的图像:

(灰色瓷砖是砖,绿色瓷砖是草,棕色瓷砖是土)

所以砖瓦是以某种奇怪的方式复制的。这是我的级别代码:

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import com.wg.MainComponent;
import com.wg.entity.Entity;
import com.wg.entity.Particle;
import com.wg.entity.Projectile;
import com.wg.entity.mob.Mob;
import com.wg.entity.mob.Player;

public abstract class Level {

    public BufferedImage levelImage;
    public BufferedImage[][] tile;
    public Rectangle[][] rect;
    public int tileSize;
    public float xOffset, yOffset;
    public ArrayList<BufferedImage> collision = new ArrayList<BufferedImage>();

    public ArrayList<Player> players = new ArrayList<Player>();
    public ArrayList<Projectile> projectiles = new ArrayList<Projectile>();
    public ArrayList<Particle> particles = new ArrayList<Particle>();
    private List<Entity> entities = new ArrayList<Entity>();

    public BufferedImage[] tilesBufferedImages;
    public int[] xCollisionOffset;
    public int[] yCollisionOffset;

    public Level(BufferedImage levelImage, int tileSize, BufferedImage[] tilesBufferedImages, int[] xCollisionOffset, int[] yCollisionOffset) {
        this.tilesBufferedImages = tilesBufferedImages;
        this.xCollisionOffset = xCollisionOffset;
        this.yCollisionOffset = yCollisionOffset;

        this.levelImage = levelImage;
        this.tileSize = tileSize;

        tile = new BufferedImage[levelImage.getWidth()][levelImage.getHeight()];
        rect = new Rectangle[levelImage.getWidth()][levelImage.getHeight()];

        generateLevel();
    }

    public abstract void generateLevel();

    public void render(float xOffset, float yOffset, int scale, Graphics2D screen) {
        this.xOffset = xOffset;
        this.yOffset = yOffset;

        for (int y = (int) Math.max(yOffset / (tileSize + scale), 0); y < Math.min((MainComponent.height + yOffset) / (tileSize + scale) + 1, levelImage.getHeight()); y++) {
            for (int x = (int) Math.max(xOffset / (tileSize + scale), 0); x < Math.min((MainComponent.width + xOffset) / (tileSize + scale) + 1, levelImage.getWidth()); x++) {
                if (tile[x][y] != null)
                    screen.drawImage(tile[x][y], (int) (x * (tileSize + scale) - xOffset), (int) (y * (tileSize + scale) - yOffset), (tileSize + scale), (tileSize + scale), null);
            }
        }

        for (int i = 0; i < entities.size(); i++) {
            entities.get(i).render(screen);
        }

        for (int i = 0; i < players.size(); i++) {
            players.get(i).render(screen);
        }

        for (int i = 0; i < projectiles.size(); i++) {
            projectiles.get(i).render(screen);
        }

        for (int i = 0; i < particles.size(); i++) {
            particles.get(i).render(screen);
        }
    }

    public void add(Entity e) {
        if (e instanceof Particle) {
            particles.add((Particle) e);
        } else if (e instanceof Player) {
            players.add((Player) e);
        } else if (e instanceof Projectile) {
            projectiles.add((Projectile) e);
        } else {
            entities.add(e);
        }
    }

    public void update(int scale) {
        for (int y = 0; y < levelImage.getHeight(); y++) {
            for (int x = 0; x < levelImage.getWidth(); x++) {
                if (tile[x][y] != null && rect[x][y] == null) {
                    for (int i = 0; i < tilesBufferedImages.length; i++) {
                        if (tilesBufferedImages[i] == tile[x][y])
                            rect[x][y] = new Rectangle(x * (tileSize + scale) - Math.round(xOffset) + xCollisionOffset[i], y * (tileSize + scale) - Math.round(yOffset) + yCollisionOffset[i], (tileSize + scale) + xCollisionOffset[i], (tileSize + scale) + yCollisionOffset[i]);
                    }
                } else if (tile[x][y] != null && rect[x][y] != null) {
                    for (int i = 0; i < tilesBufferedImages.length; i++) {
                        if (tilesBufferedImages[i] == tile[x][y])
                            rect[x][y].setBounds(x * (tileSize + scale) - Math.round(xOffset) + xCollisionOffset[i], y * (tileSize + scale) - Math.round(yOffset) + xCollisionOffset[i], (tileSize + scale) + xCollisionOffset[i], (tileSize + scale) + yCollisionOffset[i]);
                    }
                }
            }
        }

        for (int i = 0; i < entities.size(); i++) {
            entities.get(i).update();
        }

        for (int i = 0; i < players.size(); i++) {
            players.get(i).update();
        }

        for (int i = 0; i < projectiles.size(); i++) {
            projectiles.get(i).update();
        }
        for (int i = 0; i < particles.size(); i++) {
            particles.get(i).update();
        }

        remove();
    }

    public List<Player> getPlayers() {
        return players;
    }

    public Player getPlayerAt(int index) {
        return players.get(index);
    }

    public Player getClientPlayer() {
        return players.get(0);
    }

    private void remove() {
        for (int i = 0; i < entities.size(); i++) {
            if (entities.get(i).isRemoved())
                entities.remove(i);
        }
        for (int i = 0; i < projectiles.size(); i++) {
            if (projectiles.get(i).isRemoved())
                projectiles.remove(i);
        }
        for (int i = 0; i < players.size(); i++) {
            if (players.get(i).isRemoved())
                players.remove(i);
        }
        for (int i = 0; i < particles.size(); i++) {
            if (particles.get(i).isRemoved())
                particles.remove(i);
        }
    }

    public boolean tileDownCollision(Mob en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x), Math.round(en.y + en.height));
        else if (!fixed)
            p = new Point(Math.round(en.x - xOffset), Math.round(en.y + en.height - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean tileUpCollision(Mob en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x), Math.round(en.y - 1));
        else if (!fixed)
            p = new Point(Math.round(en.x - xOffset), Math.round(en.y - 1 - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean tileLeftCollision(Mob en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x - 1), Math.round(en.y));
        else if (!fixed)
            p = new Point(Math.round(en.x - 1 - xOffset), Math.round(en.y - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean tileRightCollision(Mob en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x + en.width), Math.round(en.y));
        else if (!fixed)
            p = new Point(Math.round(en.x + en.width - xOffset), Math.round(en.y - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean projectileDownCollision(Projectile en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x), Math.round(en.y + en.height));
        else if (!fixed)
            p = new Point(Math.round(en.x - xOffset), Math.round(en.y + en.height - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean projectileUpCollision(Projectile en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x), Math.round(en.y - 1));
        else if (!fixed)
            p = new Point(Math.round(en.x - xOffset), Math.round(en.y - 1 - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean projectileLeftCollision(Projectile en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x - 1), Math.round(en.y));
        else if (!fixed)
            p = new Point(Math.round(en.x - 1 - xOffset), Math.round(en.y - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean projectileRightCollision(Projectile en, boolean fixed) {
        Point p = null;
        if (fixed)
            p = new Point(Math.round(en.x + en.width), Math.round(en.y));
        else if (!fixed)
            p = new Point(Math.round(en.x + en.width - xOffset), Math.round(en.y - yOffset));
        try {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    if (tile[x][y] != null) {
                        if (rect[x][y] != null && rect[x][y].contains(p)) {
                            if (collision.contains(tile[x][y]))
                                return true;
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        return false;
    }

    public boolean mobProjectileCollision(Mob en, Projectile pr, boolean fixed) {
        Rectangle p1 = null;
        if (fixed)
            p1 = new Rectangle(Math.round(en.x), Math.round(en.y), en.width, en.height);
        else if (!fixed)
            p1 = new Rectangle(Math.round(en.x - xOffset), Math.round(en.y - yOffset), en.width, en.height);

        Rectangle p2 = null;
        if (fixed)
            p2 = new Rectangle(Math.round(pr.x), Math.round(pr.y), pr.width, pr.height);
        else if (!fixed)
            p2 = new Rectangle(Math.round(pr.x - xOffset), Math.round(pr.y - yOffset), pr.width, pr.height);

        if (p1.intersects(p2))
            return true;

        return false;
    }

    public double calcDistance(Entity e1, Entity e2) {
        return Math.sqrt(((e1.x - e2.x) * (e1.x - e2.x)) + ((e1.y - e2.y) * (e1.y - e2.y)));
    }
}
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.Rectangle;
导入java.awt.image.buffereImage;
导入java.util.ArrayList;
导入java.util.List;
导入com.wg.main组件;
导入com.wg.entity.entity;
导入com.wg.entity.Particle;
导入com.wg.entity.projection;
导入com.wg.entity.mob.mob;
导入com.wg.entity.mob.Player;
公共抽象类级别{
公共缓冲区映像级别映像;
公共缓冲区映像[][]磁贴;
公共矩形[][]矩形;
公共int tileSize;
公开浮动xOffset,yOffset;
公共ArrayList冲突=新建ArrayList();
public ArrayList players=new ArrayList();
public ArrayList projectles=new ArrayList();
public ArrayList particles=new ArrayList();
私有列表实体=新的ArrayList();
公共BuffereImage[]tiles BuffereImage;
公共int[]xCollisionOffset;
公共int[]yCollisionOffset;
公共级别(BuffereImage levelImage、int tileSize、BuffereImage[]TilesBuffereImage、int[]xCollisionOffset、int[]yCollisionOffset){
this.tilesBufferedImages=tilesBufferedImages;
this.xCollisionOffset=xCollisionOffset;
this.yCollisionOffset=yCollisionOffset;
this.levelImage=levelImage;
this.tileSize=tileSize;
平铺=新的缓冲区映像[levelImage.getWidth()][levelImage.getHeight()];
rect=新矩形[levelImage.getWidth()][levelImage.getHeight()];
generateLevel();
}
公共抽象void generateLevel();
公共无效渲染(浮点xOffset、浮点yOffset、整数比例、图形2D屏幕){
this.xOffset=xOffset;
this.yOffset=yOffset;
对于(int y=(int)Math.max(yOffset/(tileSize+scale),0);yimport static com.wg.MainComponent.spritesheet;

import java.awt.Color;
import java.awt.image.BufferedImage;

import com.wg.BufferedImageLoader;
import com.wg.entity.mob.Player;

public class Level1 extends Level {

    public static final BufferedImage bricks = crop(0, 2);
    public static final BufferedImage dirt = crop(1, 2);
    public static final BufferedImage grass = crop(2, 2);
    public static final BufferedImage[] tilesList = { bricks, dirt, grass };
    public static final int[] defaultxCollisionOffset = { 0, 0, 0 };
    public static final int[] defaultyCollisionOffset = { 0, 0, 0 };
    private static BufferedImage level = BufferedImageLoader.load("/level1.png");

    private static BufferedImage crop(int x, int y) {
        return spritesheet.getSubimage(x * 16, y * 16, 16, 16);
    }

    public void generateLevel() {
        for (int y = 0; y < levelImage.getHeight(); y++) {
            for (int x = 0; x < levelImage.getWidth(); x++) {
                Color c = new Color(level.getRGB(x, y));
                String data = String.format("%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue());
                if (data.equals("838383"))
                    tile[x][y] = bricks;
                else if (data.equals("bea100"))
                    tile[x][y] = dirt;
                else if (data.equals("23d200"))
                    tile[x][y] = grass;
            }
        }
    }

    public Level1(float xOffset, float yOffset) {
        super(level, 16, tilesList, defaultxCollisionOffset, defaultyCollisionOffset);
        collision.add(grass);
        collision.add(dirt);
        collision.add(bricks);
        add(new Player(50, 20, 1, 2, 32 + 32, 32 + 32, this));
        this.xOffset = xOffset;
        this.yOffset = yOffset;
    }
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class MCVE extends JFrame {

    public static final int WIDTH = 800;
    public static final int HEIGHT = 600;
    private MCVELevel1 level1 = new MCVELevel1(0, 0);

    public static void main(String[] args) {
        MCVE mcve = new MCVE();
        mcve.setVisible(true);
        mcve.setSize(WIDTH, HEIGHT);
        mcve.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void paint(Graphics g) {
        level1.render(50, 400, 32, (Graphics2D) g);
    }

    private static class MCVELevel1 extends MCVELevel {

        private static BufferedImage spritesheet = BufferedImageLoader.load("C://image//tiles.png");
        public static final BufferedImage bricks = crop(0, 0);
        public static final BufferedImage dirt = crop(1, 0);
        public static final BufferedImage grass = crop(2, 0);
        public static final BufferedImage[] tilesList = { bricks, dirt, grass };
        public static final int[] defaultxCollisionOffset = { 0, 0, 0 };
        public static final int[] defaultyCollisionOffset = { 0, 0, 0 };
        private static BufferedImage level = BufferedImageLoader.load("C://image//level1.png");

        private static BufferedImage crop(int x, int y) {
            return spritesheet.getSubimage(x * 16, y * 16, 16, 16);
        }

        public void generateLevel() {
            for (int y = 0; y < levelImage.getHeight(); y++) {
                for (int x = 0; x < levelImage.getWidth(); x++) {
                    Color c = new Color(level.getRGB(x, y));
                    String data = String.format("%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue());
                    if (data.equals("838383"))
                        tile[x][y] = bricks;
                    else if (data.equals("bea100"))
                        tile[x][y] = dirt;
                    else if (data.equals("23d200"))
                        tile[x][y] = grass;
                }
            }
        }

        public MCVELevel1(float xOffset, float yOffset) {
            super(level, 16, tilesList, defaultxCollisionOffset, defaultyCollisionOffset);
            this.xOffset = xOffset;
            this.yOffset = yOffset;
        }
    }

    public static class BufferedImageLoader {
        public static BufferedImage load(String path) {
            try {
                return ImageIO.read(new File(path));
            } catch (IOException e) {
                e.printStackTrace();
            }
            throw new NullPointerException("No file found at: " + path);
        }

        public static BufferedImage load(URL url) {
            try {
                return ImageIO.read(url);
            } catch (IOException e) {
                e.printStackTrace();
            }
            throw new NullPointerException("No file found at: " + url.getPath());
        }
    }
}
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

public abstract class MCVELevel {

    public BufferedImage levelImage;
    public BufferedImage[][] tile;
    public Rectangle[][] rect;
    public int tileSize;
    public float xOffset, yOffset;

    public BufferedImage[] tilesBufferedImages;
    public int[] xCollisionOffset;
    public int[] yCollisionOffset;

    public MCVELevel(BufferedImage levelImage, int tileSize, BufferedImage[] tilesBufferedImages, int[] xCollisionOffset, int[] yCollisionOffset) {
        this.tilesBufferedImages = tilesBufferedImages;
        this.xCollisionOffset = xCollisionOffset;
        this.yCollisionOffset = yCollisionOffset;

        this.levelImage = levelImage;
        this.tileSize = tileSize;

        tile = new BufferedImage[levelImage.getWidth()][levelImage.getHeight()];
        rect = new Rectangle[levelImage.getWidth()][levelImage.getHeight()];

        generateLevel();
    }

    public abstract void generateLevel();

    public void render(float xOffset, float yOffset, int scale, Graphics2D screen) {
        this.xOffset = xOffset;
        this.yOffset = yOffset;

        for (int y = (int) Math.max(yOffset / (tileSize + scale), 0); y < Math.min((MCVE.HEIGHT + yOffset) / (tileSize + scale) + 1, levelImage.getHeight()); y++) {
            for (int x = (int) Math.max(xOffset / (tileSize + scale), 0); x < Math.min((MCVE.WIDTH + xOffset) / (tileSize + scale) + 1, levelImage.getWidth()); x++) {
                if (tile[x][y] != null)
                    screen.drawImage(tile[x][y], (int) (x * (tileSize + scale) - xOffset), (int) (y * (tileSize + scale) - yOffset), (tileSize + scale), (tileSize + scale), null);
            }
        }
    }

    public void update(int scale) {
        for (int y = 0; y < levelImage.getHeight(); y++) {
            for (int x = 0; x < levelImage.getWidth(); x++) {
                if (tile[x][y] != null && rect[x][y] == null) {
                    for (int i = 0; i < tilesBufferedImages.length; i++) {
                        if (tilesBufferedImages[i] == tile[x][y])
                            rect[x][y] = new Rectangle(x * (tileSize + scale) - Math.round(xOffset) + xCollisionOffset[i], y * (tileSize + scale) - Math.round(yOffset) + yCollisionOffset[i], (tileSize + scale) + xCollisionOffset[i], (tileSize + scale) + yCollisionOffset[i]);
                    }
                } else if (tile[x][y] != null && rect[x][y] != null) {
                    for (int i = 0; i < tilesBufferedImages.length; i++) {
                        if (tilesBufferedImages[i] == tile[x][y])
                            rect[x][y].setBounds(x * (tileSize + scale) - Math.round(xOffset) + xCollisionOffset[i], y * (tileSize + scale) - Math.round(yOffset) + xCollisionOffset[i], (tileSize + scale) + xCollisionOffset[i], (tileSize + scale) + yCollisionOffset[i]);
                    }
                }
            }
        }
    }
}
public void render(float xOffset, float yOffset, int scale, Graphics2D screen) {
        this.xOffset = xOffset;
        this.yOffset = yOffset;

        for (int y = 0; y < levelImage.getHeight(); y++) {
            for (int x = 0; x < levelImage.getWidth(); x++) {
                if (tile[x][y] != null)
                    screen.drawImage(tile[x][y], (int) (x * (tileSize + scale) - xOffset), (int) (y * (tileSize + scale) - yOffset), (tileSize + scale), (tileSize + scale), null);
            }
        }
    }
for (int y = (int) Math.max(yOffset / (tileSize + scale), 0); y < Math.min((MCVE.HEIGHT + yOffset) / (tileSize + scale) + 1, levelImage.getHeight()); y++) {
    for (int x = (int) Math.max(xOffset / (tileSize + scale), 0); x < Math.min((MCVE.WIDTH + xOffset) / (tileSize + scale) + 1, levelImage.getWidth()); x++) {
        if (tile[x][y] != null)
            screen.drawImage(tile[x][y], (int) (x * (tileSize + scale) - xOffset), (int) (y * (tileSize + scale) - yOffset), (tileSize + scale), (tileSize + scale), null);
    }
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class MCVE extends JFrame {
    private static final long serialVersionUID = 1L;
    public static final int WIDTH = 800;
    public static final int HEIGHT = 600;

    public static void main(String[] args) {
        MCVE mcve = new MCVE();
        mcve.setVisible(true);
        mcve.setSize(WIDTH, HEIGHT);
        mcve.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void paint(Graphics g) {
        render((Graphics2D) g);
    }

    public BufferedImage[][] tile;
    public static final int TILE_SIZE = 16;
    private static BufferedImage spritesheet = BufferedImageLoader
            .load("tiles.png");
    private static final BufferedImage bricks = crop(0, 0);
    private static final BufferedImage dirt = crop(1, 0);
    private static final BufferedImage grass = crop(2, 0);
    private static final BufferedImage levelImage = BufferedImageLoader.load("level1.png");
    int widthInTiles;
    int heightInTiles;

    private static BufferedImage crop(int x, int y) {
        return spritesheet.getSubimage(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE,
                TILE_SIZE);
    }

    public MCVE() {
        widthInTiles = levelImage.getWidth();
        heightInTiles = levelImage.getHeight();

        generateLevel();
    }

    public void generateLevel() {
        tile = new BufferedImage[widthInTiles][heightInTiles];
        for (int y = 0; y < heightInTiles; y++) {
            for (int x = 0; x < widthInTiles; x++) {
                Color c = new Color(levelImage.getRGB(x, y));
                switch (c.getRGB()) {
                case -8158333:
                    tile[x][y] = bricks;
                    break;
                case -14429696:
                    tile[x][y] = grass;
                    break;
                case -4284160:
                    tile[x][y] = dirt;
                }
            }
        }
    }

    public void render(Graphics2D screen) {
        int scale = 16;
        int yes = 0, no = 0;
        for (int y = 0; y < heightInTiles; y++) {
            for (int x = 0; x < widthInTiles; x++) {
                if (tile[x][y] != null) {
                    screen.drawImage(tile[x][y], (int) (x * (TILE_SIZE + scale)),
                            (int) (y * (TILE_SIZE + scale)),
                            (TILE_SIZE + scale), (TILE_SIZE + scale),
                            Color.BLACK, null);
                }
            }
        }
    }

    public static class BufferedImageLoader {
        public static BufferedImage load(String path) {
            try {
                return ImageIO.read(new File(path));
            } catch (IOException e) {
                e.printStackTrace();
            }
            throw new NullPointerException("No file found at: " + path);
        }

        public static BufferedImage load(URL url) {
            try {
                return ImageIO.read(url);
            } catch (IOException e) {
                e.printStackTrace();
            }
            throw new NullPointerException("No file found at: " + url.getPath());
        }
    }
}