Skocz do zawartości
Kostek92

Gra statki - obsługa przycisków

    Rekomendowane odpowiedzi

    Mam za zadanie napisać grę statki na zaliczenie w ramach projektu. Nawet nie wiem czy dobrze zaczynam, dlatego wolę napisać tutaj. Jako planszę pod grę, wrzuciłem 10x10 kwadratów jako ImageView do GridLayout. Teraz próbuję nawiązać z nimi jakąś interakcje, w tym wypadku zmianę obrazka po naciśnięciu danego kwadracika. Póki co eksperymentuje tylko na piewszym wierszu.

    Mój kod

    package com.example.statki;
    
    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.ImageView;
    
    public class Gra extends Activity {
    
    //ImageView K0W0;
    Context context;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.gra);
    
    	//Statek statek = new Statek();
    
    	final ImageView tab[] ={
    
    			(ImageView) findViewById(R.id.K0W0),
    			(ImageView) findViewById(R.id.K1W0),
    			(ImageView) findViewById(R.id.K2W0),
    			(ImageView) findViewById(R.id.K3W0),
    			(ImageView) findViewById(R.id.K4W0),
    			(ImageView) findViewById(R.id.K5W0),
    			(ImageView) findViewById(R.id.K6W0),
    			(ImageView) findViewById(R.id.K7W0),
    			(ImageView) findViewById(R.id.K8W0),
    			(ImageView) findViewById(R.id.K9W0),
    			};
    
    
    	for (int i=0; i<tab.length; i++){
            tab[i].setOnClickListener(new OnClickListener() {
            	 public void onClick(View v) {
            		tab[i].setImageResource(R.drawable.pole_pressed);
    
    			}
            });
    	}
    }
    }

    Niestety ten sposób z tablicą na zmianę obrazka się sie sprawdza, Eclispe każe mi zmienić int i na final, co mija się z celem. Może ma ktoś jakieś inne pomysły na rozwiązanie problemu?

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Możesz dać ImageView[] tab do klasy. Final nie ma tu znaczenia bo i ta możesz zmienić tab.cośtam.

    Ogólnie ja bym polecał ta zrobić:

    int[][] plansza; // 10x10

    do tego gridview dać te imageView, osobno zadeklarować OnClick i dla każdego imageview dać ten sam onClick

    w tym onClick sprawdzić, który imageview kliknięty i zmienić odpowiedni int w planszy.

    w tym onClick zmienić wygląd tego imageview (lub każdego) odpowiednio wg planszy tj.

    np. plansza[5][2] == 1 to img[5][2].setImageResource(R.drawable.pole_pressed);

    I tu robisz logikę dla planszy czyli czy trafiony zatopiony itp., czy wygrana itp.

    edit: jeśli pole będzie mieć tylko 2 stany, to można pokusić się o ToggleButton zamiast ImageView

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    Możesz dać ImageView[] tab do klasy.

    Chodzi Ci o to, żeby zrobić nową klasę ImageView z tymi przyporządkowanymi polami?

    osobno zadeklarować OnClick i dla każdego imageview dać ten sam onClick

    w tym onClick sprawdzić, który imageview kliknięty i zmienić odpowiedni int w planszy.

    No właśnie tego nie wiem jak zrobić. Mógłbyś bardziej szczegółowo rozwinąć swoją wypowiedź? Bo jakoś nie bardzo sobie to umiem wyobrazić, w androidzie działam dopiero od 2-3 tygodni...

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    Chodzi Ci o to, żeby zrobić nową klasę ImageView z tymi przyporządkowanymi polami?

    Nie, chodziło mi jako zmienną w klasie Gra. Czyli pod Gra extends Activity... dać ImageView[] tab;

    No właśnie tego nie wiem jak zrobić. Mógłbyś bardziej szczegółowo rozwinąć swoją wypowiedź? Bo jakoś nie bardzo sobie to umiem wyobrazić, w androidzie działam dopiero od 2-3 tygodni...

    Do klasy Gra dodać implements OnClickListener. Eclipse będzie wołał, żeby do klasy dodać onClick(View v). Potem w onCreate w pętli masz tab.setOnClickListener(this); możesz w tym miejscu też dać tab.setTag(i) (lub potem 10*i+j jak będziesz operać na 2-wymiarowej tablicy), żeby przypisać do imageview konkretne pole.

    A w onClick:

    public void onClick(View v) {
     ImageView img = (ImageView)v
     int p = (Integer)img.getTag();
     if (p == -1) return; // był wcześniej kliknięty, olewamy
     plansza[0][p] = 1;
     // jakas logika gry, np. trafiony zatopiony
     img.setImageResource(...);
     img.setTag(-1); // oznaczamy jako kliknięty
    }

    Tak w skrócie.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Zrobiłem jak mówisz. Przy metodzie

    for (int i=0; i<tab.length; i++)
    		tab[i].setOnClickListener(this);
    
    	public void onClick(View v) {
    		  ImageView img = (ImageView)v;
    		  //int p = (Integer)img.getTag();
    		  //if (p == -1) return; // był wcześniej kliknięty, olewamy
    		  //	plansza[0][p] = 1;
    		  // jakas logika gry, np. trafiony zatopiony
    		  img.setImageResource(R.drawable.pole_pressed);
    		  //img.setTag(-1); // oznaczamy jako kliknięty
    		}
    

    Wyświetla mi błąd void is invalid type for onClick. I jescze 2 błędy przy nawiasach, że mają być tam średniki.

    Te tagi do logiki planszy narazie zakomentowałem, żeby cokolwiek ruszyło.

    P.S. Dzięki za pomoc

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Zupełnie pokręcone. Pisałem ogólnikowo pomysł, nie zamierzałem pisać całego kodu. OnClick jako osobna metoda. Chwytaj szkielet programu:

    public class Gra extends Activity implements OnClickListener {
    ImageView[] tab;
    int plansza[][];
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.gra);
    
    	tab = new ImageView[] {
    		(ImageView) findViewById(R.id.K0W0),
    		(ImageView) findViewById(R.id.K1W0),
    		(ImageView) findViewById(R.id.K2W0),
    		(ImageView) findViewById(R.id.K3W0),
    		(ImageView) findViewById(R.id.K4W0),
    		(ImageView) findViewById(R.id.K5W0),
    		(ImageView) findViewById(R.id.K6W0),
    		(ImageView) findViewById(R.id.K7W0),
    		(ImageView) findViewById(R.id.K8W0),
    		(ImageView) findViewById(R.id.K9W0),
    		};
    	plansza = new int[10][10];
    
    	for (int i=0;i<10;i++) {
    		tab[i].setOnClickListener(this);
    		tab[i].setTag(i);
    	}
    }
    
    @Override
    public void onClick(View v) {
    	ImageView img = (ImageView)v;
    	int p = (Integer)img.getTag();
    	if (p == -1) return; // był wcześniej kliknięty, olewamy
    	plansza[0][p] = 1;
    	// jakas logika gry, np. trafiony zatopiony
    	img.setImageResource(R.drawable.pole_pressed);
    	img.setTag(-1); // oznaczamy jako kliknięty
    }
    }

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Twój kod bardzo mi pomógł, jednak do planszy chciałem stworzyć osobną klasę. Po tworzeniu obiektu plansza Eclipse wywala okno, które pyta czy chcę przejść do trybu debugera, a cała aplikacja siada.

    Wygląda to tak

    public class Gra extends Activity implements OnClickListener{
    
    ImageView[][] tab;
    Plansza plansza;
    
    Context context;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.gra);
    	context=getApplicationContext();
    	 tab = new ImageView[][]{
    
    .
    .
    .
    //Koniec tablicy 
    
                    plansza = new Plansza();
    
    

    A kod klasy plansza to po prostu póki co jedna tablica i konstruktor

    package com.example.statki;
    
    public class Plansza  {
    
    public int[][] pola;
    
    public Plansza(){
    	pola[1][1]=1;
    
    }
    }
    

    Narazie jest tam przypisane, żeby sprawdzić czy całość pójdzie pod warunkiem do sprawdzania trafienia

    I jeszcze jedno pytanie, czy da się wykrzesać w metodzie OnClick współrzędne klikniętego kwadracika tablicy tab? Przydało by się to do ustawiania statków ;]

    if(p==plansza.pola[1][1])

    Edytowane przez Kostek92

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Wywala się, bo pola jest nullem. Trzeba na początku zainicjalizować (pola = new int[10][10]). W setTag i getTag możesz wsadzić cokolwiek, np. stringa "1x1" i go odpowiednio parsować w onClick.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

    Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

    Zarejestruj nowe konto

    Załóż nowe konto. To bardzo proste!

    Zarejestruj się

    Zaloguj się

    Posiadasz już konto? Zaloguj się poniżej.

    Zaloguj się

    • Ostatnio przeglądający   0 użytkowników

      Brak zarejestrowanych użytkowników przeglądających tę stronę.

    x