|
NPC Conversation |
allegro programmer
Member #15,653
June 2014
|
I noticed no has done a post regarding dialogue between player and NPC, im sure it would help alot of people. Does anyone have some advice for organizing a conversation between a player and npc in allegro. Right now i have blue box made in photoshop that appears when i draw text on the screen. this occurence only happens once then im unable to have the player reply and so on. for example://when enter is pressed goes to next line NPC:HI How are you can this be organized in simple if statement? if (npc.boundx.boundy>player.boundx)//this is example I know how to code detection |
Cassio Renan
Member #14,189
April 2012
|
What you're probably looking for is a GUI(Graphical User Interface). You can try designing your own, or you can search for a good one with allegro support. TGUI is a nice one that comes to mind. |
allegro programmer
Member #15,653
June 2014
|
so allegro doesnt have any built in string management seems like i could then if (keys[ENTER]) it doesnt work though for some reason |
Arthur Kalliokoski
Second in Command
February 2005
|
They all watch too much MSNBC... they get ideas. |
allegro programmer
Member #15,653
June 2014
|
i download tgui it seems cool, but outdated.also no tutorials or videos using it. |
Gideon Weems
Member #3,925
October 2003
|
allegro programmer
Member #15,653
June 2014
|
id prefer not to use a gui lib if possible how do i modify my if statement for it to display one line after the next upon pressing enter.. what is this hacker stuff? |
LennyLen
Member #5,313
December 2004
|
There have actually been quite a few discussions here on this topic. You can try using the site search engine to find them, or use Google to search the site.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
You don't need a gui, you just need a little more skill with C. To carry on a conversation, you just need to use a little linked list that moves from one conversation event to another. Or if your conversation is linear and doesn't have any branches you could use a vector. typedef std::list<const char*> CLIST; CLIST Conversation; conversation.push_back("Hello"); conversation.push_back("How are you"); conversation.push_back("Just fine thanks."); conversation.push_back("So on...");
CLIST::iterator cit = conversation.begin(); if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ENTER) { CLIST::iterator cit2 = cit; ++cit2; if (cit2 != conversation.end()) { cit = cit2; } }
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
LennyLen
Member #5,313
December 2004
|
Edgar Reynaldo said: You don't need a gui, you just need a little more skill with C++. FTFY
|
beoran
Member #12,636
March 2011
|
In C you could do it like this (untested code): 1/* Before your event loop function: */
2
3struct conversation_struct {
4 int index;
5 const char * text[];
6};
7
8struct conversation_struct
9conversation = {
10 0,
11 { "Hello", "How Are You", "Just Fine Thanks", "So On", NULL }
12};
13
14
15/* In your main event loop : */
16const char * text_to_draw = NULL;
17
18if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ENTER) {
19 if (conversation.text[conversation.index]) {
20 text_to_draw = conversation.text[conversation.index];
21 conversation.index++;
22 } else {
23 conversation.index = 0;
24 text_to_draw = NULL;
25 }
26}
27
28/* Draw text here with al_draw_text or al_draw_textf. */
|
Dizzy Egg
Member #10,824
March 2009
|
Well, just to really confuse things, I do mine like this (I like each character to appear at a time, rather than whole lines); I use little codes in the string to decide what happens next, something like: 1char NPC_Chat[CHAT_SIZE];
2
3...
4
5//NPC_Chat would hold a string like this:
6
7"Hello,~005my name is Dizzy!~005¬How can I help today?@";
8
9...
10
11//Then, in my conversation function
12
13while(strlen(NPC_Chat) > 0)
14{
15 char c = getNextChar(NPC_Chat);
16
17 if(c == '~') //Chat delay
18 {
19 //extract 3 character time, and delay
20 }
21 else if(c == '¬')
22 {
23 //new line, increase line yPos and reset line xPos
24 }
25 else if(c == '@')
26 {
27 //prompt, wait for enter key to be pressed
28 }
29 else
30 {
31 //not a special character, so just print character, increase xPos and continue
32 xPos += characterWidth(c);
33 }
34}
So basically I pick characters (like '¬' and '~') and use those as little codes in the string. This way I can have a whole multiline conversation, with delays/colour changes/prompts etc etc, that all look like: "Welcome!...~010listen, I don't suppose¬you know where...~005...oh, nevermind!@" etc etc...
---------------------------------------------------- |
#00JMP00
Member #14,740
November 2012
|
My guess would be, just look at you're conversation as an automat or machine. PC can, quit, choose an item. You only have to organize this, which is a more or less sizeable problem. Furthermore you can organize options as a tree. Each options spawns new options, which can be choosen or not. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
LennyLen said: FTFY I just meant C in general, like C and C++ together. This is what I was going to put up. It's a bastardization of C and C++. But there's a working example and source code. 1
2
3#include "allegro5/allegro.h"
4#include "allegro5/allegro_image.h"
5#include "allegro5/allegro_font.h"
6#include "allegro5/allegro_ttf.h"
7#include "allegro5/allegro_primitives.h"
8#include <cstdio>
9
10ALLEGRO_DISPLAY* display = NULL;
11ALLEGRO_EVENT_QUEUE* queue = NULL;
12ALLEGRO_BITMAP* image = NULL;
13ALLEGRO_TIMER* timer = NULL;
14ALLEGRO_FONT* font1 = NULL;
15ALLEGRO_FONT* font2 = NULL;
16ALLEGRO_COLOR color1;
17ALLEGRO_COLOR color2;
18
19
20int keys[ALLEGRO_KEY_MAX];
21
22ALLEGRO_BITMAP* MakeTile() {
23 ALLEGRO_BITMAP* tile = al_create_bitmap(256,256);
24 al_set_target_bitmap(tile);
25 for (int y = 0 ; y < 256 ; ++y) {
26 for (int x = 0 ; x < 256 ; ++x) {
27 al_draw_pixel(x , y , al_map_rgba(x , y , 0 , 255));
28 }
29 }
30 return tile;
31}
32
33class CONVERSATION {
34public :
35 const char* text;
36 ALLEGRO_COLOR text_color;
37 CONVERSATION* next;
38 CONVERSATION* prev;
39 ALLEGRO_FONT* font;
40};
41CONVERSATION* CreateConversationElement(const char* text , ALLEGRO_COLOR text_color , ALLEGRO_FONT* font) {
42 CONVERSATION* c = new CONVERSATION();
43 c->text = text;
44 c->text_color = text_color;
45 c->font = font;
46 return c;
47}
48
49CONVERSATION* SetConversationPrev(CONVERSATION* c , CONVERSATION* cprev) {
50 c->prev = cprev;
51 if (cprev) {
52 cprev->next = c;
53 }
54 return cprev;
55}
56
57
58CONVERSATION* SetConversationNext(CONVERSATION* c , CONVERSATION* cnext) {
59 c->next = cnext;
60 if (cnext) {
61 cnext->prev = c;
62 }
63 return cnext;
64}
65
66CONVERSATION* MakeFirstConversation() {
67 CONVERSATION* npcAroot = CreateConversationElement("Hello. This is the beginning of the conversation." , color1 , font1);
68 CONVERSATION* npcBroot = CreateConversationElement("Oh? We're going to have a conversation?" , color2 , font2);
69 SetConversationPrev(npcAroot , 0);
70 SetConversationPrev(npcBroot , npcAroot);
71
72 CONVERSATION* A2 = CreateConversationElement("Yes. Is there anything you'd like to talk about?" , color1 , font1);
73 SetConversationPrev(A2 , npcBroot);
74
75 CONVERSATION* B2 = CreateConversationElement("Could we talk about NPC programming?" , color2 , font2);
76 SetConversationPrev(B2 , A2);
77
78 CONVERSATION* A3 = CreateConversationElement("Sure, what do you want to know?" , color1 , font1);
79 SetConversationPrev(A3 , B2);
80
81 CONVERSATION* B3 = CreateConversationElement("How do I make a conversation?" , color2 , font2);
82 SetConversationPrev(B3 , A3);
83
84 CONVERSATION* A4 = CreateConversationElement("Well, you could use a linked list." , color1 , font1);
85 SetConversationPrev(A4 , B3);
86 SetConversationNext(A4 , 0);
87
88 return npcAroot;
89}
90
91void DestroyConversation(CONVERSATION* root) {
92 if (root->next) {
93 DestroyConversation(root->next);
94 }
95 delete root;
96}
97
98int main(int argc , char** argv) {
99
100 for (int i = 0 ; i < ALLEGRO_KEY_MAX ; ++i) {keys[i] = false;}
101
102 if (!al_init()) {return -1;}
103 if (!al_init_image_addon()) {return -2;}
104 if (!al_install_keyboard()) {return -3;}
105 if (!al_init_font_addon()) {return -4;}
106 if (!al_init_ttf_addon()) {return -5;}
107 if (!al_init_primitives_addon()) {return -6;}
108
109
110 al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);
111
112 display = al_create_display(640,480);
113
114 queue = al_create_event_queue();
115 if (!queue) {return -4;}
116
117 timer = al_create_timer(1.0/60.0);
118 if (!timer) {return -5;}
119
120 al_register_event_source(queue , al_get_display_event_source(display));
121 al_register_event_source(queue , al_get_keyboard_event_source());
122 al_register_event_source(queue , al_get_timer_event_source(timer));
123
124
125 image = MakeTile();
126 al_set_target_bitmap(al_get_backbuffer(display));
127
128 font1 = al_load_ttf_font("consola.ttf" , 20 , 0);
129 font2 = al_load_ttf_font("verdana.ttf" , 20 , 0);
130
131 color1 = al_map_rgb(255,255,0);
132 color2 = al_map_rgb(255,127,64);
133
134
135
136 bool redraw = true;
137 bool quit = false;
138
139 CONVERSATION* c = MakeFirstConversation();
140
141 do {
142 if (redraw) {
143 al_clear_to_color(al_map_rgb(255,255,255));
144/*
145 for (int y = 0 ; y < al_get_display_height(display) / al_get_bitmap_height(image) + 1 ; ++y) {
146 for (int x = 0 ; x < al_get_display_width(display) / al_get_bitmap_width(image) + 1; ++x) {
147 al_draw_bitmap(image , x*al_get_bitmap_width(image) , y*al_get_bitmap_height(image) , 0);
148 }
149 }
150*/
151 // draw current part of conversation
152 int tw = al_get_text_width(c->font , c->text);
153 int th = al_get_font_line_height(c->font);
154 int tx = al_get_display_width(display)/2 - tw/2 - 20;
155 int ty = al_get_display_height(display)/2 - th/2 - 20;
156
157 al_draw_filled_rectangle(tx , ty , tx + tw + 40 , ty + th + 40 , al_map_rgb(0,0,0));
158 al_draw_text(c->font , c->text_color , al_get_display_width(display)/2 , al_get_display_height(display)/2 ,
159 ALLEGRO_ALIGN_CENTER , c->text);
160
161
162 al_flip_display();
163 redraw = false;
164 }
165 do {
166 ALLEGRO_EVENT ev;
167 al_wait_for_event(queue , &ev);
168 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {quit = true;}
169 if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {quit = true;}
170 if (ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) {
171 al_acknowledge_resize(display);
172 redraw = true;
173 }
174 if (ev.type == ALLEGRO_EVENT_TIMER) {redraw = true;}
175
176 if (ev.type == ALLEGRO_EVENT_KEY_DOWN || ev.type == ALLEGRO_EVENT_KEY_UP) {
177 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {keys[ev.keyboard.keycode] = true;}
178 if (ev.type == ALLEGRO_EVENT_KEY_UP) {keys[ev.keyboard.keycode] = false;}
179 }
180 if (ev.type == ALLEGRO_EVENT_KEY_DOWN && (ev.keyboard.keycode == ALLEGRO_KEY_ENTER || ev.keyboard.keycode == ALLEGRO_KEY_SPACE)) {
181 if (c->next) {
182 c = c->next;
183 }
184 redraw = true;
185 }
186 if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_BACKSPACE) {
187 if (c->prev) {
188 c = c->prev;
189 }
190 redraw = true;
191 }
192
193
194 } while (!al_is_event_queue_empty(queue));
195
196 } while (!quit);
197
198 DestroyConversation(c);
199
200 return 0;
201}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Arthur Kalliokoski
Second in Command
February 2005
|
Just so we're clear on this, we're talking about a "window" that scrolls like a console? While using TTF fonts in A5 of course. They all watch too much MSNBC... they get ideas. |
allegro programmer
Member #15,653
June 2014
|
First off thanks for taking the time to reply ive been applying some of the ideas to my code trying to get them to work. edgar: im getting an abortrun error saying vector-item-0 line 174 when running the main file. *idk if this is relevant to the problem* when im looking through the zip in bittorrent.. when i click the npcexe saying im missing the libz.dll. |
allegro programmer
Member #15,653
June 2014
|
thanks edgar, nice code. I saved this in a word document and researching vectors a bit more so i can use this for my game. |
|