2009-10-28 119 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当你阅读的开销它可能是一个特定〔实施例

任何你可以在任何编程语言做可以做不好或不对。

如果你注意你在听众中所做的一切应该没事