【发布时间】:2015-05-03 22:08:15
【问题描述】:
我用 Java 制作了一个乒乓球游戏,但球拍不起作用,我无法弄清楚问题所在。
主类:在主类中我给线程并运行程序:
package pingpong;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class PingPong extends JFrame {
int Gwidth=400,Gheight=300;
Dimension screenSize = new Dimension(Gwidth,Gheight);
//double Buffering
Image dbImage;
Graphics dbg;
//ball objects
static Ball b = new Ball(193,143);
//constructor
public PingPong() {
this.setTitle("ping pong Game");
this.setResizable(false);
this.setSize(screenSize);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBackground(Color.black);
this.setVisible(true);
}
@Override
public void paint(Graphics g) {
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
draw(dbg);
g.drawImage(dbImage, 0, 0, this);
}
public void draw(Graphics g) {
b.draw(g);
b.p1.draw(g);
b.p2.draw(g);
g.setColor(Color.white);
g.drawString(""+b.p1Score,15,50);
g.drawString(""+b.p2Score,370,50);
repaint();
}
//event listining class
public class AL extends KeyAdapter { //key buildings
@Override
public void keyPressed(KeyEvent e) {
b.p1.keyPressed( e);
b.p2.keyPressed( e);
}
public void keyRealesed(KeyEvent e){
b.p1.keyReleased( e);
b.p2.keyReleased( e);
}
}
public static void main(String[] args) {
PingPong pp = new PingPong();
//create and start threads
Thread ball=new Thread(b);
ball.start();
Thread p1=new Thread(b.p1);
Thread p2= new Thread(b.p2);
p1.start();
p2.start();
}
}
这是我的球类:
package pingpong;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class Ball implements Runnable{
//global variables
int x,y,XDir,YDir;
//score
int p1Score,p2Score;
Paddle p1=new Paddle(15 , 140, 1);
Paddle p2=new Paddle(370, 140 ,2 );
Rectangle ball;
public Ball(int x,int y){
p1Score=p2Score=0;
this.x=x;
this.y=y;
//randomly moving the ball
Random r=new Random();
int rDir = r.nextInt(1);
if (rDir == 0) {
rDir--;
}setXDir(rDir);
int yrDir = r.nextInt(1);
if (yrDir == 0) {
yrDir--;
}setYDir(yrDir);
//create 'ball'
ball = new Rectangle(this.x, this.y,7, 7);
}
public void collision(){
if(ball.intersects(p1.paddle)){
setXDir(+1);}
if(ball.intersects(p2.paddle)){
setXDir(-1);}
}
public void draw(Graphics g){
g.setColor(Color.cyan);
g.fillRect(ball.x,ball.y,ball.width,ball.height);
}
public void move(){
collision();
ball.x +=XDir;
ball.y +=YDir;
//bounce the ball when edge is detected
if(ball.x<0){
setXDir(+1);
//add to score
p1Score++; //?
}
if(ball.x>=385){
setXDir(-1);
//add to score
p2Score++; //?
}
if(ball.y<=15)
setYDir(+1);
if(ball.y>=270)
setYDir(-1);
}
public void setXDir(int xdir){
XDir=xdir;
}
public void setYDir(int ydir){
YDir=ydir;
}
public void run(){
try{
while(true){
move();
Thread.sleep(4);
}
}catch(Exception e) {System.out.println("sorry"+e.getMessage());}
}
}
and there is my paddle class :
package pingpong;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
public class Paddle implements Runnable {
int x, y, yDir, id;
Rectangle paddle;
public Paddle(int x, int y, int id) {
this.x = x;
this.y = y;
this.id = id;
paddle = new Rectangle(x, y, 15, 50);
}
public void keyPressed(KeyEvent e) {
switch (id) {
default:
System.out.println("please enter a valid id");
break;
case 1:
if (e.getKeyCode() == e.VK_UP) {
setYDir(-1);
}
if (e.getKeyCode() == e.VK_DOWN) {
setYDir(+1);
}
break;
case 2:
if (e.getKeyCode() == e.VK_W) {
setYDir(-1);
}
if (e.getKeyCode() == e.VK_S) {
setYDir(+1);
}
break;
}
}
public void keyReleased(KeyEvent e) {
switch (id) {
default:
System.out.println("please enter a valid id");
break;
case 1:
if (e.getKeyCode() == e.VK_UP) {
setYDir(0);
}
if (e.getKeyCode() == e.VK_DOWN) {
setYDir(0);
}
break;
case 2:
if (e.getKeyCode() == e.VK_W) {
setYDir(0);
}
if (e.getKeyCode() == e.VK_S) {
setYDir(0);
}
break;
}
}
public void draw(Graphics g) {
switch (id) {
default:
System.out.println("please enter a valid id");
break;
case 2:
g.setColor(Color.YELLOW);
//draw paddle #1
g.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
break;
case 1:
g.setColor(Color.white);
// draw paddle #2
g.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
break;
}
}
public void setYDir(int ydir) {
yDir = ydir;
}
public void move() {
paddle.x += yDir;
if (paddle.y <= 15) {
paddle.y = 15;
}
if (paddle.y >= 250) {
paddle.y = 250;
}
}
@Override
public void run() {
try {
while (true) {
move();
Thread.sleep(6);
}
} catch (Exception e) {
System.out.println("try again" + e.getMessage());
}
}
}
我个人认为我的桨有问题,但我想不通。
【问题讨论】:
-
“不起作用”:请描述所需的行为以及发生的情况。
-
paddle.x += yDir;看起来不正确。 -
不要覆盖顶级容器的
paint,你正在重新发明一个已经有一个简单解决方案的轮子。不是从JFrame扩展,而是从JPanel扩展并覆盖其paintComponent方法,您将获得免费的双缓冲......并且您不会冒险在框架边框下进行绘画。KeyListener是处理关键事件的糟糕选择,您应该使用 key bindings api -
您还需要同步对 paddle 和 balls 的成员变量的访问,因为您无法保证来自其他线程的更新的可见性。 (或使用 AtomicInteger 代替 int)
-
Swing 也不是线程安全的,您应该避免从 EDT 外部更新 UI 或 UI 所依赖的东西...总的来说,这不是一个很好的教程...
标签: java multithreading