2012-01-08 1 views
2

Utilisation du code ci-dessous pour faire défiler J'ai un fil de Surfaceview et un bitmap de texture de toile qui est généré (changé), première rangée (ligne), chaque image, puis copié une position (ligne) vers le bas sur un bitmap de surface régulière pour faire un effet de défilement, et je continue ensuite à dessiner d'autres choses par dessus. Eh bien c'est ce que je veux vraiment, mais je ne peux pas le faire fonctionner même si je crée un canevas séparé pour bitmap hors écran. Il ne fait tout simplement pas défiler. Je possède un bitmap de mémoire, de la même taille que le canvas Surfaceview, que je dois faire défiler d'une ligne vers le bas chaque image, puis remplacer la ligne supérieure par une nouvelle texture aléatoire, puis dessiner sur une surface régulière. Toile.Comment faire défiler hors bitmap de mémoire d'écran

Voici ce que je pensais que cela fonctionnerait;

Mon surfaceChanged où je précise bitmap et toiles et commencer fil:

@Override 
    public void surfaceCreated(SurfaceHolder holder) { 
    intSurfaceWidth = mSurfaceView.getWidth(); 
    intSurfaceHeight = mSurfaceView.getHeight(); 

    memBitmap = Bitmap.createBitmap(intSurfaceWidth, intSurfaceHeight, 
      Bitmap.Config.ARGB_8888); 
    memCanvas = new Canvas(memCanvas); 

    myThread = new MyThread(holder, this); 
    myThread.setRunning(true); 
    blnPause = false; 
    myThread.start(); 
} 

Mon fils, ne montrant que milieu essentiel partie courante:

@Override 
public void run() { 
    while (running) {  
    c = null; 
try { 
    // Lock canvas for drawing 
    c = myHolder.lockCanvas(null);     

    synchronized (mSurfaceHolder) { 
     // Scroll down off screen canvas and hopefully underlying bitmap bitmap 
     Rect src = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight - 1); 
     Rect dst = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight); 
     memCanvas.drawBitmap(memBitmap, src, dst, null); 

     // Note scrolling up like this works fine 
     // Rect src = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight + 1); 
     // Rect dst = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight); 
     // memCanvas.drawBitmap(memBitmap, src, dst, null); 

     // Create random one line(row) texture bitmap 
     textureBitmap = Bitmap.createBitmap(imgTexture, 0, rnd.nextInt(intTextureImageHeight), intSurfaceWidth, 1); 

     // Now add this texture bitmap to top of screen canvas and hopefully underlying bitmap 
     memCanvas.drawBitmap(textureBitmap, 
       intSurfaceWidth, 0, null); 

     // Draw above updated off screen bitmap to regular canvas, at least I thought it would update (save changes) shifting down and add the texture line to off screen bitmap the off screen canvas was pointing to. 
     c.drawBitmap(memBitmap, 0, 0, null); 

     // Other drawing to canvas comes here 


    } finally { 
     // do this in a finally so that if an exception is thrown 
     // during the above, we don't leave the Surface in an 
     // inconsistent state 
     if (c != null) { 
      myHolder.unlockCanvasAndPost(c); 
     } 
    } 
}  
} 

Pour mon jeu Tunnel Run, https://market.android.com/details?id=com.zubima.TunnelRun, en ce moment J'ai une solution de travail où j'ai plutôt un tableau de bitmaps, la taille de la hauteur de la surface, que je remplis avec ma texture aléatoire, puis décaler dans une boucle pour chaque image. Je reçois 50 images par seconde, mais je pense que je peux faire mieux en faisant défiler plutôt bitmap.

+0

complète hors-sujet, mais la description de votre application sur le marché est le texte intégral, pas de paragraphes, pas de rien ... vous devriez le structurer! La première pensée était: tldr – WarrenFaith

+0

Bonne suggestion, paragraphes ajoutés, mais je ne sais pas ce que vous voulez dire par "texte intégral ... non rien". Ceci est un champ de texte seulement, je ne peux pas ajouter des images à cela. – DKDiveDude

+0

Vrai, mais le formatage de votre texte était plutôt moche. Je ne veux pas un guide complet "comment utiliser/jouer" dans la description.Pensez-y beaucoup plus comme un texte publicitaire. Résumez quelques fonctionnalités intéressantes dans une liste, intéressez-vous à votre jeu. – WarrenFaith

Répondre

0

Il y a une fonction DrawBitmap au sein de la toile avec la signature suivante:

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint); 

Vous pouvez faire votre dst la taille de la toile, et votre src peut être mis en place pour être nouvelle

Rect(0,offset,width,height+offset) 

Vous pouvez ensuite incrémenter le décalage de chaque image et obtenir un bitmap défilant en douceur dans votre vue.

+0

Merci pour votre suggestion. Je l'avais déjà essayé, voir mon code changer ci-dessus car il ne rentre pas ici, mais essentiellement il fait défiler le bitmap dans le mauvais sens et inverser le décalage à -1 ne le fait pas défiler vers le bas – DKDiveDude

+0

Dans votre exemple, je pense que vous êtes la source et la destination peuvent être en arrière. Source est la zone du bitmap que vous regardez et Destination est la zone sur l'affichage. De même, quel était votre code de défilement? – nmjohn

+0

Ok Je comprends avec mes commentaires ajoutés cela peut sembler déroutant, alors permettez-moi de réviser le code original et de se débarrasser des additions – DKDiveDude

1

Vous essayez de dessiner un bitmap au-dessus de lui-même, quelque chose qui n'a jamais travaillé sur Android AFAIK. Je suis tombé dans ce trou précis avec mon premier jeu, un chanteur latéral appelé Mole Miner.

Le problème est très simple: le drawBitmap() est, en substance, un type spécial de memcpy() dans lequel les octets sont toujours adressés en avant. Ce qui est bien, et utilise le cache L1 de manière optimale, etc, mais vous avez évidemment rencontré un problème si les zones source et de destination (a) se chevauchent, et (b) l'adresse source < dest.

(implémentations réelles de memcpy(), par ailleurs, vérifier cette possibilité et faire la copie en arrière si nécessaire. Canvas.drawBitmap() ne le fait pas.)

La solution j'ai utilisé pour Mole Miner deux bitmaps hors écran, et basculer entre eux sur des trames alternées. Mais c'était en 2009 et de nos jours je n'utiliserais probablement pas le défilement du tout.

+0

Yeah a pensé que c'était un bug/mauvaise implémentation. Je vais essayer les deux bitmaps hors écran et passer entre eux plus tard aujourd'hui et si cela fonctionne, je vous remercie pour la réponse, merci! – DKDiveDude

+0

Si vous ne faites que défiler dans une direction (vers le bas), vous pouvez changer cela afin de dessiner le bitmap à l'envers et de le faire défiler * vers le haut *. Vous ne rencontrerez pas le problème si dest

+0

Peut-être que je suis incapable de visualiser correctement cela, mais cela ne semble pas fonctionner. Le tunnel dans mon jeu diminue de largeur au fil du temps. Imaginez-vous sur un écran où le tunnel passe de la largeur maximale en bas à la largeur minimale en un V inversé, un défilement vers le bas l'anime parfaitement. Mirroring bitmap et encore sur un tunnel d'écran irait de la largeur max à la largeur min, il ressemblerait à un côté droit V, où le nouveau matériau bitmap (ligne) serait actualisé en bas puis défilé vers le haut, cette animation semble être à être totalement éteint. Corrigez-moi si je me trompe, merci! – DKDiveDude

Questions connexes