2012-01-03 2 views
1

Этот сценарий рисует контроль, герой, поверхность и карты:Рисунок плитки на основе карты

public void render(Canvas canvas) { 
     canvas.drawColor(Color.TRANSPARENT); 

     Drawable myImage; 

     int tileWidth = 50; 
     int tileHeight = 50; 

     int rowBaseX = 0; 
     int rowBaseY = 0; 

     int[][] board = new int[][] { 
       {0,0,0,0,0,0,2,0,0,0,}, 
       {0,0,0,0,0,2,2,0,0,0,}, 
       {0,0,0,0,0,2,0,0,0,0,}, 
       {0,0,0,0,0,2,0,0,0,0,}, 
       {0,0,0,2,2,2,0,0,0,0,}, 
       {0,0,0,2,0,0,0,0,0,0,}, 
       {0,0,0,2,0,0,0,0,0,0,}, 
       {0,0,2,2,0,0,0,0,0,0,}, 
       {0,0,2,0,0,0,0,0,0,0,}, 
       {0,0,2,0,0,0,0,0,0,0,} 
       }; 
     int mapWidth = 10; 
     int mapHeight = 10; 

     for (int row = 0; row < mapHeight; row++) 
     { 

     for (int col = 0; col < mapWidth; col++) 
     { 
     Resources res = this.getContext().getResources(); 

     switch(board[row][col]) 
     { 
     case 0: 
     myImage = res.getDrawable(R.drawable.tile1); 
     break; 
     case 1: 
     myImage = res.getDrawable(R.drawable.tile2); 
     break; 
     default: 
     myImage = res.getDrawable(R.drawable.tile3); 
     break; 
     } 

     int curL = rowBaseX + (col * tileWidth); 
     int curU = rowBaseY + (row * tileHeight); 
     int curR = curL + tileWidth; 
     int curD = curU + tileHeight; 

     myImage.setBounds(curL,curU,curR,curD); 
     myImage.draw(canvas); 
     } 
     } 

     droid.draw(canvas); 
     butt.draw(canvas); 
     butt1.draw(canvas); 
     butt2.draw(canvas); 
     butt3.draw(canvas); 
     buttz.draw(canvas); 
     buttz1.draw(canvas); 
     buttz2.draw(canvas); 
     buttz3.draw(canvas); 
     buttx.draw(canvas); 
    } 

Существует герой, который должен быть перерисованы, когда игрок перемещает его с контрольной группой, а все остальные вводимого коэффициента также необходимо перерисовать. Проблема в том, что рисование карты - это долгий процесс, поэтому большая карта, которую я создаю, медленнее движется герой, потому что каждая плитка карты должна быть нарисована. Есть ли способ поместить все плитки в одно растровое изображение в другом методе и нарисовать это одно растровое изображение в методе холста?

ответ

2

Лучшим вариантом является только нарисовать часть вашей карты, которая видна на экране. Таким образом, независимо от того, насколько велика общая карта, рисунок этой карты всегда постоянный. Так как вы на сетчатой ​​системе вы можете легко выяснить, какие клетки герой находится в:

heroGridX = hero.x % mapWidth; 
heroGridY = hero.y % mapHeight; 

Оттуда вы можете вычислить, сколько клеток вокруг игрока, которого вы хотите рисовать, используя ширину и высоту холст и постоянного размер ширины вашей ячейки сетки и высота:

leftGrid = heroGridX - (canvas.getWidth()/tileWidth)/2; 
topGrid = heroGridY - (canvas.getHeight()/tileHeight)/2; 
rightGrid = heroGridX + (canvas.getWidth()/tileWidth)/2; 
bottomGrid = heroGridY + (canvas.getHeight()/tileHeight)/2; 

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

Это будет использовать гораздо меньше памяти, чем рисование всей карты в одну большую растровую карту. Вложение в большое растровое изображение увеличивает объем использования памяти за меньшее время процессора. По мере того как ваша карта становится больше, так что память нужна для рисования этой карты. Этот алгоритм просто продолжает рисовать карту постоянной, поскольку размер экрана не изменяется во время выполнения. И, по сравнению с другим вариантом, использование вашей памяти не растет больше по мере увеличения вашей карты (она становится очень маленькой по сравнению с рисованием большего количества плиток на холсте). Один важный факт в том, что если вы получили большой экран (скажем, планшет против телефона). Этот алгоритм будет масштабироваться правильно, так что игрок увидит больше окружающего ландшафта карты.

+0

Хорошее решение, спасибо :) – Liukas

3

Если создание статической карты вне приложения не является вариантом, вы можете отделить рисунок статического содержимого от динамического содержимого.

Создайте Bitmap, создайте на нем Canvas и нарисуйте свою карту на этом Canvas. Вам нужно сделать это только один раз. Отображать динамическое содержимое один раз на кадр на другом Canvas. Затем нарисуйте как Bitmap s на «настоящем» Canvas вашего SurfaceView. Это может выглядеть следующим образом:

некогда одной карты часть:

Bitmap mapBitmap = Bitmap.createBitmap(width, height, myConfig); 
Canvas c = new Canvas(mapBitmap); 
//draw map on c 

... и часть когда-то за кадром:

//draw dynamic stuff  
Canvas canvas = getHolder().lockCanvas(); 
    canvas.drawBitmap(mapBitmap, null, targetRect, null); 
    canvas.drawBitmap(heroBitmap, null, targetRect, null); 
    getHolder().unlockCanvasAndPost(); 

EDIT:

Вы рисуете свои плитки, как будто вы использовали myImage.draw(canvas), но передаете mapBitmap-Canvas как аргумент вместо своего «реального» холста. myConfig должен быть Bitmap.Config. Возьмите RGB_565, так как это внутренний формат.

+0

но как я могу поместить свои плитки карты в mapBitmap? Мне нужно написать что-нибудь из myConfig? – Liukas

+0

@ Liukas Я отредактировал ответ, чтобы включить его. Надеюсь, это станет проще. ' – kostja

+0

Извините, но я использовал другое решение. Вы можете помочь мне по другому вопросу :) http://stackoverflow.com/questions/8717038/tile-based-map-scrolling – Liukas