Stark bemerkbare Verzögerung

  • Antworten:2
Toom
  • Forum-Beiträge: 2

01.05.2013, 22:06:22 via Website

Hallo zsm. erstmal. Ich hoffe ich bin hier richtig, wenn ich etwas Hilfe beim Einstieg in die Programmierung von Java-apps suche. :)


Nun zu meinem Problem. Falls es schon einen Thread darüber gibt, bitte verlinken.
Der Spieler bewegt sich in dem kleinem Prog. , allerdings erst nach einer kurzen Verzögerung ( ca. 2 Sek auf dem Emulator | 1 Sek auf meinem S3 ).
Wie kann ich die Verzögerung verringern, bzw. entfernen?

EDIT: Denke mal, dass das Problem in der Methode
1@Override
2 public boolean onTouchEvent(MotionEvent event) {
3 synchronized (getHolder()) {
4
5 System.out.println("###########################");
6 player.changePosition((int)Math.floor(event.getY()/80), (int)Math.floor(event.getY()/80));
7 }
8 return true;
9 }
steckt. Einer eine Idee?

1import android.content.Context;
2import android.graphics.Bitmap;
3import android.graphics.BitmapFactory;
4import android.graphics.Canvas;
5import android.graphics.Color;
6import android.graphics.Paint;
7import android.view.MotionEvent;
8import android.view.SurfaceHolder;
9import android.view.SurfaceView;
10import android.view.WindowManager;
11
12public class GameView extends SurfaceView {
13
14 private SurfaceHolder surfaceHolder;
15 private GameLoopThread theGameLoopThread;
16 private long lastFrame;
17 private long thisFrame;
18 private float tslf;
19 private Tile[][] tile = new Tile[16][9];
20 private Player player = new Player(5,5,1);
21 boolean start = true;
22
23
24
25
26 public GameView(Context context,WindowManager wm) {
27 super(context);
28
29 surfaceHolder = getHolder();
30 theGameLoopThread = new GameLoopThread(this);
31 surfaceHolder.addCallback(new SurfaceHolder.Callback() {
32
33 public void surfaceDestroyed(SurfaceHolder holder) {
34 boolean retry = true;
35 theGameLoopThread.setRunning(false);
36 while(retry){
37 try {
38 theGameLoopThread.join();
39 retry=false;
40 }catch(InterruptedException e){
41
42 }
43 }
44 }
45 public void surfaceCreated(SurfaceHolder holder) {
46 lastFrame = System.currentTimeMillis();
47 theGameLoopThread.setRunning(true);
48 theGameLoopThread.start();
49 }
50 public void surfaceChanged(SurfaceHolder holder, int format,
51 int width, int height) {
52
53 }
54 });
55
56
57 for(int x=0;x<16;x++)
58 {
59 for(int y=0;y<9;y++)
60 {
61 tile[x][y] = new Tile(x,y,0,80);
62 }
63 }
64
65
66 }
67
68
69 @Override
70 public boolean onTouchEvent(MotionEvent event) {
71 synchronized (getHolder()) {
72
73 System.out.println("###########################");
74 player.changePosition((int)Math.floor(event.getY()/80), (int)Math.floor(event.getY()/80));
75 }
76 return true;
77 }
78
79
80 public void update()
81 {
82 thisFrame = System.currentTimeMillis();
83 tslf = (float)(lastFrame-thisFrame)/1000f;
84 lastFrame = thisFrame;
85 }
86
87 @Override
88 protected void onDraw(Canvas canvas) {
89 canvas.drawColor(Color.RED);
90
91 for(int x = 0;x<16;x++)
92 {
93 for(int y = 0; y<9;y++)
94 {
95 Bitmap bmp = getSprite(tile[x][y].getType());
96
97
98 canvas.drawBitmap(bmp, x*tile[x][y].getSize(),y*tile[x][y].getSize(),null);
99
100 }
101 }
102
103
104 canvas.drawBitmap(getSprite(player.getType()),player.getX()*80,player.getY()*80,null);
105
106
107 Paint paint = new Paint();
108 paint.setColor(Color.WHITE);
109 //canvas.drawText(""+this.getWidth()+" "+this.getHeight(), 20, 30, paint);
110
111 }
112
113
114
115public Bitmap getSprite(int type)
116{
117 switch(type)
118 {
119 case 0:
120 return BitmapFactory.decodeResource(getResources(),R.drawable.grass);
121 case 1:
122 return BitmapFactory.decodeResource(getResources(),R.drawable.player);
123 }
124 return null;
125}
126
127}


1import android.graphics.Canvas;
2
3public class GameLoopThread extends Thread
4{
5 static final long FPS = 60;
6
7
8 private GameView theView;
9 private boolean isRunning = false;
10 public GameLoopThread(GameView theView) {
11 this.theView = theView;
12 }
13
14 public void setRunning(boolean run) {
15 isRunning = run;
16 }
17
18 @Override
19 public void run()
20 {
21 long TPS = 1000 / FPS;
22 long startTime, sleepTime;
23 while (isRunning) {
24 Canvas theCanvas = null;
25 startTime = System.currentTimeMillis();
26 try {
27 theCanvas = theView.getHolder().lockCanvas();
28 synchronized (theView.getHolder()) {
29 theView.update();
30 theView.onDraw(theCanvas);
31 }
32 } finally {
33 if (theCanvas != null) {
34 theView.getHolder().unlockCanvasAndPost(theCanvas);
35 }
36 }
37 sleepTime = TPS -(System.currentTimeMillis()-startTime);
38 try
39 {
40 if(sleepTime>0)
41 {
42 sleep(sleepTime);
43 }
44 else
45 {
46 sleep(15);
47 }
48 }
49 catch(Exception e){}
50 }
51 }
52
53}

— geändert am 02.05.2013, 00:21:03

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

02.05.2013, 10:21:10 via Website

Ohne den Code jetzt genau studiert zu haben.

Du nutzt synchronized methoden und einen Thread. Es riecht danach das der positions änderungen erst der Thread (?) spät sieht und dann entsprechend erst handelt wenn du den Lock verlässt (synchronized methode/block)

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Toom
  • Forum-Beiträge: 2

02.05.2013, 14:42:33 via Website

Ich hab das
1synchronized
mal entfernt, aber es läuft immer noch nicht flüssig. :S

EDIT: Die Verzögerung in der onTouchEvent- Methode wurde dadurch aber behoben. Das Problem muss noch an einer anderen Stelle sein.

EDIT: Hab noch etwas rumprobiert und rausgefunden, dass das Programm für die Methode onDraw() mind. 1,5 sek. benötigt.
Habe ich vllt. etwas falsch installiert bzw. eingestellt oder schafft ein Android so etwas schon nicht mehr?
1@Override
2 protected void onDraw(Canvas canvas) {
3 for(int x = 0;x<16;x++)
4 {
5 for(int y = 0; y<9;y++)
6 {
7 canvas.drawBitmap(getSprite(tile[x][y].getType()), x*tile[x][y].getSize(),y*tile[x][y].getSize(),null);
8 }
9 }
10 canvas.drawBitmap(getSprite(player.getType()),player.getX()*80,player.getY()*80,null);
11 }

— geändert am 02.05.2013, 17:59:18

Antworten