瘋狂java實戰(zhàn)演義書版s-復制第4章桌面彈球_第1頁
瘋狂java實戰(zhàn)演義書版s-復制第4章桌面彈球_第2頁
瘋狂java實戰(zhàn)演義書版s-復制第4章桌面彈球_第3頁
瘋狂java實戰(zhàn)演義書版s-復制第4章桌面彈球_第4頁
瘋狂java實戰(zhàn)演義書版s-復制第4章桌面彈球_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

4擋板變長、變短,小球加強等等。本章主要介紹如何實現一個簡單的彈球游戲,讓讀者了解“動畫”JavaJPanelpaint(Graphicsg)方法去繪圖,繪圖GraphicsJavaTimer去重復繪圖,產生動畫效果,4.1所示。所示。4.3己的x與y坐標屬性,有屬性,有速度屬性,所以,在這時在,設計一個基類ponent包含Ball,Brick,Magic具功能實現的抽象方法,供其子類實現)。類的子類有LongMagic與ShortMagic,作用是使Stick,片,此類還完成界面的初始化用戶的鍵盤,而與游戲相關的業(yè)務邏輯(判斷輸贏或者球的運動BallService4.4所示。,4.4 父類,定義了這些子類共有的屬性與方法,屬性有:x坐標,初始值為-1;y坐標,初始值為-1;imagenullspeed5。根據不同的需要,提供以下三個構造方法: ponent(Stringpath),path是的路徑用的路徑來構造一個ponent,在此構造方法中,將根據路徑去,再設置對象中image屬性。 pathComponent。ponent(Stringpath,intx,inty)以x坐標y坐標和path去構造一個 者改變對象的坐標位置與屬性。如果我們在編碼的過程中發(fā)現有一些共同的屬性或者方法,我們可創(chuàng)建ponent的時候,我們可以將這個類變成抽象類,即使它沒有任何的抽象方法,這樣做此類是ponetBrick(Stringpath,inttype,intx,inty)構造器,其中pah、xy參數用于調用父類的構造器,type是代表磚塊的類型:1LongMagic類型的;2代表此磚塊里面有ShortMagic類型的;其它代表此磚塊里面沒有。另外,本類Brickdiabletrue,則表明此磚塊已經不可用,不會再顯示。并提供這兩個屬性相關的voidsetMagic(Magicmagic),設置MagicgetMagic(),獲取booleanisDisable()voidsetDisablebooleandisable,停用或者啟用此類,disabletruefalseBrickBrick的二維數組,來素并不是字符串,而是具體的某個Brick對象,在以后的章節(jié)中,當遇到需要在界面中繪畫某些的Magic類是一個類,在游戲中表現包含在磚塊中,是ponet的一個抽象子類,此類提供一個Magic(Stringpath,intx,inty構造器去調用父類的構造器,并提供一個抽象的方法magicDo(Stickstick),此抽象方法是實現的效果功能,用于給其子類實現,現在實現的子類的LongMagicShortMagicmagicDo方法中分別實現使擋板變長與變短的功能。voidmagicDo(Stickstick),的功能,給其子類實現(MagicStick的參數可能并不夠,同樣,Stick類也是ponet的子類,用來代表游戲中的擋板,由于擋板只有左右移動的,所xSPEEDpreWidth,并提供此settergetter方法,如下:voidsetPreWidth(intpreWidthintgetPreWidth()由于該類繼承于ponet類,因此只需要提供一個構造器即可。在本例中,擋板是可以變長或者變短的,并且在建立抽象類的時候,已經定義了一個magicDo的方法,該方法的參數就是一長度來實現本例中所需要實現的長短擋板功能。在Stick類中并不需要關心擋板的、位置與大小,這些屬性已經在ponet中體現。Ball類也是ponet的子類,由于小球在游戲面板中運動的時候除了橫豎方向,還有各種角speedYstarted屬性來標志小球是否已經開始運動。游戲結束后,小球也是settergetter方法,如下:setSpeedXintspeedsetSpeedYintspeedbooleanisStarted()voidsetStarted(booleanbintgetSpeedX()intgetSpeedY()中體現setter方法來進行,但是我們需要知道由哪些對動(在游戲結束或者開始時Ball類添加一個stopRun的方法,總之,如果需要做到充Ball中。BallService處理了這個游戲中的大部分業(yè)務功能包括開始游戲小球移動移動擋板移動、磚塊的排列與、畫圖等功能。這些功能的實現都有對應的方法,如下voidrun()voidsetStickPos(KeyEventkebooleanisHitBrick(Brickbrickbrikc ponentimagevoidsetMagicPos(),改變的坐標位置voidsetStickWidth(Magicmagic),根據(magic)的類型去設置改變擋板的長度booleanisWon()Brick[][]createBrickArr(Stringpath,intxSizeintySizeBrick類型的數組,參數path是指磚塊的,xSize與ySize是數組的長度。voiddrawGraphicsgGraphics對象gsetStickPos的方法來改變擋BallServiceBallService處理了大部分的游戲邏輯,當然,我們也可將這些邏輯放到相關的類中(即前面提到的充血模式例如的下落、擋板的移動等。BallFrameJFrame主界面,設置主界面的標題、長與寬、畫板等屬性,并且為增加鍵盤器以及創(chuàng)立一個Timer每隔一小段時間去刷新畫板主要有初始化界面與或者畫板兩個方法,voidinitializethrowsIOExceptionIOBallServiceBallServicerun方法,再調用BallSerivce的draw方法將小球的“畫”到界面中。到此,本章中所有的對象都已經創(chuàng)建并確定了它們的行為,在建立類(Magic)的時候,我們將一個抽象為一個Magic對象,該類可以有多個實現,在使用Magic對象的時候,我們可以利用面向對象的多態(tài)特性,使用Magic的magicDo方法來進行“的使用在這個過程中,我們并不需要去關心具體的實現。在創(chuàng)建游戲各個對象的過程中,處理邏輯的方法放置到一個業(yè)務類中,Graphics對象畫出來的,所以,我們的主界面JFrameJFrame中,我們只需要提供一JPanel對象即可,因為游戲的界面并沒有多復雜的布局與界面交互。當我們實現游戲的一些相關邏輯的時候(球的運動、的下落等,我們可以調用JPanel的repaint方法將JPanel進行重繪。JFrameJPanelJPanelJFramepublicvoidinitialize()publicvoidinitialize()throwsIOExceptionthis.setResizablefalsethis.setBackground(Color.BLACK//ballPanel=this.addballPanel}看加粗的一行代碼ballPanel=getBallPanel()是調用本類中的getBallPanel方法去獲取一個BallPanle對象,BallPanelJPanel,見以下代碼。//JPanel//JPanelpublicclassBallPanelextendsJPanelvoidpaintGraphicsg*@paramg@returnpublicvoidpaint(Graphicsg)//BallServicedraw}}BallPanelBallPanelgetBallPanelPanel是單態(tài)的,BallPanle對象,見以下代碼。代碼publicBallPanelgetBallPanel(){if(ballPanel==null){//ballPanel=newpublicBallPanelgetBallPanel(){if(ballPanel==null){//ballPanel=newnewDimension(BALLPANEL_WIDTH,BALLPANEL_HEIGHT)}return}界可以通過這個點來該類的唯一實例。在我們平時開發(fā)的過程中,會遇到一些不需要多次創(chuàng)建(為外界提供唯一的點私有構造器是為了不讓外界去使用new關鍵字來創(chuàng)建該類的實現,如果new關鍵字來創(chuàng)建該類的實例,那么就意味著該類將不會是單態(tài),有可能外界多次通過new關鍵字來創(chuàng)建,這就無法保證該對象的實例的唯一性。BallFrameBallFrameballFrame=newBallFrame();4.54.5BallService中的drawBallServicedraw方法后,就可以將BallPanel中的paint方法加入BallService.draw。javax.swing.TimertaskWindow系統(tǒng)的計劃所以只鍵盤的操作,用一個KeyListener去鍵盤的動作,請看以下代碼。//定義每0.1秒執(zhí)行一//定義每0.1秒執(zhí)行一 ActionListenertask=newpublicvoidactionPerformed(ActionEvente)//}//如果timer不為空,調用timer的restartif(timer!=null)//重新開始timer}else//新建一個timer=newTimer(100,task//開始timer}//增 KeyListener[]klarr=this.getKeyListeners();if(klarr.length==0){//定義鍵 適配KeyListenerkeyAdapter=newKeyAdapter(){publicvoidkeyPressed(KeyEventke)service.setStickPos(ke}}timer非空,由于游戲停止(勝利或者失敗,因此需要調用restart方法重新啟動。由于我們是在接下來再增加器先使用JFrame的keyKeyListeners()方法獲取本窗口的KeyLister數組KeyAdaptrJFrame創(chuàng)建一個鍵盤器)并重寫KeyAdapter類的voidkeyPressed(KeyEventke)方法,這個方法用來鍵盤的按鍵是否有按下,如果有的話,就需要調用BallService的setStickPos方法。當我們去setStickPos僅僅設置小球的運動狀態(tài),換言之,setStickPosBallServicerun處理(run100毫秒執(zhí)行一次。在這個設計中,擋板、小球、磚塊與磚塊中所包含的都有一個共同的父類ponet,可以擋板(Stick類publicStick(intpanelWidthpublicStick(intpanelWidth,intpanelHeight,Stringpath)throwsIOException//super(panelWidth,panelHeight,path//設置ythis.setY(panelHeight-super.getImage().getHeight(null)this.preWidth=super.getImage().getWidth(null}首先調用父類的ponent(intx,inty,Stringpath)x坐標設置到畫板中置到畫板的底部,再根據出來的的寬度去設置Stick對象的初始長度屬性。在從磁盤 ponent(int ponent(intpanelWidth,intpanelHeight,Stringpath)throwsIOException{this.image=ImageIO.read(newFile(path)//設置xthis.x=(int)((panelWidth-image.getWidth(null))/2}SPEEDpreWidthsettergetter方法。//if(isWon())BallPanelBallServicedrawBallServicedraw//if(isWon())////g.drawImage(won.getImage(),won.getX(),won.getY(),width,height-10,null);}elseif(ball.isStop())//g.drawImage(gameOver.getImage(),gameOver.getX(),gameOver.getY(),width,height-10,null);}else//g.clearRect(0,0,width,//g.drawImage(stick.getImage(),stick.getX(),stick.getY(),.getPreWidth(),stick.getImage().getHeight(null),}4.64.6小球(Ball類publicBall(intpanelWidth,publicBall(intpanelWidth,intpanelHeight,intoffset,StringpaththrowsIOExceptionsuper(panelWidth,panelHeight,path//設置ythis.setY(panelHeight-super.getImage().getHeight(null)-offset}首先調用父類 ponent(intx,inty,Stringpath)構造器,把此對象的x坐標設置到畫板Ballstarted的屬性來標識這兩種狀態(tài)。那么當游戲開始時,就可以BallstartedspeedXspeedY兩個屬性g.drawImage(ball.getImage(),ball.getX(),ball.getY(), 4.7畫小球(Magic及其子類Magic類是一個抽像類,它 ponet的子類,又是LongMagic與ShortMagic的父類,類只有一個抽象方法magicDo,用來完成的功能,提供一個使用路徑與x、y坐標為參數的構代碼publicMagic(Stringpath,intx,inty)throwsIOException{super(path,x,y);} voidmagicDo(publicMagic(Stringpath,intx,inty)throwsIOException{super(path,x,y);} voidmagicDo(Stickstick代碼publicvoidmagicDo(Stickstick)doublepublicvoidmagicDo(Stickstick)doubleimageWidth=if(stick.getPreWidth()<=imageWidth stick.setPreWidth((int)(stick.getPreWidth()*2)}}代碼publicvoidmagicDo(Stickstick)doubleimageWidth=publicvoidmagicDo(Stickstick)doubleimageWidth=if(stick.getPreWidth()>=imageWidth)stick.setPreWidth((int)(stick.getPreWidth()*0.5)}}磚塊(Brick類Brick類是ponetbooleandisalbe去標志對象是否有效Magicmagic,在構造器中初始化這個屬性,見以下代碼中。publicBrick(Stringpath,publicBrick(Stringpath,inttype,intx,inty)throwsIOException{if(type==Brick.MAGICLONGTYPE)this.magic=newLongMagic("img/long.gif",x,y}elseif(type==Brick.MAGICSHORTTYPE){this.magic=newShortMagic("img/short.gif",x,y);}if(this.magic!=null)this.magic.setX(x);this.magic.setY(y}}在這個構造器的參數中,除了pathxyint類型的參數type,構造器主要是根據這個參數的值去決定此對象包含的Magic,如是type等于Brick.MAGIC_LONG_TYPE,magic就是一個LongMaigc對象,如果type等于x與this.magic.setX(x);this.magic.setY(y}}BallServiceBallService被定義成一個專門處理此游戲邏輯功能的類,包含處理小球的移動、處理擋板的移動、由于BallService負責處理幾乎全部的游戲邏輯,那么該類中就需要界面所有的組件:小球對象、擋板對象、磚塊的二維數組等。BallService中所有的方法都是對這些對象進行處理,修改它們的相關屬createBrickArrpublicBrick[][]createBrickArr(publicBrick[][]createBrickArr(Stringpath,intxSize,intySize)throwsIOException//創(chuàng)建一個Brick[][]bricks=newBrick[xSize][ySize];intx=0;inty=intrandom=intimageSize=28;booleanisDisable=false;for(inti=0;i<xSize;i++)for(intj=0;j<ySize;j++)random=(int)(Math.random()*3);x=i*imageSize;y=j*isDisable=Math.random()>0.8?true:false;if(isDisable){random=}Brickbrick=newBrick(path,random,x,y);//設置xbrick.setX(brick.setX(x//設置y坐標brick.setY(y);bricks[i][jbrick;}}return}行第j列。有三個參數:String類型的文件路徑path,還有代表返回數組大小的xSize與ySize,BallPanelBallServicedraw//for(int//for(inti=0;i<bricks.length;i++)for(intj=0;j<bricks[i].length;j++)ponentmagic=//if(!bricks[i][j].isDisable())//1.getX(),bricks[i][j].getY(),.getImage().getWidth(null)-1,.getImage().getHeight(null)-1,}elseif(magic!=null&&magic.getY()<height){g.drawImage(magic.getImage(),magic.getX(),magic.getY(),}}}BallPanel中,在繪畫該二維數組的時候,要判4.8所示。4.8publicvoidsetStickPos(publicvoidsetStickPos(KeyEventke)//把彈球的運動狀態(tài)設為trueball.setStarted(true);if(ke.getKeyCode()==KeyEvent.VKLEFT){if(stick.getX()-stick.SPEED>0){//xstick.setX(stick.getX()-stick.SPEED}}if(ke.getKeyCode()==KeyEvent.VKRIGHT){if(stick.getX()+stick.SPEED<width-stick.getPreWidth())//xstick.setX(stick.getX()+stick.SPEED//ballFrame.getBallGame().reStart(//ballFrame.getBallGame().reStart(ballFrame}}//如果是F2if(ke.getKeyCode()==KeyEvent.VKF2 try{}catch(IOExceptione){System.out.println(e.getMessage());}}}()4.9(x1,y1(x2,y2publicbooleanisHitBrick(publicbooleanisHitBrick(Brickbrick){if(brick.isDisable()){return}//ball的圓心xdoubleballX=+ball.getImage().getWidth(null)///ball的圓心ydoubleballY=+ball.getImage().getHeight(null)///brickxdoublebrickX=++doublebrickY=+doubledistance=Math.sqrt(Math.pow(ballX-brickX,2)+Math.pow(ballY-brickY,2//如果兩個圖 ,返回if(distance<(+brick.getImage().getWidth(null))/2)//使brick無效brick.setDisabletruereturntrue;}return}(x1y1(x2y2就調用Brick對象的setDisable方法把Brick對象設置為無效并返回true磚塊的二維數“畫”(BallPanel4.10所示。4.10。。我們需要實現BallService的isHitStick方法,該方法判斷小球、與擋板是否發(fā)生了碰撞,只要true。isHitStick方法只要判斷是否發(fā)生了碰撞,至于發(fā)生碰撞后所y坐標是不變的,y1)表示,擋板的長度為n,那么,只要小球或者的x坐標處于x1與x1+n之間(也就是處于擋板的范圍內,yy1,那么就可以判斷它們在碰撞,見以下代碼。publicbooleanpublicbooleanponentbc)//獲 對ImagetempImage=if(bc.getX()+tempImage.getWidth(null)>stick.getX()&&bc.getX()<stick.getX()+stick.getPreWidth()&&bc.getY()+tempImage.getHeight(null)>stick.getY()){returntrue;}return}bc,加粗代碼部分是判斷它們是否有碰撞,bc.getX()+tempImage.getWidth(null)>stick.getX()&&bc.getX()<stick.getX()+stick.getPreWidth()是確認bcx坐標是不是處于擋板的范圍內,bc.getY()tempImage.getHeight(null)stick.getY()是確認bcyy坐標。當小球與磚塊發(fā)生碰撞后,磚塊將會變成(如圖4.10所示。前面的章節(jié)中講到這個游戲有兩個,LongMagic與ShortMagic,作用分別是使擋板就長或者變短,而是保存在Brick對象中,所以我們需要遍歷bricks數組中的所有Brick對象,如果Brick對象的狀態(tài)是disable為true(也就是說磚塊被小球消掉,而且這個Brick對象中有Magic對象不為null,并且Magic對象的y坐標小于小于畫板的高度height(這里意思是說這個 還在畫板的范圍之內,那么,便以Magic對象的速度每次增加magic.getSpeed()個y坐標值,達到 publicvoidsetMagicPos()publicvoidsetMagicPos()for(inti=0;i<bricks.length;i++)for(intj=0;j<bricks[i].length;j++)//Magicmagic=bricks[i][j].getMagic();if(magic!=null){//brickif(bricks[i][j].isDisable()&&magic.getY()<height)//magic的ymagic.setY(magic.getY()+magic.getSpeed()setStickWidth(setStickWidth(magic}}}}}BallServicerunsetMagicPos方法(run100毫秒執(zhí)行一次話,界面中就會出現下落的,具體的效果如圖4.11所示。圖4.11的下改變擋板的長度(的作用4.6.4中實現了判斷小球與擋板、磚塊是否發(fā)生碰撞的方法,因此在這里改變擋板長度,實現起MagicmagicDo方法,magicDo方將擋板的長度

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論