问题描述
我正在创建一个拥有僵尸的顶级射击游戏,跟随你并旋转直接瞄准你。如果有多达5个僵尸,则没有闪烁。如果有超过5个僵尸,则屏幕上显示的所有其他图像都会闪烁。在我看来,随着越来越多的僵尸被添加,它会导致游戏运行速度变慢,并且会让其他图像每隔一段时间都略微不合适。
我正在使用Graphics2D并旋转图像。绘制后的图像然后旋转回原来的位置,因此它不影响其后的其他图像。
如何停止像素的闪烁和轻微移动?
预先感谢!
这是僵尸的代码...
包com.game.stayalive;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
公共类Zombie扩展了Sprite {
Zombie(){
x = -50;
width = Display.spriteWidth;
height = Display.spriteHeight;
DELAY = rand.nextInt(8)+8;
life = 5;
}
long lastUpdate;
布尔型barrierDestroyed = false;
public void drawZombie(Graphics g,int playerX,int playerY){
if(!visible){
return;
}
Graphics2D g2d =(Graphics2D)g;
direction = Math.atan2(y - playerY,x - playerX);
g2d.rotate(direction - Math.PI / 2.0,x + width / 2,y + height / 2);
if(DELAY> 10){
g2d.setColor(Color.green.darker());
} else {
g2d.setColor(Color.red.darker());
}
//主体矩形
g2d.drawRect(x,y,width,height);
//左臂
g2d.drawRect(x - 宽度/ 2,y,宽度/ 2,高度);
g2d.fillRect(x - width / 2,y,width / 2,height);
//右臂
g2d.drawRect(x + width,y,width / 2,height);
g2d.fillRect(x + width,y,width / 2,height);
//主体填充
if(DELAY> 10){
g2d.setColor(Color.green);
} else {
g2d.setColor(Color.red);
}
g2d.fillRect(x,y,width,height);
g2d.rotate( - (direction - Math.PI / 2.0),x + width / 2,y + height / 2);
}
long等待= System.currentTimeMillis();
long waitTime;
public void setWaitTime(long waitTime){
this.waitTime = waitTime;
if(System.currentTimeMillis() - 等待< waitTime){
return;
}
}
int moveSpeed = 10;
public void collisionDetection(Zombie zombie1,Zombie zombie2){
xAcc + = gradientX;
yAcc + = gradientY;
x =(int)xAcc;
y =(int)yAcc;
if(zombie1.getRect()。intersects(zombie2.getRect())& amp; zombie1.visible&& zombie1.life> 0){
xAcc - = gradientX;
yAcc - = gradientY;
xAcc + =(gradientX / 10)+ rand.nextDouble() - 0.5;
yAcc + =(gradientY / 10)+ rand.nextDouble() - 0.5;
x =(int)xAcc;
y =(int)yAcc;
}
xAcc - = gradientX;
yAcc - = gradientY;
x =(int)xAcc;
y =(int)yAcc;
}
Random rand = new Random();
long spawnRate = 10000,lastZombieAdded;
$ b public void addZombie(){
if(System.currentTimeMillis() - lastZombieAdded> spawnRate){
Display.zombie.add(new Zombie());
Display.zombie.get(Display.zombie.size() - 1).visible = true;
Display.zombie.get(Display.zombie.size() - 1).setWaitTime(500);
Display.zombie.get(Display.zombie.size() - 1).xAcc = rand.nextInt(950);
Display.zombie.get(Display.zombie.size() - 1).yAcc = rand.nextInt(600);
lastZombieAdded = System.currentTimeMillis();
$ public void removeZombie(){
for(int i = 0; i< Display.zombie.size(); i ++){
if (!Display.zombie.get(i).visible){
Display.zombie.remove(i);
}
}
}
double gradientX,gradientY;
public void move(){
setWaitTime(waitTime);
if(life< = 0){
visible = false;
}
if(System.currentTimeMillis() - lastUpdate> DELAY){
xAcc + = gradientX;
yAcc + = gradientY;
x =(int)xAcc;
y =(int)yAcc;
lastUpdate = System.currentTimeMillis();
} gradientX = -Math.cos(direction);
gradientY = -Math.sin(direction);
}
}
JPanel类...
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d =(Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
player.drawPlayer(g2d);
for(int i = 0; i< zombie.size(); i ++){
if(zombie.get(i).visible){
zombie.get (ⅰ).drawZombie(G2D,PlayerX的,playerY);
for(int i = 0; i< pistol.size(); i ++){
if(pistol.get(i).visible){
pistol.get(i).drawPistol(g2d); ($)
$ b for(int i = 0; i< machineGun.size(); i ++){
if(machineGun.get(i).visible){
machineGun.get(i).drawMachineGun(g2d); ($ i
$ b for(int i = 0; i< flamethrower.size(); i ++){
if(flamethrower.get(i).visible){
flamethrower.get(i).draw(g2d);
}
}
reloadBar.drawReloadBar(g2d);
selector.drawSelector(g2d);
money.draw(g2d);
Toolkit.getDefaultToolkit()。sync();
g.dispose();
}
@Override
public void run(){
beforeTime,timeDiff,sleep;
beforeTime = System.currentTimeMillis();
while(true){
cycle();
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if(sleep sleep = 2;
}
尝试{
Thread.sleep(sleep);
} catch(InterruptedException e){
System.out.println(interrupted);
}
beforeTime = System.currentTimeMillis();
}
}
}
zombie是类僵尸的数组列表。 手枪和其他也是用于子弹等的数组列表。被调用的循环方法用于移动所有图像,添加图像并检查碰撞。关于代码如何无组织的道歉。 (我很快就会把它放在单独的方法中来完善)
这是一个非常简单的例子,我把它放在一起.. 。
它基本上有一个精灵,它有一个随机的运动和旋转。该程序能够渲染1到10,000个僵尸......严重...
我也使用过你的主循环,只是为了肯定...
没有真正的优化,如果我真的这样做了,我会在某个地方设置一个可以从中拉出并投入的僵尸池,以减少创建所需的时间他们......
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
导入javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ZombieLand {
protected static final Random RND = new Random();
private static BufferedImage zombie;
public static void main(String [] args){
new ZombieLand();
$ b $ public ZombieLand(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
尝试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
}
try {
zombie = ImageIO.read(getClass()。getResource(/ Zombie.png));
} catch(IOException ex){
ex.printStackTrace();
}
$ b $ final ZombiePane zombiePane = new ZombiePane();
final JSlider slider = new JSlider(1,10000);
slider.setMajorTickSpacing(1000);
slider.setMinorTickSpacing(100);
slider.setPaintTicks(true);
slider.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e){
JSlider slider =(JSlider)e.getSource();
zombiePane.setZombies(slider.getValue());
}
});
JFrame frame = new JFrame(Testing);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(zombiePane);
frame.add(slider,BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
slider.setValue(10000);
}
});
}
});
}
public static class ZombiePane extends JPanel {
private List< ZombieSprite>精灵;
protected static final Object SPRITE_LOCK = new Object();
private int desiredCount = 1;
public ZombiePane(){
sprites = new ArrayList<>(25);
sprites.add(new ZombieSprite());
线程t =新线程(new MainLoop());
t.setDaemon(false);
t.start();
Font font = getFont();
setFont(font.deriveFont(Font.BOLD,48f));
}
public void setZombies(int count){
desiredCount = count;
}
@Override
public Dimension getPreferredSize(){
return new Dimension(400,400);
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d =(Graphics2D)g.create();
synchronized(SPRITE_LOCK){
for(ZombieSprite sprite:sprites){
sprite.paint(g2d);
}
}
String text = Integer.toString(sprites.size());
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString(text,getWidth() - fm.stringWidth(text),getHeight() - fm.getHeight()+ fm.getAscent());
g2d.dispose(); (){
}
protected void(){
synchronized(SPRITE_LOCK){
if(desiredCount!= sprites.size()){
int count = 0;
int fill = 100; (sprites.size()> desiredCount& count< fill){
sprites.remove(0);
。
count ++;
}
count = 0; (sprites.size()< desiredCount& count< fill){
sprites.add(new ZombieSprite());
while
count ++; (ZombieSprite sprite:sprites){
sprite.update(getWidth(),getHeight());
公共类MainLoop实现Runnable {
private int DELAY = 40;
public void run(){
beforeTime,timeDiff,sleep;
beforeTime = System.currentTimeMillis();
while(true){
cycle();
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if(sleep sleep = 2;
}
尝试{
Thread.sleep(sleep);
} catch(InterruptedException e){
System.out.println(interrupted);
}
beforeTime = System.currentTimeMillis();
public static class ZombieSprite {
// private BufferedImage zombie;
私人点motionDelta;
private double rotationDelta;
私人点位置;
私人双角度;
public ZombieSprite(){
motionDelta = new Point();
motionDelta.x =(int)((Math.random()* 3)+ 1);
motionDelta.y =(int)((Math.random()* 3)+ 1);
if(Math.random()> 0.5){
motionDelta.x * = -1;
}
if(Math.random()> 0.5){
motionDelta.y * = -1;
}
rotationDelta =(int)((Math.random()* 9)+ 1);
if(Math.random()> 0.5){
rotationDelta * = -1;
$ b $ public void paint(Graphics2D g2d){
if(location!= null){
Graphics2D g =(Graphics2D)g2d。创建();
AffineTransform at = new AffineTransform();
at.translate(location.x,location.y);
at.rotate(Math.toRadians(angle),zombie.getWidth()/ 2,zombie.getHeight()/ 2);
g.setTransform(at);
g.drawImage(zombie,0,0,null);
g.dispose();
public void update(int width,int height){
if(location == null){
angle = random()* 360d);
location = new Point();
location.x =(int)(Math.random()*(width - zombie.getWidth()));
location.y =(int)(Math.random()*(height - zombie.getHeight()));
} else {
angle + = rotationDelta;
location.x + = motionDelta.x;
location.y + = motionDelta.y;
if(location.x< 0){
location.x = 0;
motionDelta.x * = -1;
} else if(location.x + zombie.getWidth()> width){
location.x = width - zombie.getWidth();
motionDelta.x * = -1;
}
if(location.y location.y = 0;
motionDelta.y * = -1;
} else if(location.y + zombie.getHeight()> height){
location.y = height - zombie.getHeight();
motionDelta.y * = -1;
}
}
}
}
}
I am creating a top down shooter that has zombies follow you and rotate to aim directly at you. If there are up to 5 zombies following there is no flickering. If there are over 5 zombies there is a flicker on all other images drawn to the screen. It seems to me that as more zombies get added it is causing the game to run slower and for it to draw the other images slightly out of place every now and again.I am using Graphics2D and rotating the image. The image after being drawn is then rotated back to the original position so it doesn't affect other images being drawn after it.How can I stop the flickering and slight movement in pixels?
Thanks in advance!
Here is the code for the zombies...
package com.game.stayalive;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
public class Zombie extends Sprite {
Zombie() {
x = -50;
width = Display.spriteWidth;
height = Display.spriteHeight;
DELAY = rand.nextInt(8)+8;
life = 5;
}
long lastUpdate;
boolean barrierDestroyed = false;
public void drawZombie(Graphics g,int playerX, int playerY) {
if (!visible) {
return;
}
Graphics2D g2d = (Graphics2D) g;
direction = Math.atan2(y - playerY, x - playerX);
g2d.rotate(direction - Math.PI / 2.0, x + width / 2, y + height / 2);
if(DELAY > 10){
g2d.setColor(Color.green.darker());
}else{
g2d.setColor(Color.red.darker());
}
// Main body rectangle
g2d.drawRect(x, y, width, height);
// Left arm
g2d.drawRect(x - width / 2, y, width / 2, height);
g2d.fillRect(x - width / 2, y, width / 2, height);
// Right arm
g2d.drawRect(x + width, y, width / 2, height);
g2d.fillRect(x + width, y, width / 2, height);
// Main body filled
if(DELAY > 10){
g2d.setColor(Color.green);
}else{
g2d.setColor(Color.red);
}
g2d.fillRect(x, y, width, height);
g2d.rotate(-(direction - Math.PI / 2.0), x + width / 2, y + height / 2);
}
long waited = System.currentTimeMillis();
long waitTime;
public void setWaitTime(long waitTime){
this.waitTime = waitTime;
if (System.currentTimeMillis() - waited < waitTime) {
return;
}
}
int moveSpeed = 10;
public void collisionDetection(Zombie zombie1, Zombie zombie2) {
xAcc += gradientX;
yAcc += gradientY;
x = (int) xAcc;
y = (int) yAcc;
if (zombie1.getRect().intersects(zombie2.getRect()) && zombie1.visible && zombie1.life > 0) {
xAcc -= gradientX;
yAcc -= gradientY;
xAcc += (gradientX/10)+rand.nextDouble()-0.5;
yAcc += (gradientY/10) + rand.nextDouble()-0.5;
x = (int) xAcc;
y = (int) yAcc;
}
xAcc -= gradientX;
yAcc -= gradientY;
x = (int) xAcc;
y = (int) yAcc;
}
Random rand = new Random();
long spawnRate = 10000, lastZombieAdded;
public void addZombie() {
if (System.currentTimeMillis() - lastZombieAdded > spawnRate) {
Display.zombie.add(new Zombie());
Display.zombie.get(Display.zombie.size()-1).visible = true;
Display.zombie.get(Display.zombie.size()-1).setWaitTime(500);
Display.zombie.get(Display.zombie.size()-1).xAcc = rand.nextInt(950);
Display.zombie.get(Display.zombie.size()-1).yAcc = rand.nextInt(600);
lastZombieAdded = System.currentTimeMillis();
}
}
public void removeZombie(){
for (int i = 0; i < Display.zombie.size(); i++) {
if(!Display.zombie.get(i).visible ){
Display.zombie.remove(i);
}
}
}
double gradientX, gradientY;
public void move() {
setWaitTime(waitTime);
if (life <= 0) {
visible = false;
}
if (System.currentTimeMillis() - lastUpdate > DELAY) {
xAcc += gradientX;
yAcc += gradientY;
x = (int) xAcc;
y = (int) yAcc;
lastUpdate = System.currentTimeMillis();
}gradientX = -Math.cos(direction);
gradientY = -Math.sin(direction);
}
}
The JPanel Class...
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
player.drawPlayer(g2d);
for (int i = 0; i < zombie.size(); i++) {
if (zombie.get(i).visible) {
zombie.get(i).drawZombie(g2d,playerX,playerY);
}
}
for (int i = 0; i < pistol.size(); i++) {
if (pistol.get(i).visible) {
pistol.get(i).drawPistol(g2d);
}
}
for (int i = 0; i < machineGun.size(); i++) {
if (machineGun.get(i).visible) {
machineGun.get(i).drawMachineGun(g2d);
}
}
for (int i = 0; i < flamethrower.size(); i++) {
if (flamethrower.get(i).visible) {
flamethrower.get(i).draw(g2d);
}
}
reloadBar.drawReloadBar(g2d);
selector.drawSelector(g2d);
money.draw(g2d);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
@Override
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
cycle();
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0) {
sleep = 2;
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
beforeTime = System.currentTimeMillis();
}
}
}
"zombie" is an Array List of the class Zombie. "Pistol" and the others are also Array Lists used for bullets etc. The cycle method that gets called is used to move all the images, add images and check for collisions. Apologies for how unorganized the code is. (I will soon put it in separate methods to neaten things up)
This is a really simple example I put together...
It basically has a sprite which has a random motion and rotation. The program is capable of rendering between 1 and 10, 000 zombies...seriously...
I've used you "main loop" as well, just to be sure...
There's no real optimisation, if I was really doing this, I would have a pool somewhere with zombies that could pulled from and put to in order to reduce the amount of time it takes to create them...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ZombieLand {
protected static final Random RND = new Random();
private static BufferedImage zombie;
public static void main(String[] args) {
new ZombieLand();
}
public ZombieLand() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
try {
zombie = ImageIO.read(getClass().getResource("/Zombie.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
final ZombiePane zombiePane = new ZombiePane();
final JSlider slider = new JSlider(1, 10000);
slider.setMajorTickSpacing(1000);
slider.setMinorTickSpacing(100);
slider.setPaintTicks(true);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSlider slider = (JSlider) e.getSource();
zombiePane.setZombies(slider.getValue());
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(zombiePane);
frame.add(slider, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
slider.setValue(10000);
}
});
}
});
}
public static class ZombiePane extends JPanel {
private List<ZombieSprite> sprites;
protected static final Object SPRITE_LOCK = new Object();
private int desiredCount = 1;
public ZombiePane() {
sprites = new ArrayList<>(25);
sprites.add(new ZombieSprite());
Thread t = new Thread(new MainLoop());
t.setDaemon(false);
t.start();
Font font = getFont();
setFont(font.deriveFont(Font.BOLD, 48f));
}
public void setZombies(int count) {
desiredCount = count;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
synchronized (SPRITE_LOCK) {
for (ZombieSprite sprite : sprites) {
sprite.paint(g2d);
}
}
String text = Integer.toString(sprites.size());
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString(text, getWidth() - fm.stringWidth(text), getHeight() - fm.getHeight() + fm.getAscent());
g2d.dispose();
}
protected void cycle() {
synchronized (SPRITE_LOCK) {
if (desiredCount != sprites.size()) {
int count = 0;
int fill = 100;
while (sprites.size() > desiredCount && count < fill) {
sprites.remove(0);
count++;
}
count = 0;
while (sprites.size() < desiredCount && count < fill) {
sprites.add(new ZombieSprite());
count++;
}
}
for (ZombieSprite sprite : sprites) {
sprite.update(getWidth(), getHeight());
}
}
}
public class MainLoop implements Runnable {
private int DELAY = 40;
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
cycle();
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0) {
sleep = 2;
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
beforeTime = System.currentTimeMillis();
}
}
}
}
public static class ZombieSprite {
// private BufferedImage zombie;
private Point motionDelta;
private double rotationDelta;
private Point location;
private double angle;
public ZombieSprite() {
motionDelta = new Point();
motionDelta.x = (int) ((Math.random() * 3) + 1);
motionDelta.y = (int) ((Math.random() * 3) + 1);
if (Math.random() > 0.5) {
motionDelta.x *= -1;
}
if (Math.random() > 0.5) {
motionDelta.y *= -1;
}
rotationDelta = (int) ((Math.random() * 9) + 1);
if (Math.random() > 0.5) {
rotationDelta *= -1;
}
}
public void paint(Graphics2D g2d) {
if (location != null) {
Graphics2D g = (Graphics2D) g2d.create();
AffineTransform at = new AffineTransform();
at.translate(location.x, location.y);
at.rotate(Math.toRadians(angle), zombie.getWidth() / 2, zombie.getHeight() / 2);
g.setTransform(at);
g.drawImage(zombie, 0, 0, null);
g.dispose();
}
}
public void update(int width, int height) {
if (location == null) {
angle = (Math.random() * 360d);
location = new Point();
location.x = (int) (Math.random() * (width - zombie.getWidth()));
location.y = (int) (Math.random() * (height - zombie.getHeight()));
} else {
angle += rotationDelta;
location.x += motionDelta.x;
location.y += motionDelta.y;
if (location.x < 0) {
location.x = 0;
motionDelta.x *= -1;
} else if (location.x + zombie.getWidth() > width) {
location.x = width - zombie.getWidth();
motionDelta.x *= -1;
}
if (location.y < 0) {
location.y = 0;
motionDelta.y *= -1;
} else if (location.y + zombie.getHeight() > height) {
location.y = height - zombie.getHeight();
motionDelta.y *= -1;
}
}
}
}
}
这篇关于旋转多个图像导致闪烁。 Java Graphics2D的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!