2010-11-15 11 views
9

ze względu na prostotę, załóżmy, że tworzę prostą grę klonów Pong na Androida. Załóżmy, że byłby możliwy do gry tylko w trybie poziomym. (na razie ignoruj ​​kwadratowe telefony).Jak poprawnie skalować grę na Androidzie

Chciałbym, aby gra wyglądała w tej samej skali na każdym telefonie, do tego stopnia, że ​​jeśli zrobiłeś zrzut ekranu z gry na telefonie QVGA i zmieniłeś rozmiar ekranu do rozmiaru WVGA, wyglądałoby to prawie tak samo jak wyglądałaby gra na telefonie WVGA. Innymi słowy, szerokość wiosła powinna zawsze wynosić 1/32 szerokości ekranu, a średnica piłki powinna zawsze wynosić 1/16 szerokości ekranu.

Jaki byłby właściwy sposób na malowanie aplikacji? Byłby uruchamiany w standardowym SurfaceView, który zostałby narysowany na Canvas.

Załóżmy, że mam PNG o wysokiej rozdzielczości dla wiosła, piłki i czcionki gry (tablica wyników, menu główne).

Czy dowiem rozdzielczości fizycznej, a następnie przeskalować Canvas poprzez scale(float sx, float sy) aby wszystkie moje płótna (na QVGA oraz WVGA) mają ten sam wirtualny rozdzielczość , a następnie narysować dokładnie te same prymitywy na każdej pozycji na każdym ekranie rozmiar?

Czy mogę użyć w pikselach pikseli niezależnych od gęstości (dip)?

Odpowiedz

4

grałem tylko raz z funkcji draw płótnie i następnie przełączono wszystkie na opengl, ale logika pozostaje taka sama (chyba).

Pierwszy numer, w którym chcesz zachować stały stosunek z jednego telefonu do drugiego. w mojej aplikacji dodaję efekt "czarnego pasma" po każdej stronie. w onSurfaceChanged, będziesz chciał obliczyć współczynnik, ten stosunek pozwoli Ci określić, ile miejsca musisz usunąć z każdej strony, aby zachować spójny aspekt rysunku. to daje delta X lub Y, aby zmiany dotyczą wszystkich rysuje następujący kod jest coś adaptacją wersji OGL więc może trzeba tweeked nieco

@Override 
    public void onSurfaceChanged(int w, int h){ 
    float ratioPhysicScreen = nativeScreenResoltionW/nativeScreenResoltionH; 
    float ratioWanted = GameView.getWidth()/GameView.getHeight(); 
    if(ratioWanted>ratioPhysicScreen){ 
     newHeight = (int) (w*GameView.getHeight()/GameView.getWidth()); 
     newWidth = w; 
     deltaY = (int) ((h-newHeight)/2); 
    deltaX = 0; 
    }else{ 
     newWidth = (int) (h/GameView.getHeight()*GameView.getWidth()); 
     newHeight = h; 
     deltaX = (int) ((w-newWidth)/2); 
     deltaY = 0;  
} 

Pokochasz więc też chcą być w stanie narysować twoje obrazy na płótnie, znając tam rozmiar na płótnie, a także rzeczywisty rozmiar oraz różnicę między image.getWidth() (rzeczywisty rozmiar obrazu) a image.getScaledWidth (płótno), które podać rozmiar elementu w dp, co oznacza, jak duży będzie on pojawiał się na ekranie) jest ważny. spójrz na przykład pod spodem.

public class MainMenuView extends PixelRainView{ 
private Bitmap bmpPlay = null; 
private float playLeft = 0; 
private float playRight = 0; 
private float playBottom = 0; 
private float playTop = 0; 

public MainMenuView(Context context, AttributeSet attrs) { 
    super(context,attrs); 
} 



@Override 
public void unLoadBitmaps() { 
    super.unLoadBitmaps(); 
    if(bmpPlay != null){ 
     bmpPlay.recycle(); 
     bmpPlay = null; 
    } 
} 



@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    if(bmpPlay == null){ 
     bmpPlay = getBitmapFromRessourceID(R.drawable.play_bt); 
     playLeft = (this.getWidth()-bmpPlay.getScaledWidth(canvas))/2; 
     playRight = playLeft + bmpPlay.getScaledWidth(canvas); 
     playTop = (this.getHeight()-bmpPlay.getScaledHeight(canvas))/2; 
     playBottom = playTop+bmpPlay.getScaledHeight(canvas); 
    } 
    canvas.drawBitmap(bmpPlay,playLeft, playTop, null); 

    }  
} 


@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
} 



@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if(event.getAction() == MotionEvent.ACTION_DOWN){ 
     float x = event.getX(); 
     float y = event.getY(); 
     //test central button 
     if(x>playLeft && x<playRight && y<playBottom && y>playTop){ 
      Log.e("jason", "touched play"); 
      PixelRainView.changeView(R.layout.composedlayoutgroup); 
     } 
    return super.onTouchEvent(event); 
} 
} 

To powinno rozwiązać wszystkie swoje problemy stosunek krzyżowe plateforms Proponuję OpenGL, ponieważ będzie to uprościć potrzebę utrzymywania stałej aspekt, ale myślę, że jej nie jest opcją ^^

nadzieję, że to pomaga na tyle

2

Stosować dipy i malować wioseł zamiast używać PNG

+0

Jak używać spadków w metodach Canvas, takich jak drawLine()? – Axarydax

+0

OK, zapomnijmy o klanie Ponga i porozmawiajmy o grze opartej na kaflach jak Pac-man lub SimCity. Są więc płytki, które są przechowywane w PNG, a Pong może być zbyt prostym przykładem. – Axarydax

-1

myślę, że są tylko 3 standardowe rozdzielczości dostępne (ldip, mdip, hdip) i powinieneś mieć folder zasobów dla każdego z nich.

http://developer.android.com/guide/practices/screens_support.html

Jeśli ręczne skalowanie PNG, aby dopasować każdy z 3 dostępnych rozdzielczościach, telefon powinien załadować określony folder zasobów w sposób przejrzysty

Powiązane problemy