I successfully had one enemy wandering back and forth in between collision blocks in my platform scroller.
Unfortunately, I'm running into problems when trying to drop multiple enemies across the map.
I basically made 7 additional enemies and gave them different starting positions across the map, but the program crashes when I try to run it. :(
Anyone have any suggestions? There is probably a much more logical way to do it, so please give me some help and guidance!
I've attached a .zip of the program's folder to this thread.
Here is my code so far:
#include <stdio.h>
#include <stdbool.h>
#include <allegro.h>
#include "mappyal.h"
#include <time.h>
#define MODE GFX_AUTODETECT_WINDOWED
#define WIDTH 640
#define HEIGHT 480
#define JUMPIT 1600
#define RED makecol(255,0,0)
#define BLACK makecol(0,0,0)
_Bool objective1;
SAMPLE *splash;
SAMPLE *fanfare;
//define the sprite structure
typedef struct SPRITE
{
int dir, alive;
int x,y;
int width,height;
int xspeed,yspeed;
int xdelay,ydelay;
int xcount,ycount;
int curframe,maxframe,animdir;
int framecount,framedelay;
int efacing;
}SPRITE;
//declare the bitmaps and sprites
BITMAP *player_image[8];
BITMAP *enemy_image[5];
BITMAP *enemy2_image[5];
BITMAP *enemy3_image[5];
BITMAP *enemy4_image[5];
BITMAP *enemy5_image[5];
BITMAP *enemy6_image[5];
BITMAP *enemy7_image[5];
BITMAP *enemy8_image[5];
SPRITE *player;
SPRITE *enemy, *enemy2, *enemy3, *enemy4, *enemy5, *enemy6, *enemy7, *enemy8;
BITMAP *buffer;
BITMAP *temp;
//tile grabber
BITMAP *grabframe(BITMAP *source,
int width, int height,
int startx, int starty,
int columns, int frame)
{
BITMAP *temp = create_bitmap(width,height);
int x = startx + (frame % columns) * width;
int y = starty + (frame / columns) * height;
blit(source,temp,x,y,0,0,width,height);
return temp;
}
int collided(int x, int y)
{
BLKSTR *blockdata;
blockdata = MapGetBlock(x/mapblockwidth, y/mapblockheight);
return blockdata->tl;
}
int main (void)
{
int mapxoff, mapyoff;
int oldpy, oldpx;
int oldey, oldex;
int facing = 1;
int efacing = 1;
int jump = JUMPIT;
int n;
int volume = 128;
int score=0, lvl1score=0, lvl2score=0, health=0, holding=0, deposit=0;
MIDI *music1, *music2;
allegro_init();
install_timer();
install_keyboard();
set_color_depth(16);
set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0);
//load player sprites
temp = load_bitmap("guy.bmp", NULL);
for (n=0; n<8; n++)
player_image[n] = grabframe(temp,50,64,0,0,8,n);
destroy_bitmap(temp);
//load enemy sprites
temp = load_bitmap("enemy.bmp", NULL);
for (n=0; n<5; n++)
enemy_image[n] = grabframe(temp,32,32,0,0,5,n);
enemy2_image[n] = grabframe(temp,32,32,0,0,5,n);
enemy3_image[n] = grabframe(temp,32,32,0,0,5,n);
enemy4_image[n] = grabframe(temp,32,32,0,0,5,n);
enemy5_image[n] = grabframe(temp,32,32,0,0,5,n);
enemy6_image[n] = grabframe(temp,32,32,0,0,5,n);
enemy7_image[n] = grabframe(temp,32,32,0,0,5,n);
enemy8_image[n] = grabframe(temp,32,32,0,0,5,n);
destroy_bitmap(temp);
player = malloc(sizeof(SPRITE));
player->x = 0;
player->y = 0;
player->curframe=0;
player->framecount=0;
player->framedelay=6;
player->maxframe=7;
player->width=player_image[0]->w;
player->height=player_image[0]->h;
enemy = malloc(sizeof(SPRITE));
enemy->efacing=1;
enemy->x = 840;
enemy->y = 352; //352 is ground level for map1 & sections of map2
enemy->curframe=0;
enemy->framecount=0;
enemy->framedelay=6;
enemy->maxframe=4;
enemy->width=enemy_image[0]->w;
enemy->height=enemy_image[0]->h;
enemy2 = malloc(sizeof(SPRITE));
enemy2->efacing=1;
enemy2->x = 1500;
enemy2->y = 352; //352 is ground level for map1 & sections of map2
enemy2->curframe=0;
enemy2->framecount=0;
enemy2->framedelay=6;
enemy2->maxframe=4;
enemy2->width=enemy_image[0]->w;
enemy2->height=enemy_image[0]->h;
enemy3 = malloc(sizeof(SPRITE));
enemy3->efacing=1;
enemy3->x = 3000;
enemy3->y = 352; //352 is ground level for map1 & sections of map2
enemy3->curframe=0;
enemy3->framecount=0;
enemy3->framedelay=6;
enemy3->maxframe=4;
enemy3->width=enemy_image[0]->w;
enemy3->height=enemy_image[0]->h;
enemy4 = malloc(sizeof(SPRITE));
enemy4->efacing=1;
enemy4->x = 5500;
enemy4->y = 352; //352 is ground level for map1 & sections of map2
enemy4->curframe=0;
enemy4->framecount=0;
enemy4->framedelay=6;
enemy4->maxframe=4;
enemy4->width=enemy_image[0]->w;
enemy4->height=enemy_image[0]->h;
enemy5 = malloc(sizeof(SPRITE));
enemy5->efacing=1;
enemy5->x = 6500;
enemy5->y = 352; //352 is ground level for map1 & sections of map2
enemy5->curframe=0;
enemy5->framecount=0;
enemy5->framedelay=6;
enemy5->maxframe=4;
enemy5->width=enemy_image[0]->w;
enemy5->height=enemy_image[0]->h;
enemy6 = malloc(sizeof(SPRITE));
enemy6->efacing=1;
enemy6->x = 7500;
enemy6->y = 352; //352 is ground level for map1 & sections of map2
enemy6->curframe=0;
enemy6->framecount=0;
enemy6->framedelay=6;
enemy6->maxframe=4;
enemy6->width=enemy_image[0]->w;
enemy6->height=enemy_image[0]->h;
enemy7 = malloc(sizeof(SPRITE));
enemy7->efacing=1;
enemy7->x = 8500;
enemy7->y = 352; //352 is ground level for map1 & sections of map2
enemy7->curframe=0;
enemy7->framecount=0;
enemy7->framedelay=6;
enemy7->maxframe=4;
enemy7->width=enemy_image[0]->w;
enemy7->height=enemy_image[0]->h;
enemy8 = malloc(sizeof(SPRITE));
enemy8->efacing=1;
enemy8->x = 9000;
enemy8->y = 352; //352 is ground level for map1 & sections of map2
enemy8->curframe=0;
enemy8->framecount=0;
enemy8->framedelay=6;
enemy8->maxframe=4;
enemy8->width=enemy_image[0]->w;
enemy8->height=enemy_image[0]->h;
//install the sound driver
if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) != 0)
{
allegro_message("Error initializing sound system\n%s\n", allegro_error);
return 1;
}
//load the wav files
splash = load_sample("splash.wav");
fanfare = load_sample("fanfare.wav");
if (!splash || !fanfare)
{
allegro_message("Error reading .wav file!");
return 1;
}
//load the MIDI music file
music1 = load_midi("Head.mid");
music2 = load_midi("Castle.mid");
if (!music1 || !music2)
{
allegro_message("Error loading the MIDI file!");
return 1;
}
//play the music
if (play_midi(music1, 0) != 0)
{
allegro_message("Error playing the MIDI\n%s", allegro_error);
return 1;
}
//load the map
MapLoad("map1.fmp");
//create the double buffer
buffer = create_bitmap (WIDTH, HEIGHT);
clear(buffer);
//main loop
while (!key[KEY_ESC])
{
if ((player->x >= 9440) && (player->x <= 9480) && (key[KEY_ENTER]))
{
score += 100;
stop_midi();
play_sample(fanfare, 200, 128, 1000, 0);
textprintf_ex(screen, font, 150, 300, RED, BLACK, "LEVEL 1 COMPLETE! +100 points!");
textprintf_ex(screen, font, 0, 0, RED, BLACK, "Score: %d", score);
rest(5000);
MapLoad("map2.fmp");
play_midi(music2, 0);
mapxoff = 0;
facing = 1;
efacing = 1;
player->x = 80;
player->y = 351;
objective1 = false;
}
oldpy = player->y;
oldpx = player->x;
oldey = enemy->y;
oldex = enemy->x;
textprintf_ex(screen, font, 0, 0, RED, BLACK, "Score: %d", score);
textout_ex(screen, font, "Health: ", 0, 10, RED, BLACK);
textout_ex(screen, font, "Holding: ", 0, 20, RED, BLACK);
textout_ex(screen, font, "Deposit: ", 0, 30, RED, BLACK);
//textout_ex(screen, font, "Time: ", 300, 0, RED, BLACK);
textprintf_ex(screen, font, 0, 40, RED, BLACK, "player->x: %d", player->x);
textprintf_ex(screen, font, 0, 50, RED, BLACK, "player->y: %d", player->y);
//player falls in water
if (player->y > 400)
{
score -= 10;
play_sample(splash, 200, 128, 1000, 0);
textprintf_ex(screen, font, 150, 300, RED, BLACK, "YOU HAVE FALLEN INTO THE WATER! -10 points!");
textprintf_ex(screen, font, 0, 0, RED, BLACK, "Score: %d", score);
rest(3000);
player->x = 0;
player->y = 0;
}
//ADJUST THE MUSIC VOLUME
if (key[KEY_EQUALS] && volume<255)
{
volume++;
set_volume(0,volume);
}
else if (key[KEY_MINUS] && volume>0)
{
volume--;
set_volume(0,volume);
}
//ENEMY COLLISION DETECTION
if (efacing)
{
enemy->x+=2;
if (++enemy->framecount > enemy->framedelay)
{
enemy->framecount=0;
if (++enemy->curframe > enemy->maxframe)
enemy->curframe=1;
}
}
if (!efacing)
{
enemy->x-=2;
if (++enemy->framecount > enemy->framedelay)
{
enemy->framecount=0;
if (++enemy->curframe > enemy->maxframe)
enemy->curframe=1;
}
}
if (collided(enemy->x + 30, enemy->y))
{
efacing = 0;
}
if (collided(enemy->x, enemy->y))
{
efacing = 1;
}
//PLAYER COLLISION DETECTION
if (!facing)
{
if (collided(player->x, player->y + player->height))
player->x = oldpx;
}
else
{
if (collided(player->x + player->width,
player->y + player->height))
player->x = oldpx;
}
//HANDLE PLAYER MOVEMENT
if (key[KEY_RIGHT])
{
facing = 1;
if (player->x > 9550)
{
player->x=9550;
}
player->x+=24;
if (++player->framecount > player->framedelay)
{
player->framecount=0;
if (++player->curframe > player->maxframe)
player->curframe=1;
}
}
else if (key[KEY_LEFT])
{
facing = 0;
if (player->x < 1)
{
player->x=1;
}
player->x-=6;
if (++player->framecount > player->framedelay)
{
player->framecount=0;
if (++player->curframe > player->maxframe)
player->curframe=1;
}
}
//HANDLE PLAYER JUMPING
if (jump==JUMPIT)
{
if (!collided(player->x + player->width/2,
player->y + player->height + 5))
jump = 0;
if (key[KEY_SPACE])
jump = 22;
}
else
{
player->y -= jump/3;
jump--;
}
if (jump<0)
{
if (collided(player->x + player->width/2,
player->y + player->height))
{
jump = JUMPIT;
while (collided(player->x + player->width/2,
player->y + player->height))
player->y -= 2;
}
}
//PLAYER COLLISION DETECTION
if (!facing)
{
if (collided(player->x, player->y + player->height))
player->x = oldpx;
}
else
{
if (collided(player->x + player->width,
player->y + player->height))
player->x = oldpx;
}
//update the map scroll position
mapxoff = player->x + player->width/2 - WIDTH/2 + 10;
mapyoff = player->y + player->height/2 - HEIGHT/2 + 10;
//avoid moving beyond the map edge
if (mapxoff < 0) mapxoff = 0;
if (mapxoff > (mapwidth * mapblockwidth - WIDTH))
mapxoff = mapwidth * mapblockwidth - WIDTH;
if (mapyoff < 0)
mapyoff = 0;
if (mapyoff > (mapheight * mapblockheight - HEIGHT))
mapyoff = mapheight * mapblockheight - HEIGHT;
//draw the background tiles
MapDrawBG(buffer, mapxoff, mapyoff, 0, 0, WIDTH-1, HEIGHT-1);
//draw foreground tiles
//MapDrawFG(buffer, mapxoff, mapyoff, 0, 0, WIDTH-1, HEIGHT-1, 1);
//draw the player's sprite
if (facing)
draw_sprite(buffer, player_image[player->curframe],
(player->x-mapxoff), (player->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, player_image[player->curframe],
(player->x-mapxoff), (player->y-mapyoff));
//draw the enemy's sprite
if (efacing)
draw_sprite(buffer, enemy_image[enemy->curframe],
(enemy->x-mapxoff), (enemy->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy_image[enemy->curframe],
(enemy->x-mapxoff), (enemy->y-mapyoff));
if (efacing)
draw_sprite(buffer, enemy2_image[enemy2->curframe],
(enemy2->x-mapxoff), (enemy2->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy2_image[enemy2->curframe],
(enemy2->x-mapxoff), (enemy2->y-mapyoff));
if (efacing)
draw_sprite(buffer, enemy3_image[enemy3->curframe],
(enemy3->x-mapxoff), (enemy3->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy3_image[enemy3->curframe],
(enemy3->x-mapxoff), (enemy3->y-mapyoff));
if (efacing)
draw_sprite(buffer, enemy4_image[enemy4->curframe],
(enemy4->x-mapxoff), (enemy4->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy4_image[enemy4->curframe],
(enemy4->x-mapxoff), (enemy4->y-mapyoff));
if (efacing)
draw_sprite(buffer, enemy5_image[enemy5->curframe],
(enemy5->x-mapxoff), (enemy5->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy5_image[enemy5->curframe],
(enemy5->x-mapxoff), (enemy5->y-mapyoff));
if (efacing)
draw_sprite(buffer, enemy6_image[enemy6->curframe],
(enemy6->x-mapxoff), (enemy6->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy6_image[enemy6->curframe],
(enemy6->x-mapxoff), (enemy6->y-mapyoff));
if (efacing)
draw_sprite(buffer, enemy7_image[enemy7->curframe],
(enemy7->x-mapxoff), (enemy7->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy7_image[enemy7->curframe],
(enemy7->x-mapxoff), (enemy7->y-mapyoff));
if (efacing)
draw_sprite(buffer, enemy8_image[enemy8->curframe],
(enemy8->x-mapxoff), (enemy8->y-mapyoff+1));
else
draw_sprite_h_flip(buffer, enemy8_image[enemy8->curframe],
(enemy8->x-mapxoff), (enemy8->y-mapyoff));
//blit the double buffer
vsync();
acquire_screen();
blit(buffer, screen, 0, 0, 0, 0, WIDTH-1, HEIGHT-1);
release_screen();
}
for (n=0; n<8; n++)
destroy_bitmap(player_image[n]);
free(player);
destroy_bitmap(buffer);
MapFreeMem ();
allegro_exit();
return 0;
}
END_OF_MAIN()