Zarządzanie usługami w systemie Windows poprzez .NET

Jakiś czas temu pojawił się problem z moją drukarką. Zdarza się czasem, że kiedy trzeba wydrukować więcej dokumentów, drukarka drukuje pierwszy dokument i przez długi czas nie chce go usunąć z kolejki drukowania, co uniemożliwia drukowania kolejnych dokumentów.

Rozwiązaniem jest wyłączenie usługi Print Spooler w Windows. Potem wyłączenie i włączenie drukarki, a następnie włączenie usługi.

To rozwiązanie nie jest zbyt wygodne, chociażby ze względu na to, że za każdym razem trzeba uruchamiać Usługi, znajdować określoną usługę i ją włączać i wyłączać. Przyszło mi na myśl, czy nie dałoby by się napisać prostego programu w .NET, który wyłączałby i włączał usługę. Otóż, dałoby się. Służy do tego klasa ServiceController.

Pierwszym problemem, z jakim się po raz pierwszy spotkałem był brak możliwość dołączenia przestrzeni nazw System.ServiceProcess. Okazało się, że trzeba dodać referencje do tej przestrzeni w projekcie w Visual Studio.

2017-04-18 11_08_59-Reference Manager - Print Spooler Controller

Potem napisałem bardzo prosty programik konsolowy, który zarządza usługą Print Spooler.

2017-04-18 12_10_44-Print Spooler Controller - Microsoft Visual Studio (Administrator)

Jeżeli trzeba zarządzać większą ilością usług, można pobrać wszystkie usługi, a potem wyszukiwać odpowiednich poprzez LINQ. W moim przypadku wyglądałoby to tak:

2017-04-18 12_18_59-Print Spooler Controller - Microsoft Visual Studio (Administrator)

Oczywiście oprócz wyłączania i włączania usług można wykonywać o wiele więcej czynności. Wszystkie można znaleźć w dokumentacji Microsoftu.

Ostatnią rzeczą, o jakiej należy pamiętać zarządzając usługami, to nadanie uprawnień administratora do programu, bo inaczej program rzuci nam wyjątek z komunikatem o braku dostępu.

To tyle na dziś. Jeżeli macie jakieś pytania albo zastrzeżenia zapraszam do komentowania. Do następnego wpisu.

Nowy przeciwnik i umieszczanie obiektów na scenie poprzez skrypt w Unity

W ciągu ostatniego tygodnia udało mi się zaprojektować kolejnego przeciwnika – Endermana. Większość z was pewnie kojarzy tą postać z Minecrafta. W kwadratowym świecie, ta postać jest neutralna wobec nas, póki nie spojrzymy w jej oczy. Jeżeli jednak to zrobimy, teleportuje się do nas i zaczyna z nami walczyć. Nawiązując do odpowiednika tej postaci w Minecrafcie, zrobiłem postać, która jeżeli na nią patrzymy zaczyna do nas strzelać pociskami. Na filmie na YouTube możecie zobaczyć jak wygląda nowy przeciwnik. Możecie także kontynuować czytanie tego wpisu.

Enderman

Postać po prawej to nasz Enderman. Astronauta jest na poziomie wzroku niebieskiego ludzika, więc tajemnicza postać strzela do niego czerwonymi pociskami.

Implementacja

Umieszczenie na scenie nowego obiektu jest całkiem proste. Wystarczy użyć funkcji Instantiate.

public void Update()
{
   _actualReloadTime += Time.fixedDeltaTime;
   if (_actualReloadTime >= ReloadTime && !_collider2D.isTrigger && IsPlayerInFrontOf())
   {
      _actualReloadTime = 0;
      var bullet = (GameObject)Instantiate(BulletPrefab, 
      StartingBooletPosition(), _transform.rotation);
      bullet.GetComponent<Rigidbody2D>().velocity = GetBulletForce(bullet);
      Destroy(bullet, 2.0f);
    }
}

Podczas metody Update() naliczany jest czas. Jeżeli przekroczył określoną wartość, a Enderman znajduje się na przeciwko gracza, resetowany jest czas, tworzony jest obiekt na podstawie prefaba pocisku i nadawana jest mu prędkość. Po 2 sekundach pocisk jest niszczony.

Za wykrywanie tego, czy Enderman jest skierowany w kierunku gracza odpowiada metoda IsPlayerInFrontOf():

private bool IsPlayerInFrontOf()
{
   var playerPosition = _player.transform.position;
   var playerBounds = _player.GetComponent<Collider2D>().bounds;
   var endermanPosition = _transform.position;
   var endermanBounds = _collider2D.bounds;
   var isOnTheSameVerticalPosition = (playerPosition.y > endermanPosition.y && playerPosition.y < endermanPosition.y + endermanBounds.max.y) || (playerPosition.y + playerBounds.max.y > endermanPosition.y && playerPosition.y + playerBounds.max.y < endermanPosition.y + endermanBounds.max.y);
   var isInFrontOf = (FacingRight && playerPosition.x > endermanPosition.x) || (!FacingRight && playerPosition.x < endermanPosition.x);
   return isOnTheSameVerticalPosition && isInFrontOf;
 }

Jak widać jest to dosyć spore działanie logiczne. Podejrzewam, że mógłbym ten zapis jakoś uprościć korzystając chociażby z prawa de Morgana, ale w tej postaci chyba łatwiej jest zobaczyć, co tu się dzieje w tym miejscu kodu.

W całości kod Endermana można zobaczyć tutaj. Nie będę go tu pokazywać, bo kod jest podobny do implementacji poprzednich przeciwników.

Gotowy skrypt trzeba było umieścić na obiekcie Endermana i wypełnić ustawienia w inspektorze Unity:

2017-04-15 15_59_36-Unity 5.5.0f3 Personal (64bit) - Demo.unity - Moon Problem - PC, Mac &amp; Linux Sta

Oprócz tego skryptu musiałem jeszcze napisać bardzo krótką implementację pocisku. Wygląda ona tak:

public class BulletScript : MonoBehaviour 
{
   public void OnCollisionEnter2D(Collision2D collision)
   {
      if(collision.gameObject.tag=="Player")
         collision.gameObject.GetComponent<PlayerMovementScript>().Restart();
      Destroy(gameObject);
   }
}

Zadaniem tych linii kodu jest wywołanie restartu poziomu, jeżeli dojdzie do zderzenia pocisku z graczem. Jeżeli pocisk zderzy się np. ze ścianą to po prostu zostanie zniszczony.

To tyle, jeżeli chodzi o zmiany, jakich dokonałem w tym tygodniu. Jeżeli macie jakieś pytania, albo zastrzeżenia zachęcam do komentowania. Po więcej zapraszam do następnego wpisu, który już za tydzień.

Instalacja Visual Studio 2017 i pierwsze wrażenia

Mimo iż premiera Visual Studio 2017 miała miejsce nieco ponad miesiąc temu, nie miałem czasu się jej bliżej przyjrzeć. W zasadzie, to bardziej się obawiałem, że podczas instalacji się coś popsuje, jak to zdarza się z poprzednią wersją i skończy się to zabawą w rejestrze, albo co gorsza – formatem komputera, na którego nie mam czasu.

Ze względu na to, że jest przerwa świąteczna, mam trochę więcej czasu, więc zabrałem się za instalację.

Instalacja

2017-04-12 18_35_57-OneNote

Pierwszą rzeczą ewidentnie na plus, było opracowanie nowego interfejsu podczas wybierania komponentów do zainstalowania. Na estetycznych kafelkach opisane jest pokrótce, co dodaje każdy komponent. O ile to dla bardziej doświadczonych programistów nie robi to żadnej różnicy, to początkującym może znacznie ułatwić instalację. Jedyną rzeczą, do jakiej mógłbym się przyczepić w tym oknie to (przynajmniej dla mnie) ciężko dostrzegalny pasek do wybrania lokalizacji instalacji VS. Za pierwszy razem go nie zauważyłem i musiałem potem przerywać instalację.

Ja postanowiłem zainstalować pakiety związane z C++, .NET, .NET Core, ASP.NET oraz dodatek do Unity, który jest właściwie niezbędny do mojego projektu. Miałem zamiar zainstalować jeszcze Xamarina, ale kiedy zauważyłem, że musiałbym pobrać dodatkowo aż 30 GB, postanowiłem odłożyć zabawę z natywnymi aplikacjami mobilnymi na później.

Ku mojemu zaskoczeniu przy instalacji nie wyskoczył mi, ani jeden błąd, ani ostrzeżenie. Zwykle z VS2015 zdarzały się jakieś problemy. Trzeba było coś pozmieniać w rejestrze, przeinstalować program, albo w ostateczności zrobić formatowanie komputera. Albo miałem tym razem szczęście, albo rzeczywiście Microsoft rozwiązał ten problem.

Pierwsze wrażenia

2017-04-12 19_23_03-Start Page - Microsoft Visual Studio

W menu głównym zostały dokonane niewielkie kosmetyczne zmiany, ale według mnie są to dobre zmiany. Jeżeli chodzi o tworzenie projektów to praktycznie nic się nie zmieniło. Tak wygląda ekran po stworzeniu projektu aplikacji konsolowej:

2017-04-12 19_29_04-ConsoleApp1 - Microsoft Visual Studio

Na pierwszy rzut oka nie widać nic nowego. Nowe funkcje Visual Studio opiszę po jakimś czasie pracy w nim. Na razie tylko podrzucam linka do zmian opisanych w dokumentacji Microsoftu.

Jeśli macie jakieś wskazówki dotyczące nowego VS, albo chcecie się podzielić własną opinią zachęcam do komentowania.

Potrzeba WIĘCEJ przeciwników!!!

Jak zapowiadałem w poprzednik poście, w tym miesiącu trzeba zrobić więcej przeciwników. A więc tak zrobiłem. Zapraszam do obejrzenia filmu na YouTube.

Cyclon

W ciągu ostatniego tygodnia udało mi się stworzyć kolejnego przeciwnika – Cyclona (lub jeżeli ktoś woli spolszczoną nazwę – Cyklona). Przeciwnik nie wiele się różni od pająka. Ma jedną zasadniczą różnicę. Kiedy wskoczy się na niego, zamiast umierać tak jak w przypadku pająka, kurczy się i przechodzi w tryb obronny, czyli zaczyna szybciej się poruszać. Po 60 sekundach wraca do poprzedniego ustawienia.

Cyclon

Implementacja

Jeżeli mechanika Cyklona nie wiele się różni od pająka, to kod tak samo. Dlatego dokładniej pokażę tylko elementy, które różnią się względem pająka.

public class CyclonScript : MonoBehaviour
{
   private float _actualSpeed;
   public float MovementSpeed = 0.125f;
   public float DeffendModeSpeed = 0.250f;
   public float DeffendModeTime = 60f;
   private float _deffendModeTime = 0;
   public Sprite DefaultSprite;
   public Sprite DeffendSprite;
   private Transform _transform;
   private SpriteRenderer _spriteRenderer;
   private Collider2D _collider2D;
   public bool FacingRight = false;

   public void Start (){...}
   public void FixedUpdate(){...}
   private void BackToDefaultMode(){...}
   public void OnCollisionEnter2D(Collision2D collision){...}
   public void OnCollisionStay2D(Collision2D collision){...}
   private void DeffendMove(){...}
   private void Flip(){...}
   private void Move(){...}
   void Update (){...}
   private void Die(){...}
}

Pierwszą różnicą, jaką można zauważyć jest fakt, że zamiast jednego pola odpowiadającego za prędkość postaci powstały, aż 3. Wynika to z tego, że mamy 2 tryby, w których są różne prędkości. _actualSpeed przechowuje aktualną prędkość postaci. MovementSpeed ustawioną prędkość w trybie domyślnym, a DeffendModeSpeed ustawioną prędkość w trybie obronnym.

W tym skrypcie znajdziemy także pole _deffendModeTime, które przechowuje aktualny czas trwania trybu obronnego.

Zamiast Animatora, znajdziemy tutaj 3 pola. Jeden z nich to SpriteRenderer, który odpowiada za renderowanie Spritów na ekranie. Dwa pozostałe to Sprite trybu normalnego i obronnego. Brak animatora jest spowodowany tym, że tak naprawdę nie ma animacji tylko 2 klatki, dla dwóch różnych sytuacji, w których może znajdować się postać.

Kolejną różnicę można zobaczyć w OnCollisionStay2D():

public void OnCollisionStay2D(Collision2D collision)
{
   if (collision.gameObject.tag == "Player")
   {
      var collisionDetector = new CollisionDetector(_collider2D);
      if (collisionDetector.CollideOnTheTop() != null && 
      collisionDetector.CollideOnTheTop().gameObject.tag == "Player") DeffendMove();
   }
}

Zamiast umierania postaci po zetknięciu się u góry z graczem, postać przechodzi w tryb obronny:

private void DeffendMove()
{
   _spriteRenderer.sprite = DeffendSprite;
   _actualSpeed = DeffendModeSpeed;
   _deffendModeTime = 0;
}

Zmieniany jest Sprite postaci oraz prędkość. Resetowany jest także zegar odliczający czas w trybie obronnym. Liczenie czasu znajduje się w metodzie Update():

void Update()
{
   _deffendModeTime+=Time.fixedDeltaTime;
}

Czas trwania trybu obronnego jest zwiększany, co klatkę o czas trwania ostatniej klatki. Kiedy czas przekroczy ustalone 60 sekund w metodzie FixedUpdate() wywoływana jest metoda BackToDefaultMode():

public void FixedUpdate()
{
   Move();
   if (_deffendModeTime >= DeffendModeTime)
   {
      BackToDefaultMode();
   }
   Die();
}
private void BackToDefaultMode()
{
   _spriteRenderer.sprite = DefaultSprite;
   _actualSpeed = MovementSpeed;
}

Zmieniany jest w niej Sprite oraz prędkość Cyklona na domyślne wartości.

To wszystkie ważniejsze zmiany, jakie udało mi się zrobić w ciągu ostatniego tygodnia. Jeżeli macie jakieś pytania albo zastrzeżenia piszcie w komentarzach. Do następnego wpisu.

Miesiąc prowadzenia bloga – czas na pierwsze podsumowanie

Parę dni minął miesiąc od początku Daj Się Poznać, a więc i początku mojej przygody z blogowaniem. Także mój projekt też się postarzał. Czas na pierwsze podsumowanie tego co udało się zrobić w marcu, a także tego, co nie udało się zrobić. A więc zaczynamy.

Co udało się zrobić?

  • Założyłem bloga. Bardzo się obawiałem czy to w ogóle dobra decyzja. Na razie tylko wiem, że nie była beznadziejna. Ale czy dobra? Póki co, nie jestem tego wstanie stwierdzić.
  • Zrobiłem pierwszy raz grafikę. Nigdy tego nie robiłem. Zawsze korzystałem z gotowców. Może nie jest zbyt ładna, ale fajnie jest zrobić coś swojego.
  • Zrobiłem mapkę do testów. Jest mała i niezbyt zaawansowana, ale ona nie jest prawdziwym poziomem. Jej zadaniem jest bycie polem testowym do konstruowania mobów, przedmiotów, ulepszeń itp.
  • Założyłem kanał na YouTube. Od wielu lat marzyłem o tworzeniu wideo. Najpierw chciał zostać Let’s Playerem, potem streamerem. Zawsze mi coś przeszkadzało. Raz za słaby sprzęt, raz szybkość Internetu. O ile w sprawie tego drugiego nic się nie zmieniło to sprzęt mam całkiem dobry i cieszę się, że udało mi się to jakoś wykorzystać w ramach bloga.
  • Liczba unikalnych gości na blogu: 98. Liczba wyświetleń: 203. Obserwujący na Twitterze: 34. Subskrypcje na YouTube: 5. Polubień na Facebooku: 5.

Czego nie udało się zrobić?

  • Nie zadbałem o promowanie postów. Podobno należy poświęcić tyle samo czasu na pisanie wpisu, co jego promowanie. Jako, że moje promowanie polegało na wrzuceniu tweet’u na Twitterze z #dajsiepoznac oraz postu na Facebooku, można równie dobrze powiedzieć, że nie reklamowałem swoich wpisów w ogóle.
  • Nie zadbałem o różnorodność zawartości na social mediach. To wiąże się z poprzednim punktem. Twitter to Twitter. Facebook to Facebook. Wrzucanie prawie tego samego nie ma chyba sensu.
  • Nie wykorzystałem Snapchata. Nie wiem jak z niego sensownie korzystać. Śledzę profile Macieja Aniserowicza, Piotra Gankiewicza, Andrzeja Krzywy oraz innych programistów. Sposób prowadzenia Snapchata, przez nich bardzo mi się podoba, ale w moim przypadku by się nie sprawdził. Głównie z tego powodu, że nie jestem na tyle kompetentny, żeby wypowiadać się na poruszane przez nich tematy. Drugą sprawą jest fakt, że na Snapie mam znajomych, którzy nie interesują się programowaniem wcale i nie chciałbym, żeby zrobił się z tego (z ich perspektywy) spamu. Jeżeli macie jakieś rady w tym zakresie, zachęcam do komentowania.
  • Nie zarysowałem zbyt dokładnie projektu na początku. Brnąłem trochę na oślep wymyślając kolejne rzeczy na bieżąco.
  • Za długo piszę posty. Zdarza mi się, że mam taką blokadę, że wpis powstaje parę godzin, demolując mi cały dzień. Trzeba coś z tym zrobić.

Plany na kwiecień

  • Do końca tego miesiąca chciałbym zaprojektować wszystkich przeciwników do gry. Nie będzie ich zbyt wielu, bo zaledwie czterech. Zastanawiam się jeszcze nad tym, żeby każdy z przeciwników miał swoje mocniejsze warianty. Zobaczymy co z tego wyjdzie.
  • Więcej reklamy swoich wpisów.
  • Więcej różnorodnej reklamy swoich wpisów.
  • Znaleźć swoją niszę na Snapchacie.
  • Zmienić formułę filmów na YouTube. Póki nie potrafię mówić spontanicznie, muszę zacząć trochę „reżyserować” filmy. Aktualnie mam sporo problemów z montowaniem materiału, ze względu na brak płynności mówienia podczas kręcenia.

To tyle na dziś. Jeżeli masz jakieś zastrzeżenia albo pytania zapraszam do pisania komentarzy. Do zobaczenia w kolejnym wpisie.

 

Detekcja, z której strony doszło do kolizji – Unity

Ostatnio w projekcie zaszło mało widocznych w rozgrywce zmian – doszło tylko zabijanie pająka. Więcej czasu poświęciłem na refaktoryzację istniejącego kodu. Zachęcam do obejrzenia filmu na YouTube albo przeczytania tego wpisu.

Metoda Restart

private void Restart()
{
   SceneManager.LoadScene("Demo");
}

Jeżeli metoda zostanie wywołana, scena zostaje na nowo załadowana. Z tego też powodu if’a sprawdzającego czy gracz spadł w przepaść musiałem przenieść do FixedUpdate():

public void FixedUpdate()
{
   Move();
   Jump();
   if (_transform.position.y < -20)
   {
      Restart();
   }
}

Detekcja, z której strony doszło do kolizji

Jako, że dosyć często korzystam z detekcji, z której strony doszło do kolizji postanowiłem wydzielić tą funkcjonalność do osobnej klasy. Nazwałem tą klasę CollisionDetector:

public class CollisionDetector
{
   private Collider2D _collider2D;

   public CollisionDetector(Collider2D collider2D){...}
   public Collider2D CollideOnTheLeft(){...}
   public Collider2D CollideOnTheRight(){...}
   public Collider2D CollideOnTheTop(){...}
   public Collider2D CollideOnTheBottom(){...}
   private Vector3 GetLeftDownCorner(){...}
   private Vector3 GetSizeOfObject(){...}
}

Pole _collider2D przechowuje collider2D obiektu, dla którego sprawdzamy kolizje. Podajemy go w konstruktorze:

public CollisionDetector(Collider2D collider2D)
{
   _collider2D = collider2D;
}

Metody CollideOnTheLeft(), CollideOnTheRight(), CollideOnTheTop(), CollideOnTheBottom() zwracają Collider2D, z jakim doszło do kolizji, z którejś ze stron lub null, jeśli do kolizji z danej strony nie doszło. Implementacje tych metod pokażę na przykładzie CollideOnTheLeft():

public Collider2D CollideOnTheLeft()
{
   Vector3 leftDownCorner = GetLeftDownCorner();
   Vector3 size = GetSizeOfObject();

   float oneThird = (size.y-0.2f)/3;
   leftDownCorner.x -= 0.000001f;
   leftDownCorner.y += 0.1f;
   for (int i = 0; i < 3; i++)
   {
      if(i!=0) leftDownCorner.y += oneThird;
      RaycastHit2D hit = Physics2D.Raycast(leftDownCorner, Vector2.left, 0.1f);
      if (hit.collider != null) return hit.collider;
   }
   return null;
 }

Metoda pobiera lewy dolny róg oraz rozmiar Collider2D. Potem w pętli tworzony jest RaycastHit2D w 3 punktach przy lewej ścianie Collidera na dole, na środku oraz u góry. Potem, jeżeli RaycastHit2D wychwycił kolizję zwracany jest Collider2D obiektu, z którym doszło do zderzenia. Jeżeli do tego nie doszło zwracany jest null. Pozostałe 3 metody wyglądają bardzo podobnie, różnią się tylko punktami, w który powstaje RaycastHit2D. Poniżej zamieszczam implementacje metod GetLeftDownCorner() oraz GetSizeOfObject(), które można było zobaczyć w metodzie wyżej:

private Vector3 GetLeftDownCorner()
{
   Vector3 leftDownCorner = _collider2D.transform.position;
   leftDownCorner.x -= _collider2D.bounds.extents.x;
   return leftDownCorner;
}

private Vector3 GetSizeOfObject()
{
   return _collider2D.bounds.size;
}

Po stworzeniu tej klasy wystarczyło pozmieniać warunki logiczne w metodach wykonujących się przy zdarzeniu kolizji. Kod sprawdzający czy gracz został zabity przez pająka wyglądał tak:

if (collision.gameObject.tag == "Enemy")
{
   Vector3 positionLeft = _transform.position;
   positionLeft.y += 0.5f;
   positionLeft.x -= 0.7f;
   RaycastHit2D hitLeft = Physics2D.Raycast(positionLeft, Vector2.left, 0.001f);
   if (hitLeft.collider != null && hitLeft.collider.gameObject.tag == "Enemy") Restart();
 
   Vector3 positionRight = _transform.position;
   positionRight.y += 0.5f;
   positionRight.x += 0.7f;
   RaycastHit2D hitRight = Physics2D.Raycast(positionRight, Vector2.right, 0.001f);
   if (hitRight.collider != null && hitRight.collider.gameObject.tag == "Enemy") Restart();

   Vector3 positionTop = _transform.position;
   positionTop.y += 2.6f;
   RaycastHit2D hitTop = Physics2D.Raycast(positionTop, Vector2.up, 0.001f);
   if (hitTop.collider != null && hitTop.collider.gameObject.tag == "Enemy") Restart();
}

A teraz wygląda tak:

if (collision.gameObject.tag == "Enemy")
{
   var collisionDetector = new CollisionDetector(_collider2D);
   if (collisionDetector.CollideOnTheLeft() != null && 
       collisionDetector.CollideOnTheLeft().gameObject.tag == "Enemy") Restart();

   if (collisionDetector.CollideOnTheRight() != null && 
       collisionDetector.CollideOnTheRight().gameObject.tag == "Enemy") Restart();

   if (collisionDetector.CollideOnTheTop() != null && 
       collisionDetector.CollideOnTheTop().gameObject.tag == "Enemy") Restart();
}

Nie dość, że kod jest trochę czystszy to jeszcze kolizja jest sprawdzana w 3 punktach, a nie w jednym po każdej stronie, co zmniejsza szansę na błąd.

Zabijanie pająka

Rzeczą widoczną w rozgrywce, jaką udało mi się dodać było zabijanie pająka. Jeżeli gracz naskoczy na pająka z góry to ginie. Za realizację tej mechaniki odpowiadają 4 metody w skrypcie pająka:

public void OnCollisionStay2D(Collision2D collision)
{
   if (collision.gameObject.tag == "Player")
   {
   var collisionDetector = new CollisionDetector(_collider2D);
   if (collisionDetector.CollideOnTheTop() != null && 
       collisionDetector.CollideOnTheTop().gameObject.tag == "Player") Die();
   }
}

Jeżeli dojdzie do kolizji z graczem wywoływana jest metoda Die():

private void Die()
{
   DeathAnimation();
   _collider2D.isTrigger = true;
}

Metoda Die() wyłącza Collider2D pająka i wywołuje DeathAnimation():

private void DeathAnimation()
{
   _animator.SetTrigger("isDeath");
   Vector3 scale = _transform.localScale;
   scale.x *= 0.5f;
   scale.y *= 0.5f;
   _transform.localScale = scale;
}

Metoda DeathAnimation() włącza animację śmierci oraz zmniejsza pająka o połowę.

Podczas FixedUpdate() wykonywana jest jeszcze metoda PhysicalElementOfDeathAnimation():

private void PhysicalElementOfDeathAnimation()
{
   RotateSpiderGameObject();
   SpiderGameobjectDestroy();
}

Pierwsza z metod wywoływanych przez powyższą odpowiada za wykonywania obrotu umierającego pająka, a druga za zniszczenie obiektu pająka:

private void RotateSpiderGameObject()
{
   if (_collider2D.isTrigger)
   {
      Vector2 vector = new Vector2(0.125f / 2, 0.125f / 2);
      _transform.Rotate(vector, 5f);
   }
}

private void SpiderGameobjectDestroy()
{
   if (_transform.position.y <= -5f)
   {
      Destroy(gameObject);
   }
}

Po za tymi zmianami dokonałem kosmetycznych zmian nazw tagów i layerów.

To wszystko, co udało mi się zrobić w tym tygodniu. Jeżeli masz jakieś pytania lub zastrzeżenia zachęcam do komentowania. Do następnego wpisu.

Czy technikum to dobre miejsce dla przyszłego programisty?

Nieco ponad tydzień temu na blogu Łukasza Soroczyńskiego, który także uczestniczy w Daj Się Poznać, pojawił się wpis dotyczących technikum, a konkretniej profilu informatycznego i czy jest to miejsce, w którym może się spełnić przyszły programista. Jako, że po pierwsze, w projekcie mało się dzieje, a po drugie sam jestem uczniem technikum, to myślę, że warto napisać swoje własne przemyślenia. Zawsze lepiej, żeby osoba, która zastanawia się nad technikum mogła zobaczyć dwie opinie niż jedną. Jeżeli tą osobą jesteś ty to tym bardziej zachęcam do przeczytania.

Czego powinieneś oczekiwać po technikum?

Jako, że jest to szkoła, w której nauka trwa rok dłużej zapewne zakładasz, że możesz nauczyć się czegoś więcej niż liceum. W liceum na profilu mat-fiz-inf, czy mat-inf na informatyce możesz nauczyć się obsługiwać Worda, Excela i PowerPointa w stopniu nieco wyższym niż tylko umiejętność zmiany koloru i wielkości czcionki. Po liceum powinieneś także umieć tworzyć proste szablony stron internetowych oraz umieć pisać algorytmy, zarówno w postaci schematów blokowych, jak i w postaci programów napisanych w języku programowania np. C++.

Za to, jako absolwent technikum, oprócz zagadnień z informatyki w liceum na poziomie rozszerzonym, także powinieneś:

  • Umieć składać komputer, wykonywać na nim czynności administracyjne, umieć wykonywać mniej skomplikowane naprawy oraz znać budowę komputera.
  • Umieć tworzyć oraz zarządzać siecią lokalną.
  • Umieć tworzyć aplikacje webowe, bazy danych oraz nimi administrować.

Ktoś może zwrócić uwagę, że jest to bardzo szeroki zakres materiału, bo przecież ciężko jest, żeby ktoś był bardzo dobrym sieciowcem, programistą i przy okazji znać się dobrze na sprzęcie.  Na szczęście (albo nieszczęście), egzaminy nie są trudne i jeżeli  w miarę przykładasz się do przedmiotu powinieneś sobie bez większych problemów poradzić z ich zdaniem.

Jakie technikum wybrać?

Wydawałoby się, że najlepiej byłoby wybrać jak najlepsze. Im lepsze technikum tym większa jest szansa na to, że możesz nauczyć czegoś więcej niż tylko podstawowych zagadnień do egzaminów. Do tego, jeżeli wybierasz się na studia bardzo ważną zaletą dobrych techników są dobre wyniki matur. Za to dosyć sporą wadą jest fakt, że w takich technikach ma się mniej czasu na rozwijanie się w własnym zakresie.

Dobrym przykładem jest moja szkoła. Znajduje się bardzo wysoko w różnego rodzaju rankingach ogólnopolskich. Wiedza, której uczymy się na przedmiotach zawodowych wykracza ponad podstawę programową (a przynajmniej, jeśli chodzi o programowanie, bo reszta mnie średnio interesuje). Mimo iż aplikacje się od trzeciej klasy, to wiem, że oprócz standardowego PHP’a, javascript’a, SQL’a na lekcjach uczniowie uczą się jQuery, C#, Node.js oraz trochę Javy. Absolwenci mojej szkoły dostają się na dobre uczelnie, albo znajdują dobrze płatną pracę. Jednak szkoła ma jedną zasadniczą wadę, a jest nią czas, a w zasadzie jego brak. Bez dobrego zarządzania czasem raczej nie da się mieścić między lekcjami systemów operacyjnych programowania czy po prostu rozrywki.

Za to, jeżeli zdecydujesz się na nieco słabszą szkołę zapewne możesz liczyć na nieco więcej czasu, aczkolwiek mniej się dowiesz w takiej szkole. Decyzja należy do Ciebie.

Jeżeli wybierzesz się do technikum musisz być cierpliwy

Mam tu na myśli programowanie na lekcjach. Na lekcjach informatyki zaczniesz programować w języku programowania najprawdopodobniej w drugiej klasie. Jak trafi ci się odpowiedni nauczyciel informatyki to może nawet w pierwszej, ale nie oczekuj, że będziesz zaczynał (zakładam, że trochę programowałeś) od programowania obiektowego czy wielowątkowości. Będziesz potraktowany tak samo jak inni uczniowie – napiszesz w c++:

#include <iostream>
int main()
{
  std::cout << "Hello World" << std::endl;
}

albo trochę inaczej, ale w innym języku.

Tak jak już wyżej wspominałem aplikacje najprawdopodobniej zaczniesz w trzeciej klasie. Tam już prędzej poczujesz, że czegoś nowego się uczysz (nie mogę ci tego zapewnić, bo tego dowiem się, za co najmniej 2 lata).

W technikum spotkasz więcej ludzi, którzy programują

W mojej klasie jestem wstanie wymienić, co najmniej parę osób, którzy znają się już więcej niż trochę na programowaniu. Do tego prawie cała klasa uczęszcza na kółko z C++. Oznacza to tylko jedno – w klasie na pewno będziesz miał już od pierwszej klasy kompanów do dyskusji o programowaniu.

Będziesz miał wybór

Po liceum musisz pójść na studia. Po technikum masz wybór – możesz pójść na studia, albo możesz się zadowolić tytułem technika i iść szukać pracy. Nie wiem jak dla Ciebie, ale dla mnie to było ostatecznym czynnikiem, który zadecydował, że poszedłem do technikum. Rynek pracy się zmienia bardzo szybko i zamierzam się do niego jak najlepiej dostosować. Jeżeli będzie mi się opłacało iść do pracy to po prostu do niej pójdę i będę wiedział, że mam przynajmniej tytuł technika. Jeżeli jednak okażę się, że lepiej jest iść na studia będę miał zdaną maturę i będę mógł wyniki z niej złożyć na wybraną przez mnie uczelnię.

Powodzenia

Ja za Ciebie szkoły nie wybiorę. Ja poszedłem do technikum i przynajmniej na razie tego nie żałuję. Teraz ty musisz podjąć decyzję.

Jeżeli należysz już do grupy osób uczących się, albo absolwentów technikum o profilu informatycznym, serdecznie zapraszam do pisania komentarzy pod tym wpisem. Im więcej informacji będzie mogła się dowiedzieć osoba zastanawiająca się nad technikum, tym bardziej świadomy będzie jej wybór.