gpt4 book ai didi

java - 如何使用 ArrayList 来显示移动对象?

转载 作者:行者123 更新时间:2023-11-30 04:02:33 27 4
gpt4 key购买 nike

我对如何使用ArrayList有一些疑问。我是java新手,所以我想知道它的实际用途以及正确的使用方法。有人告诉我可以使用数组列表来显示我的对象,但我似乎无法理解如何将其添加到我当前的项目中。

我正在研究同时显示3个管道,用计时器控制速度和刷新率。我想我终于了解了JFrame的基础知识和JPanel ,但我已经被介绍给神秘 CardLayout最近,所以任何有关这方面的例子也会有所帮助。

到目前为止,我已经能够添加一个开始菜单,其中包含一个播放按钮。用户点击“Play!”后,菜单应替换为游戏面板,并设置playerIsReadytrue ,启动应添加 pipe.java 的三个实例的计时器。到屏幕上,每个都由 timer 向左移动称为“速度”。所有管道都从屏幕右侧开始。

我想更好地了解如何在每个 pipe 之间添加间距目的。我还对如何加载本地镜像并将其打印到屏幕感兴趣。

如果您尝试回答任何这些问题,请详细解释每个步骤,因为我是 Java 新手。感谢您抽出宝贵时间提供帮助。如果您不是来回答问题的,我希望您能够从这里的任何代码/答案中学到一些东西。

游戏

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.SwingUtilities;

public class Game {

public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
// the GUI as seen by the user (without frame)
final CardLayout cl = new CardLayout();
final JPanel gui = new JPanel(cl);
// remove if no border is needed
gui.setBorder(new EmptyBorder(10,10,10,10));

JPanel menu = new JPanel(new GridBagLayout());
JButton playGame = new JButton("Play!");
ActionListener playGameListener = new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
cl.show(gui, "game");
}
};
playGame.addActionListener(playGameListener);
Insets margin = new Insets(20, 50, 20, 50);
playGame.setMargin(margin);
menu.add(playGame);
gui.add(menu);
cl.addLayoutComponent(menu, "menu");

final JPanel pipes = new Pipes();
gui.add(pipes);
cl.addLayoutComponent(pipes, "game");

JFrame f = new JFrame("Pipes Game");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);

// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);

/*if (playerIsReady) {
Timer speed = new Timer(10, new ActionListener() { //pipe speed
@Override
public void actionPerformed(ActionEvent e) {
pipes.move();
}
});
speed.start();

Timer refresh = new Timer(30, new ActionListener() { //refresh rate
@Override
public void actionPerformed(ActionEvent e) {
pipes.repaint();
}
});
refresh.start();
}*/
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}

管道对象

import java.awt.Graphics;

public class PipeObject {
//Declare and initialiaze variables
int x1 = 754; //xVal start
int x2 = 75; //pipe width
//total width is 83
int y1 = -1; //yVal start
int y2 = setHeightVal(); //pipe height
int gap = 130; //gap height

public void drawPipe(Graphics g) {

g.clearRect(0,0,750,500); //Clear screen
g.drawRect(x1,y1,x2,y2); //Draw part 1
g.drawRect(x1-3,y2-1,x2+6,25); //Draw part 2
g.drawRect(x1-3,y2+25+gap,x2+6,25); //Draw part 3
g.drawRect(x1,y2+25+gap+25,x2,500-y2-49-gap); //Draw part 4
}

public void move() {
x1--;
}

public int getMyX() { //To determine where the pipe is horizontally
return x1-3;
}

public int getMyY() { //To determine where the pipe is vertically
return y2+25;
}

public int setHeightVal() { //Get a random number and select a preset height
int num = (int)(9*Math.random() + 1);
int val = 0;
if (num == 9)
{
val = 295;
}
else if (num == 8)
{
val = 246;
}
else if (num == 7)
{
val = 216;
}
else if (num == 6)
{
val = 185;
}
else if (num == 5)
{
val = 156;
}
else if (num == 4)
{
val = 125;
}
else if (num == 3)
{
val = 96;
}
else if (num == 2)
{
val = 66;
}
else
{
val = 25;
}
return val;
}
}

最佳答案

因此,您的 PipeObject 类只是一个数据模型类。 drawPipe 方法本身并不实际绘制任何内容。您需要一个 JPanel 类来呈现此数据,并调用 JPanelpaintComponent 方法中的 drawPipe 方法,将 Graphics 上下文传递给它。

此外,如果您想要具有不同的 x 位置值,则需要一个构造函数来接受不同的 x 值。看起来 y 值应该是相同的,因为它们总是保持在相同的 y 轴上。 PipeObject 类中的构造函数应如下所示

int x1;   // no need to give them values. 
int x2; // This will be done when you create a new PipeObject object

public PipeObject(int x1, int x2) {
this.x1 = x1;
this.x1 = x2;
}

当您创建new PipeObject对象时,您将向它传递不同的值。总结以上两点,你就会得到这样的结果。

public class PipePanel extends JPanel {
List<PipeObject> pipes = new ArrayList<PipeObject>();

public PipePanel() {
pipes.add(new PipeObject(100, 90));
pipes.add(new PipeObject(300, 290));
pipes.add(new PipeObject(500, 490));
}

protected void paintComponent(Graphics g) {
super.paintComponent(g);

for ( PipeObject pipe : pipes ){
pipe.drawPipe(g);
}
}
}

然后您可以将 PipesPanel 实例添加到您的框架中。另请注意,在 PipesPanel 中,您应该覆盖 getPreferredSize,因此它将具有首选大小,并且您只需 pack() 框架即可

@Override
public Dimension getPreferredSize() {
return new Dimension(800, 500); // or what ever values you want for screen size
}

此外,当您想要操作 PipeObject 或为其设置动画时,只需调用其方法之一,例如move(),然后调用repaint `。类似的东西

Timer timer = new Timer(50, new ActionListener(){
public void actionPerformed(ActionEvent e) {
for (PipeObject pipe : pipes) {
pipe.move();
}
repaint();
}
});

关于java - 如何使用 ArrayList 来显示移动对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21617038/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com