Продвинутый дротик

Примечание. Приносим извинения за то, что эта часть так долго не выходила. Я писал их на своем телефоне, когда укладывал ребенка спать, и мне трудно написать правильный код на телефоне.

Пройдя часть 1, вы должны быть немного знакомы с программированием в целом, а также с тем, как писать и запускать базовую программу Dart.

В этой части мы углубимся в более сложные концепции, чтобы заложить основу, необходимую для разработки игр.

Во-первых, немного по дому. Эта серия статей предназначена для того, чтобы помочь тем, у кого мало знаний в области программирования, на пути к созданию целой игры с использованием языка программирования Dart и фреймворка StageXL. Вначале мы рассмотрим базовые вещи и постепенно перейдем к созданию игры. Я предполагал, что в этом проекте будет по крайней мере дюжина частей, и что он подойдет для более молодой аудитории в качестве учебника.

Вперед

Помните последнюю часть и как я сказал, что все программы существуют для решения какой-то проблемы? И тогда мы пришли к невероятно простой проблеме, которую нужно решить?

Очень хорошо. А теперь перейдем к более интересной задаче:

Пользователь хочет преобразовать температуру из Цельсия в Фаренгейт или наоборот.

Что ж, это актуальная проблема! К счастью, не так уж и плохо. Очевидно, вы можете просто найти ответ в Google, и вам не нужно будет писать эту программу. Какому-то человеку в Google пришлось написать его для страницы поиска, так что в современном мире эту проблему все еще трудно решить.

Дизайн

Поговорим о некоторых вещах, которые нам понадобятся для нашей программы. Я всегда считаю полезным перечислить все, что, по моему мнению, мне понадобится.

Вот мой список для этого проекта, не беспокойтесь, если в вашем списке отсутствуют элементы или он выглядит иначе. Есть много способов сделать это.

  1. «Основная» функция
  2. Способ сказать пользователю, что делать
  3. Способ получения температуры от пользователя
  4. Способ получить желаемое преобразование (из C в F или из F в C)
  5. Способ расчета правильной конверсии
  6. Способ сообщить пользователю, каков результат

Я указал номер 1, потому что хотел напомнить вам, что всем программам Dart нужна main функция. В будущем мы будем предполагать, что он у нас будет. Так что никаких сюрпризов с номером 1.

Что касается номера 2, мы можем вернуться к первой части для вдохновения. Мы можем повторно использовать функцию print, которую использовали там.

Теперь мы переходим к сложным: получение информации от пользователя. Есть много способов сделать это, но мы будем простыми. Давайте воспользуемся функцией readLineSync. Мы рассмотрим, что это на самом деле означает, через мгновение, а пока знаем, что мы можем выполнить 3 и 4, используя этот метод.

Расчет числа 5 довольно прост: найдите формулу для обоих случаев, реализуйте каждый в коде, и все готово. Позже мы поговорим о том, как это сделать.

Номер 6 прост, как и номер 2: используйте эту функцию print.

Теперь, когда у нас есть план, приступим к программированию! Откройте текстовый редактор и введите следующее. Опять же, помните, что все программы Dart должны начинаться с этой основной функции, поэтому вы будете начинать таким же образом для каждой программы.

main() {
}

Здорово! Теперь добавьте биты, чтобы сообщить пользователю, что происходит:

main() {
 print('Type the number of degrees to convert'); 
 print('Type "c" to convert to Celsius or "f" to convert to Fahrenheit.');
}

Уже много всего происходит, так что давайте рассмотрим это. Во-первых, у нас все еще есть основная функция. Опять же, это всегда будет.

Затем мы дважды используем эту функцию print. Почему дважды? Разве мы не можем просто написать сразу оба предложения? Да, вы могли бы, но мы захотим разбить инструкции каждый раз, когда нам нужно получить информацию от пользователя. Когда мы приступим к нашей следующей роли, это будет иметь смысл.

Что за двойные кавычки в середине предложения? Помните, как мы говорили о строках ? Строки - это слова между набором одинарных кавычек '' или набором двойных кавычек "". Дарт не заботится о том, какие из них вы используете, пока вы помните, что все, что вы использовали для начала строки, должно быть таким, каким вы ее заканчиваете.

Что ж, возникает проблема «а что насчет того, чтобы использовать одинарные или двойные кавычки в самой строке»? Что ж, самое простое решение - использовать противоположное. Поэтому, если у вас есть строка с сокращением, используйте двойные кавычки для начала и окончания строки. Тогда вы можете использовать сколько угодно одинарных кавычек (апострофов)!

Вернемся к нашей программе, прямо сейчас она просто распечатывает некоторые инструкции, но на самом деле ничего не делает. Нам все еще нужно получить информацию от пользователя. Для этого мы воспользуемся чем-то классным, называемым стандартной библиотекой.

Стандартная библиотека - это набор функций, которые мы можем использовать для создания отличных программ. Что мы собираемся сделать, так это import кусок кода, который нам поможет. Импорт означает, что мы говорим Dart, что хотим использовать какой-то код, который существует где-то еще в нашей классной программе.

Нам нужна библиотека dart:io. Импорт находится в верхней части вашей программы, поэтому теперь это выглядит так:

import 'dart:io';

Кажется, это не так уж и много, но, добавив одну строчку, мы получаем доступ ко многим другим функциям. Тот, который нам нужен, называется stdin.readLineSync().

Странное имя. «Stdin» - это просто компьютерный разговор для «клавиатуры». Точка "." просто чтобы помочь организовать вещи. «ReadLine» означает «отслеживать, что пользователь вводит на клавиатуре, и ждать, пока он нажмет клавишу« Enter / Return »». Часть «синхронизация» означает «прекратить что-либо делать и ждать, пока пользователь сделает это». Есть версия, которая не ждет, но об этом мы поговорим в следующей статье.

Давайте добавим это в нашу программу:

import 'dart:io';
main() {
 print('Type the number of degrees to convert');
 stdin.readLineSync();
 print('Type "c" to convert to Celsius or "f" to convert to Fahrenheit.');
 stdin.readLineSync();
}

Прежде чем мы продолжим эту часть, нам нужно поговорить о другом фундаментальном моменте программирования: переменных. В нашем коде пользователя спрашивают о температуре, и, хотя он может ее ввести, мы ничего с ней не делаем. Фактически, мы сразу его выбрасываем. Не очень полезно.

Что ж, сохранение того, что вводит пользователь, осуществляется с помощью переменной . Эта переменная похожа на математическую задачу с неизвестной частью. Вроде 2 + x = 5. «X» - это переменная.

Однако, в отличие от математики, переменные в Dart могут содержать и другие вещи, кроме чисел, например, то, что пользователь вводит на клавиатуре! Здорово!

Использовать переменную просто, вам просто нужно соблюдать некоторые правила. Перед использованием переменную необходимо объявить. Объявление переменной означает просто сообщить об этом Dart, чтобы он знал, о чем вы говорите, когда вы ее используете. После этого вы можете использовать его в своем коде.

Чтобы объявить переменную, у нас есть несколько вариантов. Если мы знаем, тип того, что мы собираемся в нем хранить, мы можем сделать следующее:

String x;

Это означает, что теперь у меня есть переменная «x», которая будет использоваться для хранения строк. Есть много разных типов, но сейчас мы не будем о них беспокоиться; может быть в другой статье.

А как насчет того, если вы не уверены, что собираетесь держать? Вы можете сказать Дарт, что не знаете:

var x;

Говоря, что наш x равен var, мы говорим Дарт, что он может содержать что угодно. В другой статье мы рассмотрим, почему мы не всегда делаем это, даже если это кажется действительно удобным.

Чтобы использовать переменную, мы просто присваиваем ей значение, используя equals: =, например:

x = "String that we want to store in x";

И последнее о переменных: вы можете объявить их и присвоить им значение одновременно.

String x = "String that we want to store in x";

Объедините наше новое понимание переменных, и мы получим следующее:

String x = stdin.readLineSync();

Теперь давайте поиграем с этим в нашем коде, распечатав его:

import 'dart:io';
main() {
 print('Type the number of degrees to convert');
 String x = stdin.readLineSync();
 print(x);
 print('Type "c" to convert to Celsius or "f" to convert to Fahrenheit.');
 String y = stdin.readLineSync();
 print(y);
}

Смотреть! Мы используем переменную в функции печати вместо того, чтобы печатать строку. А что случилось, когда вы его запустили? Введенный вами текст распечатан!

Потрясающий!

Теперь, когда у нас есть эти основы, мы готовы узнать, какие степени и какой тип конверсии хочет пользователь:

import 'dart:io';
main() {
 print('Type the number of degrees to convert');
 String degrees = stdin.readLineSync();
 
 print('Type "c" to convert to Celsius or "f" to convert to Fahrenheit.');
 String conversionChoice = stdin.readLineSync();
}

Давайте сделаем половину работы и предположим, что пользователь хочет перевести градусы Цельсия в градусы Фаренгейта:

import 'dart:io';
main() {
 print('Type the number of degrees to convert');
 String degrees = stdin.readLineSync();
 
 print('Type "c" to convert to Celsius or "f" to convert to Fahrenheit.');
 String conversionChoice = stdin.readLineSync();
 num result = degrees * 9 / 5 + 32;
 
 print(result);
}

А теперь давайте запустим! Здорово! Это… подождите. Что это за чушь про «Необработанное исключение»?

Type the number of degrees to convert
49
Type "c" to convert to Celsius or "f" to convert to Fahrenheit.
c
Unhandled exception:
Class 'String' has no instance method '/'.
NoSuchMethodError: method not found: '/'
Receiver: "494949494949494949"
Arguments: [5]
#0      Object._noSuchMethod (dart:core-patch/object_patch.dart:44)
#1      Object.noSuchMethod (dart:core-patch/object_patch.dart:47)
#2      main (file:///C:/Users/Nathan/WebstormProjects/learn-to-dart/main.dart:9
:26)
#3      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart
:261)
#4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dar
t:148)

Что ж, мы пропустили шаг. Мы все погрязли в чтении ввода от пользователя, но забыли кое-что важное. Мы получаем от пользователя строку. И помните, строки - это просто строки текста. Это ужасно, потому что мы пытаемся выполнить математику с каким-то текстом.

Вот в чем проблема:

"49" * 9 / 5

Или просто:

"Hello" / 9

Компьютер пытается понять, что происходит, и просто отказался от попыток разделить слово «Привет» на 9. Как ни странно, с "Hello" * 9 все в порядке. Он решает, что вы хотите повторить «Привет» 9 раз:

HelloHelloHelloHelloHelloHelloHelloHelloHello

Чтобы решить эту проблему, нам нужно преобразовать строку, введенную пользователем, в число. Это можно сделать с помощью специальной функции num.parse(). Мы передаем String в эту функцию, и она пытается преобразовать ее в число. На данный момент нас не волнует, что произойдет, если пользователь введет что-то, кроме числа.

Вот наша программа перевода градусов Цельсия в Фаренгейт:

import 'dart:io';
main() {
 print('Type the number of degrees to convert');
 num degrees = num.parse(stdin.readLineSync());
 print('Type "c" to convert to Celsius or "f" to convert to Fahrenheit.');
 String conversionChoice = stdin.readLineSync();
 
 num result = degrees * 9 / 5 + 32;
 print(result);
}

Давай, попробуй. Попробуйте вместо этого использовать числа для градусов и какой-нибудь текст. Довольно потрясающе, правда?

Теперь нам нужно еще кое-что, чтобы закончить. Нам нужно уважать выбор пользователя, какое преобразование, и нам нужно выполнить фактическое преобразование.

Для этого нам потребуется использовать фундаментальную концепцию программирования, называемую оператором if. Это позволяет нам писать код, который будет делать разные вещи. Без него программы были бы скучными и бессмысленными.

Это выглядит так:

if (something is true) {
 doTrueSomething();
} else {
 doFalseSomething();
}

Вы можете видеть, что мы даем ему нечто вроде «проверки», а затем, если проверка верна, вызываем функцию doTrueSomething(). Если этот тест не соответствует действительности (это называется «ложь»), вызовите функцию doFalseSomething().

В нашей программе мы хотим проверить, ввел ли пользователь «c» или «f», и выполнить соответствующее преобразование. Вот мой взгляд на это:

import 'dart:io';
main() {
 print('Type the number of degrees to convert');
 num degrees = num.parse(stdin.readLineSync());
 print('Type "c" to convert to Celsius or "f" to convert to Fahrenheit.');
 String conversionChoice = stdin.readLineSync();
 num result;
 if (conversionChoice == 'c') {
  result = degrees * 9 / 5 + 32;
 } else {
  result = (degrees - 32) * 5 / 9;
 }
 print(result);
}

Моя похожа на твою? Если нет, ничего страшного! Мы в порядке, пока он соответствует требованиям к дизайну!

Поговорим о моей версии. Во-первых, в if тесте используется знак двойного равенства ==. К сожалению, знак равенства = уже используется для «присвоения переменной», о которой мы говорили ранее. Поэтому они придумали знак двойного равенства, означающий «равны друг другу».

Другое дело, что я тестирую только выбор «c». Я подумал, что если пользователь набирает что-нибудь кроме «c», он хочет по Фаренгейту. Если вы хотите сделать его более конкретным, вы можете сделать это так:

if (conversionChoice == 'c') {
 result = degrees * 9 / 5 + 32;
} 
 
if (conversionChoice == 'f') {
 result = (degrees - 32) * 5 / 9;
}

Хорошо, я думаю, что эта часть достаточно длинная. Есть и другие вещи, которые мы могли бы сделать, чтобы сделать его лучше (например, беспокоиться о том, что произойдет, когда пользователь не введет число!), Но мы пока оставим их.

В следующей части мы перейдем к предпоследнему руководству по Dart, которое нам нужно понять, прежде чем мы начнем создавать настоящую игру!