Stylizace enginu

Zdravím zdejší komunitu,

už delší dobu tvořím RPG engine pro GMS. Konkrétně mám zatím hotový inventář, truhly a dokončuji equipment. Cíle enginu jsou jak vysoká profesionalita, tak i user-friendly přístup. Jakkoli jsou tyto dvě věci částečně protichůdné, zatím se mi je dařilo spojovat. Engine by měl být vhodný i pro game designery, což zejména v GM často znamená jen minimální schopnost programovat. Rád bych se tedy poradil o optimalizaci uživatelských vstupů, poněvadž se mi v poslední době přestali líbit. Následovat bude pár ukázek kódu s vysvětlením, od Vás bych rád názor, zdali je to pro common-users přijatelné, popř. radu, kterak to zjednodušit. Občas mám tendenci chtít po koncovém uživateli přílišné znalosti.

EDITOVÁNO – Úpravy jsou na konci článku


 

  • Inicializace:

/// Initialise cargo
// ****************** Edit part *****************
slots = 9; // počet políček
slots_row = 3; // rozdělení do řad
unlocked = 1;
open_key = „E“;
active_dis = 64; // optimalizace
open_dis = 32; // aktivační zóna
locked_message = „Tak tahle truhlička je zavřená, hóšo.“;
//**********************************************
scrChestIni();

Truhla si detekci kolizí, správného natočení hráče, sebrání i opakované vložení itemů vyřeší sama, není potřeba žádný vstup. 

 

  • Přidání výchozích itemů do truhly:

scrLoot(0,oTestItem,4); // id,objekt,počet
scrLoot(1,oTestItem,2);
scrLoot(2,oTestItem3);

 

Bezejmenný

 

Inventář

  • Vytvoření

slots = 27;
draw_inventory = 0;
draw = 1;
drag_alpha = 1;
drag_controll = 0;
close_text = „Zavřít“;
drop_text = „Zahoď“;
inventoryCreate(slots);

Toť vše, inventář si vykreslování jak sebe, tak equipmentu ohlídá sám.

 

Itemy

  • Pokročilý create využívající bodového ohodnocení k přizpůsobení vzácnosti itemu:

/// Initialize item

scrItemSetUp(0,0);
scrItemBasic(3); // id

//*********** Prefix **************
image_index = 3;
randomize();

//****** Item settings ************
itm_stackable = 0;
itm_sprite_number = 3;
itm_info_head = „Dřevěný meč“;
itm_info_text = „Ok, já chápu, že nevypadá jako meč…#ale who cares?“;
itm_options[0] = „Nabídka 1“;
itm_options[1] = „Nabídka 2“;
itm_sprite = sprite_index;
itm_equip_slot = „zbraň“;
pre = irandom_range(0,100);

if (pre >= 0 && pre < 40) {vlastnost[vlastnost_poskozeni] = 5; points += 1;}
else if (pre > 40 && pre < 70) {vlastnost[vlastnost_poskozeni] = 6; points += 2;}
else if (pre > 70 && pre < 90) {vlastnost[vlastnost_poskozeni] = 7; points += 4;}
else if (pre > 90 && pre <= 100) {vlastnost[vlastnost_poskozeni] = 8; points += 6;}

if (points < 2) {itm_info_color = rarity_junk;}
else if (points < 4) {itm_info_color = rarity_normal;}
else {itm_info_color = rarity_fine;}
//*********** Suffix *****************

scrItemOptions();
itemRarity();

//************************************

 

  • Jednoduchý create:

/// Initialize item

scrItemSetUp(0,1)
scrItemBasic(1);
//****** Item settings ************
itm_stackable = 1;
itm_info_head = „Nice, white item“;
itm_info_text = „Guten morgen!#knock#knock#knock“;
itm_options[0] = „***** option 0“;
itm_options[1] = „***** option 1“;
itm_sprite = sprite_index;

scrItemOptions()
//*********************************

 

Dále musí uživatel definovat v itemu event user 0 událost, ve které provede akce po sebrání itemu, většinou:

/// After pick up

instance_destroy();

 

Bezejmenný

 

Axis mapa

Uživatel může konfigurovat počet a umístění jednotlivých equip slotů pouhým zásahem do konstant:

Bezejmenný

Konstanty určující polohu slotu mají prefix equ_axis_

Změna vlastností, rarit a samotných templatů inventáře funguje na stejné bázi. Např. přidání nové vlastnosti, se kterou můžeme pracovat provedeme pouhým přidáním nové konstanty (např. vlastnost_hodnocení), přiřazením správného indexu a editací indexu udávající celkový počet vlastností:

Bezejmenný

 

V základu je definováno 16 polí, přidání dalšího do jádra funguje na copy and paste systému:

// Draw right hand slot ——————————————————————————————————————-
if (oPlayer.equ_draw_right_hand)
{
draw_sprite(sSlotTexture,1,xx+equ_axis_right_hand_x,yy+equ_axis_right_hand_y);
if (oInventory.equiped[0] = 1) { draw_sprite(sRarityEffect,itemRarityEffect(equiped_image[0,2]),xx+equ_axis_right_hand_x,yy+equ_axis_right_hand_y); }
draw_sprite(equiped_image[0,0],equiped_image[0,1],xx+equ_axis_right_hand_x,yy+equ_axis_right_hand_y)

if (mouse_in(xx+equ_axis_right_hand_x,xx+equ_axis_right_hand_x+32,yy+equ_axis_right_hand_y,yy+equ_axis_right_hand_y+32))
{
draw_hover_block(xx+equ_axis_right_hand_x,xx+equ_axis_right_hand_x+32,yy+equ_axis_right_hand_y,yy+equ_axis_right_hand_y+32);

if (mouse_check_button_pressed(mb_left))
{
if (oInventory.equiped[0] = 1) {equipmentUnequip(0);}
}
}

Uživatel pouze změní ID slotu.

 

Abych nezapomněl na samotné skriptování optionboxu itemů:

 

Uživatel pouze edituje switch statement. Case označuje ID rodiče, number vybranou vlastnost.

 

/// scrAction(id,option_numer)

idd = 0;
number = 0;

if (argument_count > 0) {idd = argument[0];}
if (argument_count > 0) {number = argument[1];}

switch(idd)
{
case (1):
{
if (number = 0)
{
show_message(„optionbox is working!“);
}
if (number = 1)
{
show_message(„fucking option 1!“);
}

break;
}

default:
{
show_message(„Something in scrAction, switch statement went wrong :/#(probably unassigned action, check inventoryActions)“);
break;
}
}

 

Uživatel má také přímý přístup k vykreslování polí (bool):

Pokud chce nějaký slot vypnout změní 1 –> 0. 

equ_draw_head = 1;
equ_draw_left_plate = 1;
egu_draw_right_plate = 1;
equ_draw_body = 1;
equ_draw_right_hand = 1;
equ_draw_left_hand = 1;
equ_draw_left_ring1 = 1;
equ_draw_left_ring2 = 1;
equ_draw_right_ring1 = 1;
equ_draw_right_ring2 = 1;
equ_draw_crown = 1;
equ_draw_trophy1 = 1;
equ_draw_trophy2 = 1;
equ_draw_trophy3 = 1;
equ_draw_special1 = 1;
equ_draw_special2 = 1;
equ_draw_belt = 1;
equ_draw_left_boot = 1;
equ_draw_right_boot = 1;

 

Inventář podporuje standardní API obsahující: Drop,Contains,Number,Delete,Add.

Switch itemů si inventář řeší vnitřně.

Pokud chceme s vybraným itemem manipulovat jinak zakážeme v požadovaném stepu proměnnou able_to_switch, která slouží jako hlavička switche.

Inventář podporuje loot systém, kdy itemy nemají vlastnosti podle ID. Tím se liší od většiny konkurence (Davidův inventář), výpočetní nezávislostí na počtu itemů (HaRRiKiRi se sekal u 30 itemů, můj holdne 2 000 instancí bez reálného dopadu) a kompatibilitou s GMS.

 

Celý systém jsem koncipoval po vzoru svého oblíbeného PHPBB 3.1

Uživatel by neměl mít starost o práci s jednotlivými vrstvami kódu a systém rozšiřovat pomocí code-injection. To mimo jiné zajístí vysokou stabilitu systému. Na i5 běhá stabilně na 800-900 fps.

Těším se na Vaše nápady a názory. 🙂

EDITOVÁNO:

Dokončil jsem systém kombinování itemů. Uživatel kombinovatelným itemům přidá do optionboxu vlastnost a přidá indexy kombinací:

switch(id1)
{
// Dřevěný meč
case(3):
{
// Dřevěný meč
if (id2 = 3)
{
slot_vlastnosti[slot2,vlastnost_poskozeni] += slot_vlastnosti[slot1,vlastnost_poskozeni];
inventoryDrop(slot1,-1,-1);
}

break;
}

}

Provádí pouze rozšíření switch konstrukce. U funkce inventoryDrop přetížení -1,-1 (argumenty x,y pro odhození) značí smazání itemu. Ukázaná kombinace využije dva dřevěné meče, které hráč vybral, první odstraní a druhému přidá poškození rovné poškození druhého meče. Př: meč 1 – 6 bodů poškození, meč 2 – 4 body. Označení meč 1 -> meč 2. Meč 1 je odstraněn a meč 2 má 10 bodů poškození. První kombinace, která mě napadla byly brousky na zbraně… 

 

Bezejmenný

Po výběru možnosti „kombinovat“ se fade-in alpha přechodem zbarví sloty (0.3 na zelené a žluté, 0.1 na červené). Efekt trvá 10 stepů (při 60 fps 1/6 s.) Žlutý slot je kombinovaný item, zelená pole značí kombinovatelné itemy, červené nekombinovatelné. Ještě přemýšlím o přidání náhledu výsledku. Poté uživatel pouze klikne na zvolený item a tím provede kombinaci. Kvůli systému dynamického zobrazování proměnný se mi podařilo vyškrtnout z create eventu itemů tento (a podobné) inicializační řádky:

itm_info_text += „#Poškození: „+string(vlastnost[vlastnost_poskozeni]);

Upravené itemy mají nový typ vzácnosti „vytvořené“, s žlutým nadpisem.

Tato mechanika by měla sloužit k hand-craftingu, na zmar určitě nepřijde. K věcem jako alchymie, kovářství, atp. budou sloužit speciální stroje, fungující na bázi slotů. Uživatel vloží a mašinka vyhodí výsledek. U ručních kombinací může být další využití např. skládání klíče v dungeonu.