Keresés

Új hozzászólás Aktív témák

  • thon73

    tag

    válasz shinodas #661 üzenetére

    Itt egy lehetséges megoldás. API10 és AIDE alatt készült, de elvileg bármiben működik. 800x480 pixeles képernyőm van, de persze a méretek a képnek megfelelően változtathatóak. Az egyszerűség kedvéért beágyazott View-t használtam, ill. nem ellenőrzi a View beállításait, ez végleges megoldásnál ildomos!
    A kód sok helyen nincs optimalizálva, inkább jól érthetőt akartam írni. ((Pl. én nem is tennék két joysticket egy view-ba, vagy ha igen, akkor két külön objektumként stb.))

    public class JoystickActivity extends Activity
    {
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(new Felulet(this));
    }

    public class Felulet extends View
    {
    private float[] origox = {200f, 600f};
    private float[] origoy = {180f, 220f};

    private float joyx[] = {origox[0], origox[1]};
    private float joyy[] = {origoy[0], origoy[1]};

    private float joyarea = 150f;
    private float joyrad = 40f;
    private int joyid[] = {-1, -1};

    private Paint area;
    private Paint rad;

    public Felulet(Context context)
    {
    this(context, null, 0);
    }

    public Felulet(Context context, AttributeSet attrs)
    {
    this(context, attrs, 0);
    }

    public Felulet(Context context, AttributeSet attrs, int defStyle)
    {
    super(context, attrs, defStyle);

    area=new Paint();
    area.setStyle(Paint.Style.STROKE);
    area.setColor(Color.RED);
    area.setStrokeWidth(5f);

    rad=new Paint();
    rad.setStyle(Paint.Style.FILL_AND_STROKE);
    rad.setColor(Color.GREEN);
    rad.setStrokeWidth(5f);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
    switch (event.getActionMasked())
    {
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_MOVE:

    int pointerCount = event.getPointerCount();
    for (int n=0; n<2; n++)
    {
    if (joyid[n] == -1)
    {
    for (int cnt = 0; cnt < pointerCount; cnt++)
    {
    if (distance(joyx[n], joyy[n], event.getX(cnt), event.getY(cnt)) < joyrad)
    {
    joyid[n] = event.getPointerId(cnt);
    break;
    }
    }
    }
    else
    {
    boolean id_flag = false;
    for (int cnt = 0; cnt < pointerCount; cnt++)
    {
    if (joyid[n] == event.getPointerId(cnt))
    {
    if (distance(origox[n], origoy[n], event.getX(cnt), event.getY(cnt)) < joyarea - joyrad)
    {
    joyx[n] = event.getX(cnt);
    joyy[n] = event.getY(cnt);
    this.invalidate();
    }
    else
    {
    // aránypárral v. szögfüggvénnyel mozgatható a kerületen
    }
    id_flag=true;

    break;
    }
    }
    if (!id_flag)
    reset_joy(n);
    }
    }
    break;

    case MotionEvent.ACTION_UP:
    reset_joy(0);
    reset_joy(1);
    break;
    }
    return true;
    }

    protected void reset_joy(int n)
    {
    joyid[n] = -1;
    joyx[n] = origox[n];
    joyy[n] = origoy[n];

    this.invalidate();
    }

    protected float distance(float x1, float y1, float x2, float y2)
    {
    float x = x1 - x2;
    float y = y1 - y2;

    return FloatMath.sqrt(x * x + y * y);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
    for (int n=0; n<2; n++)
    {
    canvas.drawCircle (origox[n], origoy[n], joyarea, area);
    canvas.drawCircle (joyx[n], joyy[n], joyrad, rad);
    }
    }
    }
    }

    Az elv: a két index a két külön joysticket jelenti. Origox/y a közepe a két joysticknek, Joyx/y pedig az aktuális helyzete. Joyrad (kiskör) karikán belül lehet csak "megfogni" a joysticket, Joyarea (nagykör) sugaron kívül nem tud mozogni. A távolságot Pithagorasz tétellel számolja, ez nem a legjobb helyen van az osztályon belül.
    A JoyId a legfontosabb: ha -1, akkor nincs érintés hozzárendelve (középen van a joystick). Ha egy érintés belelép a kiskörbe, akkor annak id-je lesz a JoyId és azt követi. A nagykör szélén megáll, de az érintéshez továbbra is ragaszkodik. Nem akartam bonyolítani, de az igazi az lenne, ha a köríven menne az ujjad után. (a megjegyzés helyén kezelhető ez)
    Ha az Id eltűnik (ezt ellenőrzi a flag), vagyis azt az ujjad felemelted, akkor középre áll. Szintúgy akkor is, ha ACTION_UP lesz, vagyis minden ujj elhagyta a képet. Ilyenkor lehetne ütemadóval visszaúsztatni, de kis méretben az ugrás sem zavaró.
    Ilyenre gondoltál? Remélem segít továbblépni, a lényeg úgyis az ID kezelés volt. Ha valami nem tiszta, szívesen segítek.

Új hozzászólás Aktív témák