Problème grille dynamique avec SurfaceView
Bonsoir,
je débute sur Android, et je voudrais réaliser une grille dynamique en 2 dimensions de taille n * m (rentrés par l'utilisateur). On m'a dit que le plus simple pour ça c'est de partir de 0, ce que j'ai fait.
Pour l'instant, j'essaie seulement d'afficher des pixels de couleur aléatoire à la place de la grille (juste pour tester), mais l'application crash dès le départ.
Je pense que l'erreur est grosse, tellement grosse que je ne la vois pas..
Quelqu'un pourrait me dire où je me suis planté ? Je pense qu'il y a encore des notions d'Android qui m'échappent et j'aimerais qu'on me disent lesquelles..
Merci ! :)
Voici le début de mon main.xml :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
//c'est cet élément qui semble faire planter...
<com.projet.JeuDeLaVie_Android.Panel
android:id="@+id/Grille"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.projet.JeuDeLaVie_Android.Panel> |
Voici ma classe principale, qui pour l'instant ne sert à rien puisque j'essaie juste d'essayer d'afficher mon Panel :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| package com.projet.JeuDeLaVie_Android;
import android.app.*;
import android.content.*;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.*;
public class JeuDeLaVie_AndroidActivity extends Activity {
private int nombre_colonnes;
private int nombre_lignes;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Desactiver la barre de titre de notre application
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Passer la fenêtre en full-creen == cacher la barre de notification
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Panel p=new Panel(this);
setContentView(p);
Button okButton = (Button) findViewById(R.id.NewGame);
okButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
//On instancie notre layout en tant que View
LayoutInflater factory = LayoutInflater.from(v.getContext());
final View alertDialogView = factory.inflate(R.layout.diag, null);
//Création de l'AlertDialog
AlertDialog.Builder alertdiag = new AlertDialog.Builder(v.getContext());
//On affecte la vue personnalisé que l'on a crée à notre AlertDialog
alertdiag.setView(alertDialogView);
//On donne un titre à l'AlertDialog
alertdiag.setTitle("Taille du jeu");
//On modifie l'icône de l'AlertDialog
//alertdiag.setIcon(android.R.drawable.ic_dialog_alert);
//On crée un bouton "Annuler" à notre AlertDialog et on lui affecte un évènement
alertdiag.setNegativeButton("Annuler", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Lorsque l'on cliquera sur annuler on quittera l'application
dialog.cancel();
}
});
//On affecte un bouton "OK" à notre AlertDialog et on lui affecte un évènement
alertdiag.setPositiveButton("Valider", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Lorsque l'on cliquera sur le bouton "OK", on récupère l'EditText correspondant à notre vue personnalisée (cad à alertDialogView)
EditText col = (EditText)alertDialogView.findViewById(R.id.nb_col);
EditText lig = (EditText)alertDialogView.findViewById(R.id.nb_lignes);
String ccol=col.getText().toString();
String llig=lig.getText().toString();
try {
nombre_colonnes=Integer.parseInt(ccol);
nombre_lignes=Integer.parseInt(llig);
Toast.makeText(getApplicationContext(), "Grille générée !", Toast.LENGTH_SHORT).show();
}catch (Exception e) {
Toast.makeText(getApplicationContext(), "Erreur. Veuillez recommencer", Toast.LENGTH_SHORT).show();
}
dialog.cancel();
}
});
alertdiag.create();
alertdiag.show();
}
});
}
} |
Ma classe Panel :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| package com.projet.JeuDeLaVie_Android;
import java.util.Random;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class Panel extends SurfaceView
implements SurfaceHolder.Callback{
private ThreadGame tg;
public Panel(Context context) {
super(context);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
tg = new ThreadGame(this);
setFocusable(true);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Instance de Paint pour définir l'attribut couleur de notre point, ainsi que
// sa taille.
Paint paint = new Paint();
// Nous allons dessiner nos points par rapport à la résolution de l'écran
int iWidth = canvas.getWidth(); // Largeur
int iHeight = canvas.getHeight(); // Hauteur
Random rand = new Random();
//Affichons 10000 points de toutes les couleurs
for (int i=0; i < 10; i++){
// Affecter une couleur de manière aléatoire
paint.setARGB(255, rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
// Puis dessiner nos points dans le canevas
canvas.drawPoint(rand.nextInt(iWidth), rand.nextInt(iHeight), paint);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (!tg.isAlive()) {
tg = new ThreadGame(this);
tg.setRunning(true);
tg.start();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (tg.isAlive()) {
tg.setRunning(false);
}
}
} |
et enfin ma classe ThreadGame :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package com.projet.JeuDeLaVie_Android;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class ThreadGame extends Thread{
private Panel jeu;
private SurfaceHolder holder;
private boolean mRun = false;
public ThreadGame(Panel Jjeu) {
// TODO Auto-generated constructor stub
jeu = Jjeu;
holder = Jjeu.getHolder();
}
public void setRunning(boolean run) {
mRun = run;
}
@Override
public void run() {
Canvas canvas;
while (mRun) {
canvas=null;
try {
canvas = holder.lockCanvas(null);
synchronized (holder) {
jeu.onDraw(canvas);
}
} 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 (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
}
} |