2009-10-28 109 views
1

我想要一個遊戲,當鼠標到達窗口的外邊緣時,視圖將四處移動(類似於許多RTS遊戲)。我讀過使用MouseMotionListener時會產生大量開銷。鼠標移動優化

是否有可能具有遊戲窗口(的JPanel)不影響遊戲播放內的第二透明部件的一種方式,但當鼠標離開經由MouseAdapter.mouseEntered()/的mouseExited內組件將寄存器() ?

boolean mouseOnScreen; 
boolean mouseWithinInnerComponent; //is (10 <= mouse.x <= screenWidth - 10) && (10 <= mouse.y <= screenHeight) 

if(mouseOnScreen && !mouseWithinInnerComponent) 
{ 
    //do something... 
} 

我在對於如何確定哪個屏幕邊界,而無需具有上述部件在角部重疊的四到形成屏幕周圍的邊框能夠檢測鼠標是否在被穿越一個損失任何邊緣或角落。這是我想象的要相當昂貴(其同時運行遊戲,檢查每個部件)...

boolean mouseOnScreen; 
boolean mouseWithinTopComponent; //is (0 <= mouse.y <= 10) 
boolean mouseWithinBottomComponent; //is (screenHeight - 10 <= mouse.y <= screenHeight) 
boolean mouseWithinLeftComponent; //is (0 <= mouse.x <= 10) 
boolean mouseWithinRightComponent; //is (screenWidth - 10 <= mouse.x <= screenWidth) 

if(mouseOnScreen) 
{ 
    if(!mouseWithinBottomComponent) 
    { 
     //move view up 
    } 
    if(!mouseWithinTopComponent) 
    { 
     //move view down 
    } 
    if(!mouseWithinLeftComponent) 
    { 
     //move view right 
    } 
    if(!mouseWithinRightComponent) 
    { 
     //move view left 
    } 
} 

到底有多少開銷的MouseMotionListener存在?如果檢測只需要沿着遊戲窗口的邊界進行,那麼這個或類似的方法可能會更有效率嗎?

注意:這將用於窗口模式以及可能的全屏應用程序。

回答

2

我已經使用MouseMotionListener實現了您需要的相同功能。我不確定你爲什麼認爲它會增加開銷......如果你添加一個,並且簡單地要求它的每種方法打印到控制檯(這是很慢的)並移動你的鼠標,你會看到它非常活潑從用戶的角度來看。

我的實現由4個主要部分組成:滾動窗格,矩形區域,計時器和MouseMotionListener

首先,我創建了一個名爲AutoScrollPane的面板,它擴展了JScollPane。即使它是JScrollPane,也可以隱藏滾動條。這使我可以像你說的那樣利用在RTS遊戲中在地圖上移動視口的功能。其次,對於滾動區域,我實際上有8:n,ne,e,se,s,sw,w和nw(即「北」,東北「等),對角線允許對角線滾動,我將它們簡單地實現爲Rectangle s,它們不是繪製在屏幕上或任何東西 - 我只是在我的類中實例化8個矩形,大小適當,座標與窗口區域相匹配,實際上允許我的窗口成爲如果需要調整矩形大小,我需要調整矩形大小

第三,我有一個可以打開和關閉的計時器,當它打開時,每個「打勾」生成一個RunnableRunnable's作業是滾動面板的視口在適當的方向上有一定的距離。每個Runnable被交給Swing事件隊列。

最後,我有一個MouseMotionListener。攔截鼠標進入,退出和移動事件是工作。每次它接收到一個事件時,它都會檢查當前的鼠標位置以及它是否與其中一個矩形相交。基於哪個矩形,它選擇一個滾動方向。它會跟蹤鼠標是否位於上一個事件的滾動區域中。基於這些信息,它知道它是否應該開始滾動,停止滾動,或者讓任何事情繼續下去。如果鼠標移到窗格外,我希望滾動停止,因此使用exit/enter事件。無論如何,爲了開始滾動,監聽者保存滾動的方向和距離,並通知計時器開始。當停止滾動時(例如當鼠標退出滾動區域時),它會通知計時器停止。

爲平滑滾動選擇正確的計時器粒度和滾動距離需要一段時間,但它確實工作得很好。我希望這個大綱提供一些幫助。

+0

非常好的算法描述 – 2009-10-28 07:08:32

2

我認爲Martin Fowler認爲過早優化是軟件開發中所有邪惡的根源。爲什麼不嘗試MouseMotionListener,只有在發現它影響遊戲性能時才考慮優化。

+1

同意。另外,Knuth說:「我們應該忘記小效率,大約97%的時間:過早優化是萬惡之源。」 – SingleShot 2009-10-28 03:22:47

0

沒有什麼錯用的MouseMotionListener當你閱讀的開銷它可能是一個特定〔實施例

任何你可以在任何編程語言做可以做不好或不對。

如果你注意你在聽衆中所做的一切應該沒事