gpt4 book ai didi

java - 如何在 Swing 游戏上通知多线程事件

转载 作者:行者123 更新时间:2023-12-01 19:00:28 25 4
gpt4 key购买 nike

我应该做一个小游戏模拟。在这个游戏中有三个按钮。当用户单击启动时,坦克和汽车将彼此关闭 90 度。当用户单击关闭按钮时,坦克将向汽车 throw 子弹。

我为此做了一个模拟。坦克向汽车扔子弹,但当子弹撞车时我却做不到。我只需要增加坦克撞车次数的分数。

这是源代码

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

public class Vehicle extends Thread {
private JPanel box;

private int XSIZE;

private int YSIZE;

private int time;

private int x;

private int y;

private int dx = 5;

private int dy = 5;

private int dim;

public Vehicle(JPanel b, int i) {
box = b;
this.dim = i;
if (i == 0) {
x = 0;
y = 100;
time = 1000;
XSIZE = 9;
YSIZE = 20;
} else {
time = 200;
y = box.getSize().height;
x = box.getSize().width / 2;
XSIZE = 6;
YSIZE = 10;
}
}

public void draw() {
Graphics g = box.getGraphics();
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}

public void moveHorizontal() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setColor(Color.BLUE);
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
x += dx;

Dimension d = box.getSize();
if (x < 0) {
x = 0;
dx = -dx;
}
if (x + XSIZE >= d.width) {
x = d.width - XSIZE;
dx = -dx;
}

g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}

public JPanel getBox() {
return box;
}

public void setBox(JPanel box) {
this.box = box;
}

public void moveVertical() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
y += dy;
Dimension d = box.getSize();
if (y < 0) {
y = 0;
dy = -dy;
}
if (y + YSIZE >= d.height) {
y = d.height - YSIZE;
dy = -dy;
}

g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}

public void move(int i) {

if (i == 0) {

moveHorizontal();
} else {
moveVertical();
}
}

public int getYSIZE() {
return YSIZE;
}

public void setYSIZE(int ySIZE) {
YSIZE = ySIZE;
}

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public int getXSIZE() {
return XSIZE;
}

public void setXSIZE(int xSIZE) {
XSIZE = xSIZE;
}

public void setY(int y) {
this.y = y;
}

public void run() {
try {
draw();
for (;;) {
move(dim);
sleep(time);
}
} catch (InterruptedException e) {
}
}

}

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

public class Bullet extends Thread {
private JPanel box;

private int XSIZE = 3;

public int getXSIZE() {
return XSIZE;
}

public void setXSIZE(int xSIZE) {
XSIZE = xSIZE;
}

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

private int YSIZE = 1;

private int x;

private int y;

private int dx = 3;

public Bullet(JPanel b, Vehicle tank, Vehicle car) {
box = b;

x = tank.getX() + tank.getXSIZE();
if (x >= tank.getBox().getSize().width / 2)
dx = -dx;

y = tank.getY() + tank.getYSIZE() / 2;
;

}

public void draw() {
Graphics g = box.getGraphics();
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}

public void move() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setColor(Color.RED);
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
x += dx;

Dimension d = box.getSize();

if (x < 0) {
x = 0;

}
if (x + XSIZE >= d.width) {
x = d.width - XSIZE;

}
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();

}

public void run() {
try {
draw();
for (;;) {
move();

sleep(20);
}
} catch (InterruptedException e) {
}
}

}

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;

@SuppressWarnings("serial")
public class Tank_Shut_Car_ThreadFrame extends JFrame {

private JPanel canvas;
private boolean isOn = false;
private Vehicle tank;
private Vehicle car;
private JLabel score;
public static int sc = 0;

public Tank_Shut_Car_ThreadFrame() {
setResizable(false);
setSize(600, 400);
setTitle("Tank Shut Car");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});

Container contentPane = getContentPane();
canvas = new JPanel();
contentPane.add(canvas, "Center");
canvas.setLayout(null);

score = new JLabel("0");
score.setBounds(527, 11, 36, 14);
canvas.add(score);

JLabel lblScore = new JLabel("score");
lblScore.setBounds(481, 11, 36, 14);
canvas.add(lblScore);
JPanel p = new JPanel();

addButton(p, "Start", new ActionListener() {
public void actionPerformed(ActionEvent evt) {

if (!isOn) {
tank = new Vehicle(canvas, 0);
tank.start();
car = new Vehicle(canvas, 1);
car.start();
isOn = true;
}
}
});

addButton(p, "Shut", new ActionListener() {
public void actionPerformed(ActionEvent evt) {

if (isOn) {
Bullet bullet = new Bullet(canvas, tank, car);
bullet.start();
score.setText("" + sc);
}

}
});
addButton(p, "Close", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
canvas.setVisible(false);
System.exit(0);
}
});

contentPane.add(p, "South");
}

public void addButton(Container c, String title, ActionListener a) {
JButton button = new JButton(title);
c.add(button);
button.addActionListener(a);
}

}

import javax.swing.JFrame;

public class Test {
public static void main(String[] args) {

JFrame frame = new Tank_Shut_Car_ThreadFrame();
frame.setVisible(true);
}
}

最佳答案

好的,所以我玩了一下(只是为了好玩) BangBang

现在,这远非“适当”或“完整”的游戏引擎,但它提供了如何将核心线程引擎与 UI 组件混合在一起的基本想法。

我没有粘贴整个代码,而是将其源代码上传到 Tank.zip

但基本引擎看起来像这样......

public class GameEngine extends Thread {

public static final Object ASSET_LOCK = new Object();
private List<GameAsset> lstAssets;
private GameScreen screen;

public GameEngine(GameScreen screen) {
// Let the thread die when the JVM closes
setDaemon(true);
// Want to be below the UI thread (personal preference)
setPriority(NORM_PRIORITY - 1);

// A list of game assests
lstAssets = new ArrayList<GameAsset>(25);
// A reference to the screen
this.screen = screen;
// Add global key listener, this is simpler to the trying to attach a key listener
// to the screen.
Toolkit.getDefaultToolkit().addAWTEventListener(new EventHandler(), AWTEvent.KEY_EVENT_MASK);

}

public GameAsset[] getAssets() {
synchronized (ASSET_LOCK) {
return lstAssets.toArray(new GameAsset[lstAssets.size()]);
}
}

/*
* Allows for assets to be added
*/
public void addAsset(GameAsset asset) {
synchronized (ASSET_LOCK) {
lstAssets.add(asset);
}
}

@Override
public void run() {

while (true) {
try {
sleep(40);
} catch (InterruptedException ex) {
}

synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : assets) {
if (lstAssets.contains(asset)) {
asset.update(this, screen);
}
}
screen.repaint(new ArrayList<GameAsset>(lstAssets));
}
}
}

/**
* Allows the removal of an asset...
*/
public void removeAsset(GameAsset asset) {
synchronized (ASSET_LOCK) {
lstAssets.remove(asset);
}
}

/**
* Key event handling...
*/
protected class EventHandler implements AWTEventListener {

@Override
public void eventDispatched(AWTEvent event) {
KeyEvent keyEvent = (KeyEvent) event;
if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : assets) {
if (lstAssets.contains(asset)) {
asset.processKeyPressed(GameEngine.this, screen, keyEvent);
}
}
}
} else if (keyEvent.getID() == KeyEvent.KEY_RELEASED) {
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : lstAssets) {
if (lstAssets.contains(asset)) {
asset.processKeyReleased(GameEngine.this, screen, keyEvent);
}
}
}
}
}
}
}

关于java - 如何在 Swing 游戏上通知多线程事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12438619/

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