Kreatywne programowanie jako ciekawy wstęp do nauki kodowania
Gdy zaczynałem przygodę z programowaniem natknąłem się na kurs C++, w którym pierwszym zadaniem było zapytanie w konsoli o wiek i odpowiedzenie, że ktoś jest stary lub młody. Prawdopodobnie wiele osób wciąż zaczyna swoją przygodę w podobny sposób, więc za pomocą JavaScriptu, chciałbym pokazać, że nauka programowania może być ciekawsza. Artykuł zawiera bardzo dużą dawkę informacji w bardzo skróconej formie, więc nie martw się jeśli gdzieś po drodze będziesz czuł się zagubiony. Mam nadzieję że po przeczytaniu tego artykułu programowanie stanie się również Twoją pasją.
Od czego zacząć
Dla uproszczenia użyjemy narzędzi dostępnych online, które ułatwią nam start, osobiście polecam:
- codepen- bardzo proste, z tego skorzystamy w naszych przykładach
- codesandbox- świetnie nadaje się do większych projektów, bardziej zaawansowane
Po wejściu na stronę codepen'a po lewej stronie dostępne jest menu CREATE
. Pen to zestaw 3 plików - html, css i js. Project pozwala na tworzenie własnych plików, dodawania obrazków itp. ale dany użytkownik może mieć za darmo tylko jeden projekt. Utwórzmy więc nowego Pen'a klikając po lewej stronie Pen
. Naszym oczom ukaże się ekran podzielony na 4 części - części w których możemy pisać HTML, CSS, JS oraz podgląd z rezultatem naszej pracy który odświeża się na żywo.
Spróbuj napisać jakiś tekst w HTML-u, powinien wyświetlić się po chwili w podglądzie.
Osobiście wolę też widok "side by side", może go zmienić klikając "Change View" w prawym górnym rogu.
Dodanie HTML canvas
Jednym z elementów dostępnym w HTMLu jest element canvas
. Jest to element na którym z poziomu Javascriptu można malować... właściwie cokolwiek przyjdzie Ci do głowy. Od prostej kreski, po grę FPS. Dodajmy ten element w HTMLu: <canvas></canvas>
.
Aby móc się do niego odwołać jednoznacznie w pliku js musimy dodać mu jakiś identyfikator, nazwę go "creative-programming", a więc ostatecznie część html będzie wyglądać w ten sposób:
<canvas id="creative-programming"></canvas>
Strona wciąż będzie wyglądała na pustą, ponieważ nasz canvas jest cały biały.
Zmienne
Przejdźmy do Javascriptu.
Zmienne - możesz o nich myśleć jak o adresach swoich znajomych. Jak chcesz któregoś odwiedzić to prawdopodobnie musisz znać jego adres. Podobnie tutaj, jak chcesz sprawdzić zapisaną wartość musisz zapamiętać jej adres (ukryty pod nazwą zmiennej którą sam wybierasz). Bez zmiennych musiałbyś za każdym razem obliczać lub wpisywać jakąś stałą wartość. W Javascript'cie możemy zadeklarować zmienną na 3 sposoby:
var a = 5;
let b = 5;
const c = 5;
Pierwszy sposób jest stary i już nie używany więc pominę jego tłumaczenie. let
służy do deklaracji zmiennych którym potem możemy przypisać inną wartość (tak jakby znajomy który może się przeprowadzić). const
służy do deklarowania zmiennych które po przypisaniu zostaną już tam gdzie są (ale wciąż można w nich przeprowadzić remont, czyli zmienić jakąś ich część).
Zmienne w JavaScript mogą być typu:
string
(napis)number
(liczba rzeczywista)boolean
(prawda/fałsz)null
(nie istnieje)undefined
(nie zdefiniowano, zazwyczaj nie ustawiane ręcznie)symbol
,BigInt
(zaawansowany typy który pominiemy)function
(o funkcjach mowa później)object
(złożony typ zawierający w sobie jakiekolwiek typy, tak jakby książka adresowa która może też zawierać też inne książki adresowe)
Specyficznym typem obiektu jest tablica. Tablica pozwala na przechowanie jakiejś sekwencji zmiennych, gdzie ich nazwy to indeksy w tej tablicy, podobnie jak w automatach z jedzeniem - odnosisz się do danej rzeczy którą chcesz kupić przez liczbę. Z tym że tutaj pierwszy indeks to 0.
W JavaScript na wszystkich zmiennych można wykonywać operacje arytmetyczne, aczkolwiek nie wszystkie mogą mieć logiczny wynik, więc na to trzeba uważać. Np. dodanie dwóch stringów je łączy, a dodanie dwóch boolean'ów sprawi że zostaną zamienione na liczbę - fałsz na 0, prawda na 1.
Dla przykładu zadeklarujemy więc zmienną każdego z tych typów:
let a = "napis"; // string
let b = 10.5; // number
let c = true; // boolean
let d = null; // null
let e; // undefined
let f = {
a: 10,
b: {
c: "napis"
}
}; // object, do wartości napis możemy się dostać w ten sposób(kropką wchodzimy głębiej): f.b.c;
let g = a + "em jestem"; // napisem jestem
let h = c + false; // 1 + 0 = 1
let i = []; // pusta tablica
let j = ["baton", "obiad"]; // tablica gdzie j[0] to napis "baton", j[1] to napis "obiad"
Tekst za //
jest pomijany, więc możemy tam zostawiać swoje notatki.
Przeprowadzka vs remont:
// dobrze
let a = 5;
a = 10; // przeprowadzka dozwolona, bo a jest zadeklarowane jako let
const b = 10;
const c = { a : 10 };
c.a = 20; // remont
// źle
b = 5; // b jest zadeklarowane jako const, a robimy przeprowadzkę
c = { a : 20 }; // to samo co linie wyżej
Funkcje
Wiemy już o wystarczająco podstawowych typach, przejdźmy więc do funkcji. Jest to jedna czynność lub zestaw czynności które można sparametryzować. Możesz o tym myśleć jak o koledzę któremu najpierw powiesz co ma zrobić, a potem na Twój sygnał on to zrobi, np. krzyknie "Lubię masło".
Zanim przejdziemy dalej, kliknij "Console" w lewym dolnym rogu aby rozwinąć konsolę.
Jedną z wbudowanych funkcji jest console.log
która pozwala wyświetlić jakiś tekst w konsoli którą właśnie rozwinęliśmy, a własne funkcję można zadeklarować na kilka sposobów:
// powiedzenie koledze co ma zrobić i jak ma to zrobić
function yell(whatToYell) {
console.log("Heeej! " + whatToYell);
}
// danie sygnału że ma to zrobić i co ma krzyknąć:
yell("Lubię masło!"); // w konsoli powinno pojawić się "Heeej! Lubię masło!"
// inne sposoby deklaracji, funkcja to też zmienna
const yell2 = function(whatToYell) {
console.log(whatToYell);
}
const yell3 = (whatToYell) => {
console.log(whatToYell);
}
Przemalowanie canvasa na czarno
Skoro już wiemy czym są funkcję i zmienne, użyjmy ich. Korzystając z funkcji udostępnionej przez przeglądarkę, złapmy nasz element canvas po wcześniej zadeklarowanym identyfikatorze i przypisujemy go do zmiennej:
const canvas = document.getElementById('creative-programming');
Ale żeby na nim rysować musimy to zrobić poprzez coś co nazywa się context. Podobnie jak przeglądarka udostępnia nam funkcję poprzez obiekt "document", canvas robi to poprzez obiekt context. Więc zapytajmy o context i przypiszemy go sobie do zmiennej(którą nazwiemy w skrócie ctx):
const ctx = canvas.getContext('2d');
Poza contextem 2d możemy jeszcze zapytać o context 'webgl' który w uproszczeniu pozwala na wykonywanie obliczeń na karcie graficznej. Jest to znacznie bardziej skomplikowane więc my zostaniemy przy context'cie 2d.
Czas coś narysować. Jedną z funkcji w obiekcie context jest fillRect
. Gdy mu przekażemy mu lewy górny róg (współrzędne x i y, lewy górny róg to (0,0), wartości rosną w dół i w prawo, czyli prawy dolny róg to (canvas.width, canvas.height)) prostokąta który chcemy narysować oraz jego szerokość i wysokość on wypełni dany obszar kolorem (domyślnie czarnym). Zacznijmy od przemalowania całego canvasa:
ctx.fillRect(0, 0, canvas.width, canvas.height);
I naszym oczom ukazuje się czarny prostokąt. Jeśli chcemy zmienić kolor, musimy to zrobić przed narysowaniem prostokąta w ten sposób:
ctx.fillStyle = "blue";
I naszym oczom powinien ukazać się niebieski prostokąt.
Rozszerzenie canvasa na cały panel
Na ten moment nasz canvas jest małą częścią panelu z podglądem, fajnie by było mieć trochę więcej miejsca do zabawy. Dodajmy poniższe linijki przed narysowaniem prostokąta i po zadeklarowaniu zmiennej canvas(przy okazji zmieńmy kolor z powrotem na czarny - "#000"):
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
W obiekcie window mamy dostęp do zmiennych które mówią nam jaka jest wysokość i szerokość okna strony podanej w pixelach. window.innerWidth
to nic innego jak liczba np. 970
. Modyfikujemy zatem wysokość i szerokość naszego canvasa na wysokość i szerokość panelu z podglądem.
A w panelu CSS dodajmy te style:
body {
margin: 0;
}
#creative-programming {
display: block;
}
Pierwszy styl sprawi że znikną nam marginesy wokół canvasa, a drugi sprawi że znikną scrollbary.
Javascript na ten moment powinien wyglądać w ten sposób:
const canvas = document.getElementById('creative-programming'); // łapiemy element HTML po id zadeklarowanym wcześniej przez nas
canvas.width = window.innerWidth; // modyfikujemy szerokość canvasa na szerokość panelu z podglądem
canvas.height = window.innerHeight; // to samo z wysokością
const ctx = canvas.getContext('2d'); // prosimy canvasa o context dzięki któremu będziemy mogli rysować
ctx.fillStyle = "black"; // zmieniamy kolor rysowania, może być podany w postaci "red" lub #aabbcc lub #abc(skrócona #aabbcc) lub rgb(255, 0, 0) czyli 100% czerwonego, 0% zielonego i 0% niebieskiego oraz na kilka innych sposobów
ctx.fillRect(0, 0, canvas.width, canvas.height); // wypełniamy prostokąt czarnym kolorem, zaczynając od lewego górnego rogu(0, 0) który ma szerokość i wysokość równą wymiarom canvasa
Instrukcje warunkowe i pętle
Instrukcje warunkowe pozwalają na wykonanie zestawu poleceń w zależności od jakiegoś warunku. Kod zawarty wtedy pomiędzy `{` a `}` nazywamy blokiem kodu:
if (true) {
console.log("Tutaj wejdziemy zawsze");
}
if (false) {
console.log("To się nigdy nie wykona");
}
if (canvas.width < 500) {
console.log("To się wykona jeśli szerokość canvasa jest mniejsza od 500")
}
Możemy też łączyć kilka warunków korzystając z operatorów logicznych `&&`(i) i `||`(lub)
if ((canvas.width > 100 && canvas.width < 200) || canvas.width > 500) {
console.log("To wykona się gdy szerokość canvasa będzie pomiędzy 100 a 200 albo będzie większa niż 500");
}
Jeśli chcemy coś zrobić wiele razy, np. 100, to nie będziemy kopiować i wklejać danego kawałka kodu 100 razy jak za karę w podstawówce. Na ratunek przychodzą pętle. Mamy do dyspozycji pętlę while
która działa bardzo podobnie jak if
, z tą różnicą że będzie wykonywać dany blok kodu tak długo aż warunek przestanie być prawdziwy. Oraz pętle for która działa bardzo podobnie jak pętla while, tylko pozwala na zrobienie czegoś przy wejściu do niej, oraz po każdej iteracji.
Operator ++
to skrót od +=
co jest skrótem od a = a +
więc zapis a++
to tak naprawdę a = a + 1
.
while(!gameOver) {
play(); // dopóki zmienna gameOver nie jest prawdziwa wykonuj funkcję play
}
for(let i=0; i<10; i++) { // stwórz zmienną 'i' i przypisz jej wartość 0, po każdej iteracji zwiększ ją o 1 i wykonuj dane czynności póki jest mniejsza od 10
// efektywnie zrób to 10 razy
console.log("Nie będę rozmawiać na lekcji");
}
Narysujmy coś!
Kolejnym globalnym obiektem dostępnym w przeglądarce jest obiekt `Math`. Pozwala on między innymi na losowanie liczby z przedziału od 0 do 1. Skorzystajmy z tego aby narysować 100 losowych białych linii:
ctx.strokeStyle = "#fff"; // kolor zakreślania można podobnie ustawić jak kolor wypełniania
for(let i=0; i<100; i++) {
ctx.beginPath(); // zacznij rysowanie nowej figury
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height); // nie rysując, przenieś "mazak" w te miejsce (x, y)
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height); // zacznij zakreślać figure od aktualnej pozycji do podanej tutaj (x2, y2)
ctx.stroke(); // obrysuj zakreślony kształt, w tym przypadku - narysuj linie od punktu (x, y) do punktu (x2, y2)
}
Po każdym odświeżeniu okna przeglądarki dostaniemy inny efekt, który powinien się prezentować mniej więcej tak:
Końcowy Javascript:
const canvas = document.getElementById('creative-programming');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = "#fff";
for(let i=0; i<100; i++) {
ctx.beginPath();
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.stroke();
}
Link do codepena z tym kodem: Losowe linie
Podsumowanie
Cała reszta zależy od Twojej wyobraźni, a im lepiej znasz matematykę tym ciekawsze rzeczy możesz zrobić. To bardzo duża dawka informacji więc jeśli czujesz się zagubiony, nie martw się, zwolnij i spróbuj pobawić się zmiennymi i funkcjami aż w pełni zrozumiesz jak dany fragment kodu działa. Have fun :)