There are a lot of built in classes in Android and Java that you can use to avoid having to write any synchronization or lock code yourself. In my case GLSurfaceView sets up my render thread. I use HandlerThread for my game thread. The game thread sends an update object detailing all the draw commands needed for a frame to the render thread via a BlockingQueue. The render thread returns it via the game thread's Handler. The UI thread tells the game thread about input via the game thread's Handler as well. These classes are in the android.os and java.util.concurrent packages.
On Apr 9, 6:36 pm, Eddie Ringle <[email protected]> wrote: > Okay, I figured I could just pass the Activity through parameters, but > wanted to know if a better way was possible. > Thanks for all the help everyone. > > On Apr 9, 5:56 pm, Mario Zechner <[email protected]> wrote: > > > That depends on what kind of input you need. If your game is happy > > with just checking the current state of the accelerometer/touch screen/ > > keyboard/trackball simply polling will do the trick. This means that > > in the UI thread, where you have your event listeners installed, you > > simply save the last state reported to you. In your logic thread you > > can savely access this state even without synchronization as it will > > only be composed of plain old data types like booleans or ints (of > > course there are cases where you catch the x coordinate of the > > previous event and the y coordinate of the current event but i dare > > say that the differences are so tiny, it doesn't make a difference). > > > Other things might need event based input handling, like a GUI you > > implement yourself with say OpenGL. In that case you will need a queue > > that gets filled in the Android GUI thread by the listeners you have > > installed for the input devices. The logic thread acts as a consumer > > and takes the events from the queue. As you are working with a complex > > data structure you need to synchronize the adding and removing of > > events to and from the queue in both the Android GUI thread and your > > logic thread. This is a classical consumer/producer pattern which can > > be found frequently in multithreaded applications. Check out Robert's > > site athttp://www.rbgrn.net, i think he wrote an article on that sort > > of thing once. > > > it basicaly boils down to this (pseudo code, written from the top of > > my head, will not compile) > > > public class GameActivity extends Activity implements > > MotionEventListener > > { > > Queue<Event> events = new Queue<Event>(); > > > public void onTouch( MotionEvent event ) > > { > > synchronized( events ) > > { > > events.add( new Event( event.getX(), event.getY() ); > > } > > } > > > } > > > public class GameLogic > > { > > GameActivity activity; > > > public GameLogic( GameActivity activity ) > > { > > this.activity = activity; > > } > > > public void handleInput( ) > > { > > synchronized( gameActivity.events ) > > { > > // proces events here > > } > > } > > > } > > > Now, a couple of comments: You don't want to instantiate a new Event > > everytime a listener method in the GameActivity is called. You will > > need to implement a simple object pool and reuse events. That way the > > garbage collector will stay calm. Also note that the design above is a > > bit nasty, i would directly pass the GameActivity to the GameLogic > > among other things. But that's up to you. > > > Polling input handling would work like above but without a queue and > > without the need for the synchronized blocks. All you do is set some > > members of GameActivity, say touchX and touchY in the onTouch method > > and read those values in the GameLogic class' handleInput method. > > > hth, > > Mario > > > On 9 Apr., 22:39, Eddie Ringle <[email protected]> wrote: > > > > Robert, > > > > Silly question, but how do you get input to the logic thread? I have > > > to get sensor and touch data from the main Activity class and somehow > > > get it to the logic thread. > > > > Current program flow is as follows: > > > onCreate() -> GameView() -> World() & Renderer() & GameLogic() > > > > On Apr 9, 3:24 pm, Robert Green <[email protected]> wrote: > > > > > Eddie, > > > > > Yes, that'll do the trick. > > > > > As far as the multiple threads goes, sure you can drive your logic off > > > > of the call to onDrawFrame but there is a situation in which having a > > > > separate thread makes sense: > > > > > After onDrawFrame, the rendering thread is finishing/swapping. That > > > > can actually take a decent amount of time to do in certain cases and > > > > most of it is happening on the GPU, especially on a device like the > > > > Droid which has a discrete CPU/GPU. During that time, the CPU is > > > > available and can be used on the logic thread. Properly implemented, > > > > in a heavy scene you can get some or all of the logic processed before > > > > the rendering thread is ready again, which is why I favor it. > > > > > My question is: onDrawFrame is only called once the GPU is ready for > > > > another draw. Why waste those precious GPU idle moments just doing > > > > CPU stuff like physics and collisions? You can maximize with another > > > > thread. > > > > > Also - 2 (game and UI) or 3 threads (game logic, rendering and UI) > > > > does make sense because you never want to block the UI thread in > > > > Android. Get out of its way as fast as possible! :) > > > > > On Apr 9, 1:58 pm, Eddie Ringle <[email protected]> wrote: > > > > > > Is it as simple as: > > > > > > In GameView.java (my custom GLSurfaceView class): > > > > > World _world = new World(); > > > > > > GameRenderer _renderer = new GameRenderer(_world); > > > > > > In GameRenderer.java: > > > > > public World _world; > > > > > > public GameRenderer(World world) > > > > > { > > > > > _world = world; > > > > > > } > > > > > > In GameRenderer.java, _world would now have the address of world, > > > > > which is the address of GameView.java's _world, right? > > > > > > On Apr 9, 2:49 pm, Eddie Ringle <[email protected]> wrote: > > > > > > > One more thing question and I think I will be set. Coming from a > > > > > > C/C++ > > > > > > background, I enjoyed the use of references. I know that there is a > > > > > > way to pass the reference by value in Java, but am not quite clear > > > > > > on > > > > > > how. Could I, for example, create my World object, then pass that > > > > > > object to the renderer and logic objects when I create them? I did a > > > > > > small bit of reading on this topic, but still am not quite sure. > > > > > > > On Apr 9, 1:55 pm, Robert Green <[email protected]> wrote: > > > > > > > > Yeah, you're going to want to model your game like you would > > > > > > > model the > > > > > > > real world: > > > > > > > > class World { > > > > > > > public Player player; > > > > > > > public Enemy[] enemies; > > > > > > > public int timeLeft; > > > > > > > public int level; > > > > > > > //etc.. > > > > > > > > } > > > > > > > > Then you update the world (usually by calls to player.update, > > > > > > > enemy.update, etc) from your logic thread. > > > > > > > > Then what I like to do is separate the rendering stuff from the > > > > > > > simulation so that I have renderers for specific things: > > > > > > > > class PlayerRenderer extends BaseRenderer { > > > > > > > // knows about player geometry, knows how to draw the player and > > > > > > > anything player-related.. > > > > > > > > } > > > > > > > > Then in my main Renderer, I just call out to the individual > > > > > > > component > > > > > > > renderers: > > > > > > > > class WorldRenderer implements Renderer { > > > > > > > onDrawFrame(GL gl) { > > > > > > > // clear, set up projection, etc > > > > > > > playerRenderer.draw(gl, world.player); > > > > > > > enemyRenderer.draw(gl, world.enemies); > > > > > > > // etc.. > > > > > > > } > > > > > > > > } > > > > > > > > And that's how I do it. I have just a little bit of > > > > > > > initialization > > > > > > > communication from the Renderer side to the game logic so that we > > > > > > > can > > > > > > > set up positioning of touchable UI components but otherwise it's > > > > > > > always GameThread updates World, WorldRenderer draws World, > > > > > > > repeat. > > > > > > > > On Apr 9, 11:25 am, Eddie Ringle <[email protected]> wrote: > > > > > > > > > Where do you store all your attributes, like player position? > > > > > > > > Currently I just have a "GLQuad" class that I use to create new > > > > > > > > quads, > > > > > > > > texture them, and manage position and velocity. Do you store > > > > > > > > them in > > > > > > > > World, and then each side can access them from the world object? > > > > > > > > Also, threading is new to me, so I really have no clue what a > > > > > > > > lock is. > > > > > > > > > On Apr 9, 12:03 pm, Robert Green <[email protected]> wrote: > > > > > > > > > > It's pretty easy to do this: > > > > > > > > > > I use a World to write to and read from for the two "sides." > > > > > > > > > Makes > > > > > > > > > networking nice too. My World has a simple lock. Only one > > > > > > > > > thing can > > > > > > > > > write to it or read from it at a time. > > > > > > > > > > in GameLogicThread: > > > > > > > > > > run() { > > > > > > > > > while (!done) { > > > > > > > > > // wait for renderer > > > > > > > > > world.getLock(); // blocks > > > > > > > > > update() > > > > > > > > > world.releaseLock(); > > > > > > > > > } > > > > > > > > > > } > > > > > > > > > > in Renderer: > > > > > > > > > > onDrawFrame() { > > > > > > > > > world.getLock(); // blocks > > > > > > > > > draw() > > > > > > > > > world.releaseLock(); > > > > > > > > > > } > > > > > > > > > > On Apr 9, 3:27 am, Clankrieger <[email protected]> wrote: > > > > > > > > > > > Hi, > > > > > > > > > > > I had a lot of difficulties getting the threading and app > > > > > > > > > > lifecycle > > > > > > > > > > issues done, too. For my part, this was much more confusing > > > > > > > > > > than > > > > > > > > > > getting the actual game done. ;) > > > > > > > > > > > The good thing is: you do not have to do too much for the > > > > > > > > > > render- and > > > > > > > > > > logic-thread separation because most of the rendering time > > > > > > > > > > is getting > > > > > > > > > > spent "outside" of your renderer's onDraw method. This is > > > > > > > > > > how I got > > > > > > > > > > this done: The "Game" itself is owned by the glSurfaceView > > > > > > > > > > renderer > > > > > > > > > > instance. the when the game starts (at onResume), I start an > > > > > > > > > > updatethread that is very simple an does something like > > > > > > > > > > > while(bKeeprunning) { > > > > > > > > > > synchronized(Game.sInstance) { > > > > > > > > > > Game.sInstance.update(); > > > > > > > > > > } > > > > > > > > > > Thread.sleep(50); > > > > > > > > > > > } > > > > > > > > > > > I have to add that my game logic is doing only this: logic. > > > > > > > > > > The world > > ... > > read more » -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en To unsubscribe, reply using "remove me" as the subject.

