2D tutorial

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

Postby gazy » Thu Jun 25, 2009 12:20 pm

Finally I can post a reply, I must say registering for this for is a PITA!.. ok im in.

Ive used this template from mr snowflake to make a couple of apps and it works well once you start bolting things onto it. I have discovered an odd error though, if you add a frames per second counter, youll see it prob runs about 60fps, BUT if you press the "menu key" and the menu comes up youll observe the SOMETIMES the FPS drops to about 45. Im having this problem with all of my apps since they were all based on this template, they run fast and smooth but then now and again pressing the menu key to get the menu up and then just dismissing it with another press will severely hamper the performance of the surface view - it starts to drag noticably - im tearing my hair out badly over this one so if anyone has any clues please please throw them my way!!

Thanks for the excellent template it has REALLY speeded up my deving, is there any new and updated one with more issues ironed out possibly? I cant use it til my next project but it would be good to know the source of this nasty showstopper :(

Gaz
gazy
Freshman
Freshman
 
Posts: 2
Joined: Thu Jun 25, 2009 12:12 pm

Top

Postby WarrenFaith » Thu Jun 25, 2009 3:28 pm

I dont use this template, but I can just guess something like stop or pause of the application or some synchronizing could be the reason for your fps drop.

I don't know how you implemented your game loop but my game loop works with 20 game updates per second and as much frames as possible. In my case a drop of fps wouldn't result in lagging on game logic, just on drawing....
WarrenFaith
Moderator
Moderator
 
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby gazy » Thu Jun 25, 2009 4:41 pm

Yeah I have searched for as many solutions as I can but cant find one - i simply cannot see why bringing up the menu would slow everything down so badly :(
gazy
Freshman
Freshman
 
Posts: 2
Joined: Thu Jun 25, 2009 12:12 pm

Thanks.

Postby rbginsburg » Thu Jul 02, 2009 5:46 am

This template really helped me jump into Android programming.

Thanks MrSnowflake.

Does anyone know why the snowflake won't move initially on start? It always take 1 button press then on the second button press, the character will move. Any ideas?
rbginsburg
Once Poster
Once Poster
 
Posts: 1
Joined: Sun Jun 28, 2009 5:38 pm
Location: Miami, FL

Re: Is LunarLander buggy?

Postby Andrex » Sat Jul 11, 2009 8:15 am

a_droid wrote:Hi!

It seems to me that the LunarLander example has a serious bug (or I'm seriously stupid :) ):

If you press the home button, then you try to go back to the application (on a real G1 with the latest software), it will tell you that LunarLander has stopped unexpectedly.

The reason I've found:
- It creates the thread on the View's create.
- It destroys the thread (tells the thread to stop and waits for it to exit) on surface destroy.
- Android won't destroy/recreate your view on pressing the home button (going to the home screen and back)
- Android destroys the surface and creates the surface on pressing the home button (going to the home screen and back)

All this breaks one rule: It tries to restart a thread with an exited run() loop. ..and it gives you this error.

So, in my app, I've moved the creation/starting of the thread into the surface's code.
This way I'm always re-creating the thread after I destroy it (at the surface's destroy, like in the original code).

I hope this helps someone ;)


Could you (or someone else familiar) please elaborate? Where in the surface's code did you move it? Where do you destroy the thread?

This is a pretty serious bug that Google let slip, and found its way into this engine.
Andrex
Junior Developer
Junior Developer
 
Posts: 18
Joined: Mon Apr 07, 2008 5:40 am

Postby Shaka » Fri Sep 18, 2009 5:58 am

I moved the thread creation code to the surfaceCreated event, and it worked fine after that.
Shaka
Developer
Developer
 
Posts: 44
Joined: Fri Aug 28, 2009 3:01 pm

Top

Postby HectorSavage » Fri Sep 18, 2009 3:04 pm

Shaka wrote:I moved the thread creation code to the surfaceCreated event, and it worked fine after that.


can you please share the code of your surfaceCreated method? this would be really helpful!


edit: OK, i got it. thank you for your help. now it works fine. ignore my pm ;)
HectorSavage
Freshman
Freshman
 
Posts: 5
Joined: Mon Sep 07, 2009 2:08 pm

Postby Shaka » Sat Sep 19, 2009 12:14 pm

HectorSavage wrote:
Shaka wrote:I moved the thread creation code to the surfaceCreated event, and it worked fine after that.


can you please share the code of your surfaceCreated method? this would be really helpful!


edit: OK, i got it. thank you for your help. now it works fine. ignore my pm ;)


Cool! :) I'm creating my own engine so I haven't used this template but I did run into the same problem and I guess the solution is the same for both implementations.
Shaka
Developer
Developer
 
Posts: 44
Joined: Fri Aug 28, 2009 3:01 pm

Postby Amoeba » Wed Sep 30, 2009 5:39 am

I was looking at this code that was posted earlier...
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. ...
  2.     private synchronized void doDraw(Canvas canvas, Paint paint)
  3.     {
  4.         if(start)
  5.                 {
  6.                         canvas.drawColor(Color.BLACK);
  7.                         canvas.drawBitmap(scratch,10,10,paint);
  8.                         start = false;
  9.                 }
  10.                 else
  11.                 {              
  12.                 canvas.save();
  13.                 canvas.clipRect(box,8,box+32,40);              
  14.                 canvas.drawColor(Color.RED);
  15.                 // canvas.drawBitmap(scratch,box,10,paint);
  16.                 canvas.restore();              
  17.                 }
  18.     }
  19. ...    
  20.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


Is there a way to make it so it doesn't clear the screen? Instead of redrawing everything every frame I want to keep adding stuff for every frame, or updating only things that have changed.
Amoeba
Once Poster
Once Poster
 
Posts: 1
Joined: Wed Sep 30, 2009 5:34 am

Postby edzillion » Mon Oct 19, 2009 2:38 pm

**Edit: deleted project and restarted, works fine now thanks. Still interested in whether you have finished the updated version - I am interested to see a version that has the thread in it's own file.

mrsnowflake

Did you finish your updated version of gametemplate?
I am having a lot of trouble getting this working; keep getting force close. I am new to this so bear with me: the first thing I notice is that your directory structure is diff from mine, the R.java file is in the src folder but eclipse puts it in the gen folder, so I moved that and then built project (at sdk 1.5) and run as android app.

I get a force close straight away. If I close that and then check the apps menu there is an entry for game template but it goes straight to force close if I run that.

Any ideas?

TIA
Ed
edzillion
Junior Developer
Junior Developer
 
Posts: 17
Joined: Fri Oct 16, 2009 8:48 pm

Postby 3m3r1c » Mon Oct 19, 2009 9:41 pm

then, somebody have a solution to quit an game ?
because when I leave the game I put mRun at false but the activity isn't destroy. And when I'm going into develloperTool(into emulator) i can see the process of my game still processing.
The finish() method of activity don't give a good result too.

I want that user could leave the game correctly

I try that into my activity, but that don't works. Any ideas ?

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public boolean onOptionsItemSelected(MenuItem item) {
  2.  
  3.         switch (item.getItemId()) {
  4.  
  5.         case MENU_EXIT:
  6.  
  7.                 myThread.setState(MyThread.STATE_EXIT); <span style="color: green"> //=>setRunning(false)</span>
  8.  
  9.                 this.finish();
  10.  
  11.                 return true;
  12.  
  13.          case MENU_START:
  14.  
  15.                myThread.doStart();
  16.  
  17.                         return true;
  18.  
  19.                 case MENU_PAUSE:
  20.  
  21.                         myThread.pause();
  22.  
  23.                         return true;
  24.  
  25.                 case MENU_RESUME:
  26.  
  27.                         myThread.unpause();
  28.  
  29.                         return true;
  30.  
  31.                 }
  32.  
  33.  
  34.  
  35.                 return false;
  36.  
  37.     }
Parsed in 0.033 seconds, using GeSHi 1.0.8.4


(sorry for my english)
3m3r1c
Freshman
Freshman
 
Posts: 9
Joined: Fri Sep 18, 2009 1:39 pm

Postby BrutoJPO » Wed Oct 28, 2009 2:11 pm

Hey guys, to destroy an app you only need to call the finish() method from the Activity class. I did like this and worked well:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.       if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
  4.  
  5.      {
  6.  
  7.           finish();
  8.  
  9.      }
  10.  
  11.      
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


You can assign a keyboard key to be the exit of your application, this sound simple but can be very effective, since finish() clean the current Activity from the Activity stack and memory system.

John Peter
BrutoJPO
Junior Developer
Junior Developer
 
Posts: 10
Joined: Wed Oct 21, 2009 7:41 pm
Location: Brazil

Postby 3m3r1c » Thu Oct 29, 2009 5:15 pm

BrutoJPO :
When I do that into my menu EXIT (After close the thread) in my Activity

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. case MENU_EXIT:
  2.  
  3.                myThread.setState(MyThread.STATE_EXIT);
  4.  
  5.                this.finish();
  6.  
  7.                return true;
Parsed in 0.035 seconds, using GeSHi 1.0.8.4



The application still running and I can find it into Setting -> Application -> Manage applications
I need Force close to closing properly.
Now I'm on Device and it the same problem even with LunarLander example
3m3r1c
Freshman
Freshman
 
Posts: 9
Joined: Fri Sep 18, 2009 1:39 pm

Postby todd3g » Wed Dec 16, 2009 3:07 pm

http://hatsukiakio.blogspot.com/2009/06 ... on-in.html

2009年6月7日星期日
IllegalThreadStateException in LunarLander
在實驗LunarLander 的時後,如果在run LunarLander的途中,按下Home跳出
而不是按下return的話,此時在進入LunarLander,就會跑出 IllegalThreadStateException這樣的例外


稍微研究了一下這個原因


首先看一下這張圖,綠色框起來是Return,藍色框起來是Home
比較這兩鍵按下去返回主選單在回去遊戲的不同

Return生命週期變化
onCreate->onStart->onResume->按下Retuen->onPause->onStop->onDestroy->回到LunarLander->onCreate->onStart->onResume


Home生命週期變化
onCreate->onStart->onResume->按下Home->onPause->onStop->回到LunarLander->onRestart->onStart->onResume

上面的比較可以發現,按下Return的時候,整個Activity會依照正常程序Destroy在Create
但是按下Home回到主選單的時候Activity不會Destroy掉,他的資料仍然會存在記憶體,之後只是Restart他

而LunarLander遊戲設計是假設SurfaceView的生命週期跟Activity一致,在Activity的Create跟Destroy這段期間,只會發生一次的surfaceCreate跟surfaceDestroy

來觀察一下按下Home的時候,SurfaceView的生命週期
onCreate->onStart->onResumeonWindowFocusChanged->surfaceCreated->surfaceChanged->按下Home->onPause->surfaceDestroyed->onWindowFocusChanged->onStop->回到LunarLander->onRestart->onStart->onResume->surfaceCreated->surfaceChanged->onWindowFocusChanged

就像上面所示,因為Activity沒有照正常程序被Destroy掉
而在Activity的create跟destroy之間,SurfaceView的create跟Destroy執行了超過一次以上,這是沒有在當出遊戲設計者的預料之中,所以會發生IllegalThreadStateException這個例外而不能執行的Bug

而IllegalThreadStateException是怎麼發生的呢?
先來看他的定義
Thrown when an operation is attempted which is not possible given the state that the executing thread is in.
也就是試圖從相同的程序中start相同的Thread
舉個例子
Thread t=new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub}});t.start();t.start();//start兩次,拋出IllegalThreadStateException
而要避開這例外,必須使用新的Thread
Thread t=new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub}});t.start();t=new Thread(..........);t.start();


而在Lunar,IllegalThreadStateException是從LunarView的surfaceCreated中拋出來的
/* * Callback invoked when the Surface has been created and is ready to be * used. */public void surfaceCreated(SurfaceHolder holder) {....thread.start();//由此函式拋出IllegalThreadStateException }
如上面所示,因為surfaceCreated在Activity執行了兩次以上的話,相同的thread就會start兩次以上,thread的產生是在Activity的onCreate呼叫建構式LunarView時誕生,所以只會被產生一次
public LunarView(Context context, AttributeSet attrs) {....thread = new LunarThread(holder, _context, new Handler() { @Override public void handleMessage(Message m) { mStatusText.setVisibility(m.getData().getInt("viz")); mStatusText.setText(m.getData().getString("text")); }});....}
在此我提出一個暴力法的解決方案解決這Bug,就是在surfaceCreated的時候就產生一個新的LunarThread,這樣可以避免同樣的thread被start兩次以上,不過我沒做State的Retore,所以他就跟按下Return一樣是從新開始一個遊戲

我的作法就是讓LunarThread的生命週期跟Surface一致

surfaceCreated:產生LunarThread
surfaceDestroyed:消滅LunarThread


修改方法如下,粗體是我新增的程式碼
surfaceCreated
public void surfaceCreated(SurfaceHolder holder) {/*判斷thread是否為null,是的話產生新的Thread*/ if (thread == null) {/*把建構式創造thread的程式碼copy過來,記得建構式保持原樣就好,不須要更改*/ thread = new LunarThread(holder, _context, new Handler() { @Override public void handleMessage(Message m) { mStatusText.setVisibility(m.getData().getInt("viz")); mStatusText.setText(m.getData().getString("text")); } }); setFocusable(true);/*這邊是跟建構式不同的地方,因為按下Home的時候,會改變thread的狀態在這邊要手動把狀態設置為ready來讓keyEvent能正常動作*/ thread.setState(LunarThread.STATE_READY);}thread.setRunning(true);thread.start();}

surfaceDestroyed
public void surfaceDestroyed(SurfaceHolder holder) {boolean retry = true;thread.setRunning(false);while (retry) { try { thread.join(); retry = false; } catch (InterruptedException e) { } }/*在此把thread設為null消滅現有的thread這邊是為了配合surfaceCreated的if(thread==null)*/ thread=null;}

onWindowFocusChanged
public void onWindowFocusChanged(boolean hasWindowFocus) { if (!hasWindowFocus) {/*surfaceDestroy發生後會在發生 onWindowFocusChanged事件 因為thread已經被設為null了所以不能在執行函式動作 這也是為什麼surfaceCreated要手動設置Ready */ if(thread!=null) thread.pause(); }}
以上,改完就大功告成了
--------------------
更好的解決方案
在建構式ListView的時候創造跟啟動執行緒(相較於在surfaceCreate啟動執行緒)
創造一個lock的物件
而在surfaceCreate的時候使用notify跟restore
在surfaceDestroy的時候使用wait跟相關儲存動作
創造一個函式destroyGame()真正跳出整個遊戲,只有在Activity的onDestroy去呼叫他(相較於在surfaceDestroy結束執行緒)

不過我沒有去真正實作上面的方案,只是構想,不過因該是八九不離十
todd3g
Once Poster
Once Poster
 
Posts: 1
Joined: Wed Dec 16, 2009 2:58 pm

Re: 2D tutorial

Postby namrathu1 » Mon May 31, 2010 12:33 pm

I tried the GameTemplate.zip. It just displays the icon and the icon doesn't move.
Please let me know if I'm doing something wrong.

Thanks & Regards.
namrathu1
Freshman
Freshman
 
Posts: 5
Joined: Fri May 28, 2010 9:33 am

Top
PreviousNext

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests