好的,所以我环顾四周,没有找到任何对我有帮助的东西,所以我想我会继续在这里问。我想要一堆碰撞反弹的圆圈,并且通常相互交互。我遇到的问题是画很多圆圈会消耗帧速率。所以给定一个我必须画的圆圈阵列,所有这些圆圈。绘制它们的唯一方法是否只是在paintComponent中使用g.fillOval()将它们全部绘制?
例如,在 paint 组件中,我调用一个函数 drawBalls(Graphics2D g),它绘制它包含的所有球。(这就是我通过将东西传递给绘制的对象来绘制东西的方式,我不知道是否有更好的方法)
for(Ball ball:balls){
ball.drawYourself(g) //g is the Graphics2D
}
谢谢
对不起,如果这是一个糟糕的问题,这是我的程序代码。我希望它不会太长。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import java.util.*;
import javax.swing.Timer;
//###################################################\
public class Game extends JFrame implements ActionListener{
private Timer myTimer;
private GamePanel panel;
public Game() {
super("Things.py");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1000,800);
panel = new GamePanel(this);
add(panel);
myTimer = new Timer(1, this);
myTimer.start();
setResizable(false);
setVisible(true);
}
public void actionPerformed(ActionEvent evt){
panel.repaint();
}
public static void main(String[] arguments) {
Game frame = new Game();
}
}
//###################################################\
//###################################################\
class GamePanel extends JPanel implements MouseMotionListener, MouseListener,KeyListener{
// ------------ Variables ----------------------------------------------
private int mx,my;//Mouse position x and y
private boolean[]keys;//If the keys are pressed
private Boolean mousepressed=false;//If the mouse is pressed down
private Game mainframe;//The panel that created this GamePanel
private Color backmenuc;
private Color backcolor;
private bounceBalls bballs;
private bounceBalls bballs2;
// ------------ Constructor --------------------------------------------
public GamePanel(Game m){
//----- Listeners -----
addMouseMotionListener(this);//LISTEN TO ME!!!
addMouseListener(this);//Listen to me!
addKeyListener(this);//listen to me pls
//----- Variables -----
mainframe=m;
keys=new boolean[KeyEvent.KEY_LAST+1];//creates the array for keys
backcolor=new Color(0,0,0);
backmenuc=new Color(255,255,255);
bballs=new bounceBalls(this);
bballs2=new bounceBalls(this);
//----- Load Images -----
//----- End -----
}
// ------------ Drawing ------------------------------------------------
public void paintComponent(Graphics gg){
Graphics2D g=(Graphics2D) gg;
paint.drawRect(g,0,0,getWidth(),getHeight(),backcolor);
if (mousepressed){
bballs.addBall(mx,my,10);
bballs2.addBall(mx+100,my,10);
}
bBallThreading b1=new bBallThreading(g,bballs,"B1");
b1.start();
bBallThreading b2=new bBallThreading(g,bballs2,"B1");
b2.start();
//bballs.update();
//bballs2.update();
bballs.draw(g);
bballs2.draw(g);
System.out.println(bballs.size());
}
// ------------ Misc ---------------------------------------------------
public void addNotify() {
super.addNotify();
}
// ------------ MouseListener ------------------------------------------
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
mousepressed=false;
}
public void mouseClicked(MouseEvent e){
}
public void mousePressed(MouseEvent e){
mousepressed=true;
}
// ---------- MouseMotionListener --------------------------------------
public void mouseDragged(MouseEvent e){
mx=e.getX();
my=e.getY();
}
public void mouseMoved(MouseEvent e){
mx=e.getX();
my=e.getY();
}
// ---------- KeyListener -----------------------------------------------
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
}
//###################################################\
class bounceBall{
private double bx,by;
private int br;
private double vx,vy;
public bounceBall(int x,int y,int radius){
bx=(double)x;
by=(double)y;
br=radius;
vx=0;
vy=0;
}
public void move(){
if((by+vy)>800){
vy*=-.9;
}
bx+=vx;
by+=vy;
}
public void addV(double x, double y){
vx+=x;
vy+=y;
}
public void draw(Graphics2D g){
g.setColor(new Color(255,0,0));
g.fillOval((int)bx-br,(int)by-br,br*2,br*2);
}
}
class bounceBalls{
GamePanel gp;
ArrayList<bounceBall> balls;
double gravity;
public bounceBalls(GamePanel gamep){
gp=gamep;
gravity=.1;
balls=new ArrayList<bounceBall>();
}
public void draw(Graphics2D g){
//paint.setAA(g,true);
paint.setAlpha(g,.1f);
for(bounceBall ball:balls.toArray(new bounceBall[balls.size()])){
ball.draw(g);
}
paint.setAlpha(g,1f);
//paint.setAA(g,false);
}
public void setGravity(double g){
gravity=g;
}
public void update(){
for(bounceBall ball:balls.toArray(new bounceBall[balls.size()])){
ball.addV(0,gravity);
ball.move();
}
}
public void addBall(int x, int y, int radius){
balls.add(new bounceBall(x,y,radius));
}
public int size(){
return balls.size();
}
}
class bBallThreading implements Runnable{
private Thread t;
private String threadname;
Graphics2D g;
private bounceBalls bballs;
public bBallThreading(Graphics2D g, bounceBalls bballs,String s){
this.g=g;
this.bballs=bballs;
threadname=s;
}
public void run(){
bballs.update();
}
public void start(){
if (t == null)
{
t = new Thread (this, threadname);
t.start ();
}
}
}
//###################################################\
当我运行这个时,我以 4000 fps 的速度得到 30 个圆圈
bBallThreading b1=new bBallThreading(g,bballs,"B1");
b1.start();
bBallThreading b2=new bBallThreading(g,bballs2,"B1");
b2.start();
paintComponent() 方法用于绘画。这就是应该做的。
您不应该在绘画方法中启动线程。每次 Swing 绘制组件时,您都会启动另外两个线程。
向该方法添加一个 System.out.println(...) 语句,以查看该方法执行了多少次。
您应该在启动动画时启动线程。