弹球游戏总结

简述我做弹球打砖块游戏的思路吧:
1、绘制界面
相信大家对界面的绘制都很熟悉了吧,这个我就不多了
2、球与球碰撞以及球与界面、挡板碰撞的问题
球与球碰撞的问题,我用了shape类里的intersects()方法,判断b、b1两个球是否有交集 boolean b2=b.intersects(b1.x, b1.y, b1.width, b1.height);返回布尔值b2,判断b2是否为true,若为真,执行下面语句
while(b2){
b.x0=-b.x0;
b.y0=-b.y0;
b1.x0=-b1.x0;
b1.y0=-b1.y0;
System.out.println("此处运行了!");
b2=false;
}
将两个球的速度都反向。刚开始我没有语句末尾加b2=false,发现两球相撞后,就在相撞地点的左右运动,就像两个球之间有磁铁似的,两球不会远离,显示反复循环此段语句,说明两球相撞后没有立即分开,还有交集,是因为两个球的速度变量是随机的。球与界面、挡板碰撞的问题都关于小球坐标范围以及碰撞后小球速度的改变
//当小球x(y)方向速度为零时,就该方向将小球速度增加一个固定值,可以避免小球总是做横向(纵向)直线运动
if(x0==0){
x0=x0+5;
}
if(y0==0){
y0=y0+5;
}
//小球碰到界面的左右边界时,将小球的x方向的速度反向
if (x <= 0 ||x+30 >= width1) {
x0 = -x0;
}
//小球碰到界面的上边界时,将小球的y方向的速度反向
if (y <= 0) {
y0 = -y0;
}
//小球碰到挡板时,要同时判断小球x、y的坐标范围,在此范围内相撞小球的y方向的速度反向
if (y+30>= height1-20 && x>th.x1 && x<th.x1+100 ) {
y0 = -y0;
point++;
}
3、砖块的绘制
我是通过游戏中绘制地图的方法,通过读取地图中,将读取出的数据存储到定义的数组中,来表示是否有砖块,改变地图中的数据可以改变界面上砖块的位置,这们就方便我们修改
public void createMap(int[][] array, Graphics g) {
//遍历数组
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
//判断是否为零,若不为零,表示此处有砖块
if (array[i][j] != 0) {
int num = array[i][j];
//得到要插入的砖块图片的路径
String path = num + ".png";
// 根据路径构造图片对象
ImageIcon icon = MapUtil.createImageIcon(path);
//绘制砖块
g.drawImage(icon.getImage(), 72 * (j), 24 * (i), null);
//调试程序,看此段代码是否运行
System.out.println(icon.getImage().getWidth(null) + " "
+icon.getImage().getHeight(null));
}
}
}
}
做到这里后,会发现程序运行时,每次一按开始键砖块只出现瞬间就消失了,那是因为小球的位置总在变化,绘制小球时,我们都有刷新,所以我们需要重绘砖块。完成重绘后会发现,砖块会狂闪,那是因为每次paint(g)刷新时,界面上的东西都会重画,这个过程很费时,因此我们需要采用“双缓冲”,即我们创建一个绘制缓冲区,以offScreenImage表示,先将主要的图形元素一个一个地绘制到此缓冲图像上,再将此缓冲图像一次性绘到代表屏幕的Graphics对象,即paint() 方法传入的“g”上。
class MyPanel extends JPanel {
//定义一个绘制缓冲区
Image offScreenImage;
//定义缓冲区的画笔
Graphics gImage;
//重写paint方法
public void paint(Graphics g) {
//判断缓冲区是否为空,若为空执行下面代码
if (offScreenImage == null)
//得到缓冲图象,宽、高与JPanel一致
offScreenImage = this.createImage
(this.getWidth(),this.getHeight())
//得到缓冲图象的画笔
gImage = offScreenImage.getGraphics();
//绘制缓冲图象
gImage.fillRect(0, 0, this.getWidth(), this.getHeight());
//调用paint(),将缓冲图象的画笔传入
super.paint(gImage)
//遍历数组,重绘砖块
if (MapUtil.array != null) {
for (int i = 0; i < MapUtil.array.length; i++) {
for (int j = 0; j < MapUtil.array[i].length; j++) {

if (MapUtil.array[i][j] != 0) {
int num = MapUtil.array[i][j];
//得到插入图片的路径
String path = num + ".png";
// 根据路径构造图片对象
ImageIcon icon = MapUtil.createImageIcon(path);
gImage.drawImage(icon.getImage(), 72 * (j),
24 * (i), null);
}
}
}
}
//将此缓冲图像一次性绘到代表屏幕的Graphics对象,即JPanel的Graphics(g)上面
g.drawImage(offScreenImage, 0, 0, null);

}
}
4、球与砖块碰撞的算法问题
碰撞砖块分四种主要情况,砖块的上下左右四个面,可以写四个方法,然后通过循环
遍历数组判断球撞到的是哪个砖块的哪个面,然后给数组中相应的元素赋为零,用背
景色填充相应位置,从而实现对砖块的碰撞。分别用Width、Height表示砖块的宽和高
// 球撞砖块的方法
for (int i = 0; i < MapUtil.array.length; i++) {
for (int j = 0; j < MapUtil.array[i].length; j++) {
// 撞砖块下表面
if (y<= i * 24+12&&y>i * 24-12
&& x >= (j -1)* 72 - 36
&& x<=j * 72-36
&& (MapUtil.array[i][j]==1)) {
//将图片设置为背景色
g.setColor(Color.BLACK);
//使砖块消失
MapUtil.array[i][j]=0;
//将y方向的速度反向
y0= -y0;
//调试语句
System.out.println("球碰撞砖块了。。。");
}
// 撞砖块右表面
if (x <= (j + 1) *Width && x>(j+1)*Width-
30&& y>= i * Height-15
&& y <= (i + 1) * Height-15
&& (MapUtil.array[i][j]==1)) {
g.setColor(Color.BLACK);
MapUtil.array[i][j]=0;
x0=-x0;
}
//撞砖块左表面
if(x>=j*Width-30&&x<j* Width&& y> i * Height-15
&& y<= (i + 1) * Height-15
&&(MapUtil.array[i][j]==1)){
g.setColor(Color.BLACK);
MapUtil.array[i][j]=0;
x0=-x0;
}
//撞砖块上平面
if( y>=i*Height-30&& y<i*Height &&x>= j*Width - 15
&& x<=(j + 1) * Width-15
&&(MapUtil.array[i][j]==1)){
g.setColor(Color.BLACK);
MapUtil.array[i][j]=0;
y0= -y0;
}
这之后小球能碰撞砖块了,但会发现有时候小球会与砖块擦肩而过,可能原因是小球的每次运动距离过大,就有可能超过边界判断的条件,从而使碰撞消除的方法未调用或调用错误,解决办法就是,将球的每次运动距离调小,将线程休眠时间也相应调小一点。 到这里弹球打砖块游戏仍需要完整,继续改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值