|
A program in need of analysis |
Kikaru
Member #7,616
August 2006
|
OK, I wrote a program here: 1#include "allegro.h"
2#include "nl.h"
3
4//define some convenient constants
5#define MODE GFX_AUTODETECT_WINDOWED
6#define WIDTH 640
7#define HEIGHT 480
8#define S_VOLUME 25
9#define BLACK makecol (0, 0, 0)
10#define LIGHT_BLUE makecol (64, 128, 255)
11#define WHITE makecol (255, 255, 255)
12#define GRASS makecol (0, 255, 64)
13#define R 0
14#define L 1
15#define SPD 2
16#define BLOCKS 20
17#define BLOCK_FALL 2
18
19//define class: Trace
20class trace
21{
22public:
23int x1, x2, y1, y2, active;
24};
25
26//define class: Character
27class character
28{
29public:
30int x, y, dir, combo, score;
31float x_spd, y_spd;
32trace trail;
33BITMAP *image;
34void move();
35};
36
37void character::move()
38{
39x += int(x_spd);
40y += int(y_spd);
41return;
42}
43
44//define classes: part and thing
45class part
46{
47public:
48int x, y, active;
49BITMAP *image;
50};
51
52class thing
53{
54public:
55int x, y, active, weight;
56//BITMAP *image;
57};
58
59//define class: game_timer
60class game_timer
61{
62public:
63int play_loop, play_sec, play_min;
64};
65
66//variables
67BITMAP *aimer, *buffer, *resources, *player_panel, *block_pic;
68character player;
69thing block[BLOCKS];
70part piece[(BLOCKS+1)*2];
71int mouseisdown, dash_delay, gravity, till_next, next_block = 50;
72game_timer play_time, time_left;
73
74//it does what it says!
75void set_direction(int goto_x, int goto_y)
76{
77//left
78if (goto_x < player.x + 12)
79{
80player.x_spd = -SPD;
81}
82//right
83if (goto_x > player.x - 12)
84{
85player.x_spd = SPD;
86}
87//up
88if (goto_y < player.y + 12)
89{
90player.y_spd = -SPD;
91}
92//down
93if (goto_y > player.y - 12)
94{
95player.y_spd = SPD;
96}
97//got diagonal?
98if ((!(player.y_spd == 0))&&(!(player.x_spd == 0)))
99{
100player.y_spd = player.y_spd/2;
101player.x_spd = player.x_spd/2;
102}
103return;
104}
105
106//check for collisions
107int is_cut(BITMAP *obj_layer ,int obj_x, int obj_y, int obj_size)
108{
109BITMAP *clip_board = create_bitmap(obj_size, obj_size);
110int scan_x = 0, scan_y = 0;
111blit(obj_layer, clip_board, obj_x - obj_size/2, obj_y - obj_size/2, 0, 0, obj_size, obj_size);
112while (scan_y < obj_size-1)
113{
114 while (scan_x< obj_size-1)
115 {
116 if(getpixel(clip_board, scan_x, scan_y) == LIGHT_BLUE)
117 {
118 destroy_bitmap(clip_board);
119 return 1;
120 }
121 scan_x += 1;
122 }
123 scan_y += 1;
124 scan_x = 0;
125}
126destroy_bitmap(clip_board);
127return 0;
128}
129
130//main function
131void main(void)
132{
133 //initialize allegro
134 allegro_init();
135 install_keyboard();
136 install_mouse();
137 install_timer();
138 set_color_depth(24);
139 if(set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0) != 0)
140 {
141 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
142 allegro_message(allegro_error);
143 return;
144 }
145 text_mode(-1);
146 install_sound(DIGI_AUTODETECT, MIDI_NONE, "");
147 //initialize HawkNL
148 nlInit();
149
150 //load graphics
151 resources = load_bitmap("ninja.bmp", NULL);
152
153 //load sounds
154
155 //initalize settings
156 player_panel = create_bitmap(192, 64);
157 player.image = create_bitmap(64, 64);
158 block_pic = create_bitmap(64, 64);
159 stretch_blit(resources, block_pic, 0, 32, 32, 32, 0, 0, 64, 64);
160 int i = 0;
161 //while (i < 42)
162 //{
163 //piece<i>.image = create_bitmap(64, 64);
164 //i += 1;
165 //}
166 buffer = create_bitmap(WIDTH, HEIGHT);
167 aimer = create_bitmap(32, 32);
168 blit(resources, aimer, 96, 0, 0, 0, 32, 32);
169 stretch_blit(resources, player_panel, 0, 0, 96, 32, 0, 0, 192, 64);
170 blit(player_panel, player.image, 64, 0, 0, 0, 64, 64);
171 rectfill(buffer, 0, 0, WIDTH, HEIGHT, WHITE);
172 destroy_bitmap(resources);
173
174
175 //main loop
176 while (!key[KEY_ESC])
177 {
178
179 //dashing
180 if ((mouse_b & 1)&&(!mouseisdown)&&(dash_delay >= 12))
181 {
182 //new image
183 blit(player_panel, player.image, 0, 0, 0, 0, 64, 64);
184 //change direction
185 if (mouse_x > player.x)
186 player.dir = R;
187 if (mouse_x < player.x)
188 player.dir = L;
189 //make the trail
190 player.trail.x1 = player.x;
191 player.trail.y1 = player.y;
192 player.trail.x2 = mouse_x;
193 player.trail.y2 = mouse_y;
194 player.trail.active = 1;
195 //move player
196 set_direction(mouse_x, mouse_y);
197 player.x = mouse_x;
198 player.y = mouse_y;
199 //reset
200 dash_delay = 0;
201 mouseisdown = TRUE;
202 gravity = 0;
203 }
204
205 if (!mouse_b & 1)
206 mouseisdown = FALSE;
207
208 dash_delay += 1;
209
210 //trail vanishes... now!
211 if (dash_delay >= 18)
212 player.trail.active = 0;
213
214 player.move();
215
216 //fall
217 if (dash_delay >= 15)
218 {
219 blit(player_panel, player.image, 128, 0, 0, 0, 64, 64);
220 gravity += 1;
221 player.y += gravity/3;
222 player.x_spd = 0;
223 player.y_spd = 0;
224 }
225
226 till_next += 1;
227 //drop blocks
228 i = 0;
229 while (i < BLOCKS)
230 {
231 if ((!(block<i>.active))&&(till_next >= next_block - play_time.play_min*5))
232 {
233 block<i>.active = 1;
234 block<i>.x = ((rand()%17)*32)+64;
235 block<i>.y = -32;
236 block<i>.weight = rand()%3 + BLOCK_FALL;
237 till_next = 0;
238 i = BLOCKS;
239 }
240 else
241 i += 1;
242 }
243 //blocks fall
244 i = 0;
245 while (i < BLOCKS)
246 {
247 block<i>.y += block<i>.weight;
248 if (block<i>.y >= 400)
249 {
250 block<i>.active = 0;
251 }
252 i += 1;
253 }
254
255 //cut blocks
256 i = 0;
257 if (dash_delay < 3)
258 {
259 while (i < BLOCKS)
260 {
261 if (is_cut(screen, block<i>.x, block<i>.y, 64)&&(block<i>.active == 1)&&(block<i>.y > 16))
262 {
263 player.combo += 1;
264 block<i>.active = 0;
265 }
266 i += 1;
267 }
268 }
269 player.score += player.combo*player.combo;
270 player.combo = 0;
271
272 //bottom
273 if (player.y >= 400)
274 {
275 player.y = 400;
276 blit(player_panel, player.image, 64, 0, 0, 0, 64, 64);
277 }
278
279 //setup the buffer
280 rectfill(buffer, 0, 0, WIDTH, HEIGHT, WHITE);
281 //draw blocks
282 i = 0;
283 while (i < BLOCKS)
284 {
285 if (block<i>.active == 1)
286 draw_sprite(buffer, block_pic, block<i>.x-32, block<i>.y-32);
287 i += 1;
288 }
289 //draw player trail
290 if (player.trail.active == 1)
291 line(buffer, player.trail.x1, player.trail.y1, player.trail.x2, player.trail.y2, LIGHT_BLUE);
292 //draw player
293 if (player.dir == R)
294 draw_sprite(buffer, player.image, player.x-32, player.y-32);
295 else
296 draw_sprite_h_flip(buffer, player.image, player.x-32, player.y-32);
297
298 //text
299 textprintf(buffer, font, 100, 460, BLACK, "Score:%i", player.score);
300 textprintf(buffer, font, 260, 460, BLACK, "%i' ", play_time.play_min);
301 textprintf(buffer, font, 280, 460, BLACK, "%i'' ", play_time.play_sec);
302 textprintf(buffer, font, 310, 460, BLACK, "%i", play_time.play_loop);
303
304 //draw the mouse
305 draw_sprite(buffer, aimer, mouse_x, mouse_y);
306
307 //draw the screen
308 blit(buffer, screen, 0, 0, 0, 0, WIDTH, HEIGHT);
309
310 //timer
311 play_time.play_loop += 1;
312 if (play_time.play_loop >= 39)
313 {
314 play_time.play_sec += 1;
315 play_time.play_loop -= 39;
316 }
317 if (play_time.play_sec >= 60)
318 {
319 play_time.play_min += 1;
320 play_time.play_sec -= 60;
321 }
322
323 //delay
324 rest(25);
325 }
326
327 //shut down HawkNL
328 nlShutdown();
329 //clean up
330 destroy_bitmap(player_panel);
331 destroy_bitmap(aimer);
332 destroy_bitmap(buffer);
333 return;
334}
335
336END_OF_MAIN();
I have the linker set and everything works fine, only sometimes you kill an object when its up near the top. It ONLY happens when a block is near the top. anyone see what's causing it? |
Richard Phipps
Member #1,632
November 2001
|
Quote: only sometimes you kill an object when its up near the top What do you mean? I don't understand the problem. |
Indeterminatus
Member #737
November 2000
|
I'm sorry, but I also don't know what the problem is. Could you elaborate on:
Following are a few suggestions, which A construct like this: int i = 0; while ( i < SOMETHING ) { /* do something */ i += 1; } Is better expressed with a for loop, like here: for ( int i = 0; i < SOMETHING; ++i ) { /* do something */ } It's not wrong, mind you, both work just fine. On a similar note, assuming you won't need i to be a specific value later on, this could be rewritten: int i = 0; while ( i < SOMETHING ) { /* break out of loop */ i = SOMETHING; // <-- this line I'm talking about ...
Breaking out of the loop can be achieved by making its condition false, but what I saw in your code, you don't need to execute the rest of the loop body, and you also don't access i in any way that it'd be important that it had the value SOMETHING. Some of the formatting might have been lost somewhere during the copy & paste, however I feel obliged to point out to follow at least basic indentation rules. I'm sure Google will know something about them. In your class part, the member active is declared as int, however it is used like a boolean variable. I suggest using bool instead, because that's the data type you really want here. edit: Fixed a typo. _______________________________ |
Kikaru
Member #7,616
August 2006
|
Sorry, I was rushed when I wrote that. During the game, blocks fall from the top of the screen. You need to draw lines through them using the mouse to cut them. For the blocks to be hit, the line needs to actually cross through the object's on-screen image. Right now, attacks will sometimes hit blocks near the top of the screen, even if the are on the opposite side of the screen form where you drew the line. P.S. I might get a copy of the program up later. |
Erkle
Member #3,493
May 2003
|
From what i can see, your is_cut function does the following:
If obj_x > obj_size*3/2 or obj_y > obj_size*3/2 then this will be a white
bottom are light blue. This doesn't seem to have anything to do with checking if a line cuts an object. My advice would be to start is_cut from scratch after asking how to do so in this thread. Try looking up do_line, it might be a good start.
If the writing above has offended you, you've read it wrong.....fool. |
Kikaru
Member #7,616
August 2006
|
The is_cut function does the following: using its arguments, it grabs a portion of the bitmap (obj_layer), and scans it for LIGHT_BLUE pixels. LIGHT_BLUE is a color used ONLY in the slash lines. The -1 to obj_size are because position starts counting at zero. (If you have a bitmap 100 pixels wide, the far left will be 0, the far right will be 99) However, thank you for pointing out about the size error. EDIT: I changed the size, and it works now! thank you very much EDIT2: How would do_line help at all? |
Erkle
Member #3,493
May 2003
|
My bad, I got the source_x/y and dest_x/y back to front again:-[. Good thing 4.3 has a better format. I also assumed you wanted to check the line to see if an object was under it rather than check each object to see if the line is on it. Quote: The -1 to obj_size are because position starts counting at zero.
Then you want: On a side note: It would probably be more efficient to create clip_board in main() and pass it to is_cut so it doesn't have to be created and destroyed for every check.
If the writing above has offended you, you've read it wrong.....fool. |
Kikaru
Member #7,616
August 2006
|
I worked out a way to use a do_line to eliminate the need for that. Suprise suprise? |
|