(游戏设计)Java Graphics2d 中的抗锯齿

问题描述 投票:0回答:1

我想用我在其中绘制的形状(平面)对图像进行抗锯齿处理。我在 Adobe AI 中绘制平面图像并将它们放入我的资源文件夹中。图像如下所示。

当我使用这行代码时

g2.drawImage(image, (int)x, (int)y, width, height, null);
将其绘制在屏幕上时,边缘会变得尖锐。

我知道有一种方法可以使用renderingHints对g2d形状进行抗锯齿处理,但我不确定它是否会影响图像中的形状...

因此,非常感谢任何帮助!

完整代码如下:

package entity;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import main.Game;
import main.GamePanel;

// Module HP
// Acceleration and speed
public class Player extends Plane{
    
    private BufferedImage basic;
    // acceleration vector lists
    private final ArrayList<double[]> accelerations;
    
    // rate of increasing speed
    // 1.0 / (time to reach max speed in seconds) * FPS
    private final double ACCCONST = 1.0/(0.5*Game.FPS);
    // special attributes
    
    //TEMP
    private final ArrayList<Bullet> bullets;
    
    public Player(GamePanel gp) {
        this.loadImages();
        this.gp = gp;
        // set image
        image = basic;
        // basic attributes
        x = Game.SPAWNX - width/2;
        y = Game.SPAWNY - height;
        // init lists
        accelerations = new ArrayList<>();
        
        //TEMP
        bullets = new ArrayList<>();
    }
    private void loadImages() {
        try {
            basic = ImageIO.read(getClass().getResourceAsStream("/res/players/basic.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // setters
    public void addAcceleration(double[] pair) {
        if (pair.length == 2) {
            accelerations.add(pair);
        }
    }
    @Override
    public void setEnginePower(double enginePower) {
        this.enginePower = enginePower;
        this.maxSpeed = enginePower;
    }
    @Override
    public void setAtkSpeed(double atkSpeed) {
        this.atkSpeed = atkSpeed;
        if (atkSpeed == 0) atkInterval = (int)Double.POSITIVE_INFINITY;
        else atkInterval = (int)(Game.FPS/atkSpeed);
    }
    // getters
    
    // get movement info
    private double[] getRAcceleration() {
        // get resultant acceleration
        xAPF = 0; yAPF = 0;
        for (double[] pair: accelerations) {
            if (pair.length == 2) {
                xAPF += pair[0];
                yAPF += pair[1];
            }
        }
        accelerations.clear();
        return new double[]{xAPF, yAPF};
    }
    private void move() {
        double[] pair = this.getRAcceleration();
        // no acceleration
        if (pair[0] == 0 && pair[1] == 0) {
            // reset speed to 0
            if (xSPF > 0) xSPF = Math.max(xSPF - Game.DECELERATION, 0);
            else if (xSPF < 0) xSPF = Math.min(xSPF + Game.DECELERATION, 0);
            if (ySPF > 0) ySPF = Math.max(ySPF - Game.DECELERATION, 0);
            else if (ySPF < 0) ySPF = Math.min(ySPF + Game.DECELERATION, 0);
        }
        // accleration exists
        else {
            // max speed = acceleration
            if (xAPF > 0) xSPF = Math.min(xSPF + xAPF*ACCCONST, maxSpeed);
            else xSPF = Math.max(xSPF + xAPF*ACCCONST, -maxSpeed);
            if (yAPF > 0) ySPF = Math.min(ySPF + yAPF*ACCCONST, maxSpeed);
            else ySPF = Math.max(ySPF + yAPF*ACCCONST, -maxSpeed);
        }
        // move
        x += xSPF;
        y += ySPF;
    }
    private void shoot() {
        double spawnX = x + singleShootingScale * width;
        double spawnY = y;
        Bullet bullet = new Bullet(gp, this, spawnX, spawnY);
        bullet.addAcceleration(new double[]{0, -10});
        bullets.add(bullet);
    }
    private void getAFromKey() {
        boolean[] keyPressed = gp.keyH.keyPressed;
        if (keyPressed[0]) accelerations.add(new double[]{0, -enginePower / Game.FPS});
        if (keyPressed[1]) accelerations.add(new double[]{-enginePower / Game.FPS, 0});
        if (keyPressed[2]) accelerations.add(new double[]{0, enginePower / Game.FPS});
        if (keyPressed[3]) accelerations.add(new double[]{enginePower / Game.FPS, 0});
    }
    
    @Override
    public void update() {
        // check all events
        
        //TEMP
        for (Bullet bullet: bullets) bullet.update();
        
        // shoot
        if (atkInterval == 0) this.shoot();
        else if (frameCnt % atkInterval == 0) this.shoot();
        
        this.getAFromKey();
        this.move();
        
        frameCnt += 1;
    }
    @Override
    public void draw(Graphics2D g2) {
        
        //TEMP
        for (Bullet bullet: bullets) bullet.draw(g2);
        
        g2.drawImage(image, (int)x, (int)y, width, height, null);
    }
    
}

我回顾了一些关于此类问题的过去的帖子,但我没有找到适合我的[图像中的形状]。

如果在java上没有办法做到这一点,也许这就是我画画的方式? (有什么更好的方式将艺术融入到Java游戏设计中)

java game-development graphics2d
1个回答
0
投票

基本上,重画图像。我在这里做了类似的事情。 关键是

Image scaledImg = img.getScaledInstance(scaleImage[0], scaleImage[1], Image.SCALE_SMOOTH);

 private static int[] scaleImage(int originalWidth, int originalHeight) {
    int newWidth;
    int newHeight;

    // Calculate new dimensions while preserving aspect ratio
    if (originalWidth > originalHeight) {
        // Landscape orientation
        newWidth = 200;
        newHeight = (int) ((double) originalHeight / originalWidth * 200);
    } else {
        // Portrait or square orientation
        newHeight = 200;
        newWidth = (int) ((double) originalWidth / originalHeight * 200);
    }

    return new int[]{newWidth, newHeight};
}

private JButton createImageButton(String imagePath) {
    JButton button = new JButton();
    String description = "";

    try {
        int startIndex = imagePath.lastIndexOf("/") + 1;
        int endIndex = imagePath.lastIndexOf(".");
        BufferedImage img = ImageIO.read(new File(imagePath));

        int[] scaleImage = scaleImage(img.getWidth(), img.getHeight());

        Image scaledImg = img.getScaledInstance(scaleImage[0], scaleImage[1], Image.SCALE_SMOOTH);
        ImageIcon icon = new ImageIcon(scaledImg);

        if (startIndex < 0 || endIndex < 0 || startIndex >= endIndex) {
            // Handle invalid path or file extension not found
            description = imagePath;
        }
        button.setIcon(icon);
        description = imagePath.substring(startIndex, endIndex);

    } catch (IOException e) {
        if (V2RApp.DEBUG) {
            System.err.println("Error loading image: " + imagePath + e.getMessage());
        }
    } finally {
        button.setVerticalTextPosition(SwingConstants.BOTTOM);
        button.setHorizontalTextPosition(SwingConstants.CENTER);
        button.setText("<html><center>" + description + "</center></html>");
        button.setToolTipText(description);
    }

    return button;
}
© www.soinside.com 2019 - 2024. All rights reserved.