newbie 2D graphik

J

jim

Ambitioniertes Mitglied
0
Hallo liebes Forum,

ich habe mich nun durch "hello Android" gearbeitet und ein kleines Projekt angefangen. Ziel soll es sein eine Applikation zu erstellen welche einen Wert (m/s)entgegen nimmt und mit dem eingestellten Wert(Planet) verrechnet und ein Ball dann in der jeweiligen Geschwindigkeit fallen lässt. Ein Brett welcher mit der eingegebenen Geschwindigkeit über den Boden fährt soll diesen Ball auffangen. Wenn die Applikation startet können Werte eingegeben werden, nun möchte ich gern den grafischen Teil programmieren. Leider fehlt mir da das Wissen. Ich habe folgende KLasse erstellt um ein Viereck zeichnen zu können. Eigentlich soll nach dem Start der Applikation alles auf einem View sein, sowohl Eingabemöglichkleiten und der grafische Teil. Wie kann ich dies erreichen?? Leider sind die Tutorials oft nur für den Einstieg. Die folgende KLasse habe ich implementiert um die gewünschten Grafiken zu erstellen, leider überschreibt diese dann den View und der alte View mit den Buttons ist dann überschrieben?!
Code:
package com.jb;


import android.content.Context;
import android.graphics.Canvas;
import android.view.View;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;

public class MyDrawableView extends View
{
    private ShapeDrawable mDrawable;

    public MyDrawableView(Context context)
    {
        super(context);

        int x = 10;
        int y = 10;
        int width = 300;
        int height = 50;

        mDrawable = new ShapeDrawable(new OvalShape());
        mDrawable.getPaint().setColor(0xff74AC23);
        mDrawable.setBounds(x, y, x + width, y + height);
    }

    protected void onDraw(Canvas canvas) {
        mDrawable.draw(canvas);
    }
}
Code:
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        
        MyDrawableView mCustomDrawableView;
        mCustomDrawableView = new MyDrawableView(this);
        setContentView(mCustomDrawableView);
wenn ich das neue Objekt lade weis ich nicht wie ich den alten view und den neuen View kombinieren kann.

Ein Link mit tiefergehenden Tutorial würde mir auch reichen. open gl möchte ich da erstmal außer acht lassen!! wichtig wäre auch wie ich das mit der Bewegung hin bekomme!

Vielen Dank LG Jim
 
Ich nehme mal an, deine Eingabemöglichkeiten definierst du im xml File.
Code:
<LinearLayout id=l1>
EditText
EditText
</LinearLayout>
Dann kannst du deine "Custom View" hinzufügen, indem die Methode addView von dem LinearLayout aufrufst.
((LinearLayout)findViewById(R.id.l1)).addView(mCustomDrawableView);
Code:
      super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        MyDrawableView mCustomDrawableView;
        mCustomDrawableView = new MyDrawableView(this);
       ((LinearLayout)findViewById(R.id.l1)).addView(mCustomDrawableView);

Vierecke kannst du einfach mit der Funktion canvas.drawRect(links, oben, rechts, unten); zeichnen, jedoch nur, solange dessen Seiten parallel zu den Bildschirmrändern verlaufen.
Ansonsten musst du das Viereck in 2 Dreiecke unterteilen.
Bewegung bekommste, indem du die Koordinaten der Objekte veränderst, damit dass nicht alles in Sekunden Bruchteilen geschieht, kann man Thread.sleep(); benutzen.
 
Zuletzt bearbeitet:
Hallo...

ja ich definiere das Layout in der main.xml und habe dort jetzt folgendes eingefügt
Code:
[FONT=Verdana, sans-serif][SIZE=2]<LinearLayout 
   android:id="@+id/layout3"
   android:orientation="horizontal"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
  >
                
               
   </LinearLayout> [/SIZE][/FONT]
Ich kann auch jetzt den Kreis sehen, welchen ich hier erstellt habe.
Code:
package jb.com;


public class MyDrawableView extends View
{
    private ShapeDrawable mDrawable;

    public MyDrawableView(Context context)
    {
        super(context);

        int x = 100;
        int y = 100;
        int width = 5;
        int height = 5;

        mDrawable = new ShapeDrawable(new OvalShape());
        mDrawable = new ShapeDrawable(new OvalShape());

        mDrawable.getPaint().setColor(0xff74AC23);
        mDrawable.setBounds(x, y, x + width, y + height);
        
    }

    protected void onDraw(Canvas canvas) {
        mDrawable.draw(canvas);
    }
}
Mein erstes Problem wie verschiebe ich die ShapeDrawable?Der Punktoperator hat mir leider keine schlüssige Funktion geben können.. . Eine weitere Sache ist das wenn ich die Werte in der Datei
int x = 100;
int y = 100;
int width = 5;
int height = 5;
verändere und auch abspeichere sie nicht verändert auf dem Emulator zu sehen sind(die Veränderungen).

Oder gehe ich die Sache falsch an?

@Fr4gg0r -> lustiger bildschirmhintergrund
 
Mit translate kannst Du den Offset für weitere Zeichenoperationen verändern.

Code:
canvas.translate(x, y);
Dafür müsstest Du dann aber in onDraw() zeichnen. Weil Du ja das einmal im Konstruktor gezeichnetes später nicht mehr verändern kannst.
 
Hallo, ich habe jetzt mal folgenden Code hinzu gefügt.
1. jetzt werden nicht mehr die Elemente angezeigt (main.xml) sondern nur noch das canvas! ?? -> sprich schwarzer bildschirm und ein kreis welchen ich erzeugt habe
2. sogar wenn ich den Code ausdokumentiere erscheinen nicht wieder buttons & Co sondern weiterhin der grüne Kreis
3. die Bewegung, da ich die Werte ja in die hauptActivity besitzte und diese eine velocity bezeichen -> muss ich die Funktion dort aufrufen(HauptActivity ?) mit Parametern?
4. Wie bekomm ich so eine art mainloop hin?

Code:
 protected void onDraw(Canvas canvas)
    {    
        //canvas.translate(1,1);
        mDrawable.draw(canvas);
    }
gibt es eigetnlich noch eine gute lektüre ?
Pragmatic - Hello Android 2nd Edition (2009)
Android Grundlagen und Programmierung

diese beiden finde ich zwar hübsch anzuschauen und hilfreich aber das Forum hilft mir da meist weiter..... LG JIm
 
du bekommst eine Loop, indem du (z.b) innerhalb der onDraw invalidate(); aufrufst; denn dieses ruft wieder onDraw auf.
Zu 1: dafür müssten wir wohl mal dein Code sehen.
Zu 3: Geht beides. Du kannst sämtliche Methoden deiner View auch über den Punkt Operator aufrufen.

Allgemein: Warum arbeitest du mit ShapeDrawables? Ich hab keine Ahnung von denen, aber ich nehme an, dass Canvas.irgendwas(); schneller bzw. effektiver ist.

Wegen der Verschiebung:
canvas.translate(); wäre eine Möglichkeit, jedoch ist es mMn effizienter direkt die Koordinaten des Objektes zu ändern.
Es sei denn mehrere Objekte haben genau den gleichen Richtungsvektor.
Ansonsten musste nämlich wieder mit restore() und nochmal translate arbeiten, sind schonmal mindestens 3 Methodenaufrufe mehr.

Wegen Verschiebung und Canvas mal ein kurzes Codebeispiel von mir:

Code:
private class CustomView extends View {
private int x1 = 20;
private int y1 = 20;
private int x2 = 300;
private int y2 = 300;
public void onDraw(Canvas c){
   c.drawCircle(x1, y1, 10); //10 ist der Durchmesser
   c.drawCircle(x2, y2, 10);
  x1 += 2;
  y1 += 5;
  x2 -= 2;
  y2 -= 5;
  try{ Thread.sleep(50); }
  catch(Exception e){ }
  invalidate();
  }
}
Die erste Kreis wandert hierbei von oben links nach unten rechts, der andere genau entgegengesetzt.
 
Hallo,

erstmal habe ich gerade folgendes Problem
ActivityManager: Warning: Activity not started, its current task has been brought to the front

in einem Forum habe ich folgendes gefunden
On Jan 27, 3:43 am, Bob Kerns <[EMAIL PROTECTED]> wrote:
> This looks perfectly normal and correct to me. The application is
> already up-to-date on the device, and you already have the activity
> running, so it just brings it to the front.
aber das funktioniert nicht.

Der Kreis lief auch schon von links nach rechts, nun aber nicht mehr.
Hier also mal der ganze Code
Code:
public  class gravity_Game extends Activity 
{
    
    
     private EditText inputValue;
    //private double inputValueAsDouble;
     private int velocity;
    private double velocityDouble;
     /////////////////////////////////////////////////////////////////////////////////////////////
     /** Called when the activity is first created. */
    @Override
     public void onCreate(Bundle savedInstanceState)
    {
        
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
        
        
         MyDrawableView  mCustomDrawableView = new      MyDrawableView(this);
            ((LinearLayout)findViewById(R.id.layout3)).addView(mCustomDrawableView);  
        
             //////////////////////////////////////////////////////////////////////////////////////////////    
     ///spinner
        Spinner s1 =  (Spinner)findViewById(R.id.Planets);
         ArrayAdapter<CharSequence> adapter =
         ArrayAdapter.createFromResource(this,R.array.Planeten,  android.R.layout.simple_spinner_item);
         s1.setAdapter(adapter); 
      /////////////////////////////////////////////////////////////////////////////////////////////
       
        inputValue = (EditText) findViewById(R.id.EditText01);
         
        inputValue.setOnEditorActionListener(new  OnEditorActionListener()
        {
            public boolean  onEditorAction(TextView v, int actionId, KeyEvent event)
            {
                 if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
                 {
                    //velocity = getValue and cast to  double
                    velocityDouble =  Double.parseDouble(inputValue.getText().toString());
                     
                    ///Textview for Inputvalue
                     TextView velocityValue =  (TextView)findViewById(R.id.EditTextValue);
                     velocityValue.setText( velocityDouble + "ms");
                }
                 return false;
            }
        });

}
Code:
package  jb.com;

import android.content.Context;
import  android.graphics.Canvas;
import android.view.View;
import  android.graphics.drawable.ShapeDrawable;
import  android.graphics.drawable.shapes.OvalShape;

public class  MyDrawableView extends View
{
    private ShapeDrawable mDrawable;
     private int x = 10;
    private int y = 10;
    int width = 30;
     int height = 30;
    public MyDrawableView(Context context)
    {
         super(context);

       

        mDrawable = new  ShapeDrawable(new OvalShape());
         mDrawable.getPaint().setColor(0xff74AC23);
         mDrawable.setBounds(x, y, x + width, y + height);
        
    }

     protected void onDraw(Canvas canvas)
    {    
         //canvas.translate(50,10);
         x += 2;
         // y += 5;

         
          mDrawable.setBounds(x, y, x + width, y + height);
         
          
          mDrawable.draw(canvas);
           try{ Thread.sleep(50); }
          catch(Exception e){ }
           
          invalidate();

    }
}

Leider passiert es auch, als der punkt noch gewandert ist, das der rest verschwunden ist(also die buttons) und der Kreis ganz oben lief.
Wie kann ich die werte(Variable) aus der gravity_game.java bekommen?

Danke für die Hilfe!!!!!
 
also das Problem mit
"ActivityManager: Warning: Activity not started, its current task has been brought to the front "
kann doch durch das Verändern (leertaste-> abspeichern)der hauptactivity gelöst werden.
Mein Problem ist gerade das ich in der folgenden Klasse alles ausdokumentiert habe und er anscheinend irgendwoher die alte nimmt!

Code:
package jb.com;

import android.content.Context;
import android.graphics.Canvas;
import android.view.View;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;

public class MyDrawableView extends View
{
        private ShapeDrawable mDrawable;
//         int x = 10;
//         int y = 10;
//        int width = 10;
//        int height = 10;
        
    public MyDrawableView(Context context)
    {
        super(context);
    
        
       
        
        
//        mDrawable = new ShapeDrawable(new OvalShape());
//        mDrawable.getPaint().setColor(0xFF0000FF);
        
        
    }
    @Override
    protected void onDraw(Canvas canvas)
    {    
//        canvas.translate(50,10);
//         x += 2;
//          y += 5;
        
          mDrawable.draw(canvas);
//          mDrawable.setBounds(x, y, x + width, y + height);
//         
//          invalidate();
          
//          try{ Thread.sleep(50); }
//          catch(Exception e){ }
Wie kann das sein???
 
Zuletzt bearbeitet:
jim schrieb:
also das Problem mit
"ActivityManager: Warning: Activity not started, its current task has been brought to the front "

Das ist überhaupt kein Problem.
Das ist ledigliche eine "Fehlermeldung", die auftritt, wenn du versuchst dein aktuelles Projekt auf dem Emulator zu installieren, obwohl es keinen Unterschied zu der Version auf dem Emulator gibt.
Also, nur installieren drücken, wennde was geänder hast.;)
Zum Starten kannst du ja im App Menü die App im Emulator auswählen...
 
Ich bin mir nicht sicher was du mit installieren meinst. Ich benutze eclipse mit dem emulator. Wie vorher beschrieben benutze ich die "leerzeichen einfügen und löschen und dazwischen abspeichern" Technik. Jetzt habe ich festgestellt das er die Klasse nicht aktulisiert also auf dem emulator (AVD). siehe oben. ich dachte schon ich werde bescheuert!!!
 
jim schrieb:
Ich bin mir nicht sicher was du mit installieren meinst. Ich benutze eclipse mit dem emulator. Wie vorher beschrieben benutze ich die "leerzeichen einfügen und löschen und dazwischen abspeichern" Technik.

Die Frage ist "Für was zu tue"?:D
Wenn du Run (in Eclipse) auswählst, dann wird die Version auf dem Emulator installiert und die alte überschrieben; gleichzeitig wird die App gestartet.
Unterscheidet sich nun die auf dem Emulator von der die du gerade installierst nicht, so kommt die o.g. "Fehlermeldung".
Es ist total unnötig jedes mal eine kleine Änderung zu machen, damit Eclipse nicht meckert, stattdessen einfach im Emulator die App starten.
Die Ausnahme ist, wenn noch kein Emulator vorhanden ist, dann "darf" man, obwohl man nichts geändert hat, Run auswählen in Eclipse.
Achja, falls du deine App komplett abschießen und neustarten möchtest (vll. ist das ja dein Anliegen...), so reicht es wenn du den Back-Button drückst.
Dieser ruft standardmäßig die onDestroy Methode auf, womit die gesamte App tot ist.
Ich nehme mal an, dies wolltest du wohl erreichen...


Wegen dem Code:
edit: ne hab mich verguckt.
 
Zuletzt bearbeitet:
Hallo,

mein Problem war das sich jene Klasse nicht aktualisiert, welche ich in der extends activity benutze.... (und das weil ich ein Idiot bin!!--> habe die falsche Datei editiert..... grrrrrrr)
soweit klappt jetzt alles. Jetzt brauch ich den Wert aus dem Edittext und dachte ich könnte das so machen.
Da ich den Wert in der extends View
Code:
public class MyDrawableView extends View
{

        private ShapeDrawable mDrawable;
        ///Textview for Inputvalue
        TextView velocityValue;
        Drawable myImage;
        int x = 0;
        int y = 0;
        int width = 100;
        int height = 100;
        int speed =0;
        EditText inputValue = (EditText)findViewById(R.id.EditText01);
       
       
       
    
       
    public MyDrawableView(Context context)
    {
        super(context );
       
    
       
        inputValue.setOnEditorActionListener(new OnEditorActionListener()
        {
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
            {
                if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
                {
                    //speed = getValue and cast to double
                    speed = Integer.parseInt(inputValue.getText().toString());
                   
                    ///Textview for Inputvalue
                    TextView velocityValue = (TextView)findViewById(R.id.EditTextValue);
                    velocityValue.setText( speed + "ms");
                }
                return false;
            }
        }
        );
        ///load picture
        Resources res = context.getResources();
         myImage = res.getDrawable(R.drawable.cabrio);
         myImage.setBounds(x, y, x + width, y + height);
       
   
       
       
       
        mDrawable = new ShapeDrawable(new OvalShape());
        mDrawable.setBounds(x, y, x + width, y + height);
        mDrawable.getPaint().setColor(0xFF0000FF);
       
       
    }
    @Override
    public void onDraw(Canvas canvas)
    {   
       
        //canvas.translate(90,10);
         
          //y += 1;
       
        x += speed;
       
       if(x>=100 || x < 0)
            speed *= -1;
       
       
       
           
        myImage.draw(canvas);
          //mDrawable.draw(canvas);
         
          myImage.setBounds(x, y, x + width, y + height);
//         
          invalidate();
         
//          try{ Thread.sleep(50); }
//          catch(Exception e){ }

    }
}

nachdem ich den Teil mit dem Listener ausdokumentiert habe funktioniert es wieder. Gibt es einen anderen Weg den Wert zu bekommen? bzw. warum funktioniert das so nicht. vielen vielen dank!
 
Zuletzt bearbeitet:

Ähnliche Themen

P
Antworten
9
Aufrufe
1.932
pseudopat
P
C
Antworten
7
Aufrufe
2.404
coreytaylor211
C
C
Antworten
18
Aufrufe
2.365
coreytaylor211
C
Zurück
Oben Unten