我想用我在其中绘制的形状(平面)对图像进行抗锯齿处理。我在 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游戏设计中)
基本上,重画图像。我在这里做了类似的事情。 关键是
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;
}