最近想写个泡泡龙的游戏,可是遇到几个问题,其中有一个是模拟球的运行轨迹.其实以前也想过类似的问题,最初的时候是用了一个Vista的泡泡屏保然后是玩一个桌球游戏,我都在想着到底怎样计算那球何时与屏幕边沿或者是桌球桌子边沿碰撞以及碰撞后会如何改变方向,怎样运动,于是想到用数学,物理去计算,然后越想越多种情况,越想越复杂,终于觉得不可能做出也就放弃了,今天在网上看到一个类似的不过是用Flash实现的,还给出了代码,而是终于弄明白了该怎样做,改了一下用Java做,代码如下:
import javax.swing.JFrame;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.ComponentAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ComponentEvent;
public class Ball extends JFrame{
private int screenWidth,screenHeight;
private BallCanvas canvas = null;
public Ball(){
setTitle("运动的球");
setSize(500,500);
Container pane = this.getContentPane();
screenWidth = this.getWidth();
screenHeight = this.getHeight();
canvas = new BallCanvas(screenWidth, screenHeight);
Thread t = new Thread(canvas);
t.start();
//当退出时,先结束Cavans所在线程
this.addWindowListener(new WindowAdapter(){
public void windowClosed(WindowEvent e){
canvas.exit();
}
});
//监听窗口大小改变
this.addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e){
resize();
}
});
pane.add(canvas);
this.setVisible(true);
}
/**
* 主函数
*/
public void main(){
Ball b = new Ball();
}
/**
* 改变窗口的大小
*/
public void resize(){
screenWidth = this.getWidth(); //获得新的窗口大小
screenHeight = this.getHeight();
canvas.canvasResize(); //通知Canvas改变其大小
}
}
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class BallCanvas extends Canvas implements Runnable {
private int ballRadius = 30; //球的半径
private int ballX,ballY; //当前球的位置
private int ballXMoveLength= 5; //每次球在X轴和Y轴上移动的距离
private int ballYMoveLength = 8;
private Random r;
private boolean move = true; //标志球是否移动
private int screenWidth, screenHeight; //屏幕宽及高
public BallCanvas(int screenWidth, int screenHeight){
r = new Random();
ballX = r.nextInt(screenWidth - 2*ballRadius); //随机初始化球的初始位置
ballY = r.nextInt(screenHeight - 2*ballRadius);
this.screenHeight = screenHeight;
this.screenWidth = screenWidth;
}
public void paint(Graphics g){
//g.setColor(Color.WHITE); //此处使用背景色而不用白色,如果要自己清空屏幕,则需加上缓存,不然会产生画面抖动
//g.fillRect(0, 0, screenWidth, screenHeight);
g.setColor(Color.RED);
g.fillArc(ballX, ballY, ballRadius*2, ballRadius*2, 0, 360);
}
/**
* 退出
*/
public void exit(){
move = false;
}
public void run(){
while(move){
if(ballX + ballXMoveLength + 2*ballRadius > screenWidth ||
ballX + ballXMoveLength < 0){ //当在X轴上碰到墙时,X轴行进方向改变
ballXMoveLength*=-1;
}else{
ballX += ballXMoveLength; //没碰壁时继续前进
}
if(ballY + ballYMoveLength + 2*ballRadius > screenHeight ||
ballY + ballYMoveLength < 0){ //当在Y轴上碰到墙时,Y轴行进方向改变
ballYMoveLength*=-1;
}else{
ballY += ballYMoveLength;
}
repaint(); //更新画面
try{
Thread.sleep(10);
}catch(InterruptedException e){
}
}
}
public void canvasResize(){
screenWidth = this.getWidth();
screenHeight = this.getHeight();
}
}
这是比较简单的,模拟一个球在一个窗口中随机运动,其实实现也非常简单,只是给球运动时设置了X轴和Y轴的增量,即每次运动X轴和Y轴各增加多少,然后如果在X轴和Y轴上碰壁时相应的增加取反即可.(唉,就这么简单,我怎就没想到呢),这个程序还允许窗口的大小改变,其实窗口大小改变时只要用ComponentListener进行监听就行了(这个我也是在网上找到的)