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 > > > > > > > > > gets simulated. This is done less than 10 times per second - > > > > > > > > > this is > > > > > > > > > why I can have it sleep for 50 ms. sleeping is important here > > > > > > > > > to give > > > > > > > > > the render thread time to do this (I don't remember the full > > > > > > > > > method > > > > > > > > > signature, but I think you know what I mean): > > > > > > > > > > onDrawGlFrame() { > > > > > > > > > synchronized(Game.sInstance) { > > > > > > > > > Game.sInstance.render(); > > > > > > > > > } > > > > > > > > > Thread.sleep(5); > > > > > > > > > > } > > > > > > > > > > I defined the updatethread as class inside of the Renderer > > > > > > > > > because it > > > > > > > > > is so small. This gave me a huge performance boost. > > ... > > 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.

