62,612
社区成员
发帖
与我相关
我的任务
分享
package test;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class test extends JFrame {
public test() {
setSize(800, 600);
setLocation(400, 40);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addKeyListener(new pressKey());
new myAnimation().start();
}
private int X = 400;
private int Y = 300;
private final Image bg = Settings.setImg("images/bg.jpg");
private final Image plane1 = Settings.setImg("images/plane1.png");
@Override
public void paint(Graphics g) {
Image buffer = createImage(800, 600);
Graphics gg = buffer.getGraphics();
gg.drawImage(bg, 0, 0, null);
gg.drawImage(plane1, this.X, this.Y, null);
g.drawImage(buffer, 0, 0, null);
}
private boolean up = false;
private boolean down = false;
private boolean left = false;
private boolean right = false;
class pressKey extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
right = true;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left = true;
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
up = true;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down = true;
}
if (up) {
Y -= 32;
} else if (down) {
Y += 32;
} else if (right) {
X += 32;
} else if (left) {
X -= 32;
}
}
@Override
public void keyReleased(KeyEvent e) {
up = false;
down = false;
left = false;
right = false;
}
}
class myAnimation extends Thread {
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new test();
}
}
package 飞机大战;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class AircraftBattle extends RootWindow {
public AircraftBattle() {
addKeyListener(new keyPress());
}
Image buffer = null;
Plane myplane = new Plane();
@Override
public void paint(Graphics g) {
buffer = createImage(Settings.win_width, Settings.win_height); // Creates an off-screen drawable image to be used for double buffering.
Graphics gg = buffer.getGraphics();
gg.drawImage(Settings.getImg("images/bg.jpg"), 0, 0, null);
gg.drawImage(Settings.getImg("images/plane.png"), myplane.x, myplane.y, null);
myplane.move();
g.drawImage(buffer, 0, 0, null);
}
public class keyPress extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
myplane.addDirection(e);
}
@Override
public void keyReleased(KeyEvent e) {
myplane.minusDirection(e);
}
}
public static void main(String[] args) {
new AircraftBattle();
}
}
[code=java]
package 飞机大战;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
public class Plane {
public int x = 200; // 飞机x轴坐标
public int y = 700; // 飞机y轴坐标
public boolean left, right, up, down;
public int speed = 10;
public Plane() {
}
public void move() {
if (left) {
x -= speed;
}
if (right) {
x += speed;
}
if (up) {
y -= speed;
}
if (down) {
y += speed;
}
}
// 按下某个键,增加相应的方向
public void addDirection(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
left = true;
break;
case KeyEvent.VK_UP:
up = true;
break;
case KeyEvent.VK_RIGHT:
right = true;
break;
case KeyEvent.VK_DOWN:
down = true;
break;
}
}
// 按下某个键,取消相应的方向
public void minusDirection(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
left = false;
break;
case KeyEvent.VK_UP:
up = false;
break;
case KeyEvent.VK_RIGHT:
right = false;
break;
case KeyEvent.VK_DOWN:
down = false;
break;
}
}
}
[code=java]
package 飞机大战;
import java.awt.*;
import javax.swing.*;
public abstract class RootWindow extends JFrame {
public static int win_center_x; // 窗口x轴中心
public static int win_center_y; // 窗口y轴中心
public RootWindow() {
super.setTitle("飞机大战");
setSize(Settings.win_width, Settings.win_height);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(600, 40);
setVisible(true);
win_center_y = (int) Settings.win_height / 2;
win_center_x = (int) Settings.win_width / 2;
new Thread(new myAnimation()).start();
}
class myAnimation implements Runnable {
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
[code=java]
package 飞机大战;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public final class Settings {
public static final int win_width = 400;
public static final int win_height = 800;
private Settings() {
}
public static Image getImg(String path) {
BufferedImage temp = null;
try {
temp =ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
}
return temp;
}
}
[/code]
[/code]
[/code]class GameTest extends JFrame {
public GameTest() {
setSize(800, 600);
setLocation(400, 40);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addKeyListener(new pressKey());
new myAnimation().start(); //一开始直接启动连续key按下模拟线程
}
private volatile int X = 400;
private volatile int Y = 300;
private final Image bg = Settings.setImg("images/bg.jpg");
private final Image plane1 = Settings.setImg("images/plane1.png");
static class Settings {
public static Image setImg(String path) {
Image img = null;
try {
img = ImageIO.read(new File(path));
} catch(Exception e) {
e.printStackTrace();
}
return img;
}
}
@Override
public void paint(Graphics g) {
Image buffer = createImage(800, 600);
Graphics gg = buffer.getGraphics();
gg.drawImage(bg, 0, 0, null);
gg.drawImage(plane1, this.X, this.Y, null);
g.drawImage(buffer, 0, 0, null);
}
private volatile boolean up = false; //这回是4个方向的flag同时使用
private volatile boolean down = false;
private volatile boolean left = false;
private volatile boolean right = false;
private Object locker = new Object(); //为了让key按下模拟线程节省资源,加个锁控制线程的运行
class pressKey extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
up = down = left = false; //考略到key按下的优先顺序,最后按下的key优先,之前的key失效
right = true;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
up = down = right = false;
left = true;
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
down = left = right = false;
up = true;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
up = left = down = false;
down = true;
}
if (up || down || left || right) {
synchronized(locker) { //如果有方向键按下则通知key按下模拟线程
locker.notifyAll();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) { //key释放的时也分4个方向控制
up = false;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down = false;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left = false;
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
right = false;
}
}
}
class myAnimation extends Thread {
@Override
public void run() {
while (true) {
synchronized(locker) {
while (!up && !down && !left && !right) { //如果没有方向键按下,则方向键等待
try {
locker.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (up) {
Y -= 32;
} else if (down) {
Y += 32;
} else if (right) {
X += 32;
} else if (left) {
X -= 32;
}
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new GameTest();
}
}
public class GameTest extends JFrame {
public GameTest() {
setSize(800, 600);
setLocation(400, 40);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addKeyListener(new pressKey());
//new myAnimation().start(); //线程移到key按下事件触发(模拟连续key按下)
}
private volatile int X = 400; //为了线程同步,改成volatile
private volatile int Y = 300;
private final Image bg = Settings.setImg("images/bg.jpg");
private final Image plane1 = Settings.setImg("images/plane1.png");
static class Settings {
public static Image setImg(String path) {
Image img = null;
try {
img = ImageIO.read(new File(path));
} catch(Exception e) {
e.printStackTrace();
}
return img;
}
}
@Override
public void paint(Graphics g) {
Image buffer = createImage(800, 600);
Graphics gg = buffer.getGraphics();
gg.drawImage(bg, 0, 0, null);
gg.drawImage(plane1, this.X, this.Y, null);
g.drawImage(buffer, 0, 0, null);
}
private volatile boolean up = false; //为了线程同步,改成volatile
private volatile boolean down = false;
private volatile boolean left = false;
private volatile boolean right = false;
private volatile boolean keyDown = false; //为了模拟key连续按下事件,追加一个flag作为开关控制
class pressKey extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
if (keyDown) return; //如果key按下flag已经设定过,则忽略window的延时的key按下事件
keyDown = true; //设定key按下flag
if (e.getKeyCode() == KeyEvent.VK_RIGHT) { //这部分代码不变
right = true;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left = true;
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
up = true;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down = true;
}
/*
if (up) { //这部分代码移动线程处理去,因为要用线程模拟连续按下事件
Y -= 32;
} else if (down) {
Y += 32;
} else if (right) {
X += 32;
} else if (left) {
X -= 32;
}
*/
new myAnimation().start(); //启动线程模拟连续按下事件
}
@Override
public void keyReleased(KeyEvent e) {
keyDown = false; //key释放就重置key按下flag
up = false;
down = false;
left = false;
right = false;
}
}
class myAnimation extends Thread {
@Override
public void run() {
while (keyDown) { //模拟key连续按下事件
if (up) { //修改飞机的位置
Y -= 32;
} else if (down) {
Y += 32;
} else if (right) {
X += 32;
} else if (left) {
X -= 32;
}
repaint();
try {
Thread.sleep(100); //修改为0.1毫秒,否则飞机移动过快
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new GameTest();
}
}
[/quote]
谢谢回复。
一定程度上缓解了问题,但还是有问题,比如快速的不停的按每个方向键,飞机偶尔还是会卡住,而且移动程度时快时慢。
我正在学习网上教程,看看那些是怎么处理的。public class GameTest extends JFrame {
public GameTest() {
setSize(800, 600);
setLocation(400, 40);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addKeyListener(new pressKey());
//new myAnimation().start(); //线程移到key按下事件触发(模拟连续key按下)
}
private volatile int X = 400; //为了线程同步,改成volatile
private volatile int Y = 300;
private final Image bg = Settings.setImg("images/bg.jpg");
private final Image plane1 = Settings.setImg("images/plane1.png");
static class Settings {
public static Image setImg(String path) {
Image img = null;
try {
img = ImageIO.read(new File(path));
} catch(Exception e) {
e.printStackTrace();
}
return img;
}
}
@Override
public void paint(Graphics g) {
Image buffer = createImage(800, 600);
Graphics gg = buffer.getGraphics();
gg.drawImage(bg, 0, 0, null);
gg.drawImage(plane1, this.X, this.Y, null);
g.drawImage(buffer, 0, 0, null);
}
private volatile boolean up = false; //为了线程同步,改成volatile
private volatile boolean down = false;
private volatile boolean left = false;
private volatile boolean right = false;
private volatile boolean keyDown = false; //为了模拟key连续按下事件,追加一个flag作为开关控制
class pressKey extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
if (keyDown) return; //如果key按下flag已经设定过,则忽略window的延时的key按下事件
keyDown = true; //设定key按下flag
if (e.getKeyCode() == KeyEvent.VK_RIGHT) { //这部分代码不变
right = true;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left = true;
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
up = true;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down = true;
}
/*
if (up) { //这部分代码移动线程处理去,因为要用线程模拟连续按下事件
Y -= 32;
} else if (down) {
Y += 32;
} else if (right) {
X += 32;
} else if (left) {
X -= 32;
}
*/
new myAnimation().start(); //启动线程模拟连续按下事件
}
@Override
public void keyReleased(KeyEvent e) {
keyDown = false; //key释放就重置key按下flag
up = false;
down = false;
left = false;
right = false;
}
}
class myAnimation extends Thread {
@Override
public void run() {
while (keyDown) { //模拟key连续按下事件
if (up) { //修改飞机的位置
Y -= 32;
} else if (down) {
Y += 32;
} else if (right) {
X += 32;
} else if (left) {
X -= 32;
}
repaint();
try {
Thread.sleep(100); //修改为0.1毫秒,否则飞机移动过快
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new GameTest();
}
}