标题:[原创][模仿]《最终幻想》系列的ATB战斗系统简单实现
只看楼主
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
 问题点数:0 回复次数:2 
[原创][模仿]《最终幻想》系列的ATB战斗系统简单实现

昨天去了同学家,第一次接触《最终幻想》觉得做工实在非凡,一时心血来潮就模仿作了个ATB战斗系统,非常非常简陋,在我制作的过程中发现了学多学多游戏制作的技巧,感觉在模仿的同时也在得到别人赐教,真得好想做RPG游戏啊,哎,因为自己技术实在太滥,只有模仿的份了。。 高手们看了代码不要见笑阿。。。。。。。。只是一个初步的构架,但是已经可以玩了。。呵呵。。当然还是用TC3.0编译,绝对好编译,我人格担保。。。 代码如下: #include <stdio.h> #include <conio.h> #include <dos.h> #include <string.h> #include <bios.h> #include <stdlib.h> #include <math.h>

#define COMMON_DELAY 1

#define KEY_UP 0x4800 #define KEY_DOWN 0x5000 #define KEY_LEFT 0x4b00 #define KEY_RIGHT 0x4d00 #define KEY_ENTER 0x1c0d

typedef unsigned char byte; typedef enum { FALSE=0,TRUE } BOOL;

struct actor { byte id; char name[16]; // delay_time (unit=million second) unsigned int hp,delay_time,atk; // True means activity, False means freezing BOOL clock_state; struct actor *prev,*next; };

struct monster { byte id; char name[16]; unsigned int hp,delay_time,atk; BOOL clock_state; struct monster *prev,*next; };

// linked list for actors static struct actor *actor_head=NULL,*actor_tail=NULL; // linked list for monsters static struct monster *mos_head=NULL,*mos_tail=NULL;

// static constant for demo static char *actor_name[3]={"Peter","Alice","Jack"}; static char *mos_name[3]={"Spider","Gaint Ant","Phoenix"}; static char *life_state[2]={"[Alive]","[Dead]"};

static unsigned int data[18]= { 1532,31,25, 1342,25,43, 876 ,45,35, 986 ,25,15, 1322,55,65, 2745,30,48 };

// clock imitation for actors and monsters static unsigned char clock[6]={0}; static unsigned char mos_value[3]={0};

static int death_actor=0,death_mos=0;

// class class pb { public: pb(); pb(byte x,byte y); void setmaxvalue(byte m_val); void setvalue(byte val); void setblkcount(byte c); void setloc(byte x,byte y); byte getvalue(void) const; byte getoldvalue(void) const; byte getmaxvalue(void) const; void inc(void); void dec(void); protected: void paint(void) const; byte value,m_value,o_value,blk_count,pbx,pby; };

pb::pb() { pbx=0,pby=0; }

pb::pb(byte x,byte y) { pbx=x,pby=y; value=m_value=o_value=blk_count=0; }

void pb::setmaxvalue(byte m_val) { m_value=m_val; }

void pb::setvalue(byte val) { if(val<=m_value) { o_value=value; value=val; paint(); } }

void pb::setblkcount(byte c) { blk_count=c; }

void pb::setloc(byte x,byte y) { register byte i=0; while(i++<blk_count) putch(0x20); pbx=x; pby=y; paint(); }

void pb::inc(void) { if(value<m_value) { o_value=value++; paint(); } }

void pb::dec(void) { if(value>0) { o_value=value--; paint(); } }

byte pb::getvalue(void) const { return value; }

byte pb::getoldvalue(void) const { return o_value; }

byte pb::getmaxvalue(void) const { return m_value; }

void pb::paint(void) const { byte bsize=(byte)(m_value/blk_count); byte bc=(byte)(value/bsize); register byte i=0; gotoxy(pbx,pby); while(i<blk_count) { if(i<bc) putch(0xdc); else putch(0x20); ++i; } }

// functions for aids unsigned int calc_damage(unsigned int atk) { return (unsigned int)(sqrt(atk))+atk; }

void add_actor(struct actor *a) { if(!actor_head) { actor_head=a; actor_tail=actor_head; } else { actor_tail->next=a; a->prev=actor_tail; actor_tail=actor_tail->next; } }

void add_monster(struct monster *m) { if(!mos_head) { mos_head=m; mos_tail=mos_head; } else { mos_tail->next=m; m->prev=mos_tail; mos_tail=mos_tail->next; } }

void make_characters(void) { register unsigned int i; struct actor *a=NULL; struct monster *m=NULL; for(i=0;i<3;i++) { a=(struct actor *)malloc(sizeof(struct actor)); m=(struct monster *)malloc(sizeof(struct monster)); // make an actor a->id=(byte)(i); strcpy(a->name,actor_name[i]); a->hp=data[i*3]; a->delay_time=data[i*3+1]; a->atk=data[i*3+2]; a->clock_state=TRUE; // make a monster m->id=(byte)(i); strcpy(m->name,mos_name[i]); m->hp=data[i*3+9]; m->delay_time=data[i*3+10]; m->atk=data[i*3+11]; m->clock_state=TRUE; // add to linked list add_actor(a); add_monster(m); } // make a round list actor_tail->next=actor_head; actor_head->prev=actor_tail; mos_tail->next=mos_head; mos_head->prev=mos_tail; }

void destory_characters(void) { struct actor *a=actor_head,*p1=NULL; struct monster *m=mos_head,*p2=NULL;

p1=a->prev; p1->next=NULL; p2=m->prev; p2->next=NULL; a->prev=NULL; m->prev=NULL;

while(a) { p1=a->next; free(a); a=p1; } while(m) { p2=m->next; free(m); m=p2; } a=NULL; actor_head=actor_tail=NULL; m=NULL; mos_head=mos_tail=NULL; }

struct actor *dice_choose(void) { struct actor *a=actor_head; int luck=0; do { randomize(); luck=(int)(rand()%3); while(a->id!=luck) { a=a->next; } } while(!a->clock_state); return a; }

void put_monster(void) { struct monster *m=mos_head; register unsigned int x=20,y=14; do { gotoxy(x,y); cprintf("%s",m->name); m=m->next; x+=15; y-=4; } while(m!=mos_head); }

struct monster *sub_choice(void) { struct monster *m=mos_head; unsigned int x=19,y=14,i; unsigned char buffer[32]={0}; int key=0; gotoxy(x,y); putch(0x10); do { gotoxy(x,y); key=bioskey(0); switch(key) { case KEY_LEFT: if(m->id>0) { gotoxy(x,y); putch(0x20); x-=15; y+=4; gotoxy(x,y); putch(0x10); m=m->prev; } break; case KEY_RIGHT: if(m->id<2) { gotoxy(x,y); putch(0x20); x+=15; y-=4; gotoxy(x,y); putch(0x10); m=m->next; } break; case KEY_ENTER: if(!m->clock_state) { for(i=1;i<80;i++) { gotoxy(i,1); putch(0x20); } sprintf(buffer,"Unit %s is already dead!",m->name); gotoxy(1+(80-strlen(buffer))/2,1); cprintf("%s",buffer); continue; } if(!m->id) { gotoxy(19,14); putch(0x20); } return m; case 0x11b: gotoxy(x,y); putch(0x20); return NULL; } } while(TRUE); }

void cmd_menu(struct actor *a) { struct monster *m=NULL; int id=0,key=0; unsigned int x=8,y=21,i; unsigned char buffer[255]={0};

BOOL flag=TRUE; gotoxy(8,19); cprintf("-- %5s ----",a->name); gotoxy(8,21); cprintf("%c Attack",0x10); gotoxy(8,23); cprintf(" Defense"); do { key=bioskey(0); switch(key) { case KEY_UP: if(id>0) { gotoxy(x,y); putch(0x20); gotoxy(x,y-2); putch(0x10); y-=2; --id; } break; case KEY_DOWN: if(id<1) { gotoxy(x,y); putch(0x20); gotoxy(x,y+2); putch(0x10); y+=2; ++id; } break; case KEY_ENTER: if(!id) { m=sub_choice(); if(m) flag=FALSE; } else flag=FALSE; break; } } while(flag); if(m) { unsigned int damage=calc_damage(a->atk); if(m->hp<damage) { m->hp=0; m->clock_state=FALSE; if(!m->id) gotoxy(19,15); else gotoxy(19+15*m->id,14-3*m->id); cprintf("--> Death"); ++death_mos; } else { m->hp-=damage; } for(i=1;i<80;i++) { gotoxy(i,1); putch(0x20); } sprintf(buffer,"%s attacked %s, causing %d damage(s)",a->name, m->name,damage); gotoxy(1+(80-strlen(buffer))/2,1); cprintf("%s",buffer); } // clean the command menu for(y=19,i=x;i<=x+13;i++) { for(y=19;y<=23;y+=2) { gotoxy(i,y); putch(0x20); } } }

void run_clock(void) { struct actor *a=actor_head,*p=NULL; struct monster *m=mos_head;

unsigned char buffer[255]={0}; register unsigned int i; int key=0; BOOL flag_actor=FALSE,flag_mos=FALSE,flag=FALSE; pb atb_pb[3]; for(i=0;i<3;i++) { atb_pb[i].setmaxvalue(100); atb_pb[i].setblkcount(20); atb_pb[i].setloc(45,i+20); atb_pb[i].setvalue(0); sprintf(buffer,"%7s %5s %4d",life_state[0],a->name,a->hp); gotoxy(45-strlen(buffer)-1,i+20); cprintf("%s",buffer); if(!i) { gotoxy(45-strlen(buffer)-1+8,i+19); cprintf("%-5s %-4s %-20s","Name","Hp","ATB"); } a=a->next; } do { while(!bioskey(1)) { if(death_actor==3) { for(i=1;i<80;i++) { gotoxy(i,1); putch(0x20); } sprintf(buffer,"You have losed all your members! Game over!"); gotoxy(1+(80-strlen(buffer))/2,1); cprintf("%s",buffer); getch(); flag=TRUE; break; } else if(death_mos==3) { for(i=1;i<80;i++) { gotoxy(i,1); putch(0x20); } sprintf(buffer,"You have beated all your enemies! Victory!"); gotoxy(1+(80-strlen(buffer))/2,1); cprintf("%s",buffer); getch(); flag=TRUE; break; } delay(COMMON_DELAY); // actor clock process if(flag_actor) { if(atb_pb[a->id].getvalue()<atb_pb[a->id].getmaxvalue()) atb_pb[a->id].inc(); else { cmd_menu(a); atb_pb[a->id].setvalue(0); } clock[a->id]=0; flag_actor=FALSE; } // monster clock process if(flag_mos){ if(mos_value[m->id]<100) ++mos_value[m->id]; else { unsigned int damage=0; p=dice_choose(); damage=calc_damage(m->atk); if(p->hp<damage) { p->hp=0; p->clock_state=FALSE; ++death_actor; } else { p->hp-=damage; } sprintf(buffer,"%7s %5s %4d",p->hp>0 ? life_state[0] : life_state[1], p->name,p->hp); gotoxy(45-strlen(buffer)-1,p->id+20); cprintf("%s",buffer); // reset progress for monster mos_value[m->id]=0; // print damage bar for(i=1;i<80;i++) { gotoxy(i,25); putchar(0x20); } sprintf(buffer,"%s caused %d damage(s) to %s",m->name,damage, p->name); gotoxy(1+(80-strlen(buffer))/2,25); cprintf("%s",buffer); } clock[m->id+3]=0; flag_mos=FALSE; } // actor clock system if(clock[a->id]<a->delay_time&&a->clock_state) { ++clock[a->id]; a=a->next; } else if(!a->clock_state) { a=a->next; } else { flag_actor=TRUE; } // monster clock system if(clock[m->id+3]<m->delay_time&&m->clock_state) { ++clock[m->id+3]; m=m->next; } else if(!m->clock_state) { m=m->next; } else { flag_mos=TRUE; } } if(flag) break; key=bioskey(0); } while(key!=0x11b); clrscr(); }

int main() { clrscr(); make_characters(); put_monster(); run_clock(); destory_characters(); printf("ATB Imitation system, programmed by yuki\n"); printf("Have a nice day, bye bye!\n"); getch(); return 0; }

搜索更多相关主题的帖子: ATB 最终幻想 系统 模仿 战斗 
2005-08-20 00:31
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
得分:0 
源代码下载
YMvBtdqZ.rar (29.13 KB) [原创][模仿]《最终幻想》系列的ATB战斗系统简单实现


我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2005-08-20 09:30
shensheng4
Rank: 1
等 级:新手上路
帖 子:80
专家分:0
注 册:2005-8-7
得分:0 
谢了

梦想是不可能实现的,正因为如此才值得我们去追寻。 这是我选择的路,即使付出一切,我也毫无怨言。
2005-08-20 11:06



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-25604-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 1.553132 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved