libsuperderpy/src/level.c

581 lines
25 KiB
C
Raw Normal View History

2012-02-28 13:09:12 +01:00
/*! \file level.c
* \brief Playable Level code.
*/
2012-03-04 13:32:42 +01:00
/*
* Copyright (c) Sebastian Krzyszkowiak <dos@dosowisko.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
2012-02-22 12:43:14 +01:00
#include <stdio.h>
2012-05-20 14:40:49 +02:00
#include <math.h>
#include "levels/actions.h"
#include "moonwalk.h"
#include "config.h"
#include "pause.h"
2012-02-22 12:43:14 +01:00
#include "level.h"
2012-04-06 23:32:15 +02:00
#include "timeline.h"
2012-04-14 22:26:33 +02:00
/* TODO: check if spritesheet speed still depends on FPS */
2012-05-03 19:42:23 +02:00
void SelectDerpySpritesheet(struct Game *game, char* name) {
struct Spritesheet *tmp = game->level.derpy_sheets;
PrintConsole(game, "Selecting Derpy spritesheet: %s", name);
2012-05-03 19:42:23 +02:00
if (!tmp) {
PrintConsole(game, "ERROR: No spritesheets registered for Derpy!");
return;
}
while (tmp) {
if (!strcmp(tmp->name, name)) {
game->level.derpy_sheet = &(tmp->bitmap);
game->level.sheet_rows = tmp->rows;
game->level.sheet_cols = tmp->cols;
2012-05-08 13:22:56 +02:00
game->level.sheet_blanks = tmp->blanks;
2012-05-03 19:42:23 +02:00
game->level.sheet_speed_modifier = tmp->speed;
game->level.sheet_pos = 0;
game->level.sheet_scale = tmp->scale;
if (game->level.derpy) al_destroy_bitmap(game->level.derpy);
game->level.derpy = al_create_bitmap((game->viewportHeight*0.25)*tmp->aspect*tmp->scale, (game->viewportHeight*0.25)*tmp->scale);
PrintConsole(game, "SUCCESS: Derpy spritesheet activated: %s (%dx%d)", name, al_get_bitmap_width(game->level.derpy), al_get_bitmap_height(game->level.derpy));
2012-05-03 19:42:23 +02:00
return;
}
tmp = tmp->next;
}
PrintConsole(game, "ERROR: No spritesheets registered for Derpy with given name: %s", name);
return;
}
void RegisterDerpySpritesheet(struct Game *game, char* name) {
char filename[255] = { };
sprintf(filename, "data/levels/derpy/%s.ini", name);
ALLEGRO_CONFIG *config = al_load_config_file(filename);
struct Spritesheet *s = malloc(sizeof(struct Spritesheet));
s->name = malloc((strlen(name)+1)*sizeof(char));
strcpy(s->name, name);
s->bitmap = NULL;
s->cols = atoi(al_get_config_value(config, "", "cols"));
s->rows = atoi(al_get_config_value(config, "", "rows"));
2012-05-08 13:22:56 +02:00
s->blanks = atoi(al_get_config_value(config, "", "blanks"));
2012-05-03 19:42:23 +02:00
s->speed = atof(al_get_config_value(config, "", "speed"));
2012-05-08 13:22:56 +02:00
s->aspect = atof(al_get_config_value(config, "", "aspect"));
s->scale = atof(al_get_config_value(config, "", "scale"));
2012-05-03 19:42:23 +02:00
s->next = game->level.derpy_sheets;
game->level.derpy_sheets = s;
al_destroy_config(config);
PrintConsole(game, "Registering Derpy spritesheet: %s", name);
2012-05-03 19:42:23 +02:00
}
void Level_Passed(struct Game *game) {
if (game->level.current_level<6) {
int available = atoi(GetConfigOptionDefault("MuffinAttack", "level", "1"));
available++;
if ((available<2) || (available>7)) available=1;
if (available==(game->level.current_level+1)) {
char* text = malloc(2*sizeof(char));
sprintf(text, "%d", available);
SetConfigOption("MuffinAttack", "level", text);
free(text);
}
} else {
SetConfigOption("MuffinAttack", "completed", "1");
}
}
2012-02-22 12:43:14 +01:00
void Level_Draw(struct Game *game) {
2012-05-07 20:17:35 +02:00
if (!al_get_sample_instance_playing(game->level.music) && (game->loadstate==GAMESTATE_LEVEL)) {
2012-04-09 15:25:56 +02:00
al_set_sample_instance_playing(game->level.music, true);
al_set_sample_instance_position(game->level.music, game->level.music_pos);
}
if (game->level.current_level!=1) Moonwalk_Draw(game);
else {
2012-05-07 20:17:35 +02:00
2012-04-09 15:58:01 +02:00
struct ALLEGRO_KEYBOARD_STATE keyboard;
al_get_keyboard_state(&keyboard);
if (game->level.handle_input) {
2012-06-19 17:18:33 +02:00
if (game->level.derpy_angle > 0) { game->level.derpy_angle -= tps(game, 60*0.02); if (game->level.derpy_angle < 0) game->level.derpy_angle = 0; }
if (game->level.derpy_angle < 0) { game->level.derpy_angle += tps(game, 60*0.02); if (game->level.derpy_angle > 0) game->level.derpy_angle = 0; }
2012-04-09 15:58:01 +02:00
if (al_key_down(&keyboard, ALLEGRO_KEY_UP)) {
2012-06-19 17:18:33 +02:00
game->level.derpy_y -= tps(game, 60*0.005);
game->level.derpy_angle -= tps(game, 60*0.03);
if (game->level.derpy_angle < tps(game, 60*-0.15)) game->level.derpy_angle = tps(game, 60*-0.15);
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "Derpy Y position: %f", game->level.derpy_y);*/
2012-05-07 20:17:35 +02:00
}
2012-04-09 15:58:01 +02:00
if (al_key_down(&keyboard, ALLEGRO_KEY_DOWN)) {
2012-06-19 17:18:33 +02:00
game->level.derpy_y += tps(game, 60*0.005);
game->level.derpy_angle += tps(game, 60*0.03);
if (game->level.derpy_angle > tps(game, 60*0.15)) game->level.derpy_angle = tps(game, 60*0.15);
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "Derpy Y position: %f", game->level.derpy_y);*/
2012-04-09 15:58:01 +02:00
}
2012-05-18 13:12:58 +02:00
/*if ((game->level.derpy_y > 0.6) && (game->level.flying)) {
2012-05-08 13:22:56 +02:00
SelectDerpySpritesheet(game, "run");
game->level.flying = false;
game->level.sheet_speed = tps(game, 60*0.0020/game->level.speed);
}
else if ((game->level.derpy_y <= 0.6) && (!game->level.flying)) {
2012-05-08 13:22:56 +02:00
SelectDerpySpritesheet(game, "fly");
game->level.flying = true;
game->level.sheet_speed = tps(game, 60*2.4);
2012-05-19 18:48:29 +02:00
}
if (!game->level.flying) game->level.sheet_speed = tps(game, 60*0.0020/game->level.speed); */
2012-04-09 16:14:10 +02:00
if (game->level.derpy_y < 0) game->level.derpy_y=0;
else if (game->level.derpy_y > 0.8) game->level.derpy_y=0.8;
2012-05-07 20:17:35 +02:00
2012-06-19 17:18:33 +02:00
game->level.derpy_y += tps(game, 60*(game->level.derpy_angle / 30));
}
2012-04-08 19:01:30 +02:00
al_draw_bitmap(game->level.clouds, (-game->level.cl_pos)*al_get_bitmap_width(game->level.clouds), 0, 0);
al_draw_bitmap(game->level.clouds, (1+(-game->level.cl_pos))*al_get_bitmap_width(game->level.clouds), 0, 0);
al_draw_bitmap(game->level.background, (-game->level.bg_pos)*al_get_bitmap_width(game->level.background), 0, 0);
al_draw_bitmap(game->level.background, (1+(-game->level.bg_pos))*al_get_bitmap_width(game->level.background), 0, 0);
al_draw_bitmap(game->level.stage, (-game->level.st_pos)*al_get_bitmap_width(game->level.stage), 0 ,0);
al_draw_bitmap(game->level.stage, (1+(-game->level.st_pos))*al_get_bitmap_width(game->level.stage), 0 ,0);
2012-05-07 20:17:35 +02:00
int derpyx = game->level.derpy_x*game->viewportWidth;
int derpyy = game->level.derpy_y*game->viewportHeight;
int derpyw = al_get_bitmap_width(game->level.derpy);
int derpyh = al_get_bitmap_height(game->level.derpy);
int derpyo = game->viewportWidth*0.1953125-al_get_bitmap_width(game->level.derpy); /* offset */
bool colision = false;
2012-05-19 15:31:41 +02:00
struct Obstacle *tmp = game->level.obstacles;
2012-05-01 22:52:30 +02:00
while (tmp) {
/*PrintConsole(game, "DRAWING %f %f", tmp->x, tmp->y);*/
int x = (tmp->x/100.0)*game->viewportWidth;
int y = (tmp->y/100.0)*game->viewportHeight;
int w = 0, h = 0;
if (tmp->bitmap) {
w = al_get_bitmap_width(*(tmp->bitmap))/tmp->cols;
h = al_get_bitmap_height(*(tmp->bitmap))/tmp->rows;
}
2012-05-20 14:40:49 +02:00
if (x > -w) {
/*if (!tmp->hit)*/
if ((((x>=derpyx+0.38*derpyw+derpyo) && (x<=derpyx+0.94*derpyw+derpyo)) || ((x+w>=derpyx+0.38*derpyw+derpyo) && (x+w<=derpyx+0.94*derpyw+derpyo)) || ((x<=derpyx+0.38*derpyw+derpyo) && (x+w>=derpyx+0.94*derpyw+derpyo))) &&
(((y>=derpyy+0.26*derpyh) && (y<=derpyy+0.76*derpyh)) || ((y+h>=derpyy+0.26*derpyh) && (y+h<=derpyy+0.76*derpyh)) || ((y<=derpyy+0.26*derpyh) && (y+h>=derpyy+0.76*derpyh)))) {
2012-05-18 13:12:58 +02:00
tmp->hit=true;
}
2012-05-20 14:40:49 +02:00
2012-05-21 14:00:42 +02:00
if (tmp->bitmap) {
ALLEGRO_BITMAP* subbitmap = al_create_sub_bitmap(*(tmp->bitmap),w*(tmp->pos%tmp->cols), h*(tmp->pos/tmp->cols),w,h);
al_draw_rotated_bitmap(subbitmap,w/2.0, h/2.0, x+w/2.0,y+h/2.0, tmp->angle, 0);
al_destroy_bitmap(subbitmap);
}
2012-05-20 14:40:49 +02:00
if (tmp->anim_speed) {
tmp->tmp_pos+=tps(game, 60);
if (tmp->tmp_pos >= tmp->anim_speed) {
tmp->pos++;
tmp->tmp_pos = 0;
}
if (tmp->pos>=tmp->cols*tmp->rows-tmp->blanks) tmp->pos=0;
}
/*al_draw_bitmap(*(tmp->bitmap), x, y, 0);*/
2012-05-19 18:48:29 +02:00
if (game->level.debug_show_sprite_frames) al_draw_rectangle(x, y, x+w, y+h, al_map_rgba(255,0,0,255), 3);
if (tmp->hit) {
if (tmp->points<0) colision = true;
else tmp->bitmap = NULL;
game->level.hp+=tps(game, 60*0.0002*tmp->points*(((1-game->level.speed_modifier)/2.0)+1));
if (game->level.hp>1) game->level.hp=1;
PrintConsole(game, "POINTS: %d, %f", tmp->points, tps(game, 60*0.0002*tmp->points*game->level.speed_modifier));
if ((game->level.hp<=0) && (!game->level.failed)) {
game->level.failed = true;
game->level.handle_input = false;
game->level.speed_modifier = 1;
TM_AddBackgroundAction(&LevelFailed, NULL, 0, "levelfailed");
}
}
tmp->x -= tps(game, game->level.speed*game->level.speed_modifier*60*tmp->speed)*100*al_get_bitmap_width(game->level.stage)/(float)game->viewportWidth;
2012-05-03 02:19:55 +02:00
if (tmp->callback) tmp->callback(game, tmp);
tmp = tmp->next;
2012-05-01 22:52:30 +02:00
} else {
if (tmp->next)
tmp->next->prev = tmp->prev;
if (tmp->prev)
tmp->prev->next = tmp->next;
else
2012-05-19 15:31:41 +02:00
game->level.obstacles = tmp->next;
struct Obstacle *t = tmp;
tmp = tmp->next;
free(t);
2012-05-01 22:52:30 +02:00
}
}
/*if (colision) game->level.hp-=tps(game, 60*0.002);*/
2012-05-07 20:17:35 +02:00
2012-04-08 23:25:14 +02:00
al_set_target_bitmap(game->level.derpy);
al_clear_to_color(al_map_rgba(0,0,0,0));
2012-05-03 19:42:23 +02:00
al_draw_bitmap_region(*(game->level.derpy_sheet),al_get_bitmap_width(game->level.derpy)*(game->level.sheet_pos%game->level.sheet_cols),al_get_bitmap_height(game->level.derpy)*(game->level.sheet_pos/game->level.sheet_cols),al_get_bitmap_width(game->level.derpy), al_get_bitmap_height(game->level.derpy),0,0,0);
if ((game->level.sheet_speed) && (game->level.sheet_speed_modifier)) {
2012-04-14 22:26:33 +02:00
game->level.sheet_tmp+=tps(game, 60);
if (game->level.sheet_tmp >= (game->level.sheet_speed/game->level.speed_modifier)/game->level.sheet_speed_modifier) {
2012-04-14 22:26:33 +02:00
game->level.sheet_pos++;
game->level.sheet_tmp = 0;
}
2012-05-08 13:22:56 +02:00
if (game->level.sheet_pos>=game->level.sheet_cols*game->level.sheet_rows-game->level.sheet_blanks) game->level.sheet_pos=0;
2012-04-08 23:25:14 +02:00
}
al_set_target_bitmap(al_get_backbuffer(game->display));
2012-06-19 17:18:33 +02:00
al_draw_tinted_rotated_bitmap(game->level.derpy, al_map_rgba(255,255-colision*255,255-colision*255,255), al_get_bitmap_width(game->level.derpy), al_get_bitmap_height(game->level.derpy)/2, derpyx+game->viewportWidth*0.1953125, derpyy + al_get_bitmap_height(game->level.derpy)/2, game->level.derpy_angle, 0);
2012-05-04 01:12:19 +02:00
2012-05-19 18:48:29 +02:00
/* if ((((x>=derpyx+0.36*derpyw) && (x<=derpyx+0.94*derpyw)) || ((x+w>=derpyx+0.36*derpyw) && (x+w<=derpyx+0.94*derpyw))) &&
(((y>=derpyy+0.26*derpyh) && (y<=derpyy+0.76*derpyh)) || ((y+h>=derpyy+0.26*derpyh) && (y+h<=derpyy+0.76*derpyh)))) {
*/
if (game->level.debug_show_sprite_frames) {
al_draw_rectangle(derpyx+derpyo, derpyy, derpyx+derpyw+derpyo, derpyy+derpyh, al_map_rgba(0,255,0,255), 3);
al_draw_rectangle(derpyx+0.38*derpyw+derpyo, derpyy+0.26*derpyh, derpyx+0.94*derpyw+derpyo, derpyy+0.76*derpyh, al_map_rgba(0,0,255,255), 3);
}
2012-04-08 19:01:30 +02:00
al_draw_bitmap(game->level.foreground, (-game->level.fg_pos)*al_get_bitmap_width(game->level.foreground), 0 ,0);
al_draw_bitmap(game->level.foreground, (1+(-game->level.fg_pos))*al_get_bitmap_width(game->level.foreground), 0 ,0);
2012-05-04 01:12:19 +02:00
2012-04-08 19:01:30 +02:00
if (game->level.speed > 0) {
game->level.cl_pos += tps(game, 60*game->level.speed*game->level.speed_modifier) * 0.2;
game->level.bg_pos += tps(game, 60*game->level.speed*game->level.speed_modifier) * 0.6;
game->level.st_pos += tps(game, 60*game->level.speed*game->level.speed_modifier) * 1;
game->level.fg_pos += tps(game, 60*game->level.speed*game->level.speed_modifier) * 1.75;
2012-04-09 18:11:09 +02:00
if (game->level.bg_pos >= 1) game->level.bg_pos=game->level.bg_pos-1;
if (game->level.st_pos >= 1) game->level.st_pos=game->level.st_pos-1;
if (game->level.fg_pos >= 1) game->level.fg_pos=game->level.fg_pos-1;
2012-04-08 19:01:30 +02:00
}
2012-04-09 18:11:09 +02:00
game->level.cl_pos += tps(game, 60*0.00005);
if (game->level.cl_pos >= 1) game->level.cl_pos=game->level.cl_pos-1;
2012-05-07 20:17:35 +02:00
2012-05-09 10:58:45 +02:00
al_set_target_bitmap(game->level.meter_bmp);
2012-05-09 12:40:21 +02:00
al_clear_to_color(al_map_rgba(0,0,0,0));
al_draw_filled_rounded_rectangle(al_get_bitmap_width(game->level.meter_bmp)*0.1, al_get_bitmap_height(game->level.meter_bmp)*0.34, al_get_bitmap_width(game->level.meter_bmp)*0.993, al_get_bitmap_height(game->level.meter_bmp)*0.66,
6,6, al_map_rgb(232,234,239));
al_draw_horizontal_gradient_rect(al_get_bitmap_width(game->level.meter_bmp)-game->viewportWidth*0.215, (al_get_bitmap_height(game->level.meter_bmp)-game->viewportHeight*0.025)/2, game->viewportWidth*0.215*0.975, game->viewportHeight*0.025, al_map_rgb(150,159,182), al_map_rgb(130,139,162));
al_draw_filled_rectangle(al_get_bitmap_width(game->level.meter_bmp)-game->viewportWidth*0.215, (al_get_bitmap_height(game->level.meter_bmp)-game->viewportHeight*0.025)/2, al_get_bitmap_width(game->level.meter_bmp)-game->viewportWidth*0.215+(game->viewportWidth*0.215*0.975)*game->level.hp, (al_get_bitmap_height(game->level.meter_bmp)-game->viewportHeight*0.025)/2+game->viewportHeight*0.025, al_map_rgb(214,172,55));
2012-05-09 12:40:21 +02:00
al_draw_bitmap(game->level.meter_image, 0, 0, 0);
2012-05-09 10:58:45 +02:00
al_set_target_bitmap(al_get_backbuffer(game->display));
2012-05-17 00:18:19 +02:00
al_draw_tinted_bitmap(game->level.meter_bmp, al_map_rgba(game->level.meter_alpha,game->level.meter_alpha,game->level.meter_alpha,game->level.meter_alpha), game->viewportWidth*0.95-al_get_bitmap_width(game->level.meter_bmp), game->viewportHeight*0.975-al_get_bitmap_height(game->level.meter_bmp), 0);
2012-05-09 10:58:45 +02:00
2012-04-06 23:32:15 +02:00
TM_Process();
}
2012-02-22 12:43:14 +01:00
}
void Level_Load(struct Game *game) {
2012-05-19 01:20:52 +02:00
game->level.failed=false;
2012-05-17 00:18:19 +02:00
game->level.hp=1;
2012-04-08 19:01:30 +02:00
game->level.cl_pos=0;
game->level.bg_pos=0;
game->level.fg_pos=0.2;
game->level.st_pos=0.1;
2012-04-08 23:25:14 +02:00
game->level.speed = 0;
game->level.speed_modifier = 1;
2012-04-08 23:25:14 +02:00
game->level.derpy_x = -0.2;
game->level.derpy_y = 0.6;
2012-06-19 17:18:33 +02:00
game->level.derpy_angle = 0;
2012-05-08 13:22:56 +02:00
game->level.sheet_speed = tps(game, 60*2.4);
2012-04-08 23:25:14 +02:00
game->level.sheet_tmp = 0;
game->level.handle_input = false;
2012-05-19 15:31:41 +02:00
game->level.obstacles = NULL;
2012-05-09 10:58:45 +02:00
game->level.meter_alpha=0;
2012-05-19 18:48:29 +02:00
game->level.debug_show_sprite_frames=false;
2012-04-06 23:32:15 +02:00
al_clear_to_color(al_map_rgb(0,0,0));
if (game->level.current_level!=1) Moonwalk_Load(game);
2012-04-06 23:32:15 +02:00
else {
TM_Init(game);
TM_AddBackgroundAction(&FadeIn, NULL, 0, "fadein");
2012-04-08 23:25:14 +02:00
TM_AddDelay(1000);
TM_AddQueuedBackgroundAction(&Welcome, NULL, 0, "welcome");
2012-04-09 15:25:56 +02:00
TM_AddDelay(1000);
TM_AddAction(&Walk, NULL, "walk");
TM_AddAction(&Move, NULL, "move");
TM_AddAction(&Stop, NULL, "stop");
TM_AddDelay(1000);
TM_AddAction(&Letter, NULL, "letter");
2012-05-18 13:12:58 +02:00
TM_AddDelay(200);
TM_AddQueuedBackgroundAction(&Accelerate, NULL, 0, "accelerate");
TM_AddAction(&Fly, NULL, "fly");
TM_AddDelay(500);
2012-04-14 22:26:33 +02:00
/* first part gameplay goes here */
2012-04-30 00:55:27 +02:00
2012-05-19 15:31:41 +02:00
/* actions for generating obstacles should go here
2012-04-30 00:55:27 +02:00
* probably as regular actions. When one ends, harder one
* begins. After last one part with muffins starts. */
2012-05-19 15:31:41 +02:00
TM_AddAction(&GenerateObstacles, NULL, "obstacles");
TM_AddDelay(3*1000);
/* wings disappear, deccelerate */
TM_AddAction(&Run, NULL, "run");
TM_AddDelay(3*1000);
/* show Fluttershy's house
2012-05-07 20:17:35 +02:00
2012-04-08 23:25:14 +02:00
// second part gameplay goes here
2012-05-07 20:17:35 +02:00
// cutscene goes here */
TM_AddAction(&PassLevel, NULL, "passlevel");
2012-05-20 23:17:52 +02:00
struct Obstacle *obst = malloc(sizeof(struct Obstacle));
obst->prev = NULL;
obst->next = NULL;
obst->x = 83.5;
obst->y = 55;
obst->speed = 1;
obst->points = 0;
obst->hit = false;
obst->rows = 1;
obst->cols = 1;
obst->pos = 0;
obst->blanks = 0;
obst->anim_speed = 0;
obst->tmp_pos = 0;
obst->angle = 0;
2012-05-20 23:17:52 +02:00
obst->callback = NULL;
obst->data = NULL;
obst->bitmap = &(game->level.owl);
game->level.obstacles = obst;
2012-04-06 23:32:15 +02:00
}
2012-02-22 12:43:14 +01:00
}
2012-02-25 22:26:31 +01:00
2012-02-22 12:43:14 +01:00
int Level_Keydown(struct Game *game, ALLEGRO_EVENT *ev) {
2012-04-09 15:25:56 +02:00
if (ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) {
game->level.music_pos = al_get_sample_instance_position(game->level.music);
al_set_sample_instance_playing(game->level.music, false);
} else if ((game->debug) && (ev->keyboard.keycode==ALLEGRO_KEY_F2)) {
game->level.hp -= 0.1;
if (game->level.hp <= 0) game->level.hp=0.001;
2012-05-19 18:48:29 +02:00
} else if ((game->debug) && (ev->keyboard.keycode==ALLEGRO_KEY_F3)) {
game->level.hp += 0.1;
if (game->level.hp > 1) game->level.hp=1;
2012-05-19 18:48:29 +02:00
} else if ((game->debug) && (ev->keyboard.keycode==ALLEGRO_KEY_F4)) {
game->level.debug_show_sprite_frames = !game->level.debug_show_sprite_frames;
2012-04-09 15:25:56 +02:00
}
if (game->level.current_level!=1) Moonwalk_Keydown(game, ev);
else if (game->level.handle_input) {
if (ev->keyboard.keycode==ALLEGRO_KEY_LEFT) {
game->level.speed_modifier = 0.75;
} else if (ev->keyboard.keycode==ALLEGRO_KEY_RIGHT) {
game->level.speed_modifier = 1.3;
}
}
if (ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) {
game->gamestate = GAMESTATE_PAUSE;
game->loadstate = GAMESTATE_LEVEL;
Pause_Load(game);
}
return 0;
}
2012-04-06 23:32:15 +02:00
void Level_ProcessLogic(struct Game *game, ALLEGRO_EVENT *ev) {
if (game->level.handle_input) {
if ((ev->type==ALLEGRO_EVENT_KEY_UP) && (ev->keyboard.keycode==ALLEGRO_KEY_LEFT)) {
game->level.speed_modifier = 1;
struct ALLEGRO_KEYBOARD_STATE keyboard;
al_get_keyboard_state(&keyboard);
if (al_key_down(&keyboard, ALLEGRO_KEY_RIGHT)) {
game->level.speed_modifier = 1.3;
}
} else if ((ev->type==ALLEGRO_EVENT_KEY_UP) && (ev->keyboard.keycode==ALLEGRO_KEY_RIGHT)) {
game->level.speed_modifier = 1;
struct ALLEGRO_KEYBOARD_STATE keyboard;
al_get_keyboard_state(&keyboard);
if (al_key_down(&keyboard, ALLEGRO_KEY_LEFT)) {
game->level.speed_modifier = 0.75;
}
}
}
2012-04-06 23:32:15 +02:00
if (game->level.current_level==1) TM_HandleEvent(ev);
}
void Level_Preload(struct Game *game, void (*progress)(struct Game*, float)) {
2012-05-03 19:42:23 +02:00
game->level.derpy_sheets = NULL;
game->level.derpy = NULL;
Pause_Preload(game);
2012-05-03 19:42:23 +02:00
RegisterDerpySpritesheet(game, "walk");
RegisterDerpySpritesheet(game, "fly");
RegisterDerpySpritesheet(game, "run");
RegisterDerpySpritesheet(game, "stand");
if (game->level.current_level!=1) Moonwalk_Preload(game);
2012-04-09 15:25:56 +02:00
else {
game->level.sample = al_load_sample( "data/levels/1/music.flac" );
game->level.music = al_create_sample_instance(game->level.sample);
al_attach_sample_instance_to_mixer(game->level.music, game->audio.music);
al_set_sample_instance_playmode(game->level.music, ALLEGRO_PLAYMODE_LOOP);
if (!game->level.sample){
fprintf(stderr, "Audio clip sample not loaded!\n" );
exit(-1);
}
}
Level_PreloadBitmaps(game, progress);
}
void Level_Unload(struct Game *game) {
Pause_Unload_Real(game);
2012-04-09 15:25:56 +02:00
al_destroy_sample_instance(game->level.music);
al_destroy_sample(game->level.sample);
if (game->level.current_level!=1) Moonwalk_Unload(game);
2012-04-06 23:32:15 +02:00
else {
TM_Destroy();
}
2012-05-19 15:31:41 +02:00
struct Obstacle *t = game->level.obstacles;
2012-05-03 19:42:23 +02:00
if (t) {
while (t->next) {
if (t->prev) free(t->prev);
t = t->next;
}
free(t);
2012-05-01 22:52:30 +02:00
}
2012-04-08 19:01:30 +02:00
Level_UnloadBitmaps(game);
2012-05-03 19:42:23 +02:00
struct Spritesheet *tmp, *s = game->level.derpy_sheets;
tmp = s;
while (s) {
tmp = s;
s = s->next;
free(tmp);
}
2012-02-22 12:43:14 +01:00
}
2012-02-25 22:26:31 +01:00
void Level_UnloadBitmaps(struct Game *game) {
2012-04-08 23:25:14 +02:00
al_destroy_bitmap(game->level.derpy);
2012-05-03 19:42:23 +02:00
struct Spritesheet *tmp = game->level.derpy_sheets;
while (tmp) {
al_destroy_bitmap(tmp->bitmap);
tmp = tmp->next;
}
if (game->level.current_level!=1) Moonwalk_UnloadBitmaps(game);
2012-04-08 19:01:30 +02:00
else {
2012-07-08 00:23:40 +02:00
al_destroy_font(game->level.letter_font);
2012-04-08 19:01:30 +02:00
al_destroy_bitmap(game->level.foreground);
al_destroy_bitmap(game->level.background);
al_destroy_bitmap(game->level.stage);
al_destroy_bitmap(game->level.clouds);
2012-04-08 23:25:14 +02:00
al_destroy_bitmap(game->level.welcome);
2012-05-22 21:29:55 +02:00
al_destroy_bitmap(game->level.letter);
al_destroy_bitmap(game->level.owl);
al_destroy_bitmap(game->level.obst_bmps.pie1);
al_destroy_bitmap(game->level.obst_bmps.pie2);
al_destroy_bitmap(game->level.obst_bmps.pig);
2012-05-23 10:34:36 +02:00
al_destroy_bitmap(game->level.obst_bmps.cherry);
2012-05-22 21:29:55 +02:00
al_destroy_bitmap(game->level.obst_bmps.muffin);
al_destroy_bitmap(game->level.obst_bmps.badmuffin);
al_destroy_bitmap(game->level.obst_bmps.screwball);
2012-05-09 10:58:45 +02:00
al_destroy_bitmap(game->level.meter_bmp);
2012-05-09 12:40:21 +02:00
al_destroy_bitmap(game->level.meter_image);
2012-04-08 19:01:30 +02:00
}
}
void Level_PreloadBitmaps(struct Game *game, void (*progress)(struct Game*, float)) {
2012-07-08 00:23:40 +02:00
PROGRESS_INIT(19);
int x = 0;
2012-05-03 19:42:23 +02:00
struct Spritesheet *tmp = game->level.derpy_sheets;
while (tmp) {
x++;
tmp = tmp->next;
}
if (game->level.current_level==1) load_a+=x;
else load_a=2+x;
tmp = game->level.derpy_sheets;
2012-05-03 19:42:23 +02:00
while (tmp) {
char filename[255] = { };
sprintf(filename, "levels/derpy/%s.png", tmp->name);
tmp->bitmap = LoadScaledBitmap(filename, (int)(game->viewportHeight*0.25*tmp->aspect*tmp->scale)*tmp->cols, (int)(game->viewportHeight*0.25*tmp->scale)*tmp->rows);
PROGRESS;
2012-05-03 19:42:23 +02:00
tmp = tmp->next;
}
PROGRESS;
if (!game->level.derpy) SelectDerpySpritesheet(game, "stand");
game->level.derpy = al_create_bitmap(al_get_bitmap_width(*(game->level.derpy_sheet))/game->level.sheet_cols, al_get_bitmap_height(*(game->level.derpy_sheet))/game->level.sheet_rows);
if (game->level.current_level!=1) Moonwalk_PreloadBitmaps(game);
2012-04-08 19:01:30 +02:00
else {
2012-04-14 22:26:33 +02:00
/* TODO: handle strange display aspects */
game->level.clouds = LoadScaledBitmap("levels/1/clouds.png", game->viewportHeight*4.73307291666666666667, game->viewportHeight);
PROGRESS;
game->level.foreground = LoadScaledBitmap("levels/1/foreground.png", game->viewportHeight*4.73307291666666666667, game->viewportHeight);
PROGRESS;
game->level.background = LoadScaledBitmap("levels/1/background.png", game->viewportHeight*4.73307291666666666667, game->viewportHeight);
PROGRESS;
game->level.stage = LoadScaledBitmap("levels/1/stage.png", game->viewportHeight*4.73307291666666666667, game->viewportHeight);
PROGRESS;
game->level.obst_bmps.pie1 = LoadScaledBitmap("levels/pie1.png", game->viewportWidth*0.1, game->viewportHeight*0.08);
2012-05-22 21:29:55 +02:00
PROGRESS;
game->level.obst_bmps.pie2 = LoadScaledBitmap("levels/pie2.png", game->viewportWidth*0.1, game->viewportHeight*0.08);
PROGRESS;
game->level.obst_bmps.pig = LoadScaledBitmap("levels/pig.png", (int)(game->viewportWidth*0.15)*3, (int)(game->viewportHeight*0.2)*3);
2012-05-20 14:40:49 +02:00
PROGRESS;
game->level.obst_bmps.screwball = LoadScaledBitmap("levels/screwball.png", (int)(game->viewportHeight*0.2)*4*1.4, (int)(game->viewportHeight*0.2)*4);
2012-05-21 18:47:17 +02:00
PROGRESS;
game->level.obst_bmps.muffin = LoadScaledBitmap("levels/muffin.png", game->viewportWidth*0.07, game->viewportHeight*0.1);
2012-05-18 23:40:02 +02:00
PROGRESS;
game->level.obst_bmps.cherry = LoadScaledBitmap("levels/cherry.png", game->viewportWidth*0.03, game->viewportHeight*0.08);
2012-05-23 10:34:36 +02:00
PROGRESS;
game->level.obst_bmps.badmuffin = LoadScaledBitmap("levels/badmuffin.png", game->viewportWidth*0.07, game->viewportHeight*0.1);
2012-05-21 18:47:17 +02:00
PROGRESS;
game->level.owl = LoadScaledBitmap("levels/owl.png", game->viewportWidth*0.08, game->viewportWidth*0.08);
2012-05-20 23:17:52 +02:00
PROGRESS;
game->level.letter_font = al_load_ttf_font("data/DejaVuSans.ttf",game->viewportHeight*0.0225,0 );
2012-07-08 00:23:40 +02:00
PROGRESS;
game->level.letter = LoadScaledBitmap("levels/letter.png", game->viewportHeight*1.3, game->viewportHeight*1.2);
2012-05-21 22:27:49 +02:00
al_set_target_bitmap(game->level.letter);
2012-07-08 00:23:40 +02:00
float y = 0.20;
float x = 0.19;
void draw_text(char* text) {
al_draw_text(game->level.letter_font, al_map_rgb(0,0,0), al_get_bitmap_width(game->level.letter)*x, game->viewportHeight*y, ALLEGRO_ALIGN_LEFT, text);
2012-07-08 00:23:40 +02:00
y+=0.028;
}
draw_text("Dear Derpy,");
draw_text("");
x = 0.20;
draw_text("I'm glad you decided to help us! I found a few tips");
draw_text("in my library that might be useful on your mission.");
draw_text("I would like to share them with you.");
draw_text("");
x = 0.21;
draw_text("Muffins regenerate your energy, so collect as many");
draw_text("as you can. Cherries can help you as well. But be");
draw_text("careful and avoid the muffinzombies - they can");
2012-07-08 00:23:40 +02:00
draw_text("harm you!");
draw_text("");
x = 0.22;
draw_text("Discord is not fully awake yet, but he's already");
draw_text("causing chaos all over Equestria and his strange");
draw_text("creatures may try to stop you. Don't let them!");
draw_text("");
x = 0.23;
draw_text("Last but not least - You should be able to see the");
draw_text("constellation Orion in the sky tonight. Be sure to");
draw_text("take a moment to look for it if you have one to");
draw_text("spare. It's beautiful!");
draw_text("");
x = 0.25;
draw_text("The fate of Equestria rests in your hooves.");
draw_text("Be safe and good luck!");
draw_text("");
x = 0.26;
draw_text("Yours,");
draw_text("Twilight Sparkle");
al_draw_text_with_shadow(game->menu.font, al_map_rgb(255,255,255), al_get_bitmap_width(game->level.letter)*0.5, al_get_bitmap_height(game->level.letter)*0.8, ALLEGRO_ALIGN_CENTRE, "Press enter to continue...");
2012-05-21 22:27:49 +02:00
al_set_target_bitmap(al_get_backbuffer(game->display));
PROGRESS;
game->level.welcome = al_create_bitmap(game->viewportWidth, game->viewportHeight/2);
PROGRESS;
2012-04-08 23:25:14 +02:00
al_set_target_bitmap(game->level.welcome);
al_clear_to_color(al_map_rgba(0,0,0,0));
al_draw_text_with_shadow(game->menu.font_title, al_map_rgb(255,255,255), game->viewportWidth*0.5, game->viewportHeight*0.1, ALLEGRO_ALIGN_CENTRE, "Level 1");
al_draw_text_with_shadow(game->menu.font_subtitle, al_map_rgb(255,255,255), game->viewportWidth*0.5, game->viewportHeight*0.275, ALLEGRO_ALIGN_CENTRE, "Fluttershy");
PROGRESS;
2012-05-09 10:58:45 +02:00
game->level.meter_image = LoadScaledBitmap("levels/meter.png", game->viewportWidth*0.075, game->viewportWidth*0.075*0.96470588235294117647);
PROGRESS;
game->level.meter_bmp = al_create_bitmap(game->viewportWidth*0.2+al_get_bitmap_width(game->level.meter_image), al_get_bitmap_height(game->level.meter_image));
2012-05-09 12:40:21 +02:00
al_set_target_bitmap(al_get_backbuffer(game->display));
2012-04-08 19:01:30 +02:00
}
PROGRESS;
2012-02-22 12:43:14 +01:00
}