2011-07-02 4 views
1

Может ли кто-нибудь помочь мне с помощью этого простого кода? Почему круг не двигается плавно? Что в этом плохого?Android очень простая разработка игр

package chaseme; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.Window; 

public class ChaseMe extends Activity { 
/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(new SampleView(this)); 
} 

private class SampleView extends SurfaceView implements SurfaceHolder.Callback, Runnable { 
    private Point point; 
    private Thread thread; 
    private SurfaceHolder holder; 
    private Paint _rect; 
    private Paint _circle; 
    private boolean running; 
    private int WIDTH; 
    private int HEIGHT; 
    private float radius = 20; 

    public SampleView(Context context) { 
     super(context); 

     point = new Point(20, 20); 
     _rect = new Paint(); 
     _rect.setColor(Color.BLACK); 

     _circle = new Paint(); 
     _circle.setColor(Color.BLUE); 

     holder = this.getHolder(); 
     holder.addCallback(this); 
     thread = new Thread(this); 

    } 

    private void updateModel() { 
     if(point.x > WIDTH - radius) { 
      point.x = 20; 
     } 
     if(point.y > HEIGHT - radius) { 
      point.y = 20; 
     } 
     point.x++; 
     point.y++; 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     WIDTH = getWidth(); 
     HEIGHT = getHeight(); 
     this.setRunning(true); 
     thread.start(); 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     boolean retry = true; 

     this.setRunning(false); 
     while (retry) { 
      try { 
       thread.join(); 
       retry = false; 
      } 
      catch (InterruptedException e) {} 
     } 
    } 

    private void setRunning(boolean b) { 
     running = b; 
    } 

    @Override 
    public void run() { 
     while(running) { 
      Canvas c = null; 
      updateModel(); 

      try { 
       c = holder.lockCanvas(null); 
       // synchronized (holder) {      
        render(c); 
       // } 
      } 
      catch(Exception e) { 
       Log.e("main", e.getMessage()); 
      } 
      finally { 
       if(c!=null) { 
        holder.unlockCanvasAndPost(c); 
       }     
      }    
     } 
    } 

    private void render(Canvas c) {   
     c.drawRect(0, 0, WIDTH, HEIGHT, _rect);  
     c.drawCircle(point.x, point.y, radius , _circle); 

     //c.save(); 
     //c.restore(); 
    } 
} 
} 
+0

Если вы печатаете некоторые вещи в консоли в режиме рендеринга, частота кадров хорошая? Интересно, работает ли ваше приложение слишком быстро, так как вы никогда не просите ваш поток спать между кадрами анимации. – Snicolas

+0

Ну, я знаю, в чем проблема, это эмулятор работает очень медленно, я проверил тест, чтобы увидеть fps, и он падает примерно с 20 до 10. – Yotam

+0

Устройство - это только реальный тест на Android. Это действительно самый быстрый способ отладки приложения. Я использую эмулятор только для проверки того, что мои устройства не могут проверить (разрешение, версии sdk ...). Но обычно я тестирую свой код на устройстве. – Snicolas

ответ

1

Вы не можете просто вызвать point.x ++, как вы сейчас это делаете. Вам нужно рассчитать движение относительно прошедшего времени и размера экрана.

Шаг 1: В каждом кадре, вычислить, сколько времени прошло с момента последнего кадра, делая

long now = System.currentTimeMillis(); 
elapsed = (now - mLastTime); 
totalTimeElapsed += elapsed; 

, а затем в конце основного цикла вы

mLastTime = now; 

Шаг 2. Получить соотношение экранов:

screenWidth = MyClass.this.getWidth(); 
screenHeight = MyClass.this.getHeight(); 
float a = screenWidth; 
float b = screenHeight; 
screenRatioX = a/WIDTH_OF_YOUR_PHONE; 
screenRatioY = b/HEIGTH_OF_YOUR_PHONE; 

Шаг 3. Теперь вы можете начать делать анимации, например, если хотите переместите свой круг справа налево:

spriteX1 = (int) ((spriteX1 + (VELOCITY*screenRatioX*elapsed))+0.5); 
spriteX2 = spriteX1 + spriteWidth; 

Начните со скорости 2,0 или что-то еще и откорректируйте оттуда.

Удачи вам!

1

Я думаю, что для плавного перемещения объекта вы должны использовать функцию прослушивания жестов на событии касания.

Ниже ссылка может вам помочь.

1.http: //mobile.tutsplus.com/tutorials/android/android-gesture/ 2.http: //stackoverflow.com/questions/937313/android-basic-gesture-detection

0

Протестируйте код по моему желанию, и он работает очень гладко.

Я предлагаю протестировать подобные проекты на реальных устройствах, эмулятор может быть очень непредсказуемым и медленным, в зависимости от вашего процессора.

Не большое дело, но вы можете очистить холст с

canvas.drawColor(Color.BLACK); 

вместо рисования прямоугольника.

Смежные вопросы