如何在Java中在运行时创建和绘制对象
因此,我的目标是让连续的对象流从帧的右侧开始,在它们到达帧的左侧后消失/被删除。我将有一个球对象/图像,它将是静止的,但似乎向前移动,并跳过我希望创建的矩形对象。我希望在用户“存活”一段时间后停止创建对象如何在Java中在运行时创建和绘制对象,java,swing,graphics,paint,Java,Swing,Graphics,Paint,因此,我的目标是让连续的对象流从帧的右侧开始,在它们到达帧的左侧后消失/被删除。我将有一个球对象/图像,它将是静止的,但似乎向前移动,并跳过我希望创建的矩形对象。我希望在用户“存活”一段时间后停止创建对象 基本上,我的问题是如何加载JFrame,然后在运行时继续绘制对象。这样做一段时间,不断地绘制和移除对象。好的,这是一个非常基本的例子 基本上,它有两个Lists,一个是可用对象的“池”,另一个是当前屏幕上对象的List 其目的是减少需要创建的新对象的数量,而是保留一个可用对象池,主循环可以从中
基本上,我的问题是如何加载JFrame,然后在运行时继续绘制对象。这样做一段时间,不断地绘制和移除对象。好的,这是一个非常基本的例子 基本上,它有两个
List
s,一个是可用对象的“池”,另一个是当前屏幕上对象的List
其目的是减少需要创建的新对象的数量,而是保留一个可用对象池,主循环可以从中绘制。如果池为空且需要新对象,则将创建它,但一旦它离开屏幕,它将被替换到池中(假设我们需要它)
此示例使您能够动态更改活动对象的数量(25-10000)。系统将尝试平衡它在两个列表中管理的对象总数,使之精确到这个数量。如果你经常改变活动对象的数量,你可能会考虑允许池有一个“软糖”的因素,但是我会把它留给你。
还有一个增长率因子,这意味着当您在主循环的每个循环上增加活动对象的数量时,它将使可用对象的数量增加该数量,这有助于减少创建9000个新对象可能产生的延迟的可能性;)
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Font;
导入java.awt.FontMetrics;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.Iterator;
导入java.util.List;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JSlider;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
导入javax.swing.event.ChangeEvent;
导入javax.swing.event.ChangeListener;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
公共测试窗格(){
setLayout(新的BorderLayout());
GamePane GamePane=新建GamePane();
JSlider滑块=新JSlider(2510000);
添加(游戏窗格);
添加(滑块,BorderLayout.SOUTH);
slider.addChangeListener(新的ChangeListener(){
@凌驾
公共无效状态已更改(更改事件e){
gamePane.setActiveEntityCount(slider.getValue());
}
});
滑块设置值(25);
}
}
公共类游戏窗格扩展了JPanel{
私人实体名单;
私有实体;
私有int-activeCount;
私有整数增长率=100;
公共游戏窗格(){
实体池=新阵列列表(25);
activeEntities=新的ArrayList(25);
setFont(getFont().deriveFont(Font.BOLD,48f));
计时器计时器=新计时器(40,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
Iterator it=activeEntities.Iterator();
while(it.hasNext()){
MovableEntity=it.next();
if(entity.update(getWidth(),getHeight())){
it.remove();
//如果对象总数超过activeCount,则此操作将删除对象
if(poolOfEntities.size()+activeEntities.size()import java.awt.BorderLayout;
import java.awt.Color;
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.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
GamePane gamePane = new GamePane();
JSlider slider = new JSlider(25, 10000);
add(gamePane);
add(slider, BorderLayout.SOUTH);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
gamePane.setActiveEntityCount(slider.getValue());
}
});
slider.setValue(25);
}
}
public class GamePane extends JPanel {
private List<MovableEntity> poolOfEntities;
private List<MovableEntity> activeEntities;
private int activeCount;
private int growthRate = 100;
public GamePane() {
poolOfEntities = new ArrayList<>(25);
activeEntities = new ArrayList<>(25);
setFont(getFont().deriveFont(Font.BOLD, 48f));
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Iterator<MovableEntity> it = activeEntities.iterator();
while (it.hasNext()) {
MovableEntity entity = it.next();
if (entity.update(getWidth(), getHeight())) {
it.remove();
// This drop objects if the total number of objects exceeds the activeCount
if (poolOfEntities.size() + activeEntities.size() < activeCount) {
poolOfEntities.add(entity);
}
}
}
for (int growth = 0; growth < growthRate && activeEntities.size() < activeCount; growth++) {
MovableEntity entity = null;
if (poolOfEntities.isEmpty()) {
entity = createNewEntity();
} else {
entity = poolOfEntities.remove(0);
}
activeEntities.add(entity);
}
repaint();
}
});
timer.start();
}
protected MovableEntity createNewEntity() {
int width = getWidth();
int height = getHeight();
if (width == 0) {
width = getPreferredSize().width;
} else if (height == 0) {
height = getPreferredSize().height;
}
return new ShapeEntity(width, height);
}
public void setActiveEntityCount(int count) {
if (count != activeCount) {
activeCount = count;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Iterator<MovableEntity> it = activeEntities.iterator();
while (it.hasNext()) {
MovableEntity entity = it.next();
entity.paint(g2d);
}
String text = Integer.toString(activeEntities.size());
FontMetrics fm = g2d.getFontMetrics();
int x = getWidth() - fm.stringWidth(text);
int y = (getHeight() - fm.getHeight() )+ fm.getAscent();
g2d.setColor(Color.WHITE);
g2d.drawString(text, x, y);
g2d.dispose();
}
}
public interface Entity {
public void paint(Graphics2D g);
}
public interface MovableEntity extends Entity {
public boolean update(int width, int height);
}
public static class ShapeEntity implements MovableEntity {
protected static final Color COLORS[] = {Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW};
protected static final Random RND = new Random();
private Rectangle bounds;
private final Color color = COLORS[RND.nextInt(COLORS.length)];
private int xDelta;
public ShapeEntity(int width, int height) {
reset(width, height);
}
protected void reset(int width, int height) {
bounds = new Rectangle();
bounds.width = 5 + RND.nextInt(25);
bounds.height = 5 + RND.nextInt(25);
bounds.x = -bounds.width; // offscreen
bounds.y = RND.nextInt(height - bounds.height);
xDelta = 1 + RND.nextInt(8);
}
@Override
public boolean update(int width, int height) {
boolean reset = false;
bounds.x += xDelta;
if (bounds.x > width) {
reset(width, height);
reset = true;
}
return reset;
}
@Override
public void paint(Graphics2D g) {
g.setColor(color);
g.fill(bounds);
}
}
}