Android – dobór koloru tekstu pod kolor tła

Gdy dodajemy tekst na jakimś tle, którego kolor ustawiany jest dynamicznie, mamy problem: jaki kolor tekstu? Czarny czy biały?

Aby rozwiązać ten problem, należy sprawdzić, jak jasny jest kolor tła. Problem w tym, że wpływ poszczególnych komponentów RGB na ogólną jasność jest różna, stąd trzeba ową jasność policzyć uwzględniając tę zasadę. Ja użyłem dość popularnej w internecie formuły – i spisuje się naprawdę dobrze.

    /**
     * Find the right color of the text, depending on the color of the background.
     * @param aColor Color, to which we're adjusting by contrast.
     * @return Black or white color.
     */
    public int getBlackOrWhite(int aColor)
    {
        int red = (aColor >> 16) & 0xFF;
        int green = (aColor >> 8) & 0xFF;
        int blue = (aColor >> 0) & 0xFF;
        int result = 0;
        if (((double)red*0.299 + (double)green*0.587 + (double)blue*0.114) > 186)
            result = Color.BLACK;
        else
            result = Color.WHITE;
        return result;
    }

Parametrem wejściowym jest kolor tła, wartość zwracana to kolor czarny lub biały. Formuła doboru wygląda na dobrą, bo spośród tych kolorów, które przetestowałem, wybór: czarny-biały zawsze był trafny, stąd mogę ją z czystym sumieniem polecić – co też czynię.

Facebooktwittergoogle_plusredditpinterestlinkedinmail
twitterlinkedin

Android: pełna obsługa multitouch w grze

Dodać do programu (gry) obsługę dotyku pod Androidem jest niezmiernie prosto. Wystarczy kilka linijek kodu:

 

@Override
public boolean onTouchEvent(MotionEvent event)
{
	float x = event.getX();
	float y = event.getY();

	switch (event.getAction())
	{
	case MotionEvent.ACTION_DOWN:
		processTouchDown(x, y);
		break;
	case MotionEvent.ACTION_UP:
		processTouchUp(x, y);
		break;
	}		
	return false;
}

 

Schody zaczynają się w momencie, gdy chcemy zrobić np. pełne sterowanie postacią – a jego ramach np. ruch oraz strzelanie. Już przy pierwszym teście dochodzimy do wniosku, że chcemy obsługiwać wiele palców naraz, niezależnych od siebie.

 

Z pomocą przychodzi nam mechanizm dodany w API Level 8, czyli od Androida 2.2.x Froyo. Każdy event dotyku zawiera w sobie pełną informację o wszystkich ewentualnych punktach nacisku, ich pozycji itd. Dlatego, naszą obsługę zdarzeń rozwiniemy tak:

 

private int actionMovementId = -1;
private int actionFiringId = -1;

 

@Override
public boolean onTouchEvent(MotionEvent event)
{
	int actionId = event.getActionIndex();
	float x = event.getX(actionId);
	float y = event.getY(actionId);

	switch (event.getActionMasked())
	{
	case MotionEvent.ACTION_DOWN:
	case MotionEvent.ACTION_POINTER_DOWN:
		processTouchDown(x, y, actionId);
		break;
	case MotionEvent.ACTION_UP:
	case MotionEvent.ACTION_POINTER_UP:
		processTouchUp(x, y, actionId);
		break;
	}

	return false;
}

 

private void processTouchDown(float x, float y, int actionId)
{
	Point displaySize = new Point(CgEngine.display.getWidth(), CgEngine.display.getHeight());
	int touchableArea = displaySize.y * 3 / 4;
	int halfX = displaySize.x / 2;

	if (y > touchableArea)
	{
		// fire!
		if (x < halfX)
		{
			CgEngine.playerFireAction = CgEngine.PLAYER_FIRE_SHOOT;
			actionFiringId = actionId;
		}
		// steering
		else
		{
			if (x < halfX * 1.5)
				CgEngine.playerRunAction = CgEngine.PLAYER_TURN_LEFT_1;
			else
				CgEngine.playerRunAction = CgEngine.PLAYER_TURN_RIGHT_1;

			actionMovementId = actionId;
		}
	}
}

 

private void processTouchUp(float x, float y, int actionId)
{
	if (actionFiringId == actionId)
	{
		CgEngine.playerFireAction = CgEngine.PLAYER_FIRE_HOLD;
		actionFiringId = -1;
	}
	if (actionMovementId == actionId)
	{
		CgEngine.playerRunAction = CgEngine.PLAYER_RELEASE;
		actionMovementId = -1;
	}
}

 

Jak widać, przy rozpoczynaniu każdej akcji, musimy zapamiętać identyfikator palca, który ją uruchomił – później, gdy przyjdzie event puszczenia palca, będzie można łatwo zidentyfikować, która akcja powinna się zakończyć.

 

Powodzenia!

 

Facebooktwittergoogle_plusredditpinterestlinkedinmail
twitterlinkedin