суббота, 3 марта 2012 г.

Давайте сделаем рогалик. Глава 02. Улучшаем код

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


utils.bi
/'****************************************************************************
*
* Name: utils.bi
*
* Synopsis: Utility routines for DOD.
*
* Description: This file contains misc utility routines used in the program.  
*
* Copyright 2010, Richard D. Clark
*
*                          The Wide Open License (WOL)
*
* Permission to use, copy, modify, distribute and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice and this license appear in all source copies. 
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
* ANY KIND. See http://www.dspguru.com/wol.htm for more information.
*
*****************************************************************************'/

'Очистим буфер клавиатуры.
Sub ClearKeys
  Do:Sleep 1:Loop While Inkey <> ""
End Sub

Мы добавили только одну процедуру в файл с утилитами — ClearKeys, которая очищает буфер клавиатуры. Мы просто перенесли в нее код, который писали ранее. Очистку буфера клавиатуры мы использовали только в подпрограмме DisplayTitle, но, очевидно, мы будем пользоваться ею достаточно часто, поэтому эта процедура — хороший кандидат на вынесение в отдельную подпрограмму. Может показаться глупым — создавать отдельный файл для одной процедуры, но мы добавим сюда намного больше кода, прежде чес закончим.

Еще одна функция, которая нам, возможно, потребуется более одного раза — это вычисление X координаты для строки символов, чтобы отобразить эту строку по центру экрана. Вместо того, чтобы написать дополнительную функцию и использовать ее вызов в каждом месте программы, мы можем для нее определить макрос, который будет подставляться компилятором непосредственно в исходный код. Определим макрос CenterX в файле defs.bi

#Define CenterX(ct) ((txcols / 2) - (Len(ct) / 2))

Опять же, мы просто поместили в макрос код, который писали ранее. Теперь нам нужно изменить процедуру DisplayTitle, чтобы она использовала наш макрос и процедуру очистки буфера клавиатуры:

dod.bas
'Отображает игровую заствку.
Sub DisplayTitle
  Dim As String txt
  Dim As Integer tx, ty

  'Установим значения для копирайтов.
  txt = "Copyright (C) 2010, by Richard D. Clark"
  tx = CenterX(txt)
  ty = txrows - 2

  'Заблокируем экран перед выводом.
  ScreenLock
  Cls
  'Перебор значений массива, рисуем символ блока используя цвет из массива.
  For x As Integer = 0 To titlew - 1
    For y As Integer = 0 To titleh - 1
      'Получим цвет из массива, используя формулу.
      Dim clr As UInteger = title(x + y * titlew)
      'Используем draw string т. к. это быстрее и нам не нужно заботится об расположении.
      Draw String (x * charw, y * charh), acBlock, clr
    Next
  Next
  'Выведем информацию о копирайтах.
  Draw String (tx * charw, ty * charh), txt, fbYellow
  ScreenUnlock
  Sleep
  'Очистим буфер клавиатуры.
  ClearKeys
End Sub

Изменилась только строка tx = CenterX(txt) и строка после инструкции Sleep. Если откомпилировать программу, то можно убедиться, что она работает также как и раньше. Эти изменения весьма не значительны, но мы всегда должны стараться к обобщению и оптимизации программного кода. На протяжении разработки эти небольшие изменения добавят большие изменения над проектом в целом. Время потраченное сейчас сэкономит нам время в будущем, т.к. нам не нужно будет возвращаться и исправлять уже оттестированный код. Его можно многократно использовать и быть уверенным что он работает правильно. Это нам очень поможет при добавлении новых функций и возможностей при разработке и тестировании основной программы.

Как определить, нужно ли выносить код в отдельную функцию? Ксли вы используете один и тот же код более одного раза — имеет смыл записать его отдельной функцией. Это даст нам только одно место в программе для поиска ошибок и одно место для внесения изменений.

С оптимизацией кода не все так просто. Это, скорее, проблема производительность, а обнаружить «узкие» места в программе бывает очень сложно, пока потери производительности не накопятся. В случае с нашим макросом — код очень прост и является хорошим кандидатом для встроенного кода, поэтому макрос. Макрос экономит производительность, т.к. не требует вызова функции. На данный момент это не очень нам поможет, но, возможно, поможет в будущем, а может и не особо помочь. Трудно сказать на данном этапе развития проекта. Тем не менее, встроенный код. Как правило, работает быстрее, чем вызов функции, особенно если это простой код как у нас. Если код более сложный, то использовать макрос нецелесообразно, и нам придется мириться с вызовом функции.

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

Комментариев нет:

Отправить комментарий