前段线程学习过程中 小组合作完成的一个项目 我主要负责算法 嘿嘿 写的比较啰嗦 见谅 感谢各大牛指正
先上个图吧
欢迎界面
游戏中
实际开发过程中,经过第一次讨论,我们就定下了主要需要完成的几个模块:
1 挡板运动-鼠标或键盘监听器的运行方法
2 球的运行-球运动线程
3 砖块的显现-数组填充
4 球的碰撞算法
5 界面美化,图片插入等
我主要负责小球的碰撞算法和挡板的运动部分。我首先想到的是五子棋游戏过程中棋盘的绘制。所以将砖块宽高设置为Config接口中的属性,然后用数组表示砖块,插入图片。用属性值表示砖块有无,若小球碰到砖块,则将属性值赋为空,用背景色填充原位置。
弹球碰撞砖块的方法就是在线程中每次都遍历数组,判断球与哪个砖块碰撞。挡板与球碰撞时会根据水平方向球与挡板运动的方向使球加速或减速。
然后我就开始敲代码,先做了一个打企鹅的游戏,想法很清楚但是在实现过程中遇到一系列的问题:
首先就是如何碰撞砖块问题,如何判断小球碰撞的是哪个砖块的那个面这个问题摆在了面前,现在想起来很自然而然,但是开始确实很纠结了两天,后来忽然想到其实碰撞砖块就是四种主要情况,砖块的上下左右四个面,可以写四个方法,然后通过循环遍历数组判断球撞到的是哪个砖块的哪个面,然后给数组中相应的元素赋为空,用背景色填充相应位置,从而实现对砖块的碰撞。
搞定这个问题后,马上第二个就来了:小球能碰撞了,也能消除了,但是有时候消不掉,想了一阵后发现这个是因为碰撞时同时碰到两个球,所以我就在原来的四个方法里每个多加了一种判断情况,特别处理这种两个同时碰到的情况,发现问题解决了。
之后小球能碰砖块,也能消了了,运行起来没问题,但是有很小的概率会有擦肩而过,没有消除的状况。这个我一直到把其他部分做好后才想清楚,由于小球每次运动的距离是设定的,而砖块的宽高也是设定的,碰撞的边界消除条件就是根据这两部分设定的,如果小球的每次运动距离过大,就有可能超过边界判断的条件,从而使碰撞消除的方法未调用或调用错误,后来想到解决办法就是,将球的每次运动距离调小,将线程休眠时间也相应调小一点,就OK了,至此,砖块与小球碰撞的算法算是搞定。
然后就是挡板与小球的碰撞问题。最简单的就是用键盘或鼠标监听器控制每次画一个挡板。然后当小球与挡板碰撞时就将小球的竖直速度反向。呵呵,很快就做出来了,但是,在同志们的一致要求下,我们的目标是实现小球能与挡板摩擦,从而加速或减速。然后我就被迫开始另外想了。首先,玩了一阵网上的弹球游戏后,我借鉴了下别人的想法,将挡板分区,当球撞到左边某一块区域,就将小球的速度设为相应的值,撞到右边,设为另外的值,改变了小球的速度。但是发现这样虽然实现了碰撞改变速度和方向,但是小球的运动不符合物理规律,在同组成员的批评下,我再次做出了改正。实现接近物理规律的碰撞,在这里,暂不考虑能量损失,所以就需要水平方向动量守恒或接近守恒,用键盘监听器设置每次按键后挡板运动速度为固定值,然后就是对球速的判断,但是每次挡板碰撞是不会变速的,不符合动量守恒条件,所以最终我妥协了,只是根据球的速度和运动方向进行判断,每次球与挡板同向则给小球加速,反向减速,都是加减固定值,调整后使效果看起来不是太差。最终挡板碰撞算法版本暂定为这样,我也还在其他地方寻求相应算法,后续改进进行中。
算法写了个类如下:
public class SuFa {
private BallListener bl;
private int ballX;
private int ballY;
private String[][] brick;
private int X0,Y0;
private Graphics g;
private boolean gameOver=false;
public SuFa(BallListener bl,int ballX,int ballY,String[][] brick,int X0,int Y0,Graphics g){
this.bl=bl;
this.ballX=ballX;
this.ballY=ballY;
this.brick=brick;
this.X0=X0;
this.Y0=Y0;
this.g=g;
}
public int getX(){
return X0;
}
public int getY(){
return Y0;
}
public boolean isOver(){
return gameOver;
}
public void judge(){
//撞墙
if(ballX<=2|ballX>=558){
X0 = -X0;
}
if(ballY<=0){
Y0 = -Y0;
}
//游戏结束
if(ballY>=472){
javax.swing.JOptionPane.showMessageDialog(null, "游戏结束");
gameOver=true;
}
//球撞挡板的方法
if(ballX>=bl.getX()-30&&ballX<=bl.getX()+150&&ballY>=448){
Y0=-Y0;
if(X0>=0&&bl.getT().equals("right")){
X0=X0+5;
}else if(X0>=0&&bl.getT().equals("left")){
X0=X0-5;
}else if(X0<0&&bl.getT().equals("right")){
X0=X0+5;
}else if(X0<0&&bl.getT().equals("left")){
X0=X0-5;
}
}
// 球撞砖块的方法
for (int i = 0; i < brick.length; i++) {
for (int j = 0; j < brick[i].length; j++) {
// 撞砖块下表面
if (ballY <= (i + 1) * Config.Height&&ballY>(i + 1) * Config.Height-10
&& ballX >= j * Config.Width - 15
&& ballX <=(j + 1) * Config.Width-15
&& (brick[i][j].equals("") == false)&&Y0<0) {
if((ballX==j*Config.Width - 15)&&(brick[i][j-1].equals("") == false)){
brick[i][j] = "";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i][j-1]="";
g.setColor(Color.white);
g.fillRect((j-1)*Config.Width, i*Config.Height, Config.Width, Config.Height);
Y0 = -Y0;
}
if((ballX==(j+1)*Config.Width - 15)&&(brick[i][j+1].equals("") == false)){
brick[i][j] = "";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i][j+1]="";
g.setColor(Color.white);
g.fillRect((j+1)*Config.Width, i*Config.Height, Config.Width, Config.Height);
Y0 = -Y0;
}else{
brick[i][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
Y0=-Y0;
}
}
// 撞砖块右表面
if (ballX <= (j + 1) * Config.Width && ballX>(j+1)*Config.Width-30&&ballY>= i * Config.Height-15
&& ballY <= (i + 1) * Config.Height-15
&& (brick[i][j].equals("") == false)&&X0<0) {
if((ballY==i * Config.Height-15)&&(brick[i-1][j].equals("")==false)){
brick[i][j] = "";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i-1][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, (i-1)*Config.Height, Config.Width, Config.Height);
X0 = -X0;
System.out.println("小球撞向右表面");
}
if((ballY==(i+1)*Config.Height-15)&&(brick[i+1][j].equals("")==false)){
brick[i][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i+1][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, (i+1)*Config.Height, Config.Width, Config.Height);
X0=-X0;
System.out.println("小球撞向右表面");
}
else{
brick[i][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
X0=-X0;
System.out.println("小球撞向右表面");
}
}
//撞砖块左表面
if(ballX>=j*Config.Width-30&&ballX<j* Config.Width&&ballY> i * Config.Height-15
&& ballY<= (i + 1) * Config.Height-15
&&(brick[i][j].equals("")==false)&&X0>0){
if((ballY==i * Config.Height-15)&&(brick[i-1][j].equals("")==false)){
brick[i][j] = "";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i-1][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, (i-1)*Config.Height, Config.Width, Config.Height);
X0 = -X0;
System.out.println("小球撞向左表面");
}
if((ballY==(i+1)*Config.Height-15)&&(brick[i+1][j].equals("")==false)){
brick[i][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i+1][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width,(i+1)*Config.Height, Config.Width, Config.Height);
X0=-X0;
System.out.println("小球撞向左表面");
}
else{
brick[i][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
X0=-X0;
System.out.println("小球撞向左表面");
}
}
//撞砖块上平面
if(ballY>=i*Config.Height-30&&ballY<i*Config.Height&&ballX>= j*Config.Width - 15
&& ballX<=(j + 1) * Config.Width-15
&&(brick[i][j].equals("")==false)&&Y0>0){
if(ballX==j*Config.Width-15&&brick[i][j-1].equals("")==false){
brick[i][j-1]="";
g.setColor(Color.white);
g.fillRect((j-1)*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i][j]="";
Y0=-Y0;
System.out.println("小球撞向上表面");
}
if(ballX==(j + 1) * Config.Width-15&&brick[i][j+1].equals("")==false){
brick[i][j+1]="";
g.setColor(Color.white);
g.fillRect((j+1)*Config.Width, i*Config.Height, Config.Width, Config.Height);
brick[i][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
Y0=-Y0;
System.out.println("小球撞向上表面");
}
else{
brick[i][j]="";
g.setColor(Color.white);
g.fillRect(j*Config.Width, i*Config.Height, Config.Width, Config.Height);
Y0=-Y0;
System.out.println("小球撞向上表面");
}
}
}
}
}
}
总共我的项目设计部分完成过程就是这样。在此过程中,我最大的感触就是如何把握好独立与合作的关系。开始分工,我主负责算法,想法主线很清晰,但是实现过程各种错误不断,很多意想不到的问题出现,我就乱了,想找其他人沟通,但是种种原因吧,最终还是自己纠结又纠结把它给搞出来了。最终我意识到其实项目的真正团队开发就是分工与合作,每个人负责不同的部分,自己负责的部分问题出现都是难免的,调试再调试这才是学习和进步的最终方式。先将框架,主题功能实现,然后再步步优化。最终合作的结果是下一个人不需要了解前一个人的工作,只需要在相应的功能块上直接添加自己的部分,组合,拼装,OK了。如果每个自己的问题都需要团队其他人放下工作,一起来想,那么整个项目计划就会打乱。
第二个收获就是代码优化,思路实现。其实很久有句话就徘徊在我脑子里,姑且就当我说的吧:对代码的掌控力。必须时刻知道你这一块代码是干什么的,会有什么样的功能,也可能会有什么样的问题。我感觉自己每次敲,开始思路很清晰,但是确实也没法具体想到每个细节,然后出现问题,分析,分析,要不就马上搞定,要不就是一个很简单的问题在那绕圈,放一段时间再想忽然发现竟然如此简单,痛悔不已。也许这确实就是能力的问题,我个人的思路有时很清晰,有时有很凌乱,这个我发现问题越来越厉害了。主线思路可以很快有想法,但是到具体实现,一有问题出现就容易乱。回到掌控力,我觉得这个项目给我的启发就是下一次先把框架都先定好。例如第一遍写完了这些方法,看到那个Config类,我发现其实像这种砖块宽高,球的速度等涉及到参数的都可以写入一个这样个类,以后如果需要调整会很方便,所以我把所有涉及球的算法判断都写入了一个Sufa类,然后后期修改调整简洁了不少。
废话说了很多,不过该说的都说到了,这个算是给自己的一个总结吧,Java之路继续加油吧!!!
最新版游戏
- 大小: 295.3 KB
- 大小: 26.7 KB
分享到:
相关推荐
【桌面弹球游戏代码及个人总结】 在编程领域,创建一款桌面弹球游戏是一个常见的学习项目,它能够帮助开发者理解游戏的基本机制、图形用户界面(GUI)和对象导向编程的概念。在这个项目中,作者使用Java语言进行...
总结来说,《易语言源码桌面弹珠》为学习者提供了一个实践易语言编程、理解和掌握游戏开发原理的平台,无论是对个人兴趣的培养还是专业技能的提升,都有着积极的意义。通过对源码的深入学习,开发者将能够更好地运用...
总结来说,“3DPinball 三维弹球 复制版 Unity”是一个展示Unity引擎强大功能和跨平台能力的项目。它涉及到的游戏开发技术包括3D建模、物理引擎应用、脚本编程、平台适配以及社区互动等多个方面。对于希望学习游戏...
总结,Flounce是一款集趣味性、创新性和教育性于一体的独立游戏,它的成功在于将弹球和塔防游戏玩法的结合以及对JavaScript和Phaser的灵活应用。通过自定义游戏区域和引入策略元素,Flounce不仅为玩家提供了独特的...
总结来说,素质拓展训练小游戏是团队建设的重要组成部分,它们通过寓教于乐的方式,帮助团队成员提升沟通、协作和信任能力,从而促进团队的整体表现和工作效率。在组织此类活动时,可以根据团队的特点和需求选择合适...
文件还提到了一些传统的游戏和娱乐活动,例如marbles(弹珠游戏),hopscotch(跳房子)等,这些词汇有助于描述儿童的玩耍活动。 #### 交通与出行 提到了rickshaw(人力车)、trainers(运动鞋)、mobile-phones...
【中学生活动趣味游戏大全】是一份专为中学生...总结来说,这份中学生活动趣味游戏大全不仅提供了丰富的娱乐活动,更注重学生的全面发展,通过游戏的方式寓教于乐,让学生在享受乐趣的同时提升个人技能和团队合作意识。
fans(风扇),stoves(炉子),play computer games(玩电脑游戏),fly kites(放风筝),play hopscotch(跳房子),make nets(做网),catch butterflies(捉蝴蝶),play marbles(玩弹珠),draw a circle...
这种动画特效常用于游戏、互动展示、活动页面或者个人网站,以增加视觉吸引力和互动性。特别是在需要营造活跃氛围或强调动态元素的场合,这种特效能够有效吸引用户的注意力。 总结,"HTML5弹珠火花四溅动画特效...
这篇内容是针对鄂教版2015年春季...总结来说,这个课件通过中国传统儿童游戏为载体,巧妙地教授汉字,旨在提高学生的识字能力和对中国传统文化的理解,同时也培养了他们的团队合作、动手实践和思维策略等多方面的能力。
- 实例化Sprite类,创建可走动的小猫和最简单的弹球游戏。 - 使用内置造型制作可拖动的角色和旋转的文字。 - 利用Sprite类提供的方法制作漫游功能和角色的移动、旋转、缩放等。 5. 精灵模块功能详解 - 碰撞检测:...
【活动内容】:活动方案中详细列出了多种游戏项目,包括但不限于套圈、猜谜语、夹弹珠、词语接龙和双人夹夹乐。这些游戏项目不仅有趣味性,而且能够锻炼学生的身体协调能力、语言表达能力以及团队合作精神。例如,...
- **电子相册**:展示个人或家庭的照片。 - **音频播放**:支持多种音频格式的播放。 - **视频播放**:兼容常见的视频格式,提供流畅的视频观看体验。 - **技术实现**: - 利用GEC6818开发板的强大性能,结合...
总结,这份文档提供了丰富的趣味运动会项目,涵盖了团队协作、个人技巧、策略运用等多个方面,适合不同年龄层次的孩子参与,旨在通过游戏促进孩子们的身心健康,增进友谊,营造欢乐的儿童节氛围。
Puzzle Bobble,最初在日本名为"Bubble Bobble",是一款风靡全球的弹珠台式解谜游戏,玩家需要发射不同颜色的泡泡,通过匹配消除来过关。GBA-Puzzle-Bobble则是对这一经典游戏的致敬,它融入了独特的怪异主题,为...
通过反思环节,教师引导孩子们总结活动经验,理解在相同的时间内,由于个人动作的快慢,结果会有所差异。 总的来说,这个教案旨在通过实践活动,让幼儿在游戏中学习时间管理,体验数学的乐趣,同时培养他们的观察力...