- Add new nifty wiki pages to manual - Update wiki pages git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7135 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
@ -0,0 +1,339 @@ |
||||
|
||||
<h1><a>Multiplayer Networking</a></h1> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
This provides an overview of the new SpiderMonkey <acronym title="Application Programming Interface">API</acronym> and a path for migrating from the old, now deprecated, <acronym title="Application Programming Interface">API</acronym> to the newer version. Much has changed. |
||||
</p> |
||||
|
||||
<p> |
||||
The <a href="/com/jme3/gde/core/docs/spidermonkey.html">original SpiderMonkey</a> implementation was a good concept and a clever implementation but suffered under the weight of rapid patches and some creeping design deficit. In the end, there were enough small problems, long-term maintenance issues, and limitations that a newer design was warranted. |
||||
</p> |
||||
|
||||
<p> |
||||
Some things will be very similar but others have changed very much. Hopefully for the better. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Overview</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
Most of the new SpiderMonkey <acronym title="Application Programming Interface">API</acronym> now exists as a set of interfaces and helper classes in the 'com.jme3.network' package. For most users, this package and the 'message' package will be all they need to worry about. The 'base' and 'kernel' packages only come into play when implementing custom network transports or alternate client/server protocols (<em>which are now possible</em>). |
||||
</p> |
||||
|
||||
<p> |
||||
Clients and Servers can be created from the factory methods on the Network helper class. Once a Server instance is created and started, it can accept remote connections from Clients. The Client objects represent the client-side of a client→server connection. Within the Server, these are HostedConnections. This is a distinct change from the old <acronym title="Application Programming Interface">API</acronym>. |
||||
|
||||
</p> |
||||
<table> |
||||
<tr> |
||||
<th> Client </th><th> </th><th> Server </th> |
||||
</tr> |
||||
<tr> |
||||
<td> com.jme3.network.Client </td><td> ←→ </td><td> com.jme3.network.HostedConnection </td> |
||||
</tr> |
||||
</table> |
||||
|
||||
<p> |
||||
HostedConnections can hold application defined client-specific session attributes that the server-side listeners and services can use to track player information, etc.. |
||||
</p> |
||||
|
||||
<p> |
||||
MessageListeners can be registered with either the Client or the Server to be notified when new messages arrive. As before, these listeners can be registered to be notified about only specific |
||||
types of messages. |
||||
</p> |
||||
|
||||
<p> |
||||
ClientStateListeners can be registered with a Client to detect changes in connection state. |
||||
</p> |
||||
|
||||
<p> |
||||
ConnectionListeners can be registered with a Server to be notified about HostedConnection arrivals and removals. |
||||
|
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>What's Gone?</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
All of 'connection', 'events', 'queue', 'service', 'streaming', and 'sync' are now deprecated. The 'service', 'streaming', and 'sync' packages were too difficult to easily port to the new <acronym title="Application Programming Interface">API</acronym> and would have required additional code review for thread-related issues. Since the service manager model has _not_ been ported and will likely live on in a different way, it was better to let these go until better solutions evolve. For example, streaming is probably better done more tightly integrated with the core <acronym title="Application Programming Interface">API</acronym> and as actual java.io streams. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Migration</a></h2> |
||||
<div> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>Package/Class Imports</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
As a first pass, use the following table for conversion and then see specific class notes. |
||||
|
||||
</p> |
||||
<table> |
||||
<tr> |
||||
<th> Old Class </th><th> New Class </th> |
||||
</tr> |
||||
<tr> |
||||
<td>com.jme3.network.connection.Client </td><td> com.jme3.network.Client or com.jme3.network.HostedConnection </td> |
||||
</tr> |
||||
<tr> |
||||
<td>com.jme3.network.connection.Server </td><td> com.jme3.network.Server </td> |
||||
</tr> |
||||
<tr> |
||||
<td>com.jme3.network.event.MessageListener </td><td> com.jme3.network.MessageListener </td> |
||||
</tr> |
||||
<tr> |
||||
<td>com.jme3.network.event.ConnectionListener </td><td> com.jme3.network.ClientStateListener or com.jme3.network.ConnectionListener </td> |
||||
</tr> |
||||
<tr> |
||||
<td>com.jme3.network.event.MessageAdapter </td><td> no equivalent class, implement MessageListener directly </td> |
||||
</tr> |
||||
<tr> |
||||
<td>com.jme3.network.event.ConnectionAdapter </td><td> no equivalent class, implement ClientStateListener or ConnectionListener directly </td> |
||||
</tr> |
||||
<tr> |
||||
<td>com.jme3.network.message.Message </td><td> if used as a reference and not a superclass, com.jme3.network.Message. The base class stays the same for message subclasses. </td> |
||||
</tr> |
||||
</table> |
||||
|
||||
<p> |
||||
Doing all of those changes will certainly break your build… so now let's fix it. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>Client and MessageListener</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
This class is the hardest migration to perform. Do not get discouraged. |
||||
</p> |
||||
|
||||
<p> |
||||
The old version used com.jme3.network.connection.Client for both client side and server side. So, depending on context, these references will either change to com.jme3.network.Client or com.jme3.network.HostedConnection. In the case where calling code is not client or server specific, then there is also the common com.jme3.network.MessageConnection interface. |
||||
</p> |
||||
|
||||
<p> |
||||
In general, the actual client changes are of one of the following to types: |
||||
|
||||
</p> |
||||
<pre> Client client = new Client( host, port ); |
||||
|
||||
...becomes... |
||||
|
||||
Client client = Network.connectToServer( host, port );</pre> |
||||
<p> |
||||
In the delayed connection case: |
||||
|
||||
</p> |
||||
<pre> Client client = new Client(); |
||||
... |
||||
client.connect( host, port ); |
||||
|
||||
...becomes... |
||||
|
||||
NetworkClient client = Network.createClient(); |
||||
... |
||||
client.connectToServer( host, port );</pre> |
||||
<p> |
||||
NetworkClient is a Client. The rest of your code can just refer to Client. |
||||
</p> |
||||
|
||||
<p> |
||||
Those are the easy changes. The trickier ones are related to the MessageListeners. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h4><a>MessageListener</a></h4> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
By now you've figured out that all of your MessageListeners are broken because the new method signature is different. The source of a message is no longer stored with the message and is instead provided to the MessageListener. |
||||
</p> |
||||
|
||||
<p> |
||||
Depending on whether your MessageListener is being added to the Client or the Server, it will need to refer to either com.jme3.network.Client or com.jme3.network.HostedConnection in its messageReceived(), respectively. The MessageListener interface is generically typed to help make sure the right listener goes where it's supposed to and so the listener implementations don't have to cast all the time. |
||||
</p> |
||||
<pre>// An example client-specific listener |
||||
public class MyClientListener implements MessageListener<Client> { |
||||
|
||||
public void messageReceived( Client source, Message m ) { |
||||
...do stuff... |
||||
} |
||||
} |
||||
|
||||
// And example server-specific listener |
||||
public class MyServerListener implements MessageListener<HostedConnection> { |
||||
|
||||
public void messageReceived( HostedConnection source, Message m ) { |
||||
...do stuff... |
||||
} |
||||
} |
||||
|
||||
// A client or server listener |
||||
public class MyGenericListener implements MessageListener<MessageConnection> { |
||||
|
||||
public void messageReceived( MessageConnection source, Message m ) { |
||||
... do limited stuff.... |
||||
} |
||||
}</pre> |
||||
<p> |
||||
Your listeners will fall into one of those three categories. |
||||
</p> |
||||
|
||||
<p> |
||||
<p><div>Several of the old MessageListener's methods have gone away. The object-based methods didn't fit with the new <acronym title="Application Programming Interface">API</acronym> and messageSent() seemed of little utility. It could be resurrected if there is demand. |
||||
</div></p> |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h4><a>Client method changes</a></h4> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
Some of the methods on the old Client class have changed or been removed. Here is a basic summary: |
||||
|
||||
</p> |
||||
<table> |
||||
<tr> |
||||
<th> Old Method </th><th> New Method </th> |
||||
</tr> |
||||
<tr> |
||||
<td> Client.disconnect() </td><td> Client.close() or HostedConnection.close(reason) </td> |
||||
</tr> |
||||
<tr> |
||||
<td> Client.kick(reason) </td><td> HostedConnection.close(reason) </td> |
||||
</tr> |
||||
<tr> |
||||
<td> Client.getClientID() </td><td> Client.getId() or HostedConnection.getId() </td> |
||||
</tr> |
||||
<tr> |
||||
<td> Client.get/setPlayerID() </td><td> no equivalent </td> |
||||
</tr> |
||||
<tr> |
||||
<td> Client.get/setLabel() </td><td> no equivalent </td> |
||||
</tr> |
||||
</table> |
||||
|
||||
</div> |
||||
|
||||
<h4><a>No IOExceptions</a></h4> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
After you've done all of that, the compiler will be complaining about the fact that send(), broadcast(), etc. no longer throw IOException. So remove all of those try/catch blocks. |
||||
<p><div>The truth is that even in the old <acronym title="Application Programming Interface">API</acronym>, expecting a real IOException from these methods was unreasonable because often times the message was queued and actually sent later by a separate thread. The new <acronym title="Application Programming Interface">API</acronym> assumes that all underlying transports will operate this way and so forgoes the artificial annoyance or sense of security provided by these 'throws' clauses. It also simplifies the calling code a great deal. |
||||
|
||||
</div></p> |
||||
</p> |
||||
|
||||
<p> |
||||
Only <acronym title="Application Programming Interface">API</acronym> methods that actually perform direct IO (such as the Network.connectToServer() and NetworkClient.connectToServer() methods) will ever be declared to throw IOException. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>Message.getClient() and Message.getConnection()</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
This is important enough to deserve its own sub-heading because your code <strong>will</strong> break if you use these as they now return null. Any reason for calling them is now provided directly to the MessageListener in the form of the source Client or source HostedConnection. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>Client ID and Player ID</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
The ID of the Client and HostedConnection are now the same at both ends of a connection and the ID is given out authoritatively by the hosting Server. This removes some of the inconsistency on when to use the old player ID and when to use the old client ID as the new client ID serves both purposes. This leaves the game to be able to define its own player ID based on whatever user criteria it wants. |
||||
</p> |
||||
|
||||
<p> |
||||
<p><div>Many of the reasons for accessing the client ID on the server can now be taken care of using the session attributes on HostedConnection. It seems like a common use-case for these IDs was to look-up player/client-specific information in a java.util.Map. This information can now be set directly on the HostedConnection. |
||||
</div></p> |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>com.jme3.network.event.ConnectionListener</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
Along with the shift from not using the same object at both ends of the client connection was a shift in the interfaces that are notified about those ends. |
||||
</p> |
||||
|
||||
<p> |
||||
On the client, there is now com.jme3.network.ClientStateListener which is notified when the client fully connects to the server (including any internal handshaking) and when the client is disconnected. |
||||
</p> |
||||
|
||||
<p> |
||||
On the server, com.jme3.network.ConnectionListener will be notified whenever new HostedConnections are added or removed. This listener isn't notified until the connection is fully setup (including any internal handshaking). |
||||
|
||||
</p> |
||||
<table> |
||||
<tr> |
||||
<th> Old Method </th><th> New Method </th> |
||||
</tr> |
||||
<tr> |
||||
<td> clientConnected(Client) </td><td> connectionAdded(Server,HostedConnection) </td> |
||||
</tr> |
||||
<tr> |
||||
<td> clientDisconnected(Client) </td><td> connectionRemoved(Server,HostedConnection) </td> |
||||
</tr> |
||||
</table> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Why am I doing this again?</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
As you've seen above, there are quite a few changes necessary to migrate to the new <acronym title="Application Programming Interface">API</acronym>. You might be asking yourself if it's worth the trouble. |
||||
</p> |
||||
|
||||
<p> |
||||
The bottom line is that the old architecture had threading and stability issues that just couldn't be fixed in any reasonable way. Some were minor, others kind of severe… and they combined to make trouble. If you've ever wondered why sometimes your clients connect and then the network connection hangs or stops sending data. Or if you've ever wondered why UDP/unreliable messages get corrupted or somehow won't deserialize properly then you've run into some of these issues. |
||||
</p> |
||||
|
||||
<p> |
||||
Moreover, the lack of thread safety meant that user code sometimes had to do some strange and/or complicated work-arounds. The goal should be that the <acronym title="Application Programming Interface">API</acronym> should just work like it looks like it will with a minimum of hassle. |
||||
</p> |
||||
|
||||
<p> |
||||
The new architecture is built from the ground up for threading stability and for a clean separation between the public <acronym title="Application Programming Interface">API</acronym>, the message passing layer, and the underlying network transport implementations. You should be able to throw all kinds of stuff at it that would make the old system fall over and it should just hum along. |
||||
</p> |
||||
|
||||
<p> |
||||
There will certainly be some growing pains as we work the kinks out of the new system but it is already much more stable in even the most basic of stress tests. |
||||
|
||||
</p> |
||||
<div><span> |
||||
<a href="/wiki/doku.php/tag:documentation?do=showtag&tag=tag%3Adocumentation">documentation</a>, |
||||
<a href="/wiki/doku.php/tag:network?do=showtag&tag=tag%3Anetwork">network</a> |
||||
</span></div> |
||||
|
||||
</div> |
||||
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:networking?do=export_xhtmlbody">view online version</a></em></p> |
After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 40 KiB |
@ -0,0 +1,184 @@ |
||||
|
||||
<h1><a>Interacting with the GUI from Java</a></h1> |
||||
<div> |
||||
<ol> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> |
||||
</li> |
||||
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Java Interaction</strong></div> |
||||
</li> |
||||
</ol> |
||||
|
||||
<p> |
||||
|
||||
The main purpose of the <acronym title="Graphical User Interface">GUI</acronym> is to send events back to your Java class that indicate what the users clicked, which settings they chose, which values they entered into a field, etc. In the Java class, you want to respond with an appropriate action, or store the entered settings in a file, etc. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Connect GUI to Java Controller</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
How does the <acronym title="Extensible Markup Language">XML</acronym> file send a message back to your Java application? You register a ScreenController (a Java class) to every NiftyGUI screen. |
||||
</p> |
||||
|
||||
<p> |
||||
Create a ScreenController by creating a Java class that implements the <code>de.lessvoid.nifty.screen.ScreenController</code> interface and its abtract methods. |
||||
</p> |
||||
<pre>package my.game; |
||||
import de.lessvoid.nifty.Nifty; |
||||
import de.lessvoid.nifty.screen.Screen; |
||||
import de.lessvoid.nifty.screen.ScreenController; |
||||
|
||||
public class MySettingsScreen implements ScreenController { |
||||
|
||||
public void bind(Nifty nifty, Screen screen) { } |
||||
|
||||
public void onStartScreen() { } |
||||
|
||||
public void onEndScreen() { } |
||||
}</pre> |
||||
<p> |
||||
The name and package of your custom ScreenController class (here <code>my.game.MySettingsScreen</code>) goes into the controller parameter of the respective screen it belongs to: |
||||
</p> |
||||
<pre><span><span><nifty></span></span> |
||||
<span><screen id="settings" controller="my.game.MySettingsScreen"></span> |
||||
<!-- layer and panel code ... --> |
||||
<span><span></screen></span></span> |
||||
<span><span></nifty></span></span></pre> |
||||
<p> |
||||
Now the Java class <code>my.game.MySettingsScreen</code> and this <acronym title="Graphical User Interface">GUI</acronym> screen (<code>settings</code>) are connected. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Make GUI and Java Interact</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
You can use any of the three following approaches to interact, and you can also combine them, depending on what you want to do. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>GUI Calls a Void Java Method</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
To respond to an interaction, add the <interact /> element to a panel and specify the Java method you want to call. In this example, we want to call <code>sayHello()</code> when a panel on the screen is clicked. |
||||
</p> |
||||
<pre>... |
||||
<span><panel id="panel" height="25%" width="35%" align="center" valign="center" </span> |
||||
<span> backgroundColor="#f60f" childLayout="center" visibleToMouse="true"></span> |
||||
<span><text id="text" font="aurulent-sans-17.fnt" color="#000f" </span> |
||||
<span> text="Hello World!" align="center" valign="center" /></span> |
||||
<span><interact onClick="sayHello(hi)"/></span> |
||||
<span><span></panel></span></span> |
||||
...</pre> |
||||
<p> |
||||
Back in this screen's Java class, we specify what the <code>sayHello()</code> method does. As you see, you can include String arguments in the call. |
||||
</p> |
||||
<pre>public class MySettingsScreen implements ScreenController { |
||||
... |
||||
public void sayHello(String myarg) { |
||||
System.out.println("Nifty says "+myarg); |
||||
} |
||||
}</pre> |
||||
</div> |
||||
|
||||
<h3><a>GUI Gets Return Value from Java Method</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
You can send a message from Java to Nifty. In this example, the Java class <code>callThis()</code> in MySettingsScreen defines the Text that is displayed in the textfield after the words <code>Hello World, …!</code> |
||||
</p> |
||||
|
||||
<p> |
||||
First define a Java method in the screen controller, in this example, <code>callThis()</code>. |
||||
</p> |
||||
<pre>public class MySettingsScreen implements ScreenController { |
||||
... |
||||
public String callThis() { |
||||
return "my friend"; |
||||
} |
||||
}</pre> |
||||
<p> |
||||
Nifty uses <code>${CALL.callThis()}</code> to get the return value of a method from your ScreenController Java class. |
||||
</p> |
||||
<pre>... |
||||
<span><panel id="panel" height="25%" width="35%" align="center" valign="center" </span> |
||||
<span> backgroundColor="#f60f" childLayout="center" visibleToMouse="true"></span> |
||||
<span><text id="text" font="aurulent-sans-17.fnt" color="#000f" </span> |
||||
<span> text="Hello World, ${CALL.callThis()}!" align="center" valign="center" /></span> |
||||
<span><interact onClick="sayHello(hi)"/></span> |
||||
<span><span></panel></span></span> |
||||
...</pre> |
||||
<p> |
||||
You can also use this for Strings and numeric values, e.g. when you read settings from a file, you read them like this. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>Java Modifies Nifty Elements and Events</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
You can also alter the appearance and functions of your nifty elements from Java. |
||||
</p> |
||||
|
||||
<p> |
||||
Here's an example of how to change the image <code>myElement</code>: |
||||
</p> |
||||
<pre>NiftyImage img = nifty.getRenderEngine().createImage("Interface/Images/image.png", false); |
||||
Element niftyElement = nifty.getCurrentScreen().findElementByName("myElement"); |
||||
niftyElement.getRenderer(ImageRenderer.class).setImage(img);</pre> |
||||
<p> |
||||
The same is valid for other elements, for example text fields: |
||||
|
||||
</p> |
||||
<pre>niftyElement.getRenderer(TextRenderer.class).setText("New text");</pre> |
||||
<p> |
||||
Similarly, to change the onClick() event of an element, create an <code>ElementInteraction</code> object: |
||||
</p> |
||||
<pre>Element niftyElement = nifty.getCurrentScreen().findElementByName("myElement"); |
||||
niftyElement.setInteraction(new ElementInteraction(nifty) { |
||||
|
||||
@Override |
||||
public void onClick() { |
||||
// call java functions normally. |
||||
niftyController.onElementClicked(); |
||||
super.onClick(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean onClick(MouseInputEvent inputEvent) { |
||||
niftyController.onElementClicked(); |
||||
return super.onClick(inputEvent); |
||||
} |
||||
});</pre> |
||||
<p> |
||||
For this to work, there already needs to be an < interact > tag inside your xml element: |
||||
</p> |
||||
<pre><interact onClick="doNothing()"/></pre> |
||||
|
||||
<p> |
||||
Learn more: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=MarkUp"><param name="text" value="<html><u>Nifty Syntax</u></html>"><param name="textColor" value="blue"></object> |
||||
|
||||
</p> |
||||
<div><span> |
||||
<a href="/wiki/doku.php/tag:gui?do=showtag&tag=tag%3Agui">gui</a>, |
||||
<a href="/wiki/doku.php/tag:documentation?do=showtag&tag=tag%3Adocumentation">documentation</a>, |
||||
<a href="/wiki/doku.php/tag:input?do=showtag&tag=tag%3Ainput">input</a>, |
||||
<a href="/wiki/doku.php/tag:controller?do=showtag&tag=tag%3Acontroller">controller</a>, |
||||
<a href="/wiki/doku.php/tag:controllers?do=showtag&tag=tag%3Acontrollers">controllers</a> |
||||
</span></div> |
||||
|
||||
</div> |
||||
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_java_interaction?do=export_xhtmlbody">view online version</a></em></p> |
@ -0,0 +1,69 @@ |
||||
|
||||
<h1><a>Integrating Nifty GUI: Overlay</a></h1> |
||||
<div> |
||||
<ol> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> |
||||
</li> |
||||
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Overlay</strong> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> |
||||
</li> |
||||
</ol> |
||||
|
||||
<p> |
||||
Define a key (for example escape) that switches the <acronym title="Graphical User Interface">GUI</acronym> on and off. |
||||
You can either overlay the running game with the <acronym title="Graphical User Interface">GUI</acronym> (you will most likely pause the game then), or even <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">project</a> it as a texture onto a mesh texture (but then you cannot click to select). |
||||
</p> |
||||
|
||||
<p> |
||||
On this page, we look at the overlay variant (more commonly used). |
||||
</p> |
||||
|
||||
<p> |
||||
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui-example.png"> |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Sample Code</a></h2> |
||||
<div> |
||||
<ul> |
||||
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java"><param name="text" value="<html><u>TestNiftyGui.java</u></html>"><param name="textColor" value="blue"></object></div> |
||||
</li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Overlaying the User Interface Over the Screen</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
This code shows you how to overlay anything on the screen with the <acronym title="Graphical User Interface">GUI</acronym>. This is the most common usecase. |
||||
</p> |
||||
<pre>NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay( |
||||
assetManager, inputManager, audioRenderer, guiViewPort); |
||||
Nifty nifty = niftyDisplay.getNifty(); |
||||
|
||||
// init Nifty start screen |
||||
nifty.fromXml("Interface/helloworld.xml", "start"); |
||||
|
||||
// attach the Nifty display to the gui view port as a processor |
||||
guiViewPort.addProcessor(niftyDisplay); |
||||
// disable the fly cam |
||||
flyCam.setDragToRotate(true);</pre><hr /> |
||||
<ol> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> |
||||
</li> |
||||
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Overlay</strong> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> |
||||
</li> |
||||
</ol> |
||||
<div><span> |
||||
<a href="/wiki/doku.php/tag:documentation?do=showtag&tag=tag%3Adocumentation">documentation</a>, |
||||
<a href="/wiki/doku.php/tag:gui?do=showtag&tag=tag%3Agui">gui</a> |
||||
</span></div> |
||||
|
||||
</div> |
||||
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_overlay?do=export_xhtmlbody">view online version</a></em></p> |
@ -0,0 +1,96 @@ |
||||
|
||||
<h1><a>Integrating Nifty GUI: Projection</a></h1> |
||||
<div> |
||||
<ol> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Projection</strong></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> |
||||
</li> |
||||
</ol> |
||||
|
||||
<p> |
||||
Define a key (for example escape) that switches the <acronym title="Graphical User Interface">GUI</acronym> on and off. You can either <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">overlay</a> the running game with the <acronym title="Graphical User Interface">GUI</acronym> (you will most likely pause the game then), or even project it as a texture onto a mesh textures (but then you cannot click to select). |
||||
</p> |
||||
|
||||
<p> |
||||
On this page, we look at the projection variant (less commonly used). |
||||
</p> |
||||
|
||||
<p> |
||||
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui.png"> |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Sample Code</a></h2> |
||||
<div> |
||||
<ul> |
||||
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyToMesh.java"><param name="text" value="<html><u>TestNiftyToMesh.java</u></html>"><param name="textColor" value="blue"></object></div> |
||||
</li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Projecting the User Interface Onto a Texture</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
You can project the Nifty <acronym title="Graphical User Interface">GUI</acronym> onto a texture, load the texture into a material, and assign it to a 3D mesh. Allthough this is possible the approach is rarely used since it is difficult to record clicks this way, you can only interact with this UI by keyboard. |
||||
</p> |
||||
<pre>/** Create a new viewport for the GUI */ |
||||
ViewPort niftyView = renderManager.createPreView("NiftyView", new Camera(1024, 768)); |
||||
niftyView.setClearEnabled(true); |
||||
|
||||
|
||||
/** Create a new NiftyJmeDisplay for the integration */ |
||||
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay( |
||||
assetManager, inputManager, audioRenderer, niftyView); |
||||
|
||||
/** Create a new NiftyGUI object and read your XML */ |
||||
Nifty nifty = niftyDisplay.getNifty(); |
||||
nifty.fromXml("Interface/helloworld.xml", "start"); |
||||
|
||||
/** We prepare a framebuffer for the texture niftytex */ |
||||
niftyView.addProcessor(niftyDisplay); |
||||
FrameBuffer fb = new FrameBuffer(1024, 768, 0); |
||||
fb.setDepthBuffer(Format.Depth); |
||||
Texture2D niftytex = new Texture2D(1024, 768, Format.RGB8); |
||||
fb.setColorTexture(niftytex); |
||||
niftyView.setClearEnabled(true); |
||||
niftyView.setOutputFrameBuffer(fb); |
||||
|
||||
/** This is the 3D cube we project the GUI on */ |
||||
Box(Vector3f.ZERO, 1, 1, 1); |
||||
Geometry geom = new Geometry("Box", b); |
||||
Material mat = new Material(assetManager, "Common/MatDefs/Misc/SimpleTextured.j3md"); |
||||
mat.setTexture("m_ColorMap", niftytex); /** Here comes the texture! */ |
||||
geom.setMaterial(mat); |
||||
rootNode.attachChild(geom);</pre> |
||||
<p> |
||||
You select buttons on this <acronym title="Graphical User Interface">GUI</acronym> with the arrow keys and then press return – Clicking them will not work. |
||||
</p> |
||||
|
||||
<p> |
||||
Again, check the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Main_Page"><param name="text" value="<html><u>Nifty GUI wiki</u></html>"><param name="textColor" value="blue"></object> to get all the “bells and whistles”! |
||||
|
||||
</p> |
||||
<hr /> |
||||
<ol> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Projection</strong></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> |
||||
</li> |
||||
</ol> |
||||
<div><span> |
||||
<a href="/wiki/doku.php/tag:documentation?do=showtag&tag=tag%3Adocumentation">documentation</a>, |
||||
<a href="/wiki/doku.php/tag:gui?do=showtag&tag=tag%3Agui">gui</a>, |
||||
<a href="/wiki/doku.php/tag:texture?do=showtag&tag=tag%3Atexture">texture</a> |
||||
</span></div> |
||||
|
||||
</div> |
||||
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_projection?do=export_xhtmlbody">view online version</a></em></p> |
@ -0,0 +1,193 @@ |
||||
|
||||
<h1><a>Laying out the GUI in XML</a></h1> |
||||
<div> |
||||
<ol> |
||||
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> <acronym title="Extensible Markup Language">XML</acronym> Layout</strong></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> |
||||
</li> |
||||
</ol> |
||||
|
||||
<p> |
||||
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-screen-layer-panel.png"> |
||||
</p> |
||||
|
||||
<p> |
||||
You “draw” the <acronym title="Graphical User Interface">GUI</acronym> to the screen by writing <acronym title="Extensible Markup Language">XML</acronym> code. We will be referring to the following elements: |
||||
</p> |
||||
<ul> |
||||
<li><div> Every Nifty Gui is made up of screens.</div> |
||||
<ul> |
||||
<li><div> Nifty can display only one screen at a time.</div> |
||||
</li> |
||||
<li><div> You must name the first screen <code>id=“start”</code>. Name any others whatever you like.</div> |
||||
</li> |
||||
<li><div> Every screen is <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">controlled by a Java class</a>.</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
<li><div> A screen contains one or more layers. </div> |
||||
<ul> |
||||
<li><div> Layers are containers that impose an alignment on their content (vertical, horizontal, centered)</div> |
||||
</li> |
||||
<li><div> Layers can overlap (z-order), but cannot be nested.</div> |
||||
</li> |
||||
<li><div> Layers are usually transparent (but can be opaque).</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
<li><div> A layer contains panels.</div> |
||||
<ul> |
||||
<li><div> Panels are containers that impose an alignment on their content (vertical, horizontal, centered)</div> |
||||
</li> |
||||
<li><div> Panels can be nested, but not overlap.</div> |
||||
</li> |
||||
<li><div> Panels are usually opaque (but can be transparent). ?</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
<li><div> A panel can contain images, text fields, buttons, controls.</div> |
||||
</li> |
||||
<li><div> Every element has an id to refer to it.</div> |
||||
</li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>How to Use Screens and Layers</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
Create an empty helloworld.xml file in the <code>assets/Interfaces/</code> directory of your project. |
||||
</p> |
||||
|
||||
<p> |
||||
Here's a minimal example showing an empty centered layer on the start screen: |
||||
</p> |
||||
<pre><span><?xml version="1.0" encoding="UTF-8"?></span> |
||||
<span><nifty xmlns="http://nifty-gui.sourceforge.net/nifty.xsd" </span> |
||||
<span> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" </span> |
||||
<span> xsi:schemaLocation="http://nifty-gui.sourceforge.net/nifty.xsd |
||||
http://nifty-gui.sourceforge.net/nifty.xsd"></span> |
||||
|
||||
<span><screen id="start" controller="de.lessvoid.nifty.examples.helloworld.HelloWorldStartScreen"></span> |
||||
<span><layer id="layer1" backgroundColor="#003f" childLayout="center"></span> |
||||
<!-- ... panels go here... --> |
||||
<span><span></layer></span></span> |
||||
<span><span></screen></span></span> |
||||
|
||||
<span><span></nifty></span></span></pre> |
||||
<p> |
||||
Into a layer, you add panels (text, images, etc), and specify their properties: |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>Panel</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
A panels looks like a rectangular colored box. |
||||
</p> |
||||
<pre>... |
||||
<span><panel height="25%" width="35%" align="center" valign="center" backgroundColor="#f60f"</span> |
||||
<span> childLayout="center" visibleToMouse="true"></span> |
||||
<span><span></panel></span></span> |
||||
...</pre> |
||||
</div> |
||||
|
||||
<h3><a>Text</a></h3> |
||||
<div> |
||||
<pre>... |
||||
<span><text font="verdana-24-shadow.fnt" text="Hello World!" align="center" valign="center" /></span> |
||||
...</pre> |
||||
<p> |
||||
|
||||
or |
||||
</p> |
||||
<pre>... |
||||
<span><label text="this is my text" align="left"/></span> |
||||
...</pre> |
||||
</div> |
||||
|
||||
<h3><a>Image</a></h3> |
||||
<div> |
||||
<pre><span><image filename="Textures/jme-logo.png" ><span></image></span></span></pre> |
||||
<p> |
||||
Nifty additionally offers predefined controls – learn more from the NiftyGUI page: |
||||
</p> |
||||
<ul> |
||||
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction</u></html>"><param name="textColor" value="blue"></object></div> |
||||
</li> |
||||
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements</u></html>"><param name="textColor" value="blue"></object></div> |
||||
</li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Effects</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
You can register effects to screen elements. |
||||
</p> |
||||
<ul> |
||||
<li><div> Respond to element events such as onStartScreen, onEndScreen, onHover, onFocus, onActive,</div> |
||||
</li> |
||||
<li><div> Trigger effects that change movement, blending, size, color, fading, and much more.</div> |
||||
</li> |
||||
</ul> |
||||
|
||||
<p> |
||||
|
||||
Here is an example that moves a panel when the startScreen opens. You place an < effect > tag inside the element that you want to want to be affected. |
||||
</p> |
||||
<pre>... |
||||
<span><panel height="25%" width="35%" ...></span> |
||||
<span><span><effect></span></span> |
||||
<span><onStartScreen name="move" mode="in" direction="top" </span> |
||||
<span> length="300" startDelay="0" inherit="true"/></span> |
||||
<span><span></effect></span></span> |
||||
<span><span></panel></span></span> |
||||
...</pre> |
||||
<p> |
||||
Playing sounds using nifty is also possible with effects as triggers. Remember to first register the sound you're going to play: |
||||
</p> |
||||
<pre>... |
||||
<span><registerSound id="click" filename="Sounds/Gui/ButtonClick.ogg" /></span> |
||||
... |
||||
<span><span><label></span></span> |
||||
<span><span><effect></span></span> |
||||
<span><onClick name="playSound" sound="click"/></span> |
||||
<span><span></effect></span></span> |
||||
<span><span></label></span></span> |
||||
...</pre> |
||||
<p> |
||||
|
||||
Learn more from the NiftyGUI page: |
||||
</p> |
||||
<ul> |
||||
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects</u></html>"><param name="textColor" value="blue"></object></div> |
||||
</li> |
||||
</ul> |
||||
<hr /> |
||||
<ol> |
||||
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> <acronym title="Extensible Markup Language">XML</acronym> Layout</strong></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> |
||||
</li> |
||||
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> |
||||
</li> |
||||
</ol> |
||||
<div><span> |
||||
<a href="/wiki/doku.php/tag:documentation?do=showtag&tag=tag%3Adocumentation">documentation</a>, |
||||
<a href="/wiki/doku.php/tag:gui?do=showtag&tag=tag%3Agui">gui</a> |
||||
</span></div> |
||||
|
||||
</div> |
||||
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_xml_layout?do=export_xhtmlbody">view online version</a></em></p> |
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,174 @@ |
||||
|
||||
<h1><a>Physics Listeners</a></h1> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
You can control physical objects by triggering forces. Or maybe you want to respond to collisions, e.g. by substracting health points, or by playing a sound. To specify how the game responds to such physics events, you use Physics Listeners. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Physics Tick Listener</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
The jBullet Physics implementation is stepped at a constant 60 physics ticks per second frame rate. |
||||
Applying forces or checking for overlaps only has an effect right at a physics update cycle, which is not every frame. If you do physics interactions at arbitrary spots in the simpleUpdate() loop, calls will be dropped at irregular intervals, because they happen out of cycle. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>When (Not) to Use Tick Listener?</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
When you write game mechanics that apply forces, you must implement a tick listener (com.jme3.bullet.PhysicsTickListener) for it. The tick listener makes certain the forces are not dropped, but applied in time for the next physics tick. |
||||
</p> |
||||
|
||||
<p> |
||||
Also, when you check for overlaps of physical objects with a PhysicsGhostObject, you cannot just go <code>physicsSpace.add(ghost); ghost.getOverLappingObjects()</code> somewhere. You have to make certain 1 physics tick has passed before the overlapping objects list is filled with data. Again, the PhysicsTickListener does that for you. |
||||
</p> |
||||
|
||||
<p> |
||||
When your game mechanics however just poll the current state (e.g. location) of physical objects, or if you only use the Ghost control like a sphere trigger, then you don't need a PhysicsTickListener. |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>How to Listen to Physics Ticks</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
Here's is the declaration of an examplary Physics Control that listens to ticks. |
||||
</p> |
||||
<pre>public class MyCustomControl |
||||
extends RigidBodyControl implements PhysicsTickListener { ... }</pre> |
||||
<p> |
||||
When you implement the interface, you have to implement preTick() and postTick() methods. |
||||
</p> |
||||
<ul> |
||||
<li><div> <code>prePhysicsTick()</code> is called before the step, here you apply forces (change the state).</div> |
||||
</li> |
||||
<li><div> <code>physicsTick()</code> is called after the step, here you poll the results (get the current state).</div> |
||||
</li> |
||||
</ul> |
||||
<pre>@override |
||||
public void prePhysicsTick(PhysicsSpace space, float f){ |
||||
// apply state changes ... |
||||
} |
||||
@override |
||||
public void physicsTick(PhysicsSpace space, float f){ |
||||
// poll game state ... |
||||
}</pre> |
||||
</div> |
||||
|
||||
<h2><a>Physics Collision Listener</a></h2> |
||||
<div> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>When (Not) to Use Collision Listener</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
If you do not implement the Collision Listener interface (com.jme3.bullet.collision.PhysicsCollisionListener), a collisions will just mean that physical forces are applied automatically. If you just want “Balls rolling, bricks falling” you do not need a listener. |
||||
</p> |
||||
|
||||
<p> |
||||
If however you want to respond to a collision event (com.jme3.bullet.collision.PhysicsCollisionEvent) with a custom action, then you need to implement the PhysicsCollisionListener interface. Typical actions triggered by collisions include: |
||||
|
||||
</p> |
||||
<ul> |
||||
<li><div> Increasing a counter (e.g. score points)</div> |
||||
</li> |
||||
<li><div> Decreasing a counter (e.g. health points)</div> |
||||
</li> |
||||
<li><div> Triggering an effect (e.g. explosion)</div> |
||||
</li> |
||||
<li><div> Playing a sound (e.g. explosion, ouch) </div> |
||||
</li> |
||||
<li><div> … and countless more, depending on your game</div> |
||||
</li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>How to Listen to Collisions</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
Again, here's the example declaration of a Physics Control that uses a collision listener. |
||||
</p> |
||||
<pre>public class MyCustomControl |
||||
extends RigidBodyControl |
||||
implements PhysicsCollisionListener { ... }</pre> |
||||
<p> |
||||
To respond to the PhysicsCollisionEvent you have to override the <code>collision()</code> method. This gives you access to the event object. Mostly you will be interested in the identity of any two nodes that collided: <code>event.getNodeA()</code> and <code>event.getNodeB()</code>. |
||||
</p> |
||||
|
||||
<p> |
||||
After you identify the colliding nodes, specify the action to trigger when this pair collides. Note that you cannot know which one will be Node A or Node B, you have to deal with either variant. |
||||
</p> |
||||
<pre> public void collision(PhysicsCollisionEvent event) { |
||||
if ( event.getNodeA().getName().equals("player") ) { |
||||
final Node node = event.getNodeA(); |
||||
/** ... do something with the node ... */ |
||||
} else if ( event.getNodeB().getName().equals("player") ) { |
||||
final Node node = event.getNodeB(); |
||||
/** ... do something with the node ... */ |
||||
} |
||||
}</pre> |
||||
<p> |
||||
<p><div>Note that after the collision() method ends, the PhysicsCollisionEvent is cleared. You must get all objects and values you need within the collision() method. |
||||
</div></p> |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h3><a>Reading Details From a PhysicsCollisionEvent</a></h3> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
The PhysicsCollisionEvent <code>event</code> gives you access to detailed information about the collision. You already know the event objects can identify which nodes collided, but it even knows how hard they collided: |
||||
|
||||
</p> |
||||
<table> |
||||
<tr> |
||||
<th>Method </th><th>Purpose</th> |
||||
</tr> |
||||
<tr> |
||||
<td> getNodeA() <br/> |
||||
getNodeB() </td><td> The two participants in the collision. You cannot know in advance whether some node will be recorded as A or B, you always have to consider both cases. </td> |
||||
</tr> |
||||
<tr> |
||||
<td> getAppliedImpulse() </td><td> A float value representing the collision impulse </td> |
||||
</tr> |
||||
<tr> |
||||
<td> getAppliedImpulseLateral1() </td><td> A float value representing the lateral collision impulse </td> |
||||
</tr> |
||||
<tr> |
||||
<td> getAppliedImpulseLateral2() </td><td> A float value representing the lateral collision impulse </td> |
||||
</tr> |
||||
<tr> |
||||
<td> getCombinedFriction() </td><td> A float value representing the collision friction </td> |
||||
</tr> |
||||
<tr> |
||||
<td> getCombinedRestitution() </td><td> A float value representing the collision restitution (bounciness) </td> |
||||
</tr> |
||||
</table> |
||||
|
||||
<p> |
||||
|
||||
Note that after the collision method has been called the object is not valid anymore so you should copy any data you want to keep into local variables. |
||||
|
||||
</p> |
||||
|
||||
</div> |
||||
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:physics_listeners?do=export_xhtmlbody">view online version</a></em></p> |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
@ -1,135 +1,252 @@ |
||||
|
||||
<h1><a>My First Game - Tutorial Series (Draft)</a></h1> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
<strong>DRAFT!</strong> |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Outline</a></h2> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
Goal: Concisely show how to write simple game, in context, from end to end. |
||||
</p> |
||||
<ul> |
||||
<li><div> Top-down overview of the finished game and its parts.</div> |
||||
</li> |
||||
<li><div> Bottom-up tutorial series.</div> |
||||
<ol> |
||||
<li><div> Analysis phase – What questions do I answer myself before I can start implementing?</div> |
||||
</li> |
||||
<li><div> Development phase – What is the work process like? (With code samples)</div> |
||||
<ul> |
||||
<li><div> Best practices for project structure (asset directories, packages, classes)</div> |
||||
</li> |
||||
<li><div> Best practices for common functionalities (input, settings, <acronym title="Graphical User Interface">GUI</acronym>, formats)</div> |
||||
</li> |
||||
<li><div> including debugging, profiling, QA testing</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
<li><div> Release phase – When do I consider my game complete?</div> |
||||
</li> |
||||
</ol> |
||||
</li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>User Suggested Topics</a></h2> |
||||
<div> |
||||
<ol> |
||||
<li><div> Create and load a scene/terrain</div> |
||||
<ul> |
||||
<li><div> Creation: Refer to Blender tutorials until we have our own terrain/scene editor</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
<li><div> Create, load and animate models</div> |
||||
<ul> |
||||
<li><div> Creation: Refer to Blender tutorials</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
<li><div> Basic camera navigation (first-person/third-person view)</div> |
||||
</li> |
||||
<li><div> User input (character moves, attacks)</div> |
||||
</li> |
||||
<li><div> Collision (physics: floor/walls/obstacles)</div> |
||||
</li> |
||||
<li><div> Mouse interaction (shooting/picking up)</div> |
||||
</li> |
||||
<li><div> Basic enemy AI</div> |
||||
<ul> |
||||
<li><div> Mainly show how to integrate a simple interactive decision process</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
<li><div> Enhancements: Effects, scores, settings, audio, <acronym title="Graphical User Interface">GUI</acronym>, HUD </div> |
||||
<ul> |
||||
<li><div> Show very briefly what is possible and how to integrate L0l</div> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
</ol> |
||||
|
||||
<p> |
||||
|
||||
See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.jmonkeyengine.com/wiki/doku.php?id=flag_rush_tutorial_series_by_mojomonkey"><param name="text" value="<html><u>Flag Rush series</u></html>"><param name="textColor" value="blue"></object> for jme2 |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h2><a>Tutorial Deliverables</a></h2> |
||||
<div> |
||||
<ol> |
||||
<li><div> Playable finished game executable available for download.</div> |
||||
</li> |
||||
<li><div> Finished sources (build script, libraries, assets) available for download.</div> |
||||
</li> |
||||
<li><div> Tutorial series describing the evolution of the project.</div> |
||||
</li> |
||||
<li><div> Snapshots of sources at different stages of development (to go with tutorials).</div> |
||||
</li> |
||||
<li><div> Illustrations and screenshots (to go with tutorials)</div> |
||||
</li> |
||||
</ol> |
||||
<hr /> |
||||
|
||||
<p> |
||||
|
||||
Draft |
||||
</p> |
||||
<hr /> |
||||
|
||||
</div> |
||||
|
||||
<h1><a>Taking a Look At the Finished JME3 Game</a></h1> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
… |
||||
</p> |
||||
|
||||
</div> |
||||
|
||||
<h1><a>Developing your First JME3 Game</a></h1> |
||||
<div> |
||||
|
||||
<p> |
||||
|
||||
<a href="/com/jme3/gde/core/docs/jme3/intermediate/best_practices.html">Best Practices</a> |
||||
</p> |
||||
|
||||
<p> |
||||
… |
||||
</p> |
||||
|
||||
</div> |
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html |
||||
xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"><head |
||||
profile="http://gmpg.org/xfn/11"><link |
||||
rel="shortcut icon" href="http://jmonkeyengine.org/favicon.ico" /><meta |
||||
http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>jMonkeyEngine.org |</title><meta |
||||
name="generator" content="WordPress 3.1" /><link |
||||
rel="stylesheet" href="http://jmonkeyengine.org/wp-content/themes/bp-jme-1/style.css" type="text/css" media="screen" /><link |
||||
rel="alternate" type="application/rss+xml" title="jMonkeyEngine.org | Site Wide Activity RSS Feed" href="http://jmonkeyengine.org/activity/feed/" /><link |
||||
rel="alternate" type="application/rss+xml" title="jMonkeyEngine.org Blog Posts RSS Feed" href="http://jmonkeyengine.org/feed/" /><link |
||||
rel="alternate" type="application/atom+xml" title="jMonkeyEngine.org Blog Posts Atom Feed" href="http://jmonkeyengine.org/feed/atom/" /><link |
||||
rel="pingback" href="http://jmonkeyengine.org/xmlrpc.php" /> <script type="text/javascript">var _gaq=_gaq||[];_gaq.push(['_setAccount','UA-17652261-1']);_gaq.push(['_trackPageview']);(function(){var ga=document.createElement('script');ga.type='text/javascript';ga.async=true;ga.src=('https:'==document.location.protocol?'https://ssl':'http://www')+'.google-analytics.com/ga.js';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(ga,s);})();</script> <link |
||||
rel='stylesheet' id='fancybox-css' href='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancybox/jquery.fancybox-1.3.4.css?ver=1.3.4' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='fancybox-ie-fix-css' href='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancybox/jquery.fancybox-1.3.4.css-png-fix.php?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='fancy-gallery-css' href='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancy-gallery.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='gsc_style-css' href='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/css/smoothness/jquery-ui-1.7.3.custom.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='gsc_style_search_bar-css' href='http://www.google.com/cse/style/look/minimalist.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='gsc_style_search_bar_more-css' href='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/css/gsc.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='gsc_style_search_bar_even_more-css' href='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/css/gsc-no-search-button.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='toc_css-css' href='http://jmonkeyengine.org/wp-content/plugins/seo-friendly-table-of-contents/style.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='bpgc_screen-css' href='http://jmonkeyengine.org/wp-content/plugins/bp-group-control/css/screen.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='tabbed-widgets-css' href='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/css/tabbed-widgets.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='bp-post-buttons-css-css' href='http://jmonkeyengine.org/wp-content/plugins/bp-post-buttons/include/style/bp_post_buttons.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='bubbleSheets-css' href='http://jmonkeyengine.org/wp-content/plugins/cd-bp-avatar-bubble/_inc/css/css3/bubble-green.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='wp_dlmp_styles-css' href='http://jmonkeyengine.org/wp-content/plugins/download-monitor/page-addon/styles.css?ver=3.1' type='text/css' media='all' /><link |
||||
rel='stylesheet' id='activity-subscription-style-css' href='http://jmonkeyengine.org/wp-content/plugins/buddypress-group-email-subscription/css/bp-activity-subscription-css.css?ver=3.1' type='text/css' media='all' /> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/l10n.js?ver=20101110'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/emailprotect/EMAILProtect.js?ver=0.8'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/jquery.js?ver=1.4.4'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancybox/jquery.fancybox-1.3.4.pack.js?ver=1.3.4'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/jquery.easing.1.3.js?ver=1.3'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/jquery.mousewheel-3.0.4.pack.js?ver=3.0.4'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancy-js.php?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/js/gsc.js?ver=3.1'></script> <script type='text/javascript' src='http://www.google.com/jsapi?ver=3.1'></script> <script type='text/javascript'>var BP_DTheme={my_favs:"My Favorites",accepted:"Accepted",rejected:"Rejected",show_all_comments:"Show all comments for this thread",show_all:"Show all",comments:"comments",close:"Close",mention_explain:"@ is a unique identifier for that you can type into any message on this site. will be sent a notification and a link to your message any time you use it."};</script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/global.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/bp-group-control/js/screen.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/bp-post-buttons/include/js/insert_tags.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/buddypress-group-tags/group-tags.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/cd-bp-avatar-bubble/_inc/bubble-click.js?ver=3.1'></script> <link |
||||
rel="EditURI" type="application/rsd+xml" title="RSD" href="http://jmonkeyengine.org/xmlrpc.php?rsd" /><link |
||||
rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://jmonkeyengine.org/wp-includes/wlwmanifest.xml" /><link |
||||
rel='index' title='jMonkeyEngine.org' href='http://jmonkeyengine.org/' /><meta |
||||
name="generator" content="WordPress 3.1" /><link |
||||
rel="stylesheet" type="text/css" href="http://jmonkeyengine.org/wp-content/plugins/buddypress-better-pagination/pagination.css" media="screen" /><link |
||||
rel="stylesheet" type="text/css" href="http://jmonkeyengine.org/wp-content/plugins/buddypress-group-tags/group-tags.css" media="screen" /><link |
||||
rel="stylesheet" type="text/css" href="http://jmonkeyengine.org/wp-content/plugins/buddypress-rate-forum-posts/css/rating.css" media="screen" /> <script type="text/javascript">var ajaxurl="http://jmonkeyengine.org/wp-load.php";</script> <script type="text/javascript">var ajax_url="http://jmonkeyengine.org/wp-admin/admin-ajax.php";var ajax_image="http://jmonkeyengine.org/wp-content/plugins/cd-bp-avatar-bubble/_inc/images";var ajax_delay="0";</script> <meta |
||||
name="generator" content="DokuWiki Release 2009-02-14b" /><meta |
||||
name="robots" content="noindex,follow" /><meta |
||||
name="date" content="1970-01-01T00:00:00+0000" /><meta |
||||
name="keywords" content="jme3,intermediate,my_first_game" /><link |
||||
rel="search" type="application/opensearchdescription+xml" href="/wiki/lib/exe/opensearch.php" title="jMonkeyEngine.org" /><link |
||||
rel="start" href="/wiki/" /><link |
||||
rel="contents" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=index" title="Index" /><link |
||||
rel="alternate" type="application/rss+xml" title="Recent Changes" href="/wiki/feed.php" /><link |
||||
rel="alternate" type="application/rss+xml" title="Current Namespace" href="/wiki/feed.php?mode=list&ns=jme3:intermediate" /><link |
||||
rel="alternate" type="text/html" title="Plain HTML" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=export_xhtml" /><link |
||||
rel="alternate" type="text/plain" title="Wiki Markup" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=export_raw" /><link |
||||
rel="stylesheet" media="all" type="text/css" href="/wiki/lib/exe/css.php?s=all&t=wp-integration" /><link |
||||
rel="stylesheet" media="screen" type="text/css" href="/wiki/lib/exe/css.php?t=wp-integration" /><link |
||||
rel="stylesheet" media="print" type="text/css" href="/wiki/lib/exe/css.php?s=print&t=wp-integration" /> <script type="text/javascript" charset="utf-8" src="/wiki/lib/exe/js.php?edit=0&write=0" ></script> <style type="text/css">#header{background-image:url(http://jmonkeyengine.org/wp-content/uploads/2010/09/header-new-31.gif)}#header h1, #header |
||||
#desc{display:none}</style><meta |
||||
id="syntaxhighlighteranchor" name="syntaxhighlighter-version" content="3.1.1" /> <script type="text/javascript">jQuery(document).ready(function(){jQuery("a.confirm").click(function(){if(confirm('Are you sure?'))return true;else return false;});});</script> </head><body |
||||
class=""><div |
||||
id="header"><h1><a |
||||
href="http://jmonkeyengine.org" title="Home">jMonkeyEngine.org</a></h1><div |
||||
id="search-bar"><div |
||||
id="custom-search"><form |
||||
action="http://jmonkeyengine.org/search" method="post"> <input |
||||
type="text" id="search-terms" name="search-terms" value="" /> <select |
||||
name="search-which"><option |
||||
value="wiki">Wiki</option><option |
||||
value="forums">Forums</option><option |
||||
value="posts">Blog</option><option |
||||
value="groups">Groups</option><option |
||||
value="members">Members</option><option |
||||
value="links">Links</option></select> <input |
||||
type="submit" name="search-submit" id="search-submit" value="Search" /> <input |
||||
type="hidden" id="_wpnonce" name="_wpnonce" value="401c23b197" /><input |
||||
type="hidden" name="_wp_http_referer" value="/com/jme3/gde/core/docs/jme3/intermediate/my_first_game.html" /></form></div></div><div |
||||
id="access"><ul |
||||
id="menu-mainmenu"><li |
||||
id="menu-item-688"><a |
||||
href="http://jmonkeyengine.org/">Home</a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-1698"><a |
||||
href="http://jmonkeyengine.org/">News</a></li><li |
||||
id="menu-item-705"><a |
||||
href="http://jmonkeyengine.org/news-archives/">News Archives</a></li><li |
||||
id="menu-item-437"><a |
||||
href="http://jmonkeyengine.org/activity/">Activity</a></li><li |
||||
id="menu-item-641"><a |
||||
href="http://jmonkeyengine.org/members/">Members</a></li><li |
||||
id="menu-item-474"><a |
||||
href="http://jmonkeyengine.org/legacy-links/">Links</a></li></ul></li><li |
||||
id="menu-item-696"><a |
||||
href="http://jmonkeyengine.org/introduction/">Introduction</a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-1697"><a |
||||
href="http://jmonkeyengine.org/introduction/">About</a></li><li |
||||
id="menu-item-944"><a |
||||
href="http://jmonkeyengine.org/introduction/website-manual/">Website Manual</a></li><li |
||||
id="menu-item-706"><a |
||||
href="http://jmonkeyengine.org/introduction/team/">Core Team</a></li><li |
||||
id="menu-item-1142"><a |
||||
href="http://jmonkeyengine.org/introduction/contributors-handbook/">Contributor’s Handbook</a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-1140"><a |
||||
href="http://jmonkeyengine.org/introduction/contributors-handbook/anyones-contribution-guidelines/">Anyone’s Contribution Guidelines</a></li><li |
||||
id="menu-item-1141"><a |
||||
href="http://jmonkeyengine.org/introduction/contributors-handbook/modelers-contribution-guidelines/">Modeler’s Contribution Guidelines</a></li><li |
||||
id="menu-item-1138"><a |
||||
href="http://jmonkeyengine.org/introduction/contributors-handbook/web-developers-contribution-guidelines/">Web Developer’s Contribution Guidelines</a></li><li |
||||
id="menu-item-1137"><a |
||||
href="http://jmonkeyengine.org/introduction/contributors-handbook/technical-writers-contribution-guidelines/">Technical Writer’s Contribution Guidelines</a></li><li |
||||
id="menu-item-1139"><a |
||||
href="http://jmonkeyengine.org/introduction/contributors-handbook/programmers-contribution-guidelines/">Programmer’s Contribution Guidelines</a></li></ul></li><li |
||||
id="menu-item-470"><a |
||||
href="http://jmonkeyengine.com">Product Showcase</a></li></ul></li><li |
||||
id="menu-item-693"><a |
||||
href="http://jmonkeyengine.org/forums">Forums</a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-473"><a |
||||
href="http://jmonkeyengine.org/forums">Latest Topics</a></li><li |
||||
id="menu-item-513"><a |
||||
href="http://jmonkeyengine.org/forums-index">All Categories</a></li><li |
||||
id="menu-item-330"><a |
||||
href="#">Troubleshooting ></a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-331"><a |
||||
href="http://jmonkeyengine.org/groups/general-2/forum/">General</a></li><li |
||||
id="menu-item-819"><a |
||||
href="http://jmonkeyengine.org/groups/import-assets/forum/">Import Assets</a></li><li |
||||
id="menu-item-332"><a |
||||
href="http://jmonkeyengine.org/groups/graphics/forum/">Graphics</a></li><li |
||||
id="menu-item-333"><a |
||||
href="http://jmonkeyengine.org/groups/effects/forum/">Effects</a></li><li |
||||
id="menu-item-334"><a |
||||
href="http://jmonkeyengine.org/groups/gui/forum/">GUI</a></li><li |
||||
id="menu-item-336"><a |
||||
href="http://jmonkeyengine.org/groups/physics/forum/">Physics</a></li><li |
||||
id="menu-item-338"><a |
||||
href="http://jmonkeyengine.org/groups/sound/forum/">Sound</a></li><li |
||||
id="menu-item-339"><a |
||||
href="http://jmonkeyengine.org/groups/networking/forum/">Networking</a></li><li |
||||
id="menu-item-690"><a |
||||
href="http://jmonkeyengine.org/groups/spidermonkey/forum/">SpiderMonkey</a></li><li |
||||
id="menu-item-689"><a |
||||
href="http://jmonkeyengine.org/groups/terramonkey/forum/">TerraMonkey</a></li><li |
||||
id="menu-item-360"><a |
||||
href="http://jmonkeyengine.org/groups/jmonkeyplatform/forum/">jMonkeyPlatform</a></li></ul></li><li |
||||
id="menu-item-345"><a |
||||
href="#">Project Relations ></a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-346"><a |
||||
href="http://jmonkeyengine.org/groups/free-announcements/forum/">Free Announcements</a></li><li |
||||
id="menu-item-347"><a |
||||
href="http://jmonkeyengine.org/groups/user-code-projects/forum/">User Code & Projects</a></li><li |
||||
id="menu-item-352"><a |
||||
href="http://jmonkeyengine.org/groups/site-project/forum/">Site & Project Feedback</a></li><li |
||||
id="menu-item-354"><a |
||||
href="http://jmonkeyengine.org/groups/features/forum/">Feature Discussion</a></li><li |
||||
id="menu-item-348"><a |
||||
href="http://jmonkeyengine.org/groups/general/forum/">Small Talk</a></li></ul></li><li |
||||
id="menu-item-340"><a |
||||
href="#">Development ></a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-343"><a |
||||
href="http://jmonkeyengine.org/groups/development-discussion-jme3/forum/">Developers Discussion</a></li><li |
||||
id="menu-item-344"><a |
||||
href="http://jmonkeyengine.org/groups/contribution-depot-jme3/forum/">Contributions</a></li><li |
||||
id="menu-item-710"><a |
||||
href="http://jmonkeyengine.org/groups/documentation-jme3/">Docs Discussion</a></li><li |
||||
id="menu-item-349"><a |
||||
href="http://jmonkeyengine.org/groups/jmonkeyplatform/forum/">jMonkeyPlatform</a></li><li |
||||
id="menu-item-350"><a |
||||
href="http://jmonkeyengine.org/groups/android/forum/">Android</a></li><li |
||||
id="menu-item-1475"><a |
||||
href="http://jmonkeyengine.org/groups/monkeyzone/forum/">MonkeyZone</a></li></ul></li><li |
||||
id="menu-item-699"><a |
||||
href="#">Legacy jME2 ></a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-341"><a |
||||
href="http://jmonkeyengine.org/groups/development-discussion-jme2/forum/">Discussion</a></li><li |
||||
id="menu-item-342"><a |
||||
href="http://jmonkeyengine.org/groups/contribution-depot-jme2/forum/">Contributions</a></li><li |
||||
id="menu-item-353"><a |
||||
href="http://jmonkeyengine.org/groups/documentation/forum/">Docs Discussion</a></li></ul></li></ul></li><li |
||||
id="menu-item-351"><a |
||||
href="http://jmonkeyengine.org/wiki/doku.php">Documentation</a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-1671"><a |
||||
href="http://jmonkeyengine.org/wiki/doku.php">Installation & Setup</a></li><li |
||||
id="menu-item-1672"><a |
||||
href="http://jmonkeyengine.org/wiki/doku.php/jme3#tutorials_for_beginners">Tutorials & Docs</a></li><li |
||||
id="menu-item-1673"><a |
||||
href="http://jmonkeyengine.org/wiki/doku.php/sdk">SDK Documentation</a></li><li |
||||
id="menu-item-1674"><a |
||||
href="http://jmonkeyengine.org/javadoc/">JavaDoc</a></li><li |
||||
id="menu-item-1675"><a |
||||
href="http://jmonkeyengine.org/groups/documentation-jme3/forum/">Docs Discussion</a></li></ul></li><li |
||||
id="menu-item-319"><a |
||||
href="http://jmonkeyengine.org/groups/tag/projects">Projects</a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-1699"><a |
||||
href="http://jmonkeyengine.org/groups/tag/projects">All Projects</a></li><li |
||||
id="menu-item-320"><a |
||||
href="http://jmonkeyengine.org/groups/tag/game">Games</a></li><li |
||||
id="menu-item-1117"><a |
||||
href="http://jmonkeyengine.org/groups/tag/tool">Tools</a></li><li |
||||
id="menu-item-323"><a |
||||
href="http://jmonkeyengine.org/groups/tag/oss">Open Source</a></li></ul></li><li |
||||
id="menu-item-717"><a |
||||
href="http://jmonkeyengine.org/downloads/">Downloads</a><ul |
||||
class="sub-menu"><li |
||||
id="menu-item-1695"><a |
||||
href="http://jmonkeyengine.org/downloads/">Download jME3 SDK</a></li><li |
||||
id="menu-item-464"><a |
||||
href="http://code.google.com/p/jmonkeyengine/source/checkout">SVN Checkout</a></li><li |
||||
id="menu-item-697"><a |
||||
href="http://code.google.com/p/jmonkeyengine/">GoogleCode</a></li><li |
||||
id="menu-item-463"><a |
||||
href="http://jmonkeyengine.com/nightly/">Nightly Builds</a></li></ul></li></ul></div></div><div |
||||
id="container"><div |
||||
class="dokuwiki"><div |
||||
class="stylehead"><div |
||||
class="breadcrumbs"> <span |
||||
class="bchead">You are here: </span><a |
||||
href="/wiki/doku.php/Documentation" title="Documentation">Documentation</a> » <a |
||||
href="/wiki/doku.php/jme3" title="jme3">jme3</a> » <a |
||||
href="/wiki/doku.php/jme3:intermediate:documentation" title="jme3:intermediate:documentation">intermediate</a> » <a |
||||
href="/wiki/doku.php/jme3:intermediate:my_first_game" title="jme3:intermediate:my_first_game">my_first_game</a></div></div><div |
||||
class="page"><h1><a |
||||
name="this_topic_does_not_exist_yet">This topic does not exist yet</a></h1><div |
||||
class="level1"><p>You've followed a link to a topic that doesn't exist yet. If permissions allow, you may create it by using the <code>Create this page</code> button.</p></div></div><div |
||||
class="clearer"> </div><div |
||||
class="stylefoot"><div |
||||
class="license">Except where otherwise noted, content on this wiki is licensed under the following license:<a |
||||
href="http://creativecommons.org/licenses/by/3.0/" rel="license">CC Attribution 3.0 Unported</a></div><div |
||||
class="breadcrumbs"> <span |
||||
class="bchead">Trace:</span></div></div></div><div |
||||
class="no"></div></div><div |
||||
id="footer"><p>jMonkeyEngine.org is proudly powered by <a |
||||
href="http://wordpress.org">WordPress</a> and <a |
||||
href="http://buddypress.org">BuddyPress</a></p></div><div |
||||
id="wp-admin-bar"><div |
||||
class="padder"><a |
||||
href="http://jmonkeyengine.org">jMonkeyEngine.org</a><ul |
||||
class="main-nav"><li |
||||
class="bp-login no-arrow"><a |
||||
href="http://jmonkeyengine.org/wp-login.php?redirect_to=http%3A%2F%2Fjmonkeyengine.org">Log In</a></li><li |
||||
class="bp-signup no-arrow"><a |
||||
href="http://jmonkeyengine.org/register">Sign Up</a></li><li |
||||
class="align-right"> <a |
||||
href="#">Visit</a><ul |
||||
class="random-list"><li><a |
||||
href="http://jmonkeyengine.org/members/?random-member">Random Member</a></li><li |
||||
class="alt"><a |
||||
href="http://jmonkeyengine.org/groups/?random-group">Random Group</a></li><li><a |
||||
href="http://jmonkeyengine.org/links/?random-link">Random Link</a></li></ul></li></ul></div></div> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.core.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.widget.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.mouse.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.resizable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.draggable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.button.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.position.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.dialog.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-ui-custom.min.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-cookie.min.js?ver=3.1'></script> <script type="text/javascript">var $rotateoptions=new Array();$rotateoptions[2]=new Array();$rotateoptions[2]["style"]="";$rotateoptions[2]["rotate"]=0;$rotateoptions[2]["random_start"]=0;$rotateoptions[2]["start_tab"]=0;$rotateoptions[2]["interval"]=10000;$rotateoptions[3]=new Array();$rotateoptions[3]["style"]="tabs";$rotateoptions[3]["rotate"]=0;$rotateoptions[3]["random_start"]=0;$rotateoptions[3]["start_tab"]=0;$rotateoptions[3]["interval"]=10000;</script> <script type="text/javascript" src="http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/init-plugin.js"></script> |
||||
<script src="http://stats.wordpress.com/e-201113.js" type="text/javascript"></script> <script type="text/javascript">st_go({blog:'14883676',v:'ext',post:'0'});var load_cmc=function(){linktracker_init(14883676,0,2);};if(typeof addLoadEvent!='undefined')addLoadEvent(load_cmc);else load_cmc();</script> </body></html> |
||||
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/ |
||||
|
||||
Minified using apc |
||||
|
||||
Served from: jmonkeyengine.org @ 2011-03-28 14:38:52 --> |
||||
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:my_first_game?do=export_xhtmlbody">view online version</a></em></p> |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 108 KiB |