java实战多个对象同时移动_java – 如何同时滚动多个对象?

在这个问题之后被问到新的问题,找到了here.

我是Java的新手,但我正在开发“Flappy Bird”,以了解有关java和图形显示方式的更多信息.我非常感谢任何解决方案或建议.谢谢!

现在,我的程序制作一个随机管道并滚动它,但是当x1-3 = -83时,我不需要它继续滚动(这时管道将完全脱离屏幕并且不再需要).

问题

如何让我的Game.class滚动多个Pipes.class实例,同时在它们之间添加预设距离?我可以找出它们之间的距离,但就显示不止一个,我不知道该怎么做.最多只能同时显示3个管道.

如何显示主菜单的面板,然后在按下启动按钮后切换到管道面板?

Game.java

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.SwingUtilities;

import javax.swing.Timer;

public class Game {

Pipes panel = new Pipes();

public Game() {

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.add(panel);

f.setTitle("Pipe Game");

f.setResizable(false);

f.pack();

f.setLocationRelativeTo(null);

f.setVisible(true);

Timer timer = new Timer(10, new ActionListener() { //pipe speed

@Override

public void actionPerformed(ActionEvent e) {

panel.move();

}

});

timer.start();

Timer refresh = new Timer(30, new ActionListener() { //refresh rate

@Override

public void actionPerformed(ActionEvent e) {

panel.repaint();

}

});

refresh.start();

}

public static void main(String args[]) {

SwingUtilities.invokeLater(new Runnable() {

@Override

public void run() {

new Game();

}

});

}

}

Pipes.java

import java.awt.Dimension;

import java.awt.Graphics;

import javax.swing.JPanel;

public class Pipes extends JPanel {

//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

@Override

public void paintComponent(Graphics g) {

super.paintComponent(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;

}

@Override

public Dimension getPreferredSize() {

return new Dimension(751, 501);

}

}

解决方法:

“How can I make my Game.class scroll more than one instance of Pipes.class while adding a preset distance between them? “

这是一些简单的逻辑.您想使用数据结构来保存管道.这个数据结构将保留的是当时需要绘制的任何数据,如x,y,坐标.对于这个任务,我更喜欢用它自己的draw方法创建一个新类,我将paintComponent的Graphics上下文传递给.例如

public class Pipe {

int x;

int y;

public class Pipe(int x, int y) {

this.x = x;

this.y = y;

}

public void drawPipe(Graphics g) {

g.fillRect(x, y, 50, 100);

}

}

现在这只是一个示例类.上面只绘制一个矩形,但这只是为了向您展示您应该做什么.

接下来,您希望将数据结构保存为三个Pipe对象,如数组.我更喜欢使用List.你需要在Pipes类中使用List,并向它添加三个Pipe对象.您可以将x指定为您喜欢的任何内容,以使它们保持相同的距离

public class Pipes extends JPanel {

List pipes = new ArrayList();

public Pipes() {

pipes.add(new Pipe(50, 100));

pipes.add(new Pipe(150, 100));

pipes.add(new Pipe(250, 100));

}

}

现在在paintComponent方法中,您需要做的就是遍历它们并使用它的drawPipe方法

protected void paintComponent(Graphics g) {

super.paintComponent(g);

for ( Pipe pipe : pipes ){

pipe.drawPipe(g);

}

}

现在你移动它们你需要做的就是在计时器中移动x个位置,然后调用重绘.您可能还需要检查x以确保它不会离开屏幕,或者如果您向右移动它们,您可以将它们放在最左边然后乳清离开屏幕,就像传送带一样.所以你可以这样做

private static final int X_INC = 5;

...

Timer timer = new Timer(40, new ActionListener(){

public void actionPerformed(ActionEvent e) {

for (Pipe pipe : pipes ){

if (pipe.x >= screenWidth) {

pipe.x = 0;

} else {

pipe.x += X_INC;

}

}

repaint();

}

});

如您所见,我所做的是遍历List并只更改其所有x坐标,然后重绘().因此,您可以使用您需要绘制的任何值创建自己的Pipe类,并在循环中移动它们.

对于速度的改变,而不是像计时器那样使用像10这样的硬编码vakue,使用可变延迟,你可以像点击按钮一样改变

int delay = 100;

JButton speedUp = new JButton("Speed UP");

JButton slowDown = new JButton("Slow Down");

Timer timer = null;

public Pipes() {

timer = new Timer(delay, new ActionListener(){

...

});

timer.start();

speedUp.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e) {

if (!((delay - 20) < 0)) {

delay -=20;

timer.setDelay(delay);

}

}

});

// do the same for slowDown, but decrease the delay

}

测试一下

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.net.URL;

import java.util.ArrayList;

import java.util.List;

import java.util.logging.Level;

import java.util.logging.Logger;

import javax.imageio.ImageIO;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.SwingUtilities;

import javax.swing.Timer;

public class Mario extends JPanel {

private static final int D_W = 800;

private static final int D_H = 300;

private static final int X_INC = 5;

BufferedImage bg;

BufferedImage pipeImg;

List pipes = new ArrayList<>();

int delay = 50;

Timer timer = null;

public Mario() {

try {

bg = ImageIO.read(new URL("http://farm8.staticflickr.com/7341/12338164043_0f68c73fe4_o.png"));

pipeImg = ImageIO.read(new URL("http://farm3.staticflickr.com/2882/12338452484_7c72da0929_o.png"));

} catch (IOException ex) {

Logger.getLogger(Mario.class.getName()).log(Level.SEVERE, null, ex);

}

pipes.add(new Pipe(100, 150, pipeImg));

pipes.add(new Pipe(400, 150, pipeImg));

pipes.add(new Pipe(700, 150, pipeImg));

timer = new Timer(delay, new ActionListener(){

public void actionPerformed(ActionEvent e) {

for (Pipe pipe : pipes) {

if (pipe.x > D_W) {

pipe.x = 0;

} else {

pipe.x += X_INC;

}

}

repaint();

}

});

timer.start();

}

@Override

protected void paintComponent(Graphics g) {

super.paintComponent(g);

g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);

for (Pipe pipe : pipes) {

pipe.drawPipe(g);

}

}

@Override

public Dimension getPreferredSize() {

return new Dimension(D_W, D_H);

}

public class Pipe {

int x;

int y;

Image pipe;

public Pipe(int x, int y, Image pipe) {

this.x = x;

this.y = y;

this.pipe = pipe;

}

public void drawPipe(Graphics g) {

g.drawImage(pipe, x, y, 75, 150, Mario.this);

}

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

JFrame frame = new JFrame("Mario Pipes");

frame.add(new Mario());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

}

});

}

}

标签:java,swing,jframe,awt,flappy-bird-clone

来源: https://codeday.me/bug/20190624/1280196.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值