Game này mình làm có nhiều object lắm, khó có thể hướng dẫn chi tiết được tất cả, thế nên mình up file gốc gm6 lên để mọi người có thể tự nghiên cứu
:
Link file này: http://files.myopera.com/magclock/Legend/Anh hung huyen thoai ver0.04.gm6
Bây giờ là hướng dẫn cho những object quan trọng:
1. obj_hero:
Object này là object gốc của các hero, các object khác như obj_fighter01, obj_hunter01... đều kế thừa object này.
* Event step:
Event này thực hiện nhiệm vụ tính toán các thông số cho nhân vật, đồng thời kiểm tra xem nhân vật đã lên lvl hay chưa.
* Event left button:
Khi bạn nhấn nút trái chuột vào nhân vật, nhân vật sẽ được chọn.
Mình dùng biến global là global.choosing_hero để lưu địa chỉ của nhân vật đang được chọn.
2. obj_fighter01: (giống với obj_hunter01 và obj_cleric01)
Các object này kế thừa obj_hero, các bạn có thể thấy rõ điều đó qua event của chúng. Sở dĩ mình dùng obj_hero làm object gốc là vì mình muốn các nhân vật có thể được quản lý dễ dàng. Chẳng hạn, mình muốn tìm một nhân vật gần một quái vật nhất, nếu sử dụng tính kế thừa (như trên) mình sẽ chỉ cần dùng một lệnh rất đơn giản là:
Tất nhiên, các obj_fighter01, obj_hunter01 ... không thể không có những đặc điểm riêng.
* Event Create:
Sau khi kế thừa event create của obj_hero, các thông số, vật dụng của từng nhân vật sẽ được tạo trong event này.
* Event Step:
Event này chủ yếu thực hiện việc di chuyển (Move) của nhân vật. Khi bạn điều khiển nhân vật di chuyển đến một ô nào đó trên map, một loạt obj_find_way sẽ được tạo ra để dánh dấu đường, khi đã tạo xong đường, script move_the_hero sẽ lưu con đường vào mảng global.gridd[.,.]. Nhân vật sẽ dựa vào mảng trên để di chuyển.
global.gridd[.,.] = {0,1,2,3} = {Left,Up,Right,Down}
Để tạo delay cho việc di chuyển, mình dùng đồng hồ Alarm0 để dánh dấu. Nhân vật di chuyển một bước (1 ô) hết 8 nhịp đồng hồ nên sau mỗi lần di chuyển, mình đặt biến can_action của nhân vật là false, hẹn giờ Alarm0 là 8. Trong event Alarm0 mình sẽ đặt lại biến can_action của nhân vật thành true
để nhân vật có thể xử lý típ :
Thực sự với object nhân vật việc dùng Alarm0 giúp nhân vật di chuyển có lẽ là việc khiến mình phải suy nghĩ nhiều nhất ::(
3. obj_monster:
Cũng giống như obj_hero, obj_monster chủ yếu dùng để đơn giản hóa việc quản lý quái vật (khi bạn xem toàn bộ game, bạn sẽ thấy mình dùng các object gốc để quản lý rất nhiều)
* Event step:
Trong event này, quái vật sẽ được quản lý về lượng máu và quản lý việc tấn công nhân vật.
Quản lý lượng máu:
Nếu HP của quái vật giảm xuống 0, đương nhiên là nó phải die #
Khi quái vật chết, sẽ có một thông báo trên màn hình, đồng thới, nhân vật giết chết quái vật sẽ được cộng thêm một số điểm exp ứng với từng quái vật.
Quái vật tấn công:
Lện collision_point(...) sẽ tìm các nhân vật ở 8 ô xung quanh quái vật để tấn công (bạn thấy việc dùng obj_hero tiện lợi thế nào rồi chứ :
) Nếu tìm thấy bất cứ một nhân vật nào, quái vật sẽ tự động tấn công X(. Sau khi tấn công, quái vật sẽ hết lượt và chuyển lượt sang quái vật khác.
Mình cũng dùng biến global.choosing_monster để quản lý quái vật đang được chọn. Nếu tất cả các quái vật đã hết lượt thì sẽ đến lượt người chơi.
4.obj_monster01:
Xét một cách khái quát thì obj_monster01 đối với obj_monster cũng giống như obj_fighter01 đối với obj_hero. Bạn có thể dễ dàng hiều được obj này :
(Còn nữa...(nếu mọi người yêu cầu
))
:
Link file này: http://files.myopera.com/magclock/Legend/Anh hung huyen thoai ver0.04.gm6
Bây giờ là hướng dẫn cho những object quan trọng:
1. obj_hero:
Object này là object gốc của các hero, các object khác như obj_fighter01, obj_hunter01... đều kế thừa object này.
* Event step:
Event này thực hiện nhiệm vụ tính toán các thông số cho nhân vật, đồng thời kiểm tra xem nhân vật đã lên lvl hay chưa.
if exp>=global.level[level]
{
maxHP+=add_more_HP+round(random(5));
HP=maxHP;
maxMP+=add_more_MP+round(random(2));
MP=maxMP;
exp-=global.level[level];
level+=1;
AP+=3; // Ability point
SP+=1; // Skill point
instance_create(x,y,obj_lvlup);
mess=instance_create(0,0,obj_message);
mess.message=name+" ®· lªn cÊp ®é "+string(level)+"!!";
}
* Event left button:
Khi bạn nhấn nút trái chuột vào nhân vật, nhân vật sẽ được chọn.
if (global.turntime==global.playerturn)
{
clear_hero_action_object();
global.choosing_hero=instance_position(x,y,obj_hero).object_index;
enter_hero_menu();
}
Mình dùng biến global là global.choosing_hero để lưu địa chỉ của nhân vật đang được chọn.
2. obj_fighter01: (giống với obj_hunter01 và obj_cleric01)
Các object này kế thừa obj_hero, các bạn có thể thấy rõ điều đó qua event của chúng. Sở dĩ mình dùng obj_hero làm object gốc là vì mình muốn các nhân vật có thể được quản lý dễ dàng. Chẳng hạn, mình muốn tìm một nhân vật gần một quái vật nhất, nếu sử dụng tính kế thừa (như trên) mình sẽ chỉ cần dùng một lệnh rất đơn giản là:
nếu không sử dụng obj_hero, mình sẽ phải dùng nhiều code hơn:hero = instance_nearest(monster_x,monster_y,obj_hero);
và điều này thực sự vô cùng bất tiện X(hero = instance_nearest(monster_x,monster_y,obj_fighter01);
if (hero>0) return hero else
hero = instance_nearest(monster_x,monster_y,obj_hunter01);
if (hero>0) return hero else
hero = instance_nearest(monster_x,monster_y,obj_cleric01);
....
Tất nhiên, các obj_fighter01, obj_hunter01 ... không thể không có những đặc điểm riêng.
* Event Create:
Sau khi kế thừa event create của obj_hero, các thông số, vật dụng của từng nhân vật sẽ được tạo trong event này.
* Event Step:
Event này chủ yếu thực hiện việc di chuyển (Move) của nhân vật. Khi bạn điều khiển nhân vật di chuyển đến một ô nào đó trên map, một loạt obj_find_way sẽ được tạo ra để dánh dấu đường, khi đã tạo xong đường, script move_the_hero sẽ lưu con đường vào mảng global.gridd[.,.]. Nhân vật sẽ dựa vào mảng trên để di chuyển.
global.gridd[.,.] = {0,1,2,3} = {Left,Up,Right,Down}
Để tạo delay cho việc di chuyển, mình dùng đồng hồ Alarm0 để dánh dấu. Nhân vật di chuyển một bước (1 ô) hết 8 nhịp đồng hồ nên sau mỗi lần di chuyển, mình đặt biến can_action của nhân vật là false, hẹn giờ Alarm0 là 8. Trong event Alarm0 mình sẽ đặt lại biến can_action của nhân vật thành true
để nhân vật có thể xử lý típ :
Thực sự với object nhân vật việc dùng Alarm0 giúp nhân vật di chuyển có lẽ là việc khiến mình phải suy nghĩ nhiều nhất ::(
3. obj_monster:
Cũng giống như obj_hero, obj_monster chủ yếu dùng để đơn giản hóa việc quản lý quái vật (khi bạn xem toàn bộ game, bạn sẽ thấy mình dùng các object gốc để quản lý rất nhiều)
* Event step:
Trong event này, quái vật sẽ được quản lý về lượng máu và quản lý việc tấn công nhân vật.
Quản lý lượng máu:
global.showexp=exp;
mess=instance_create(0,0,obj_message);
mess.message=name+' bÞ tiªu diÖt.';
mess=instance_create(0,0,obj_message);
if (object_get_parent(global.choosing_hero)==obj_hero)
{
mess.message=global.choosing_hero.name+" nhËn ®îc "+string(exp)+"®iÓm kinh nghiÖm.";
global.choosing_hero.exp+=exp;
}
if (object_get_parent(global.choosing_hero)==obj_summon_hero)
{
switch (global.choosing_hero)
{
case obj_summon_dragon:
mess.message=obj_fighter01.name+" nhËn ®îc "+string(exp)+"®iÓm kinh nghiÖm.";
obj_fighter01.exp+=exp;
}
}
monster_drop(level);
Nếu HP của quái vật giảm xuống 0, đương nhiên là nó phải die #
Khi quái vật chết, sẽ có một thông báo trên màn hình, đồng thới, nhân vật giết chết quái vật sẽ được cộng thêm một số điểm exp ứng với từng quái vật.Quái vật tấn công:
for (i=0;i<=7;i+=1)
{
if (collision_point(x+global.attack_griddx*32,y+global.attack_griddy*32,obj_hero,0,1)>=0)
{
global.attackedhero=instance_position(x+global.attack_griddx*32,y+global.attack_griddy*32,obj_hero);
instance_create(x+global.attack_griddx*32,y+global.attack_griddy*32,obj_damagemonster01);
global.damage=round(random(attack/2)+attack/2);
i=8;
}
}
Lện collision_point(...) sẽ tìm các nhân vật ở 8 ô xung quanh quái vật để tấn công (bạn thấy việc dùng obj_hero tiện lợi thế nào rồi chứ :
) Nếu tìm thấy bất cứ một nhân vật nào, quái vật sẽ tự động tấn công X(. Sau khi tấn công, quái vật sẽ hết lượt và chuyển lượt sang quái vật khác.{
if (global.monster_number<global.monster_quantity)
{
while (!instance_find(obj_monster,global.monster_number)) global.monster_number+=1;
global.choosing_monster=instance_find(obj_monster,global.monster_number);
global.choosing_monster.on_use=1;
// global.choosing_monster.move_point=5;
global.monster_number+=1;
}
on_use=0;
}
Mình cũng dùng biến global.choosing_monster để quản lý quái vật đang được chọn. Nếu tất cả các quái vật đã hết lượt thì sẽ đến lượt người chơi.
...
else
{
instance_create(0,0,obj_playerturn);
}
...
4.obj_monster01:
Xét một cách khái quát thì obj_monster01 đối với obj_monster cũng giống như obj_fighter01 đối với obj_hero. Bạn có thể dễ dàng hiều được obj này :
(Còn nữa...(nếu mọi người yêu cầu
))
Mình dùng biến alpha để làm việc này. Ban đầu alpha=2.5 .