Monthly Archives: Kwiecień 2015

Czytnik kodów kreskowych Android

W tym tutorialu użyjemy bibliotekę ZXing (Zebra Crossing) aby móc skanować kody kreskowe na Androidzie. Nauczymy się wywoływać okno skanowania prosto z tej biblioteki i pobierać wynik jej działania. Nie musimy się martwić o to czy użytkownik zainstalował aplikację ZXing, ponieważ w bibliotece, której użyjemy znajdują się wszystkie potrzebne elementy.

Dzięki tej bibliotece jesteśmy w stanie skanować kody: EAN-8, EAN-13, UPC-A, Code 39, QR Code, UPC-E, Code 93, Data Matrix, Code 128, Codabar, ITF, RSS-14, RSS-Expanded, jednakże dla nas najważniejsze będą: Ean-8 i Ean-13, ponieważ znajdują się one na większości produktów, które można kupić w sklepie.

Do tworzenia aplikacji na telefon polecam program Android Studio, w którym ja sam tworzyłem, ponieważ automatycznie przygotowuje całe środowisko (wystarczy zainstalować i zacząć tworzyć).Uwaga! W ustawieniach telefonu musi być zaznaczona opcja „Debugowanie USB”, żeby móc testować aplikację podczas tworzenia.

1. Tworzenie projektu

Tworzenie nowego projektu

Tworzenie nowego projektu

Wybór platformy na którą chcemy pisać

Wybór platformy na którą chcemy pisać

Wybór typu aktywności, która ma zostać domyślnie utworzona

Wybór typu aktywności, która ma zostać domyślnie utworzona

Nazwanie nowo utworzonej aktywności

Nazwanie nowo utworzonej aktywności

2. Ustawianie wyglądu aktywności

Należy kliknąć w zakładkę "Text" aby przejść do tekstowej edycji wyglądu aktywności

Należy kliknąć w zakładkę „Text” aby przejść do tekstowej edycji wyglądu aktywności

Domyślnie wygenerowany tekst zaznaczamy i zamieniamy kodem poniżej

Domyślnie wygenerowany tekst zaznaczamy i zamieniamy kodem poniżej

 


[xml]
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<Button
android:id="@+id/scan_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/scan" />

<TextView
android:id="@+id/scan_format"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:layout_centerHorizontal="true"
android:layout_below="@id/scan_button" />

<TextView
android:id="@+id/scan_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:layout_centerHorizontal="true"
android:layout_below="@id/scan_format" />

</RelativeLayout>

[/xml]

Po poprzedniej operacji zostanie wypisany na ekranie błąd.

Po poprzedniej operacji zostanie wypisany na ekranie błąd.

Błąd wynika z tego, że chcielibyśmy, żeby na przycisku wypisany był tekst, który znajduje się w "@string/scan". Ale co to znaczy? Chodzi o to, że niektóre wartości (np. teksty) mogą w Androidzie być przechowywane w pliku XML, dzięki czemu bardzo łatwo jest stworzyć aplikację wielojęzyczną, ładując odpowiedni plik XML, w zależności od języka.

Przechodzimy do pliku strings.xml

Przechodzimy do pliku strings.xml

Dodajemy tam kod:

[xml]<string name="scan">Scan</string>[/xml]

Dopisany kod

Dopisany kod

Po przejściu do aktywności zobaczymy, że w podglądzie jest odpowiedni tekst

Po przejściu do aktywności zobaczymy, że w podglądzie jest odpowiedni tekst

W tej chwili możemy już uruchomić aplikację na telefonie, ale po naciśnięciu przycisku nic się jeszcze nie stanie.

3. Dodawanie biblioteki ZXing do aplikacji

Teraz będziemy potrzebować dwa pliki (IntentIntegrator.java i IntentResult.java), które są do pobrania tutaj. Ja osobiście pobrałem sobie wszystkie pliki ZXing z Githuba i dzięki temu mam odpowiednie ścieżki do plików. Polecam również tak zrobić.

Wyszukujemy w projekcie katalog java, klikamy prawym przyciskiem i klikamy "Show in Explorer"

Wyszukujemy w projekcie katalog java, klikamy prawym przyciskiem i klikamy "Show in Explorer"

Do otwartego katalogu kopiujemy katalog java, który po rozpakowaniu u mnie znajdował się w katalogu: C:\Users\admin\Downloads\zxing-master\zxing-master\android-integration\src\main

4. Pisanie kodu uruchamiania skanowania

Przechodzimy do kodu java aktywności

Przechodzimy do kodu java aktywności

Zaznaczamy tutaj cały kod który znajduje się w klamrze "public class MainActivity extends ActionBarActivity {"

i zamieniamy go na ten:

[java]

    //UI instance variables
    private Button scanBtn;
    private TextView formatTxt, contentTxt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //instantiate UI items
        scanBtn = (Button)findViewById(R.id.scan_button);
        formatTxt = (TextView)findViewById(R.id.scan_format);
        contentTxt = (TextView)findViewById(R.id.scan_content);

        //listen for clicks
        scanBtn.setOnClickListener(this);
    }

    public void onClick(View v){
        //Sprawdzanie czy został kliknięty przycisk skanowania
        if(v.getId()==R.id.scan_button){
            //instantiate ZXing integration class
            IntentIntegrator scanIntegrator = new IntentIntegrator(this);
            //start scanning
            scanIntegrator.initiateScan();
        }
    }
[/java]

Uwaga! Prawdopodobnie w tej chwili na ekranie masz mnóstwo kodu który świeci na czerwono. Należy każdy taki fragment zaznaczyć, nacisnąć skrót klawiszowy "Alt + Enter" i kliknąć "Import Class".

Dzięki temu po kliknięciu przycisku zostanie wyświetlony ekran skanowania i już można skanować, ale niestety wynik skanowania nie jest jeszcze odczytywany przez naszą aplikację. W następnym punkcie dopiszemy funkcję, która obsłuży wynik skanowania.

5. Pobieranie wyników skanowania

[java]
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        //pobranie wyniku za pomocą klasy IntentResult
        IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
        //sprawdzenie czy mamy poprawny wynik
        if (scanningResult != null) {
            //pobieramy wynik skanowania
            String scanContent = scanningResult.getContents();
            //pobieramy format kodu skanowania
            String scanFormat = scanningResult.getFormatName();
            //wyświetlamy na ekranie aplikacji
            formatTxt.setText("FORMAT: "+scanFormat);
            contentTxt.setText("CONTENT: "+scanContent);
        }
        else{
            //złe dane zostały pobrane z ZXing
            Toast toast = Toast.makeText(getApplicationContext(),
                    "No scan data received!", Toast.LENGTH_SHORT);
            toast.show();
        }
    }
[/java]

Uwaga! Prawdopodobnie w tej chwili na ekranie masz mnóstwo kodu który świeci na czerwono. Należy każdy taki fragment zaznaczyć, nacisnąć skrót klawiszowy "Alt + Enter" i kliknąć "Import Class".

6. Koniec pracy

Możesz już przetestować swój program. Gotowy projekt projekt możesz pobrać stąd.

Przetestuj skaner na tym kodzie kreskowym

Przetestuj skaner na tym kodzie kreskowym

Listy obiektów GameMaker

Wielokrotnie na tym blogu pisałem o tym, że lubię strukturę danych jaką jest lista, ponieważ jest mega wygodna i okazuj się bardzo szybka. Tak więc również napiszę trochę o tym, że w GameMaker da się korzystać z list, chociaż jest to trochę bardziej skomplikowane niż w C# czy Javie. Jeżeli nie wiesz na czym polegają listy, a chciałbyś się dowiedzieć, to bardzo fajnie wytłumaczone są tutaj.

Warto zacząć od tego jakie funkcje do zarządzania listami są dostępne w GM:

  • ds_list_create()– Tworzy nową listę. Funkcja tworzy wartość Integer (liczba całkowita) jako id (identyfikator) listy w pamięci operacyjnej. Tę wartość wykorzystuje się podczas manipulacji na liście.
  • ds_list_destroy(id)- Usuwa wartości listy z pamięci. Nie zapomnij używać tej funkcji, gdy kończysz pracę z listą.
  • ds_list_clear(id)- Czyści zawartość listy z danych, ale nie usuwa jej z pamięci jak poprzednia.
  • ds_list_copy(id,source)- Kopiowanie zawartości listy do innej listy.
  • ds_list_size(id)- Zwraca ilość elementów zapisanych w liście.
  • ds_list_empty(id)- Zwraca informacje czy lista jest pusta. To samo można sprawdzić za pomocą poprzedniej funkcji, czy wartość jest równa 0.
  • ds_list_add(id,val)- Dodaje wartość na koniec listy.
  • ds_list_insert(id,pos,val)- Dodaje wartość na konkretną pozycję w liście. Pierwszą pozycją jest 0, a ostatnią jest wynik funkcji size pomniejszony o 1.
  • ds_list_replace(id,pos,val)- Zamienia wartość z konkretnej pozycji w liście na nową wartość.
  • ds_list_delete(id,pos)- Usuwa wartość z konkretnej pozycji w liście.
  • ds_list_find_index(id,val)- Odszukuje indeks pozycji szukanej wartości w liście. Jeśli wartość nie zostanie znaleziona, to funkcja zwróci -1.
  • ds_list_find_value(id,pos)- Zwraca wartość zapisaną w podanej pozycji na liście.
  • ds_list_sort(id,ascend)- Sortuje elementy na liście. Kiedy ascend jest true wartości są sortowane rosnąco, jeżeli false, to malejąco.
  • ds_list_shuffle(id)- Tasuje listę, tak aby elementy były rozmieszczone losowo.
  • ds_list_write(id)- Zamienia listę na wartość typu string, dzięki czemu w łatwy sposób można zapisać ją w pliku tekstowym.
  • ds_list_read(id,str)- Odtwarza listę na podstawie wartości typu string. Bardzo pomocne gdy chcemy odtworzyć dane na podstawie tekstu, który został wygenerowany przy pomocy poprzedniej funkcji.

Przykład użycia listy (dodawanie elementów do listy):

[csharp]
list = ds_list_create();
ds_list_add(list, "value 1");
ds_list_add(list, "value 2");
ds_list_add(list, "value 3");
ds_list_add(list, "value 4");
ds_list_add(list, "value 5");
ds_list_add(list, "value 6");
// tutaj możesz dodać inne działania na tej liście
ds_list_destroy(list);
[/csharp]

 

Wspomniałem, że można zapisywać listę do pliku tekstowego, ale również ją z niego odczytać, a tutaj jest kod:

[csharp]

//Dla zapisu
var dslist,file;
dslist = ds_list_write([your list id]);
file = file_text_open_write("MyList.dslist");
file_text_write_string(file,dslist);
file_text_close(file);

//Dla odczytu
var dslist,file,str;
dslist = ds_list_create();
file = file_text_open_read("MyList.dslist");
str = file_text_read_string(file);
file_text_close(file);
ds_list_read(dslist,str);

[/csharp]

 

Wykrywanie jednocześnie dotyku i kliknięcia myszą WPF (MouseDown, TouchDown)

Dla niektórych tytuł może być nieco enigmatyczny, więc wyjaśnię w czym tkwi problem. Jeżeli używamy eventu „MouseDown”, to możemy również obsługiwać aplikacje za pomocą dotyku, ale niestety tylko jednego palca na raz, a my chcielibyśmy mieć możliwość obsługi za pomocą kilku punktów dotyku.

Więc następną próbą jest zamiana eventu „MouseDown” na „TouchDown”. Okazuje się, że dzięki temu możemy obsługiwać aplikację za pomocą kilku punktów dotyku, ale straciliśmy możliwość sterowania aplikacji myszką. Czyli ten pomysł też jest nie najlepszy.

Kolejna próba zbliżająca do rozwiązania problemu prawdopodobnie będzie polegać na ustawieniu dwóch eventów jednocześnie, czyli MouseDown i TouchDown. Przy korzystaniu z myszki wszystko działa jak należy, ale przy korzystaniu z dotyku okazuje się, że wszystko wykonuje się jakby dwa razy, ponieważ jednocześnie łapie i „MouseDown” i „TouchDown”.

Tak więc trzeba już tylko wymyślić sposób na rozdzielenie tych dwóch eventów. Można to zrobić w ten sposób:

[csharp]
       private void aplikacja1_MouseDown(object sender, MouseButtonEventArgs e)
        {
            MouseOrTouchApplication1Start(e);
        }

        private void aplikacja1_TouchDown(object sender, TouchEventArgs e)
        {
            MouseOrTouchApplication1Start(e);
        }

        void MouseOrTouchApplication1Start(InputEventArgs e)
        {
            if (e is TouchEventArgs)
            {
                Application1Start();
            }
            else if (e is MouseButtonEventArgs)
            {
                Application1Start();
            }
        }
[/csharp]

Jak widać na załączonym przykładzie użyłem tego kodu do uruchamiania innej aplikacji i dzięki temu zabezpieczeniu uruchomi się ona tylko raz podczas użycia dotyku.

Szybkie debugowanie – wyświetlanie wiadomości w konsoli GameMaker

Debugowanie kodu nie jest dobrą zabawą. Po prostu czasami coś się psuje i nie wiadomo dlaczego. Wtedy przychodzi moment na przejście działania programu lub jego części krok po kroku. Dlatego w GameMaker zastosowano nowy Debuger, który daje możliwość odtwarzania programu linijka po linijce, czy też stawianie tzw. „break points”.

Ale w większości zastosowań potrzeba nam prostego wypisywania pewnych danych na konsole i tego właśnie Was teraz nauczę.

Debuger - GameMaker

Debuger – GameMaker

Tak więc, zadanie jest mega proste. Wystarczy użyć tej krótkiej linijki kodu:

[csharp]show_debug_message(string(x) + "," + string(y))[/csharp]

aby wyświetlić wartość zmiennej i już nie błądzić w poszukiwaniu błędów. Pamiętajcie jednak o tym, że należy zmienne liczbowe najpierw parsować do postaci ciągu znaków (string) tak jak to zrobione jest w linijce kodu powyżej.

Okazuje się, że można wyświetlić te wartości jeszcze szybciej, pisząc o kilkadziesiąt znaków mniej za pomocą tej linijki kodu:

[csharp]trace(x, y)[/csharp]

Widok konsoli z wypisanymi danymi debugowania - GameMaker

Widok konsoli z wypisanymi danymi debugowania – GameMaker

Ale to jeszcze nie koniec. Można równie łatwo zapisywać te dane do pliku tekstowego, dzięki czemu nawet po wyeksportowaniu gry jesteście w stanie zobaczyć jakie są wartości interesujących Was zmiennych. Wystarczy oprócz użycia w kodzie poprzednich funkcji dopisać linijkę kodu uruchamianą przy starcie gry:

[csharp]global.logfile = file_text_open_write(working_directory + "\temp1.txt")[/csharp]

oraz dodać ten kod:

[csharp]file_text_write_string(global.logfile, r)<br />
file_text_writeln(global.logfile)[/csharp]

Wszędzie tam, gdzie zależy nam, żeby nastąpił zrzut konsoli do pliku tekstowego. Najlepiej nie robić tego zbyt często, ponieważ może to znacząco wpływać na wydajność działania aplikacji.

Pierwsze starcie z GameMaker

Czym jest GameMaker?

Jest to środowisko programistyczne, takie jak VisualStudio, czy Eclipse, które pozwala nam „programować” i tworzyć gry. Programować wziąłem w cudzysłów nie bez powodu, bo tak na prawdę każdy nawet osoba kompletnie bez umiejętności pisania kodu, może w tym środowisku wy-klikać coś co będzie działać. Nie perfekcyjnie, ale będzie działać.

Osobiście idea tego programu podoba mi się, ale jednak czuję wiele ograniczeń, które są nie do przeskoczenia, gdy pisało się wcześniej w czymś innym. Przede wszystkim wydaje mi się, że warto w GameMaker robić gierki planszowe, ponieważ znalazłem wiele Eventów, czy też fragmentów kodu, który znakomicie ułatwia pisanie takich gier. Nawet są wbudowane elementy w ten system, predefiniowana zmienna przechowująca informacje o ilości żyć gracza, itp.

GameMaker - widok głównego okna programu

GameMaker – widok głównego okna programu

Może też się przydać to narzędzie, do zrobienia szybkiego pokazu aplikacji dla klienta, który będzie ilustrował w prosty sposób działanie. Chociaż uważam, że do takich zastosowań są lepsze programy (ale też i droższe).

 

Plusy

Wieloplatformowość
Super, że jedną aplikację można wydać jednocześnie na kilka platform (oczywiście trzeba pamiętać o pewnych ograniczeniach, ale się da).

Tworzenie instalatora aplikacji
Fajną rzeczą jest również to, że po wyeksportowaniu aplikacji, buduje się instalator aplikacji, więc nie musisz już nic więcej robić, tylko przesłać to klientowi, a klient z instalatorem powinien sobie poradzić.

GameMaker - pisanie skryptów w aplikacji

GameMaker – pisanie skryptów w aplikacji

Każdy może w nim programować
W tej chwili modne jest programowanie i dlatego cieszę się, że dzięki GameMaker pisać, mogą również te osoby, które nie są jeszcze doświadczeni w klepaniu kodu, a być może nauczą się tu pewnych zachowań, dzięki którym będzie im łatwiej zacząć klepać.

 

Minusy

Niestety minusy też się znalazły. Dwa pierwsze niestety dyskwalifikują dla mnie tę aplikację. A mianowicie wielokrotne powtarzanie części kodu i brak pełnej obsługi dotyku.

GameMaker - edycja grafiki wstawionej do programu

GameMaker – edycja grafiki wstawionej do programu

Powtarzanie kodu
Trochę już w życiu napisałem i szczerze mówiąc w ciągu tych lat programowania stałem się nieco leniwy. A przynajmniej staram się pisać zwięźle i czysto, a pisanie w GM niestety nie dawało mi swobody. Przede wszystkim okazywało się wielokrotnie, że byłem zmuszony powtarzać pewne linijki kodu, a przez to kod stawał się ciężki do zmian.

Brak obsługi dotyku
Brak obsługi dotyku, jest dla mnie kpiną, ze względu na to, że w dzisiejszych czasach wszędzie się go używa, bo jest to jak najbardziej naturalne. Nie chce się w tym temacie bardziej rozpisywać, ponieważ po prostu dla mnie coś takiego powinno być w standardzie. Mogę jedynie podpowiedzieć, że dotyk jest rozpoznawany jako mysz, a gdy chce się zrobić Event dla tapnięcia, to należy użyć Eventu Mouse Release, w innym przypadku będzie trzeba podwójnie tapnąć żeby kliknąć. 2/10 nie polecam 🙂

 

Podsumowanie

Ale tak serio już podsumowując, to nie chcę nikogo zniechęcać do tego programu. Warto go wypróbować. W moich zastosowaniach się nie sprawdza, ale może w twoich będzie. Ponieważ byłem zmuszony zrobić jeden projekt w oparciu o GameMakera, to zrobię parę artykułów na jego temat wkrótce. Zapraszam do czytania i komentowania.

Modulo dodatnie C# (Dodatnia reszta z dzielenia)

Dzielenie z resztą w C# może zwracać wynik ujemny, co jest dość zaskakujące, ponieważ gryzie się z tym, czego uczyłem się na uczelni, czy w technikum. Tak więc, aby poprawić ten… błąd (?) napisałem krótki kod. Oczywiście mógłbym za każdym razem sobie coś takiego szybko napisać, ale co by było gdybym się pomylił, a tutaj jest pewny kod Continue reading

Zamiana domyślnej powłoki systemu Windows (explorer.exe) na własny program

Domyślnie w systemach z rodziny Windows po starcie systemu i zalogowaniu się odpalany jest Explorer, czyli powłoka systemu Windows. Dzięki niej możemy przeglądać pliki, zmieniać ustawienia systemu, widzimy pasek zadań, itp.

Jeżeli z jakiś powodów chcemy zamienić domyślną powłokę systemu Windows na jakiś inny program, to bez problemu można to wykonać tworząc wpis w rejestrze systemu Windows Continue reading

Automatyczne logowanie z hasłem do systemu Windows 8.1, 8, 7, XP

Zabezpieczenie komputera dobrym hasłem, jest istotną sprawą. Jednak do niektórych celów potrzebny jest komputer, który nie będzie wymagał wpisywania hasła. Dzięki czemu użytkownik od razu będzie z niego mógł korzystać. Oczywiście ze względów bezpieczeństwa nie zalecam automatycznego logowania na konto administratora.

Windows 8.1, 8, 7

Aby ustawić automatyczne logowanie, należy:

1. Nacisnąć skrót klawiszowy „Windows”+ „R”.

2. W oknie, które się wyświetliło należy wpisać „netplwiz” i zatwierdzić Enterem.

3. Następnie przejść do karty „Użytkownicy” i odznaczyć opcje „Aby używać tego komputera, użytkownik musi wprowadzić nazwę użytkownika i hasło”.

4. Kliknij przycisk „Zastosuj”, wpisz dwa razy poprawnie hasło tego użytkownika i naciśnij przycisk „OK”

5. Po tych operacjach należy zrestartować komputer. System już nie powinien pokazywać ekranu wyboru użytkownika do logowania.

Windows XP

1. Nacisnąć skrót klawiszowy „Windows”+ „R”.

2. W oknie, które się wyświetliło należy wpisać „control userpasswords2” i zatwierdzić Enterem.

3. Następnie przejść do karty „Użytkownicy” i odznaczyć opcje „Aby używać tego komputera, użytkownik musi wprowadzić nazwę użytkownika i hasło”.

4. Kliknij przycisk „Zastosuj”, wpisz dwa razy poprawnie hasło tego użytkownika i naciśnij przycisk „OK”

5. Po tych operacjach należy zrestartować komputer. System już nie powinien pokazywać ekranu wyboru użytkownika do logowania.