Sprite Rotation в Android с использованием Canvas.DrawBitmap. Я близок, что я делаю не так?

У меня есть этот алгоритм вращения спрайтов (он плохо назван и используется только для тестирования). Это так близко, спрайты, нарисованные с его помощью, вращаются. Каждый кадр я могу добавить к нему +5 градусов и увидеть, как мой милый маленький спрайт вращается вокруг. Проблема в том, что другой материал, нарисованный на холсте, теперь мигает. Если я не делаю вращение, то обычные нарисованные спрайты работают отлично. Я думаю, что я близко, но я просто не знаю, что мне не хватает. Ниже приведены два моих метода «Draw_Sprite», один из которых просто рисует ранее загруженное растровое изображение на переданный холст. Другой, делает какое-то вращение лучше, чем я знаю, как повернуть спрайт на столько х градусов ... а затем нарисовать его , Если у меня есть хороший игровой цикл, который рисует несколько объектов, то один тип будет повернутым. Тогда не повернутые спрайты мерцают, а вращающийся спрайт никогда не появляется. Хотя, если я сначала рисую не повернутые спрайты, все будет хорошо, но тогда Z-упорядоченность может быть испорчена (спрайты поверх элементов пользовательского интерфейса и т. Д.) ... Определения метода:

    /*************************************************
 * rotated sprite, ignore the whatever, its for ease of use and testing to have this argument list
 * @param c canvas to draw on.
 * @param whatever ignore 
 * @param rot degrees to rotate
 * @return
 */
public int Draw_Sprite(Canvas c, int whatever, int rot) {   
    //rotating sprite
    Rect src = new Rect(0, 0, width, height);
    Rect dst = new Rect(x, y, x + width, y + height);
    Matrix orig = c.getMatrix();        
    mMatrix = orig;
    orig.setTranslate(0, 0);
    orig.postRotate(rot, x+width/2, y+height/2); 
    c.setMatrix(orig);
    c.drawBitmap(images[curr_frame], src, dst, null);
    c.setMatrix(mMatrix); //set it back so all things afterwards are displayed correctly.

    isScaled=false;
    return 1;

}

/********************************************************
 * draw a regular sprite to canvas c
 * @param c
 * @return
 */
public int Draw_Sprite(Canvas c) {  

    Rect src = new Rect(0, 0, width, height);
    Rect dst = new Rect(x, y, x + width, y + height);       
    c.drawBitmap(images[curr_frame], src, dst, null);

    isScaled=false;
    return 1;
}

А теперь использование:

void onDraw(Canvas c)
{
    canvas.drawRect( bgRect, bgPaint); //draw the background

    //draw all game objects
      // draw the normal items
    for (GameEntity graphic : _graphics) { 
        graphic.toScreenCoords((int)player_x, (int)player_y);
        if(graphic.getType().equals("planet")) //draw planets
            graphic.Draw_Sprite(canvas); //before the rotation call draws fine
        else
        {
            //rotate all space ships every frame so i see them spinning        
            //test rotation
            mRot +=5;
            if(mRot>=360)
                mRot=0;
            graphic.Draw_Sprite(canvas, 0, mRot); //yes function name will be better in future.  this rotates spins draws fine


        }                           
       }

       thePlayer.Draw_Sprite(canvas); //FLICKERS
       drawUI(canvas);//all things here flickr

}  

Так оно и есть, вещи после вызова ротационного розыгрыша отрисовываются правильно. Но проблема в том, что это мерцает. Теперь можно сказать, что я должен просто сделать все мои не вращательные вещи и сохранить это в последнюю очередь, но zordering будет отключен .... группировать my require в начале класса или где-то в инициализаторе при загрузке Rails?

Имеет ли это значение с точки зрения производительности? С точки зрения читабельности? Имеет ли значение, если я использую Rails 3?

Спасибо!

27
задан casperOne 13 August 2012 в 01:33
поделиться

2 ответа

Если вы беспокоитесь о производительности, вам следует требовать вещи в контексте того, где они нужны, чтобы, если эта часть вашего кода не выполнялась , библиотека не загружена. Любые последующие вызовы require не имеют никакого эффекта, так как этот файл уже был загружен. Это выглядит примерно так:

if (user.using_openid?)
  require 'openid'

  # ... Do OpenID stuff
end

Хотя это более эффективно с точки зрения ресурсов, это может сильно затруднить определение зависимостей вашего приложения. Объявление их заранее делает их понятными для других людей, обслуживающих программное обеспечение. Имейте в виду, что «другие люди» всегда включают вас в будущем, когда вы забыли о некоторых деталях своего приложения.

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

require 'library1'
require 'library2'
require 'library3'
require 'library4'
require 'library5'

# Other libraries loaded as required:
#  * slowimagelibrary
#  * slowencryptionlibrary
#  * openid

Возможно, это не такая проблема с bundler, потому что вы можете более формально объявить свои драгоценные камни заранее, а фактический вызов require может произойти позже.

22
ответ дан 28 November 2019 в 05:45
поделиться

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

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

Я считаю, что в случае с Rails все зависит от того, что вы хотите делать.

Если вы используете Bundler, вы можете предположить, что ваш драгоценный камень «требуется» (конечно, вы можете переопределить то, что требуется, с помощью опции :require).

Если вы хотите что-то автоматически загружать при запуске сервера (например, валидаторы или конструкторы форм), вам следует посмотреть, как это сделать с конфигурацией (autoload_paths и await_load_paths).

require также может использоваться для загрузки только части драгоценного камня, например его расширения. Потом конечно требуется где конфигурация.

Если вы работаете в многопоточной среде, это может вас беспокоить, поскольку с этим возникают некоторые проблемы. Затем вы должны убедиться, что все загружено, прежде чем ваши потоки будут запущены.(Что-то типа константы класса подгружается, а методов пока нет, была хорошая статья но больше не могу найти).

Вы также можете попробовать {Module,Kernel}.autoload, Rails широко использует его для загрузки только того, что необходимо при доступе (но это выглядит довольно уродливо).

Вы также можете взломать его самостоятельно с помощью const_missing (так что это может выполнять простую ленивую загрузку, если вы принимаете структуру). Это простой пример (не подходит для вложенных классов).

def Object.const_missing c
  if (file = Dir["#{c.downcase}.rb"]).size == 1 
    require_relative(file)
  end
  if const_defined? c
    const_get c
  else
    super # Object < Module
  end
end

Что касается производительности, вызов require обходится относительно дорого, поэтому, если вы знаете, что собираетесь его использовать, по возможности делайте это только один раз. Однако для управления сложными зависимостями в вашем проекте вам могут потребоваться относительные файлы. Тогда require_relative — это путь в 1.9.

Наконец, для проекта я бы рекомендовал требовать все в основном файле в lib/ с некоторым выражением Dir["**/*.rb"]. Тогда вам редко понадобится require_relative, потому что это необходимо только в том случае, если вы ссылаетесь в теле класса на другую константу (все содержимое методов не разрешается, так что с этим проблем нет).

Другим решением было бы определить эти константы в вашем основном файле, это также дало бы вам представление о структуре.

5
ответ дан 28 November 2019 в 05:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: