Я учу своих детей Шона и Талию программировать на языке C, чтобы мы могли вместе создавать видеоигры. Они учатся использовать те же инструменты, что и я сам, а именно: Debian GNU/Linux, xterm, bash, vim, cc, make и git.
Вот краткое описание того, что мы сделали, чтобы начать работу, и некоторых вещей, которые мы узнали на данный момент.
Установка
- Мы создали страницу на github, чтобы мы могли делиться нашим кодом.
- Мы создали страницу на dev.to, чтобы писать сообщения в блог в одном и том же месте. Мы думаем, что это хорошая идея — писать о том, что мы делаем, и надеемся, что некоторые люди будут следить за нашим прогрессом.
- Я установил несколько библиотек, которые понадобятся нам на компьютерах:
sudo apt install libsdl2-dev libsdl2-gfx-dev libsdl2-ttf-dev
libsdl2-image-dev libsdl2-mixer-dev libglew-dev
Для каждого из моих детей я выполнил следующую настройку:
- Создал учетную запись на github.
- Добавил в нашу организацию github.
- Создал ключ RSA ssh с помощью
ssh-keygen
. - Скопировал закрытый и открытый ключи ssh на наш другой ПК.
- Добавили открытый ключ ssh в учетную запись github. Это позволит нам отправлять изменения на github.
- Создал учетную запись dev.to, используя github для входа в систему.
Для каждого из моих детей, на каждом из двух наших основных ПК:
- Создали учетную запись пользователя.
- Вошел в Chrome sync.
- Вошел в github и dev.to.
- Отключил программируемое завершение в
~/.bashrc
. Меня раздражает, когда bash не завершает имена файлов, потому что пытается сделать что-то умное. - Клонирование двух наших git-репозиториев:
git clone git@github.com:gamedevfromscratch/gamedev.git
git clone git@github.com:gamedevfromscratch/kisskit.git
Основные команды командной оболочки
Мы изучили несколько основных команд оболочки:
- Мы можем остановить работу, например, vim, с помощью ctrl-Z.
Мы можем использовать стрелки вверх и вниз, чтобы просмотреть предыдущие команды, изменить их, если нужно, и запустить их снова.
Мы также можем использовать ctrl-R для обратного поиска в истории команд, и ctrl-S для повторного поиска в прямом направлении… но сначала прочитайте, как исправить ctrl-S!
Базовое редактирование в vim
- Vim имеет несколько режимов редактирования. Он начинается в «обычном режиме».
- Перед вводом программы нажмите
i
, чтобы войти в «режим вставки». - Чтобы сохранить изменения, вернитесь в «обычный режим», нажав Esc, затем введите
:w
для записи и нажмите Enter. - Введите
:q
, чтобы выйти из редактора, или:q!
, чтобы выйти без сохранения изменений. - Когда мы нажимаем
:
для ввода команды, например:w
, vim переходит в «командный режим».
Копирование-вставка в vim
- Мы можем выделять строки, используя мышь для выделения текста. Тройной щелчок и перетаскивание позволяют выделить целые строки. Или мы можем нажать
v
для «визуального режима» или заглавнуюV
для «визуального режима линий», и выделять строки с помощью клавиш со стрелками. - Нажмите
y
, чтобы «выдернуть» или скопировать выбранные линии. - Вы также можете нажать
d
, чтобы «удалить» или вырезать выделенные линии. - С помощью мыши или клавиш со стрелками переместитесь в то место, где вы хотите вставить строки.
- Нажмите
p
, чтобы вставить скопированные строки ниже. - Когда нам нужно переместиться в другую точку файла, обычно лучше использовать мышь, а не клавиши со стрелками.
Компиляция и запуск программы на языке Си
Моя дочь описала некоторые из первых простых программ, которые она написала, в своем посте «Мои простые программы».
После того, как мы ввели программу и сохранили ее, нажав Esc, затем :w
, нам нужно остановить редактор и вернуться в оболочку, нажав ctrl-Z.
Затем мы компилируем программу. Самая простая команда для этого:
cc -o hello hello.c
Это создаст исполняемый файл hello
из файла исходного кода hello.c
. Если мы опустим -o hello
и просто напечатаем cc hello.c
, компилятор назовет исполняемый файл a.out
, что не очень полезно.
Компилятор сообщит нам о наличии ошибок.
Если компиляция прошла успешно, мы можем запустить нашу программу hello следующим образом:
./hello
Нам нужно написать ./hello
, а не просто hello
, потому что в целях безопасности оболочка обычно не ищет программы для запуска в текущем каталоге; кто знает, какие опасные программы могут скрываться вокруг, притворяясь ls
или vi
?
Компилятор лучше предупредит нас о том, что может быть не так с нашей программой, если мы запустим ее в таком виде:
cc -o hello -Wall hello.c
-Wall
означает «предупреждения: все».
После тестирования нашей программы мы можем вернуться в остановленный редактор, введя fg
.
Иногда нам нужно «слинковать» с другими библиотеками Си. Например, если наша программа хочет использовать функцию sqrt
для вычисления квадратного корня, нам нужно установить связь с библиотекой math. Опция для этого — -lm
. Это полная команда для компиляции программы math.c
и связывания с математической библиотекой:
cc -o math -Wall math.c -lm
Использование компилятора немного затруднительно, поэтому я написал скрипт-обертку под названием ccw
для «C compiler with warnings». Он запускает компилятор со всеми опциями и библиотеками, которые могут нам понадобиться. Например:
ccw hello
Мы также можем использовать программу make
для запуска компилятора, получая параметры и команды из Makefile
. Мы рассмотрим, как это сделать, в другой статье.
Демонстрационная программа
Перед тем, как дети начнут писать свои собственные программы, я написал небольшую демонстрационную программу, чтобы показать им некоторые базовые вещи на C:
- basic «Hello, world»
- строковые переменные, приветствие с именем человека
- переменная int, математическое умножение
- цикл for, печать несколько раз
- if, вывести разные сообщения, четные и нечетные
- оператор modulo
%
для получения остатка после деления - подпрограммы: rep, nl
- функция: pythagores
- В чем разница между подпрограммой и функцией?
- дети написали подпрограмму: похвала
- макрос REPEAT для упрощения цикла.
Это демонстрационная программа, которую мы написали. Она немного беспорядочна, но демонстрирует несколько возможностей языка:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void rep(char c, int n)
{
for (int i=0; i<n; i++)
putchar(c);
}
void nl(void)
{
putchar('n');
}
float pythagores(float x, float y)
{
return sqrt(x*x + y*y);
}
#define REPEAT(n) for (int i=0; i<10; i++)
void praise(int n, char *name)
{
for(int i=0; i<n; i++) {
printf("%s is the best. ", name);
}
nl();
nl();
}
int main(void)
{
char *name1 = "Thalia";
char *name2 = "Sean";
srandom(time(NULL));
int a = random() % 11 + 2;
int b = random() % 11 + 2;
praise(50, "Nika");
praise(30, "Sam");
praise(25, "Sean");
praise(20, "Thalia");
nl();
nl();
for (int i=0; i<10; i++) {
if (i % 2 == 0)
printf("hello %s %d*%d=%dn", name1, a, b, a*b);
else
printf("hello %s %dn", name2, i);
}
nl();
nl();
int size = 10;
for (int i=0; i<size; i++) {
rep(' ', size-i);
rep('*', i*2+1);
nl();
}
for (int i=size-2; i>=0; i--) {
rep(' ', size-i);
rep('*', i*2+1);
nl();
}
nl();
nl();
printf("pythagores(30, 40) = %fn", pythagores(30, 40));
return 0;
}
Следующий пост: kisskit: Упрощение разработки игр на C, автор Сэм
Предыдущий пост: Циклы и математика на C, автор Шон
Содержание: Разработка игр с нуля