By Excilys
Développeur Android et JEE chez Excilys.
Formateur Android.
Publiée par NBC News.
<activity android:name=".MainActivity"
android:screenOrientation="portrait"
android:configChanges="keyboard|keyboardHidden|orientation">
onResume = resume the game
onPause = pause the game
public class CustomView extends View {
// ...
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
// make your changes
canvas.drawRect(...);
canvas.drawPath(...)
canvas.restore();
}
}
Important: Le rendu est fait sur l'UIThread.
Récupérer le canvas utilisé pour dessiner sur la "Surface"
Canvas canvas = getHolder().lockCanvas()
Affichage de la "Surface" à l'écran
getHolder().unlockCanvasAndPost(Canvas canvas)
Savoir si la surface est prête
SurfaceHolder.Callback.surfaceCreated(SurfaceHolder holder)
SurfaceHolder.Callback.surfaceDestroyed(SurfaceHolder holder)
ou
boolean isCreated = holder.getSurface().isValid();
Relatif au projet "Spaceship" !
Exercices d'entraînement.
N'oubliez pas d'effectuer le rendu dans un autre thread.
<uses-feature android:name="android.hardware.touchscreen.multitouch"
android:required="true"/>
Permet de vérifier que le device est compatible.
Autres exemples:
<uses-feature android:name="android.hardware.bluetooth" />
<uses-feature android:name="android.hardware.camera" />
// Récupérer le type d'action
int action = event.getActionMasked();
// Récupérer l'index
int actionIndex = event.getActionIndex();
// Récupérer l'id du pointeur
int pointerId = event.getPointerId(actionIndex);
Actions possibles
switch (action) {
case MotionEvent.ACTION_UP:
// premier touch uniquement
case MotionEvent.ACTION_POINTER_UP:
// autres touch
case MotionEvent.ACTION_DOWN:
// premier touch uniquement
case MotionEvent.ACTION_POINTER_DOWN:
// autres touch
case MotionEvent.ACTION_MOVE:
// tous les touch
}
La classe MotionEventCompat, disponible dans la librairie support-v4, intégre la nouvelle API.
Veillez à avoir compris la différence entre actionIndex et pointerId
Your project/
|_ assets/
|_music/
|_bfx/
|_image/
|_src/
|_res/
try {
// à partir d'un Context on récupère l'AssetManager
AssetManager assetManager = getAssets();
// plusieurs méthodes à disposition pour charger un fichier
InputStream inputStream = assetManager.open("dir1/file_name");
AssetFileDescriptor fd = assetManager.openFd("dir1/file_name");
} catch (IOException e) {
Log.e(TAG, "problem during files loading", e);
}
Activity.setVolumeControlStream (int streamType)
On va utiliser le MediaPlayer.
try {
// on set le fichier audio
mediaPlayer.setDataSource(...);
// on prépare l'audio
mediaPlayer.prepare();
// on commence à jouer l'audio
mediaPlayer.start();
mediaPlayer.pause();
mediaPlayer.stop();
} catch (IOException e) {
Log.e(TAG, "Problem during audio loading", e);
}
Besoin de jouer plusieurs son rapidement et simultanément.
// Création d'un SoundPool
// 10 = nb max de sons joués simultanément
// STREAM_MUSIC = type de stream sur lequel seront joué les sons
SoundPool soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, O);
AssetFileDescriptor fd = assetManager.openFd("path_to_the_file");
// pré-charge le son
sound1 = soundPool.load(fd, 1);
// ...
// on joue le son correspondant à l'ID donné
soundPool.play(sound1, 1, 1, 0, 0, 1);
bfxr.net, pour générer des sons de jeux en ligne.
dig.ccmixter.org, pour télécharger des musiques de jeux libres de droit.
Être un bon citoyen Android
AudioManager am = ...;
// On demande le focus de l'audio
am.requestAudioFocus(AudioManager.OnAudioFocusChangeListener l, int streamType, ...);
// On restitue le focus de l'audio
am.abandonAudioFocus(AudioManager.OnAudioFocusChangeListener l);
// AudioManager.OnAudioFocusChangeListener
@Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
// Récupération du son suite à une perte
// on continue de jouer si on revient d'une pause
// ou on rejoue le son depuis le début si c'était un stop
// ou encore on restitue le niveau de volume
// tout dépend du type de AUDIOFOCUS_LOSS
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
// perte de l'audio focus pour une longue durée
// mettre en stop
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
// perte de l'audio focus pour une petite durée
// mettre en pause
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
// perte de l'audio focus pour une petite durée et
// possibilité de jouer un son en même temps
// Baisser le volume
}
}
BitmapFactory.decodeFile("path_name");
//...
BitmapFactory.decodeFileDescriptor(aFileDescriptor);
//...
BitmapFactory.decodeResource(res, R.drawable.my_bitmap);
Utiliser le canvas!
// Dessiner un bitmap
Canvas.drawBitmap(...);
Versions inférieures à Honeycomb 3.0 (Api 11)
Quand un Bitmap est inutilisé -> Bitmap.recycle()
Native heap vs Dalvik's heap.
Depuis Honeycomb: on peut recycler un bitmap.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inBitmap = recycledBitmap;
// ...
BitmapFactory.decodeFile("my_file_path", options);
// ou
BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
// ...
Ajouter des images.