ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

线程游戏2.0

线程游戏2.0 一.项目总览类名作用Die绘制角色死亡时的动画在角色被击中时生效Bulletad敌方子弹类绘制子弹对象以及设置速度AdverThread新增绘制敌方弓箭手对象MusicThread设置音乐播放功能Spear2设置敌方弓箭手对象TopFile写入数据使数据从内存流入文件TopFileTopFile的优化版本将多个数据一次写入top.txt以文本形式存储数据GameThread新增碰撞检测、敌方箭手自动射击、积分系统开始界面功能UI只提供背景板不再填充画面二.开始界面的优化让开始界面与游戏画面共用一个窗体不用在不同的窗体运行1.直接在GameThread中定义set设置玩家属性publicvoidsetMp(Archerar){this.arar;}2.标记位控制使当前画面在开始界面和运行界面间转换publicvoidisStart(booleanstart){this.startstart;}if(start){startui();}else{gamerun();}3.新增开始界面方法publicvoidstartui(){ImageIconimgnewImageIcon(C:\\Users\\admin\\IdeaProjects\\Pro26\\photo\\封面.jpg);buffg.drawImage(img.getImage(),0,0,null);if(isHover){ImageIconimg1newImageIcon(C:\\Users\\admin\\IdeaProjects\\Pro26\\photo\\开始游戏2.png);buffg.drawImage(img1.getImage(),515,600,null);}else{ImageIconimg1newImageIcon(C:\\Users\\admin\\IdeaProjects\\Pro26\\photo\\开始游戏.png);buffg.drawImage(img1.getImage(),515,600,null);}}4.在开始界面中改变标记位从而控制当前画面为开始界面还是运行界面if(x515y600x645y650){System.out.println(-----------------------);gt.setMp(ar);gt.isStart(false);}}三.双缓冲解决闪烁问题1.创建一个缓冲对象publicclassGameThreadextendsThread{publicGraphicsbuffg;}2.在run方法中创建缓冲面板publicvoidrun(){// System.out.println(Thread.currentThread().getName() :线程启动...);//缓冲图片BufferedImagebufferedImagenewBufferedImage(1215,1205,BufferedImage.TYPE_3BYTE_BGR);//按顺序在缓冲图片绘制所有图层内容//获取缓冲图片的画笔对象用buffg代替g绘制对象buffgbufferedImage.getGraphics();// 把缓冲图整体刷到屏幕上g.drawImage(bufferedImage,0,0,null);}run方法整体publicvoidrun(){// System.out.println(Thread.currentThread().getName() :线程启动...);BufferedImagebufferedImagenewBufferedImage(1215,1205,BufferedImage.TYPE_3BYTE_BGR);buffgbufferedImage.getGraphics();while(true){try{Thread.sleep(20);}catch(InterruptedExceptionex){thrownewRuntimeException(ex);}if(paused)continue;if(start){startui();}else{gamerun();}// 把缓冲图整体刷到屏幕上g.drawImage(bufferedImage,0,0,null);}}四.敌方箭手自动射击publicvoidgamerun(){// 红色弓箭手定期射箭每 50 帧约1秒射一支 50帧1秒shootTimer;if(shootTimer150){shootTimer0;for(inti0;ispear2s.size();i){Spear2s2spear2s.get(i);BulletadbulletadnewBulletad(s2.x20,s2.y40);bulletads.add(bulletad);}}}五.背景的滚动效果绘制两张连续的背景交替左移并通过循环重置坐标publicvoidgamerun(){ImageIconimg1newImageIcon(C:\\Users\\admin\\IdeaProjects\\Pro26\\photo\\gameUI.png);buffg.drawImage(img1.getImage(),0,0,null);bgx-bgspeedx;//重置的大小一定要与图片原大小相同if(bgx-1239){bgx1239;}buffg.drawImage(img,bgx1239,0,null);buffg.drawImage(img,bgx,0,null);}六.敌方对象死亡动画新建一个Die类用于绘制publicclassDie{// 死亡动画帧数组存2张图片死亡第1帧、死亡第2帧publicImageIcon[]dieArrnewImageIcon[2];// 当前播放到第几帧publicintindex0;// 构造方法初始化加载两张死亡图片publicDie(){for(inti1;i2;i){// die红‑1.png、die红‑2.png 载入数组 dieArr[0]、dieArr[1]dieArr[i-1]newImageIcon(C:\\Users\\admin\\IdeaProjects\\Pro26\\photo\\die红-i.png);}}// 绘制死亡动画传入画笔g、绘制坐标x,ypublicvoiddrawDie(Graphicsg,intx,inty){System.out.println(die);// 控制台打印用来调试看这个方法有没有被调用indexindex%dieArr.length;// 取模防止index越界// 绘制当前帧绘制完 index 1切换下一帧g.drawImage(dieArr[index].getImage(),x,y,null);}}七.碰撞检测通过判断两个对象的坐标范围来呈现歼敌效果for(intiarrayList.size()-1;i0;i--){BulletbarrayList.get(i);for(intjspear1s.size()-1;j0;j--){Spear1sspear1s.get(j);if(s.x10b.x-30s.yb.y-100s.yb.ys.x10b.x){//通过移除实现死亡效果spear1s.remove(j);score10;arrayList.remove(i);die.drawDie(buffg,s.x10,s.y20);}}}for(intiarrayList.size()-1;i0;i--){BulletbarrayList.get(i);for(intjspear2s.size()-1;j0;j--){Spear2sspear2s.get(j);if(s.x10b.x-30s.yb.y-100s.yb.ys.x10b.x){spear2s.remove(j);score10;arrayList.remove(i);die.drawDie(buffg,s.x20,s.y40);}}}玩家死亡触发游戏结束for(intibulletads.size()-1;i0;i--){Bulletadbdbulletads.get(i);if(bd.xar.x50bd.yar.ybd.yar.y100bd.xar.x){bulletads.remove(i);System.out.println(被击败游戏结束);TopFileV2.writeData(newFile(C:\\Users\\admin\\IdeaProjects\\Pro26\\src\\bullet\\top.txt));TopFileV2.readData(newFile(C:\\Users\\admin\\IdeaProjects\\Pro26\\src\\bullet\\top.txt));}}for(inti0;ispear1s.size();i){Spear1sspear1s.get(i);if(s.x-10ar.x50s.y100ar.ys.yar.y100s.xar.x){System.out.println(被击败游戏结束);TopFileV2.writeData(newFile(C:\\Users\\admin\\IdeaProjects\\Pro26\\src\\bullet\\top.txt));TopFileV2.readData(newFile(C:\\Users\\admin\\IdeaProjects\\Pro26\\src\\bullet\\top.txt));}}两支箭碰撞抵消必须在末尾加上break避免报错当玩家的两只箭同时碰到敌方箭矢时会导致数组无法判断for(intibulletads.size()-1;i0;i--){Bulletadbdbulletads.get(i);for(intjarrayList.size()-1;j0;j--){BulletbarrayList.get(j);if(b.xbd.x-70b.ybd.y-15b.ybd.y15b.xbd.x){bulletads.remove(i);arrayList.remove(j);score20;break;}}}八.音乐播放publicclassMusicThreadimplementsRunnable{Overridepublicvoidrun(){try{FilefilenewFile(C:\\Users\\admin\\IdeaProjects\\Pro26\\music\\背景音乐.wav);AudioInputStreamaudioInAudioSystem.getAudioInputStream(file);//获取一个 ClipClipclipAudioSystem.getClip();// 打开音频流clip.open(audioIn);// 无限循环播放背景音乐clip.loop(Clip.LOOP_CONTINUOUSLY);// 开始播放clip.start();//设置音量大小//音量取值范围 -80 ~ 6FloatControlcontrol(FloatControl)clip.getControl(FloatControl.Type.MASTER_GAIN);floatvaluecontrol.getValue();Thread.sleep(3000);control.setValue(value-5);}catch(Exceptione){e.printStackTrace();}}}九.TopFilepublicclassTopFile{//写入数据publicstaticvoidwriteData(Filefile){//创建文件字节流读写数据以字节为单位try{FileOutputStreamfosnewFileOutputStream(file);Stringname张三;//把字符转成byte数组byte[]bname.getBytes();//写入字符数据的长度writeInt(fos,b.length);//字节流写入字符数据,把byte数组中的数据写入 管道-- FileOutputStream 底层连接到文件的数据通道,FileOutputStream//就像一根水管一端接着 Java 程序内存另一端接着目标文件磁盘,数据从内存流向文件中间经过这根管道fos.write(b);intscore1000;//写入数据writeInt(fos,score);System.out.println(写入成功);// 写入数据小端序低字节先写// fos.write(score);// fos.write(score 8);// fos.write(score 16);// fos.write(score 24);// 关闭流close 内部会自动 flush// fos.close();}catch(Exceptione){thrownewRuntimeException(e);}}publicstaticvoidwriteInt(FileOutputStreamfos,inti)throwsException{//写入数据小端序低字节先写fos.write(i);fos.write(i8);fos.write(i16);fos.write(i24);//强制写入fos.flush();}//读取数据publicstaticvoidreadData(Filefile){System.out.println(/);//输入流try{FileInputStreamfisnewFileInputStream(file);//先读取长度intlenreadInt(fis);byte[]bnewbyte[len];fis.read(b);//把byte数组转成字符串StringnamenewString(b);intscorereadInt(fis);System.out.println(namename score:score);}catch(Exceptione){thrownewRuntimeException(e);}}publicstaticintreadInt(FileInputStreamfis)throwsException{inti1fis.read();inti2fis.read();inti3fis.read();inti4fis.read();returni424|i316|i28|i10;}publicstaticvoidmain(String[]args){StringpathC:\\Users\\admin\\IdeaProjects\\Pro26\\src\\bullet\\top.txt;FilefilenewFile(path);TopFile.writeData(file);TopFile.readData(file);System.out.println( invoke public static void readData(File file) );}}
返回列表