2D Kolissions Erkennung Problem

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • 2D Kolissions Erkennung Problem

    Aloha android-developers Community,

    Ich beschäftige mich seit einiger Zeit mit Java und Android und hab bin jetzt dabei ein kleines 2D Android Spiel zu entwickeln.
    So
    weit so gut, das Spiel besteht im wesentlichen daraus, dass der Spieler
    ein Objekt(character) lenkt und einem Anderem Objekt(Sprite) ausweichen
    muss. also sehr einfach.

    Zum Laufen hab ich schon recht viel
    bekommen: Layout,Musik, Automatische Bewegung von Sprite, interaktive
    Bewegung von Character,usw.

    Nun das Problem: Die Kolissions Erkennung

    Jetzt denken einige bestimmt, wie einfach:
    jedem Objekt ein Rechteck zuordnen und per intersect-Methode kolissionen überprüfen...
    die Kolissionerkennung hab ich dabei in einen extra Thread ausgelagert.

    So hab ich es auch gemacht, aber es funktioniert nicht wie gewollt.
    Das Problem liegt vermutlich daran:


    [IMG:http://s14.directupload.net/images/140520/56bi53o9.jpg]
    Intersect zwischen Character(orange) und Sprite(gruen) wird ausgeführt und Kolission erkannt;
    KolissionThread führt aus:

    Java-Quellcode

    1. public class KolissionsThread extends Thread {
    2. private boolean x=true;
    3. @Override
    4. public void run() {
    5. // TODO Auto-generated method stub
    6. super.run();
    7. if(Character.rect.intersect(Sprite.rect2)){
    8. MainActivity.handir.sendEmptyMessage(1);
    9. GameLoopThread.setRunning(false);
    10. }
    11. }
    12. }
    Alles anzeigen


    handir ist der Handler, der bei Kolission die GameOver Activity startet
    .
    er führt aus:

    Java-Quellcode

    1. public void handleMessage(Message msg) {
    2. Intent inti = new Intent(getApplicationContext(), GameOver.class);
    3. startActivity(inti);
    4. this.finish();
    5. super.handleMessage(msg);
    6. }


    Soweit so gut, Kolission erkannt, Intent gesendet und Gameover gestartet....
    Nur
    brauch der Intent dermaßig lange(1,5s) um die Activity zustarten, dass
    es dazu kommt das trotz Kolission, das Bild erneut gezeichnet wird:

    [IMG:http://s14.directupload.net/images/140520/evse7b7b.jpg]

    Es entsteht also eine überlappung, die sehr schlampig wirkt.

    das
    komische: bei einer kollision wird der GameLoopThread, der für das
    aufrufen der ondraw Methode der SurfaceView zuständig ist gestoppt(
    siehe oben "GameLoopThread.setRunning(false);"), dennoch wird es noch
    ein letztes mal gezeichnet.

    ich weiß nicht was ich noch anders
    machen kann, wenn bei einer Kolission GameLoopThread.sleep() als erstes
    aufgerufen wird, funktioniert die Kollision tadelos, wenn jedoch die
    Sleep Zeit vorbei ist und der Intent gesendet wird entsteht wieder das
    bekannte Problem des weiterzeichnens.

    Ich hoffe das war nicht zu verwirrend, zum besseren Verständniss hier:

    der Code des GameLoopThreads:

    Java-Quellcode

    1. import android.graphics.Canvas;
    2. public class GameLoopThread extends Thread {
    3. private static GameView theView;
    4. static KolissionsThread kolli;
    5. private static boolean isRunning = false;
    6. static final long FPS=60;
    7. public GameLoopThread(GameView theView) {
    8. this.theView = theView;
    9. }
    10. public static void setRunning(boolean run) {
    11. isRunning = run;
    12. }
    13. @Override
    14. public void run() {
    15. long TPS=1000/FPS;
    16. long startTime,sleepTime;
    17. while (isRunning) {
    18. Canvas theCanvas = null;
    19. startTime=System.currentTimeMillis();
    20. try {
    21. theCanvas = theView.getHolder().lockCanvas();
    22. synchronized (theView.getHolder()) {
    23. theView.onDraw(theCanvas);
    24. }
    25. } finally {
    26. if (theCanvas != null) {
    27. theView.getHolder().unlockCanvasAndPost(theCanvas);
    28. }
    29. sleepTime=TPS-(System.currentTimeMillis()-startTime);
    30. try{
    31. if(sleepTime>0){
    32. sleep(sleepTime);}
    33. else
    34. sleep(10);
    35. }
    36. catch (Exception e){
    37. }
    38. }
    39. }
    40. }
    41. public static void los() {
    42. // TODO Auto-generated method stub
    43. kolli=new KolissionsThread();
    44. kolli.run();
    45. }
    46. }
    Alles anzeigen


    und der SurfaceView mit dem Canvas:

    Java-Quellcode

    1. public GameView(Context context) {
    2. super(context);
    3. gameloopthread = new GameLoopThread(this);
    4. maini=(MainActivity) context;
    5. surfaceHolder = getHolder();
    6. bmphg=BitmapFactory.decodeResource(getResources(), R.drawable.hintergrund2);
    7. surfaceHolder.addCallback(new SurfaceHolder.Callback() {
    8. public void surfaceDestroyed(SurfaceHolder holder) {
    9. boolean retry = true;
    10. gameloopthread.setRunning(false);
    11. while (retry) {
    12. try {
    13. gameloopthread.join();
    14. retry = false;
    15. } catch (InterruptedException e) {
    16. }
    17. }
    18. }
    19. public void surfaceCreated(SurfaceHolder holder) {
    20. gameloopthread.setRunning(true);
    21. gameloopthread.start();
    22. }
    23. public void surfaceChanged(SurfaceHolder holder, int format,
    24. int width, int height) {
    25. // TODO Auto-generated method stub
    26. }
    27. });
    28. }
    29. @Override
    30. protected void onDraw(Canvas canvas) {
    31. time = (System.currentTimeMillis() - time_start) / 1000d;
    32. Paint pinselrot=new Paint();
    33. pinselrot.setColor(Color.RED);
    34. Paint pinsel=new Paint();
    35. pinsel.setAlpha(0);
    36. pinselrot.setAlpha(0);
    37. canvas.drawBitmap(bmphg, 0, 0, null);
    38. this.setOnTouchListener(this);
    39. Character.verschieben();
    40. boolean charr = true;
    41. Paint pinsel2= new Paint();
    42. pinsel2.setColor(Color.BLACK);
    43. pinsel2.setStrokeWidth(50);
    44. float textSize = pinsel2.getTextSize();
    45. pinsel2.setTextSize(textSize*4);
    46. if (charr == true) {
    47. bmp2 = BitmapFactory.decodeResource(getResources(),
    48. R.drawable.gruen);
    49. character = new Character(bmp2, this);
    50. character.onDraw(canvas);
    51. charr = false;
    52. }
    53. if (createSprites == true) {
    54. initialSprites();
    55. }
    56. for (Sprite sprite : spriteList) {
    57. sprite.onDraw(canvas);
    58. }
    59. canvas.drawRect(Character.rect, pinselrot);
    60. canvas.drawRect(Sprite.rect2,pinsel);
    61. canvas.drawText(""+ time, bmphg.getWidth()-150,50 , pinsel2);
    62. GameLoopThread.los();
    63. }
    Alles anzeigen


    Ich vermute das man das SurfaceView irgendwie dazubringen müsste sofort stehenzubleiben und nichts mehr zu zeichnen,aber egal...

    Hat jemand eine Idee wie man das Problem lösen kann? :D

    Grüße Jan