Captain Drexx изнутри. Часть 5. User interface


В этой части я хочу рассказать о управлении игрой.
Содержание цикла «Captain Drexx изнутри»

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

Надо сказать, что это один из самых нагруженных логикой блоков игры, так как интерфейс пользователя построен на некоторой событийной системе, основанной на переключателях событий.
Нужно отрабатывать такие ситуации как:
  • установка башни
  • апгрейд башни
  • отображение радиуса поражения выбранной башни
  • отработка ситуации отказа или нехватки денег (что делать, если клиент говорит — нет?)
  • отработка ситуаций когда апгрейд уже не доступен, или башню пытаются поставить на другую, либо воткнуть на путь крипов
  • прочие подобные странные ситуации

Как происходит управление? мы выбираем башню которую хотим установить, возле указателя появляется зона поражения. По клику на место установки башня будет поставлена.
Если-же клик приходится на установленную башню, мы показываем её охват и отображаем в меню данные по апгрейду башни.

Пример работы UI хорошо виден в видео прохождения игры:


А вот пример первого варианта UI:

Данный способ оказался менее понятным и менее удобным и был переписан.



Итак, давайте посмотрим как это происходит. Смотрим на обработчик прерываний:


interrupt      
di
               
push af
               
ex af,af
               
push af
               
push hl
               
push de
               
push bc
               
push ix
intro_int      
ld a,0
               
or a
               
jr nz,game_int

отработка прерывания для интро / аутро игры. проигрываем необходимую музыку.

               
ld a,(current_page)
               
push af
               
ld a,3
               
call page
               
call vtplayer
               
pop af
               
call page
               
jp rmc_exit

Обработка игровых событий:
проигрываем звуки, подсчитываем количество фреймов, прошедших после обнуления счётчика. Это даст нам фпс игры, который крайне желателен для комфортной игры — 25 кадров.

game_int
;               ld a,7
;               out (#fe),a
               
call AFXFRAME
;               ld a,(int_calk+1)
;               ld de,#50e8
;               call view_energy
int_init        
ld a,0
               
or a
               
jp z,rmc_exit

int_calk        
ld a,0
               
inc a
               
ld (int_calk+1),a
md1            
LD A,(current_page)
               
LD (int_ram+1),A

               
ld a,7
               
call page

               
call mouse_restore_screen
               
call mouse_pos
               
call mouse_map_adr

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

tower_upgrade_range_flag
               
ld a,#ff
               
cp #ff
               
call nz,tower_upgrade_range

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

stat_upgrade_flag
               
ld a,#ff
               
ld b,a
               
cp #ff
               
call nz,stat_upgrade
;               ld a,7
;               out (#fe),a
stat_new_tower_flag
               
ld a,0
               
or a
               
call z,stat_new_tower

отметка цветом башен в меню при доступном для них апгрейде

;               xor a
;               out (#fe),a

               
LD A,(screen_ready)
               
or a
               
jr nz,int_1
               
CALL CHANGE_SCREEN
               
ld a,1
               
ld (screen_ready),a
int_1  

если основной цикл игры отработал, всё полностью отрисовано — переключаем экран для отрисовки

               
ld a,(end_wave+1)
               
or a
               
jr nz,int_ram

tower_preview_range_flag
               
ld a,0
               
or a
               
call nz,tower_preview_range

отображаем радиус действия башни

;               ld a,6
;               out (#fe),a
               
call mouse_pressed

mouse_pressed — основная процедура, которая отрабатывает нажатия клавиш мыши / стрельбы на клавиатуре

;               ld a,7
;               out (#fe),a

int_ram        
ld a,7
               
call page
               
ld a,(end_wave+1)               ; fix
               
or a
               
call z, mouse_view              

pause_view      
ld a,(pause_button_view+1)
               
or a
               
call nz,pause_view_atr

отображаем состояние паузы

red_lives_counter
               
ld a,0
               
or a
               
jr z,red_money_counter
               
dec a
               
ld (red_lives_counter+1),a
               
or a
               
jr nz,red_money_counter
               
call fill_lives_atr

посветка количества жизни при их уменьшении

red_money_counter
               
ld a,0
               
or a
               
jr z,rmc_exit
               
dec a
               
ld (red_money_counter+1),a
               
or a
               
jr nz,rmc_exit
               
ld a,#47
               
call fill_money_atr
rmc_exit

подкрашивание на экране количества денег при их недостатке для покупки/апгрейда

;               xor a
;               out (#fe),a
               
pop ix
               
pop bc
               
pop de
               
pop hl
               
pop af
               
ex af,af
               
pop af
               
ei
               
ret


Для управления указателем можно использовать как мышь, так и клавиатуру, даже одновременно. Если мыша у нас включена, то читаем её кнопки, потом уже читаем клавиатуру:

mouse_pos	
mouse_update	ld a,0
		or a
		jr nz,key_in
		LD BC,#FADF
		IN A,(C)     ;читаем порт кнопок
		
		
/*
  D0 - левая кнопка
  D1 - правая кнопка
  D2 - средняя кнопка

Standard Kempston Mouse
#FADF - buttons
#FBDF - X coord
#FFDF - Y coord
*/
key_in		ld (mouse_button),a
		call key_scan	
ki0		LD hl,MOUSE11+1
		ld a,d
		cp #af
		jr nc,ki5

kileft		and left
		jr z,ki1	
		inc (hl)
		inc (hl)
ki1		ld a,d
kiright		and right
		jr z,ki2
		dec (hl)
		dec (hl)
ki2		LD hl,MOUSE12+1
		ld a,d
kidown		and down
		jr z,ki3
		inc (hl)
		inc (hl)
ki3		ld a,d
kiup		and up
		jr z,ki4
		dec (hl)
		dec (hl)

в зависимости от нажатой клавиши меняем координаты указателя

ki4            
ld a,d
               
and fire
               
or a
               
jr z,ki5
               
ld a,#0e
               
ld (mouse_button),a

ki5            
ld a,d
               
cp rmb_key

правая кнопка мыши или BREAK у нас — кнопка отбоя выбранного действия


               
jr nz,ki8
               
ld a,#0d
               
ld (mouse_button),a
               
jr ki6

смотрим на нажатие пробела, что есть пауза в игре

ki8            
call keys_wait_proc
               
ld a,d
               
cp key_pause
               
jp z,pause_button_view
               
cp key_tower1
               
jr c,ki6
               
ld c,a
keys_wait      
ld a,0
               
or a
               
jr z,ki7
               
jr ki6

отрабатываем задержку нажатого пробела, дабы клавиша не дребезжала

keys_wait_proc  
ld a,(keys_wait+1)
               
or a
               
ret z
               
dec a
               
ld (keys_wait+1),a
               
ret

ki7            
ld a,(tower_upgrade_flag)
               
or a
               
jr z,ki9
               
ld a,c
               
ld (upgrade_but+1),a
               
jr ki10

ki9            
ld a,c
               
ld (tower_keys+1),a
ki10            
xor a
               
ld (tpr_old+1),a
               
ld a,18
               
ld (keys_wait+1),a
               
ld a,#0e
               
ld (mouse_button),a
ki6

читаем данные портов XY мыши

               
LD     HL,(mouse_xy)
               
LD     BC,#FBDF
mz0            
IN     A,(C)
MOUSE11        
LD     D,0
               
LD     (MOUSE11+1),A
               
SUB    D
               
CALL   NZ,MOUSE30
               
LD     B,#FF
mz1            
IN     A,(C)
MOUSE12        
LD     D,0
               
LD     (MOUSE12+1),A
               
SUB    D
               
CALL   NZ,MOUSE40
               
ld a,h
               
cp #f7
               
jr c,mouse13
               
ld h,#f7
mouse13        
ld a,l
               
cp #b6
               
jr c,mouse14
               
ld l,#b6
mouse14        
LD     (mouse_xy),HL
               
RET

координаты указателя получены и сложены в переменную mouse_xy

MOUSE30
     
JP     M,MOUSE35
     
ADD    A,H
     
LD     H,A
     
RET    NC
     
LD     H,#Ff
     
RET
MOUSE35
     
XOR    #FF
     
INC    A
     
LD     D,A
     
LD     A,H
     
SUB    D
     
LD     H,A
     
RET    NC
     
LD     H,0
     
RET

MOUSE40
     
JP     M,MOUSE45
     
LD     E,A
     
LD     A,L
     
SUB    E
     
LD     L,A
     
RET    NC
     
LD     L,#0
     
RET
MOUSE45
     
XOR    #FF
     
INC    A
     
ADD    A,L
     
LD     L,A
     
RET    NC
     
LD     L,#FF
     
RET


Спасибо alex rider за процедуру для работы с клавиатурой!

; ----- alex rider keys

right
:                  equ #01
left
:                   equ #02
down
:                   equ #04
up
:                     equ #08
fire
:                   equ #10
rmb_key                
equ #f0

key_pause              
equ #cf
key_tower1              
equ #b0
key_tower2              
equ #b2
key_tower3              
equ #b4
key_tower4              
equ #b6
key_code                
equ #b8

                                             
; in: nothing
                                               
; out:
key_scan                                      
;       d - pressed directions in kempston format
       
ld a,#fe                               ; check for CAPS SHIFT
       
in a,(#fe)
       
rra
       
ld hl,key_table - 1         ; selection of appropriate keyboard table
       
jr c,.no_cs
       
ld hl,cs_key_table - 1      ; hl - keyboard table (zero-limited)
.no_cs
:
       
ld d,#00                               ; clear key flag
       
ld c,#0fe                              ; low address of keyboard port
.loop
:
       
inc hl                                 ; next key
       
ld b,(hl)                              ; high byte of port address from table
       
inc b                                  ; end of table check
       
dec b
       
ret z
       
inc hl                                 ; going to key mask
       
in a,(c)                               ; reading half-row state
       
or (hl)                                ;
       
inc hl                                 ; going to key flag
       
inc a                                  ; a = half-row state or mask. if #ff - current key isn't pressed
       
ld a,d
       
jr z,.loop                             ; key isn't pressed
       
or (hl)                                ; result or key flag
       
ld d,a                                 ; store it
       
jr .loop

непосредственно данные портов для чтения клавиш

       
; key table format
; 1st byte - high byte of keyboard half-row address
; 2nd byte - inverted key mask (e.g. outer key - #fe, next key - #0fd etc)
; 3rd byte - direction bit

key_table
:
       
db #0ef, #0fe, fire     ;0
       
db #0ef, #0fd, up       ;9
       
db #0ef, #0fb, down     ;8
       
db #0ef, #0f7, right    ;7
       
db #0ef, #0ef, left     ;6


       
db #0f7, #0fe, key_tower1       ;1
       
db #0f7, #0fd, key_tower2       ;2
       
db #0f7, #0fb, key_tower3       ;3
       
db #0f7, #0f7, key_tower4       ;4
       
db #0f7, #0ef, key_code         ;5

       
db #0df, #0fe, right    ;p
       
db #0df, #0fd, left     ;o
       
db #0fb, #0fe, up       ;q
       
db #0fd, #0fe, down     ;a
       
db #07f, #0fb, fire     ;m
       
db #07f, #0fe, key_pause        ;space

       
db #000


cs_key_table
:
       
db #0ef, #0fe, fire     ;0
       
db #0ef, #0fb, right    ;8
       
db #0ef, #0f7, up       ;7
       
db #0ef, #0ef, down     ;6
       
db #0f7, #0ef, left     ;5
       
db #07f, #fd , rmb_key  ;caps+sym
       
db #000


Итак, координаты получены. Нужно получить номер клетки на поле, над которым расположен указатель.
Так как поле у нас разбито на блоки 16х16, вычислить положение указателя над определённым квадратом довольно просто — берём положение указателя и сдвигами получаем конкретный квадрат игрового поля:

mouse_map_adr
               
ld hl,(mouse_xy)
               
ld a,h
               
srl a
               
srl a
               
srl a          
               
srl a
               
ld h,a
               
ld a,l
               
srl a
               
srl a
               
srl a          
               
srl a
               
ld l,a
               
ld (mouse_map),hl
               
ret            




mouse_pressed. Глубокое погружение в события игры.
Начинаем самую сложную для понимания ветку логики.
Fire был нажат. на каком обьекте? когда? что делать? кто виноват?

mouse_pressed  
ld c,0
               
ld a,(mouse_button)
               
cpl
               
and #3
               
or a
               
jr nz,mpr0
               
ld (mouse_pressed+1),a
               
ld a,c
               
ret

сохраняем старое состояние нажатий, если правая / левая кнопка (либо fire / break клавиатуры) нажаты, начинаем процесс:

mpr0            
cp c
               
ret z
               
ld (mouse_pressed+1),a

               
cp 1
               
jp nz,rmb2

похоже, бащню собираются апгрейдить! смотрим:

upgrade_but    
ld a,0
               
or a
               
jr z,tk0
               
ld c,a
               
xor a
               
ld (upgrade_but+1),a
               
ld a,(tower_upgrade_flag)
               
jp tower_upgrading

да, нажали, нажааали. вычисляем клетку 16х16 на экране:

tk0            
ld hl,(mouse_map)
               
ld a,l  ;Y
               
add a,a
               
add a,a
               
add a,a        
               
add a,a
               
add h   ;X
               
ld c,a
               
cp #ba
               
jp z,pause_button_view

могли нажать на поле «пауза». нет?
или, возможно, хотят поставить новую башню?

               
ld a,(tower_preview_range_flag+1)
               
or a
               
jp nz,set_new_tower

похоже, башню собираются апгрейдить!

               
ld a,(tower_upgrade_flag)
               
or a
               
jp nz,tower_upgrading

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

tower_keys      
ld a,0
               
or a
               
jr nz,cmp_towers_ex_keys

таки да, но место для башни вообще на игровом поле?

               
ld a,c
               
cp #af
               
jp nc,cmp_towers

               
ld hl,(map)
               
ld a,c
               
add l
               
ld l,a
               
ld a,(hl)
               
cp #ff
               
jp nc,rmb2              ; #ff - можно ставить башни, else exit

можно ли там вообще башню ставить? если можно, смотрим что там сейчас находится:

cmp_towers      
ld hl,towers    ; поиск башни по позиции
mp0            
ld a,(hl)
               
cp #fe
               
jp z,cmp_towers_ex

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

               
ld b,a          ; type
               
inc hl
               
ld a,(hl)       ; position
               
cp c
               
jp z,tower_upgrade_view
mpn0            
inc hl
               
ld a,(hl)       ; range propusk
               
cp #ff
               
jr nz,mpn0
               
inc hl
               
jr mp0

cmp_towers_ex  
               
ld a,c
               
cp #af
               
jp c,rmb2
               
cp #b8
               
jp nc,rmb2

если мы за пределами карты — выходим

cmp_towers_ex_keys
               
ld c,a
               
xor a
               
ld (tower_keys+1),a
               
ld a,c
               
sub #b0
               
rra
               
ld hl,tower_list
               
ld e,a
               
ld d,0
               
add hl,de
               
ld a,(hl)
               
cp #ff
               
jp z,rmb2

вычисляем что за башня у нас будет

               
ld a,c
               
ld (tower_preview_range_flag+1),a

включаем, какая зона поражения будет показана для этой башни

               
sub #b0
               
and #fe
               
add a,a
               
add #c0
               
ld l,a
               
ld h,#5a
               
ld e,a
               
ld d,#da
               
ld bc,#4202
               
call block_attr_fill
               
jp lowbright_atr

затемняем экран, посвечиваем только зону поражения

если всё-таки будем апгрейдить башню, начинаем вычисления — а не на максимум она у нас раскачана?

tower_upgrading
ld (tupos+1),a
               
ld a,c
               
cp #af          
               
jp c,rmb2
               
ld a,(tower_upgrade_power)
               
cp #ff
               
jp z,rmb2

если да, то выход, выше апгрейда у нас нет.

               
ld a,(tower_upgrade_price)
               
ld b,a
               
ld a,(money)
               
sub b
               
jp c,low_money
               
ld (money),a
               
ld de,money_adr
               
push bc
               
call view_dec_energy
               
pop bc

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

               
ld hl,towers
tu0            
inc hl
               
ld a,(hl)       ; position
tupos          
cp 0
               
jr z,tower_upgrade1
tun0            
inc hl
               
ld a,(hl)       ; range propusk
               
cp #ff
               
jr nz,tun0
               
inc hl
               
jr tu0

tower_upgrade1  
inc hl
               
inc hl
               
inc hl
               
inc hl  ; power of this tower
               
ld a,(tower_upgrade_power)
               
ld (hl),a
               
call tower_attr_restore
               
ld a,(tower_upgrade_flag)
               
push af
               
call tower_screen_adr
               
ld a,h
               
RRCA
               
RRCA
               
RRCA
               
AND 3
               
OR #58
               
LD h,a
               
ld bc,#21
               
add hl,bc
               
or #80
               
ld d,a
               
ld e,l
               
dec (hl)
               
ex de,hl
               
dec (hl)
               
pop af

Так как все башни отображают свой уровень цветом в правом нижнем аттрибуте,
подкрашиваем цвета башни дабы показать её новый уровень.
Сохраняем аттрибуты цвета, проигрываем звук апгрейда, выходим.

               
call tower_attr_store
               
xor a
               
ld (stat_new_tower_flag+1),a
               
call stat_new_tower
               
call mouse_store_adr
               
ld a,create_tower_sound
               
call AFXPLAY
               
ld hl,tower_upgraded_count
               
inc (hl)
               
jp rmb


При выборе апгрейда башни нужно показать что по чём:

tower_upgrade_view
               
push bc ; in b:type, c:position, in hl- towers+1
               
push bc
               
push hl
               
ld (tower_upgrade_flag),a
               
; set on view range and towers
               
ld (stat_new_tower_flag+1),a
               
ld (tower_upgrade_range_flag+1),a ; pos
               
push af
               
ld a,b
               
ld (tower_upgrade_range_type+1),a ; type
               
pop af
               
push af
               
call tower_attr_restore
               
pop af
               
call tower_attr_store

               
call clear_menu_tower
               
ld hl,#5800
               
ld de,map_color
               
ld bc,#2c0
               
ldir

               
pop hl
               
pop bc
               
inc hl
               
inc hl
               
inc hl
               
inc hl  ; power of this tower
               
ld c,(hl)
               
ld hl,tower_upgrade
tuv0            
ld e,(hl)       ; price
               
inc hl
               
ld a,(hl)
               
cp b
               
jr z,tuv2

tuv12          
inc hl
               
ld a,(hl)
               
cp #ff
               
jr nz,tuv12

               
inc hl
               
jr tuv0

tuv2            
inc hl
               
ld a,(hl)
               
cp c
               
jr nz,tuv2


tuv21          
ld a,e
               
ld (tower_upgrade_price),a              
               
inc hl
               
ld a,(hl)       ; in a: new power, e:price
               
ld (tower_upgrade_power),a
               
cp #ff
               
jr nz,tuv24    

               
dec hl                  ; max upgrade
               
ld a,(hl)
               
ld de,upgrade_power_adr
               
push de
               
call view_3dec
               
pop de
               
dec e
               
ld a,'F'
               
call char_print
               
ld de,upgrade_price_adr
               
ld a,#2f
               
call char_print
               
ld a,#2f
               
call char_print
               
ld a,#ff
               
ld (tower_upgrade_price),a
               
jr tuv23

отобразили все данные по апгрейду текущей бащни — её новый урон (Force) и цену апгрейда:

tuv24          
               
push de
               
ld de,upgrade_power_adr
               
push de
               
call view_3dec
               
pop de
               
dec e
               
ld a,'F'
               
call char_print
               
pop de
               
ld a,e
               
ld de,upgrade_price_adr
               
call view_dec_energy

               

tuv23          
push hl
               
push de
               
push bc

               
call clear_status_attr
               
ld hl,upgrade_price_adr-1
               
call money_view
               
ld a,#44
               
ld hl,#5ac2
               
ld de,#dac2
               
call fill_colors
               
ld a,#42
               
ld l,#e2
               
ld e,l
               
call fill_colors
               
pop bc
               
pop de
               
pop hl

               
pop bc
               
ld a,b
               
ld (stat_upgrade_flag+1),a
               
ld a,(tower_upgrade_price)
               
ld c,a
               
ld a,(money)
               
sub c
               
jr c,$+3
               
xor a
               
ld (st_color+1),a

при нехватке финансов отображаем недоступность покупки, выделяя башню в меню серым цветом. либоб всё нормально, включаем отображение её охвата:

tuv30
               
ld c,b          ; вывод типа башни
               
ld hl,#50c0
               
call view_tower_instatus
               
ld (st_clr1+1),hl
               
ex de,hl
               
ld (st_clr2+1),hl
               
jp st_color

stat_upgrade    
ld a,(st_color+1)
               
ld e,a
               
ld a,(tower_upgrade_price)
               
ld c,a
               
ld a,(money)
               
sub c
               
jr c,$+3
               
xor a
               
ld (st_color+1),a
               
cp e
               
ret z
               
xor a
               
ld (tower_upgrade_range+1),a
               
jr tuv30

stat_new_towers
ld a,(st_color+1)
               
ld e,a
               
ld a,(tower_upgrade_price)
               
ld c,a
               
ld a,(money)
               
sub c
               
jr c,$+3
               
xor a
               
ld (st_color+1),a
               
cp e
               
ret z

               
jr tuv30


башню здесь не поставить. отрубаем всё:


tower_not_set  
ld a,cancel_sound
               
jp AFXPLAY


Ставим башню на новую позицию. Проверим, есть ли на этом месте башня?

set_new_tower  
               
ld hl,towers    ; поиск башни по позиции
snt01          
ld a,(hl)
               
cp #fe
               
jr z,begin_set_new_tower
               
ld b,a          ; type
               
inc hl
               
ld a,(hl)       ; position
               
cp c
               
jp z,rmb2
snt0            
inc hl
               
ld a,(hl)       ; range propusk
               
cp #ff
               
jr nz,snt0
               
inc hl
               
jr snt01

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

begin_set_new_tower
               
ld a,c
               
ld hl,(map)
               
add l
               
ld l,a
               
ld a,(hl)
               
cp #ff
               
jp nz,rmb2              ; #ff - можно ставить башни
               
push hl
               
ld a,c
               
ld (new_tower_pos+1),a
               
ld a,(tower_preview_range_flag+1)
               
sub #b0
               
rra
               
ld (cmp_towers0+1),a

смотрим на выбранную в меню башню, получаем её номер, и по нему — цену.
вдруг денег не хватит?


;               sub #b0
               
ld c,a
               
ld b,0
               
ld hl,tower_price
               
add hl,bc
               
ld c,(hl)
               
pop hl
               
ld a,(money)
               
sub c
               
jr c,low_money
               
ld (money),a
               
ld (hl),#fe
               
ld de,money_adr
               
call view_dec_energy
               
call tower_preview_range_restore
cmp_towers0    
ld c,0
;               sub #b0                 ; первая башня
                                       
; type
new_tower_pos  
ld b,0                  ; pos

               
ld hl,towers_fire_rate
               
ld e,c
               
ld d,0
               
add hl,de
               
ld a,(hl)               ; fire rate
;                               ; create tower, b - pos:#21, c - type: 0

да, башня будет! все её стартовые данные получены. начинаем монтаж:

               
call tower_create
               
ld a,(new_tower_pos+1)
               
call tower_attr_store
               
ld a,create_tower_sound
               
call AFXPLAY
               
jr rmb

монтаж закончен, играем по этому поводу ТУШ. tower_create разбирали в прошлой статье.
если денег таки не хватило, это дело нужно подсказать подсветкой индикатора финансов на экране на некоторое время и блямкнуть звуком — нифига, зарабатывай, копи, потом придёшь :)

Captain Drexx download page

3 комментария

avatar
Должен заметить, что эта статья — самая сложная для понимания.
Это связано с тем, что здесь описывается такая трудная для понимания вещь как пользовательский интерфейс.

Оказалось, что простой интерфейс как «выбрал — поставил» выглядит настолько дубовым, древним и неюзабельным, что эту часть кода игры я переписывал два раза.
Из-за того, что первоначальный вариант, в котором нужно было сначала ткнуть на место где хочешь поставить башню, а потом выбрать — какую, оказался далеко не таким понятным для игрока как мне казалось, и первые тестирования это показало: из троих игроков двое мне заявили, что интерфейс — не тот. Не привычный, не такой как должен быть.

Надо «drag'n'drop».
Да, ушло много времени на переделку. Но!
В процессе переделки добавилось много того, что оживляет игру — это различные состояния игры, которые позволяют, например, визуально оценить выбор игрока при принятии решений; подсказать когда у него не хватает финансов / каких либо возможностей; были расширено управление — введением дополнительных быстрых клавиш для установки / апгрейда башен, пауза для размышлением над стратегией и т.д., что в целом уже придаёт игре законченный, понятный и привлекательный вид.

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

А то что ААА не вкурил игру — я ни при чём :))
  • VBI
  • +4
avatar
Во первых я не вкурил игру потому что мой уровень это Assain или Farcry, самая трудная Thief, в стратегии я не играю. Во вторых ААА в принципе на спектруме игры использует как источник графики и идей для дем.
avatar
трудная для понимания — потому что интерфейс должен быть понятен интуитивно.
  • VBI
  • +2
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.