2705 lines
94 KiB
ObjectPascal
2705 lines
94 KiB
ObjectPascal
program Volcano;
|
|
{$IFDEF DARWIN}
|
|
{$linkframework Cocoa}
|
|
{$linkframework SDL2}
|
|
{$linkframework OpenGL}
|
|
{$linkframework SDL2_image}
|
|
{$linkframework SDL2_mixer}
|
|
{$ELSE}
|
|
{$APPTYPE GUI}
|
|
{$ENDIF}
|
|
|
|
|
|
// Volcano (abans "Rise of the Bal1")
|
|
// Programat i dissenyat per Sergio Valor @JailDesigner
|
|
// Editor, música i suport técnic per Raimon Zamora @JailDoc
|
|
// Gràfics per Diego Valor @JailBrother
|
|
// Començat un 19 de febrer de 2016
|
|
|
|
uses sdl2, SDL2_image, SDL2_mixer;
|
|
|
|
const
|
|
GAME_SPEED = 24; //16 = normal-rapid, 24 = normal. Quan menor, més ràpid
|
|
|
|
UP = 0;
|
|
DOWN = 2;
|
|
RIGHT = 1;
|
|
LEFT = 3;
|
|
NONE = 4;
|
|
|
|
MAP_TILE_HEIGHT = 16;
|
|
MAP_TILE_WIDTH = 16;
|
|
|
|
ROOM_WIDTH_IN_TILES = 20;
|
|
ROOM_HEIGHT_IN_TILES = 14;
|
|
|
|
GAME_WINDOW_WIDTH = 320;
|
|
GAME_WINDOW_HEIGHT = 234;
|
|
|
|
TEST_ROOM = 118;
|
|
STARTING_ROOM = 161;//TEST_ROOM;
|
|
STARTING_PLAYER_TILE_X = 5;
|
|
STARTING_PLAYER_TILE_Y = 11;
|
|
ENEMY_HITBOX_REDUCTION = 4;
|
|
COOLDOWN_TIME = 50;
|
|
GRAVITY = 1;
|
|
MAX_SPEED_Y = 5;
|
|
BASE_SPEED = 1;
|
|
MAX_SPEED = 8;
|
|
RATIO_SPEED = 8;
|
|
DROP_TIMER = 100;
|
|
|
|
TOP_COLLISION = 0;
|
|
BOTTOM_COLLISION = 1;
|
|
LEFT_COLLISION = 2;
|
|
RIGHT_COLLISION = 3;
|
|
NO_COLLISION = 4;
|
|
|
|
MAX_ACTORS = 50;
|
|
|
|
KIND_FLYING_ENEMY = 0;
|
|
KIND_COIN = 1;
|
|
KIND_HEART = 2;
|
|
KIND_STATIC_ENEMY = 3;
|
|
KIND_MOBILE_PLATFORM = 4;
|
|
KIND_WALKING_ENEMY = 5;
|
|
KIND_DROP_GENERATOR = 6;
|
|
KIND_DROP_ENEMY = 7;
|
|
KIND_DROP_SPLAT = 8;
|
|
KIND_SPEED_ENEMY = 9;
|
|
KIND_KEY = 10;
|
|
KIND_LOCK = 11;
|
|
|
|
CODE_ENEMY_V1U = 208;
|
|
CODE_ENEMY_V2U = 209;
|
|
CODE_ENEMY_V3U = 210;
|
|
CODE_ENEMY_V1D = 211;
|
|
CODE_ENEMY_V2D = 212;
|
|
CODE_ENEMY_V3D = 213;
|
|
|
|
CODE_ENEMY_H1L = 214;
|
|
CODE_ENEMY_H2L = 215;
|
|
CODE_ENEMY_H3L = 216;
|
|
CODE_ENEMY_H1R = 217;
|
|
CODE_ENEMY_H2R = 218;
|
|
CODE_ENEMY_H3R = 219;
|
|
|
|
CODE_ENEMY_W1L = 224;
|
|
CODE_ENEMY_W2L = 225;
|
|
CODE_ENEMY_W3L = 226;
|
|
CODE_ENEMY_W1R = 227;
|
|
CODE_ENEMY_W2R = 228;
|
|
CODE_ENEMY_W3R = 229;
|
|
|
|
CODE_ENEMY_DRP = 230;
|
|
|
|
CODE_ENEMY_SPL = 231;
|
|
CODE_ENEMY_SPR = 232;
|
|
|
|
CODE_COIN = 240;
|
|
CODE_HEART = 241;
|
|
CODE_KEY_RED = 242;
|
|
CODE_LOCK_RED = 243;
|
|
CODE_KEY_BLUE = 244;
|
|
CODE_LOCK_BLUE = 245;
|
|
CODE_KEY_GREEN = 246;
|
|
CODE_LOCK_GREEN = 247;
|
|
CODE_KEY_YELLOW = 248;
|
|
CODE_LOCK_YELLOW = 249;
|
|
|
|
MAX_ANIMATED_TILES = 200;
|
|
|
|
TILE_BACKGROUND = 0;
|
|
TILE_PLATFORM = 1;
|
|
TILE_KILLING_PLATFORM = 2;
|
|
TILE_ACTOR = 3;
|
|
TILE_TRAVESABLE_PLATFORM = 4;
|
|
|
|
PLAYER_ANIMATION_STANDING_LEFT = 0;
|
|
PLAYER_ANIMATION_STANDING_RIGHT = 1;
|
|
PLAYER_ANIMATION_WALKING_LEFT = 2;
|
|
PLAYER_ANIMATION_WALKING_RIGHT = 3;
|
|
PLAYER_ANIMATION_JUMPING_LEFT = 4;
|
|
PLAYER_ANIMATION_JUMPING_RIGHT = 5;
|
|
PLAYER_ANIMATION_DYING_LEFT = 6;
|
|
PLAYER_ANIMATION_DYING_RIGHT = 7;
|
|
|
|
SECTION_MENU = 0;
|
|
SECTION_GAME = 1;
|
|
SECTION_QUIT = 2;
|
|
|
|
MENU_SECTION_MAIN = 0;
|
|
MENU_SECTION_CREDITS = 1;
|
|
MENU_SECTION_ANIMATION = 2;
|
|
|
|
ZONE_SURFACE = 0;
|
|
ZONE_VOLCANO = 1;
|
|
|
|
WINDOW_TITLE = 'Volcano v0005';
|
|
BUILD = '.05';
|
|
FILE_MAP_VOLCANO = './data/volcano.map';
|
|
FILE_TILES_VOLCANO = './data/gfx/tiles_volcano.png';
|
|
FILE_TILES_SURFACE = './data/gfx/tiles_surface.png';
|
|
FILE_BKG_SURFACE = './data/gfx/bkg_surface.png';
|
|
FILE_MENU = './data/gfx/menu.png';
|
|
FILE_MENU_ANIMATION = './data/gfx/menu_animation.png';
|
|
FILE_ACTORS = './data/gfx/actors.png';
|
|
FILE_PLAYER = './data/gfx/player.png';
|
|
FILE_HUD = './data/gfx/hud.png';
|
|
FILE_FILTER = './data/gfx/filter.png';
|
|
FILE_SOUND_JUMP = './data/sound/sound_player_jump.wav';
|
|
FILE_SOUND_DEATH = './data/sound/sound_player_death.wav';
|
|
FILE_SOUND_COIN = './data/sound/sound_player_coin.wav';
|
|
FILE_SOUND_MENU_LOGO = './data/sound/sound_menu_logo.wav';
|
|
FILE_SOUND_MENU_START = './data/sound/sound_menu_start.wav';
|
|
FILE_SOUND_DROP_ENEMY = './data/sound/sound_drop_enemy.wav';
|
|
FILE_SOUND_DROP_SPLAT = './data/sound/sound_drop_splat.wav';
|
|
FILE_MUSIC_SURFACE = './data/music/music_surface.mp3';
|
|
FILE_MUSIC_VOLCANO = './data/music/music_volcano.mp3';
|
|
FILE_MUSIC_MENU = './data/music/music_menu.mp3';
|
|
|
|
type
|
|
Tanimation = record
|
|
num_frames: byte;
|
|
index: byte;
|
|
speed: byte;
|
|
timer: longword;
|
|
loops: boolean; // salta a TRUE quan la animació es reinicia
|
|
frame: array [0 .. 49] of byte;
|
|
end;
|
|
|
|
Tprogram = record
|
|
music_enabled: boolean;
|
|
filter: boolean;
|
|
section: byte;
|
|
debug: boolean;
|
|
sprite: PSDL_Texture;
|
|
src_rect: TSDL_Rect;
|
|
dst_rect: TSDL_Rect;
|
|
end;
|
|
|
|
Tgame = record
|
|
zone: byte; // Zona en la que estem
|
|
music: PMix_Music;
|
|
enabled: boolean;
|
|
sound_drop_enemy: PMix_Chunk;
|
|
sound_drop_splat: PMix_Chunk;
|
|
end;
|
|
|
|
Tmenu = record
|
|
section: byte;
|
|
sprite: PSDL_Texture;
|
|
sprite_animation: PSDL_Texture;
|
|
src_rect_fondo: TSDL_Rect;
|
|
dst_rect_fondo: TSDL_Rect;
|
|
src_rect_logo: TSDL_Rect;
|
|
dst_rect_logo: TSDL_Rect;
|
|
dst_rect_logo_zoom: TSDL_Rect;
|
|
src_rect_text: TSDL_Rect;
|
|
dst_rect_text: TSDL_Rect;
|
|
src_rect_text2: TSDL_Rect;
|
|
dst_rect_text2: TSDL_Rect;
|
|
music: PMix_Music;
|
|
sound_logo: PMix_Chunk;
|
|
sound_start: PMix_Chunk;
|
|
frame: integer;
|
|
enabled: boolean;
|
|
timer: integer;
|
|
animation: array [0..1] of Tanimation;
|
|
src_rect_animation: TSDL_Rect;
|
|
dst_rect_animation: TSDL_Rect;
|
|
end;
|
|
|
|
Tplayer = record
|
|
sprite: PSDL_Texture;
|
|
src_rect: TSDL_Rect;
|
|
dst_rect: TSDL_Rect;
|
|
direction: byte; // Sentit del desplaçament
|
|
speed_x,
|
|
speed_y: integer; // Quantitat de pixels a desplaçar
|
|
jumpforce: integer; // Quantitat de pixels a desplaçar i velocitat que pilla al saltar
|
|
active_animation: byte; // Index per al array d'animació
|
|
animation: array [0 .. 7] of Tanimation;
|
|
can_jump: boolean; // Indica si el jugador pot saltar (FALSE si ja està saltant)
|
|
jump_pressed_now,
|
|
jump_pressed_before: boolean; // Indica si el botó de saltar està apretat, per evitar el autofire
|
|
standing: boolean; // Indica si el jugador está quet.
|
|
respawn_x,
|
|
respawn_y: integer; // Coordenades per a reviure
|
|
respawn_direction: byte; // Per a reviure en la mateixa direcció que s'entra a la habitació
|
|
enabled: boolean; // Indica si pot rebre ordres
|
|
cooldown: integer; // Temps d'inhabilitació
|
|
lifes: byte; // Quantitat de vides
|
|
coins: integer; // Quantitat de monedes
|
|
key: array [0..5] of boolean;
|
|
sound_jump: PMix_Chunk;
|
|
sound_death: PMix_Chunk;
|
|
sound_coin: PMix_Chunk;
|
|
was_on_background: boolean; // Ens guardem si en l'anterior loop el tile sobre el qual teniem els nostres peus era background [27/05/2016] [DOC]
|
|
end;
|
|
|
|
Tactor = record
|
|
src_rect: TSDL_Rect;
|
|
dst_rect: TSDL_Rect;
|
|
//animation: Tanimation;
|
|
kind: byte; // Tipus d'actor: enemic, moneda, clau, plataforma ...
|
|
direction: byte; // Sentit del desplaçament
|
|
id: byte;
|
|
speed_x,
|
|
speed_y: integer; // Velocitat = quantitat de pixels a desplaçar
|
|
frame: integer;
|
|
timer: integer;
|
|
enabled: boolean;
|
|
parent: byte; // Index al pare de l'actor
|
|
end;
|
|
|
|
Tanimated_tile = record
|
|
enabled: boolean;
|
|
x, y: integer;
|
|
index: integer;
|
|
frame: byte;
|
|
end;
|
|
|
|
Thud = record
|
|
sprite: PSDL_Texture;
|
|
src_rect: TSDL_Rect;
|
|
dst_rect: TSDL_Rect;
|
|
num_src_rect: TSDL_Rect;
|
|
num_dst_rect: TSDL_Rect;
|
|
bignum_src_rect: TSDL_Rect;
|
|
bignum_dst_rect: TSDL_Rect;
|
|
end;
|
|
|
|
Pmap = ^Tmap;
|
|
Tmap = record
|
|
sprite_tile: PSDL_Texture;
|
|
sprite_actor: PSDL_Texture;
|
|
background: PSDL_Texture;
|
|
src_rect: TSDL_Rect;
|
|
dst_rect: TSDL_Rect;
|
|
tile: array of byte;
|
|
actor: array of byte;
|
|
w, h: byte;
|
|
room: byte;
|
|
end;
|
|
|
|
var
|
|
fullscreen: boolean;
|
|
window: PSDL_Window;
|
|
renderer: PSDL_Renderer;
|
|
prog: Tprogram;
|
|
menu: Tmenu;
|
|
game: Tgame;
|
|
player: Tplayer;
|
|
map: Tmap;
|
|
hud: Thud;
|
|
actor: array [0..MAX_ACTORS - 1] of Tactor;
|
|
animated_tile: array [0..MAX_ANIMATED_TILES - 1] of Tanimated_tile;
|
|
e: TSDL_Event;
|
|
keys: PUInt8;
|
|
quit: boolean;
|
|
delta_time: Uint32;
|
|
i: byte;
|
|
|
|
function max(a,b:integer):integer;
|
|
begin
|
|
if a > b then max:=a else max:=b;
|
|
end;
|
|
|
|
function min(a,b:integer):integer;
|
|
begin
|
|
if a < b then min:=a else min:=b;
|
|
end;
|
|
|
|
function OpenPicture(name: PChar) : PSDL_Texture;
|
|
var
|
|
image: PSDL_Surface;
|
|
texture: PSDL_Texture;
|
|
begin
|
|
image := IMG_Load(name);
|
|
texture := SDL_CreateTextureFromSurface(renderer, image);
|
|
SDL_FreeSurface(image);
|
|
OpenPicture := texture;
|
|
end;
|
|
|
|
procedure CloseSound(var sound: PMix_Chunk);
|
|
begin
|
|
if sound <> nil then
|
|
Mix_FreeChunk(sound);
|
|
sound := nil;
|
|
end;
|
|
|
|
procedure CloseMusic(var music: PMix_Music);
|
|
begin
|
|
if music <> nil then
|
|
Mix_FreeMusic(music);
|
|
music := nil;
|
|
end;
|
|
|
|
procedure ClosePicture(var picture: PSDL_Texture);
|
|
begin
|
|
if picture <> nil then
|
|
SDL_DestroyTexture(picture);
|
|
picture := nil;
|
|
end;
|
|
|
|
function GetTile(x, y: byte): byte;
|
|
// Entrada: coordenades en tiles relatives a la habitació actual
|
|
// Eixida: el valor del byte
|
|
var
|
|
room_x, room_y: byte;
|
|
begin
|
|
room_x := (map.room mod 12) * ROOM_WIDTH_IN_TILES;
|
|
room_y := (map.room div 12) * ROOM_HEIGHT_IN_TILES;
|
|
GetTile := map.tile[(room_x + x ) + (room_y + y) * map.w];
|
|
end;
|
|
|
|
function ReadMapTile(x, y: byte): byte;
|
|
begin
|
|
case GetTile(x,y) of
|
|
000 .. 063: ReadMapTile := TILE_BACKGROUND;
|
|
064 .. 143: ReadMapTile := TILE_PLATFORM;
|
|
144 .. 175: ReadMapTile := TILE_TRAVESABLE_PLATFORM;
|
|
176 .. 207: ReadMapTile := TILE_KILLING_PLATFORM;
|
|
208 .. 255: ReadMapTile := TILE_ACTOR;
|
|
else ReadMapTile := TILE_BACKGROUND;
|
|
end;
|
|
end;
|
|
|
|
function GetActor(x, y: byte): byte;
|
|
var
|
|
room_x, room_y : byte;
|
|
begin
|
|
room_x := (map.room mod 12) * ROOM_WIDTH_IN_TILES;
|
|
room_y := (map.room div 12) * ROOM_HEIGHT_IN_TILES;
|
|
GetActor := map.actor[(room_x + x) + (room_y + y) * map.w];
|
|
end;
|
|
|
|
Procedure SetActor(x, y, valor: byte);
|
|
var
|
|
room_x, room_y : byte;
|
|
begin
|
|
room_x := (map.room mod 12) * ROOM_WIDTH_IN_TILES;
|
|
room_y := (map.room div 12) * ROOM_HEIGHT_IN_TILES;
|
|
map.actor[(room_x + x) + (room_y + y) * map.w] := valor;
|
|
end;
|
|
|
|
procedure SetMapGFX(zone: byte);
|
|
begin
|
|
case zone of
|
|
ZONE_SURFACE:
|
|
begin
|
|
map.sprite_tile := OpenPicture(FILE_TILES_SURFACE);
|
|
map.background := OpenPicture(FILE_BKG_SURFACE);
|
|
end;
|
|
|
|
ZONE_VOLCANO:
|
|
begin
|
|
map.sprite_tile := OpenPicture(FILE_TILES_VOLCANO);
|
|
map.background := OpenPicture(FILE_BKG_SURFACE);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure SetMapMusic(zone: byte);
|
|
begin
|
|
case zone of
|
|
ZONE_SURFACE:
|
|
game.music := Mix_LoadMUS(FILE_MUSIC_SURFACE);
|
|
|
|
ZONE_VOLCANO:
|
|
game.music := Mix_LoadMUS(FILE_MUSIC_VOLCANO);
|
|
end;
|
|
end;
|
|
|
|
function CheckZoneChange(room: integer): boolean;
|
|
var
|
|
zone: byte;
|
|
begin
|
|
case room of
|
|
0 .. 23:
|
|
zone := ZONE_SURFACE;
|
|
24 .. 255:
|
|
zone := ZONE_VOLCANO;
|
|
end;
|
|
|
|
if (zone = game.zone) then
|
|
CheckZoneChange := FALSE
|
|
else
|
|
CheckZoneChange := TRUE;
|
|
end;
|
|
|
|
procedure SetZone(room: integer);
|
|
begin
|
|
case room of
|
|
0 .. 23:
|
|
game.zone := ZONE_SURFACE;
|
|
|
|
24 .. 255:
|
|
game.zone := ZONE_VOLCANO;
|
|
end;
|
|
|
|
SetMapGFX(game.zone);
|
|
SetMapMusic(game.zone);
|
|
Mix_PlayMusic(game.music, -1);
|
|
end;
|
|
|
|
procedure SetPlayerAnimation(anim: byte);
|
|
begin
|
|
if (anim <> player.active_animation) then
|
|
begin
|
|
player.active_animation := anim;
|
|
player.src_rect.y := anim * player.src_rect.h;
|
|
player.animation[anim].index := 0;
|
|
player.animation[anim].timer := 0;
|
|
player.animation[anim].loops := FALSE;
|
|
end;
|
|
end;
|
|
|
|
procedure Animate(var a:Tanimation; var s:TSDL_Rect);
|
|
begin
|
|
// Mirem si estem en el penultim frame per avisar de que anem a pintar el ultim
|
|
if (a.timer = (a.num_frames * a.speed) - 2) then
|
|
a.loops := TRUE
|
|
else
|
|
a.loops := FALSE;
|
|
|
|
a.timer := (a.timer + 1) mod (a.num_frames * a.speed);
|
|
a.index := a.timer div a.speed;
|
|
s.x := (a.frame[a.index]) * s.w;
|
|
end;
|
|
|
|
procedure AnimateIntroMenu(var a:Tanimation; var s:TSDL_Rect);
|
|
begin
|
|
// Mirem si estem en el penultim frame per avisar de que anem a pintar el ultim
|
|
if (a.timer = (a.num_frames * a.speed) - 2) then
|
|
a.loops := TRUE
|
|
else
|
|
a.loops := FALSE;
|
|
|
|
a.timer := (a.timer + 1) mod (a.num_frames * a.speed);
|
|
a.index := a.timer div a.speed;
|
|
s.x := (a.frame[a.index] mod 4) * s.w;
|
|
s.y := (a.frame[a.index] div 4) * s.h;
|
|
end;
|
|
|
|
procedure CreateActor(var a : Tactor; kind, id : byte; dstx, dsty, dstw, dsth, srcx, srcy, sx, sy, timer, frame : smallint; direction, parent : byte);
|
|
begin
|
|
a.kind := kind;
|
|
a.id := id;
|
|
a.dst_rect.x := dstx;
|
|
a.dst_rect.y := dsty;
|
|
a.dst_rect.w := dstw;
|
|
a.dst_rect.h := dsth;
|
|
a.src_rect.x := srcx;
|
|
a.src_rect.y := srcy;
|
|
a.src_rect.w := a.dst_rect.w;
|
|
a.src_rect.h := a.dst_rect.h;
|
|
a.direction := direction;
|
|
a.speed_x := sx;
|
|
a.speed_y := sy;
|
|
a.timer := timer;
|
|
a.frame := frame;
|
|
a.enabled := TRUE;
|
|
a.parent := parent;
|
|
end;
|
|
|
|
procedure LoadMap(map:Pmap);
|
|
var
|
|
f: File;
|
|
numread: Word;
|
|
size: array[0..1] of byte;
|
|
begin
|
|
Assign(f, FILE_MAP_VOLCANO);
|
|
Reset(f, 1);
|
|
BlockRead(f, size, 2, numread);
|
|
map^.w := size[0];
|
|
map^.h := size[1];
|
|
SetLength(map^.tile, map^.w * map^.h);
|
|
SetLength(map^.actor, map^.w * map^.h);
|
|
BlockRead(f, map^.tile[0], map^.w * map^.h, numread);
|
|
BlockRead(f, map^.actor[0], map^.w * map^.h, numread);
|
|
Close(f);
|
|
end;
|
|
|
|
procedure LoadRoom(num:integer);
|
|
var
|
|
i, j, k: integer;
|
|
begin
|
|
if (CheckZoneChange(num)) then
|
|
begin
|
|
SetZone(num);
|
|
end;
|
|
|
|
// Coloquem el numero d'habitació corresponent al mapa
|
|
map.room := max(0, num);
|
|
|
|
// Guardem les coordenades i el sentit que te el jugador al entrar a la habitació
|
|
player.respawn_x := player.dst_rect.x;
|
|
player.respawn_y := player.dst_rect.y;
|
|
player.respawn_direction := player.direction;
|
|
|
|
// Esborrem la llista de tiles animats
|
|
for i:=0 to MAX_ANIMATED_TILES - 1 do
|
|
animated_tile[i].enabled := FALSE;
|
|
|
|
// Escanejem la habitació en busca de tiles animats
|
|
k := 0;
|
|
for i:=0 to (ROOM_WIDTH_IN_TILES - 1) do
|
|
for j:=0 to (ROOM_HEIGHT_IN_TILES - 1) do
|
|
case GetTile(i, j) of
|
|
48 .. 63, 128 .. 143, 160..175, 192..207:
|
|
begin
|
|
animated_tile[k].enabled := TRUE;
|
|
animated_tile[k].x := i * MAP_TILE_WIDTH;
|
|
animated_tile[k].y := j * MAP_TILE_HEIGHT;
|
|
animated_tile[k].index := GetTile(i, j);
|
|
animated_tile[k].frame := 0;
|
|
inc(k);
|
|
end;
|
|
end;
|
|
|
|
// Esborrem la llista d'actors actius
|
|
for i:=0 to MAX_ACTORS - 1 do
|
|
actor[i].enabled := FALSE;
|
|
|
|
// Escanejem la habitació en busca d'actors per afegirlos a la llista d'actors actius
|
|
k := 0;
|
|
for i:=0 to (ROOM_WIDTH_IN_TILES - 1) do
|
|
for j:=0 to (ROOM_HEIGHT_IN_TILES - 1) do
|
|
begin
|
|
case GetActor(i, j) of
|
|
CODE_ENEMY_V1U:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 1, 0, 0, UP, k);
|
|
|
|
CODE_ENEMY_V2U:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 2, 0, 0, UP, k);
|
|
|
|
CODE_ENEMY_V3U:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 3, 0, 0, UP, k);
|
|
|
|
CODE_ENEMY_V1D:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 1, 0, 0, DOWN, k);
|
|
|
|
CODE_ENEMY_V2D:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 2, 0, 0, DOWN, k);
|
|
|
|
CODE_ENEMY_V3D:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 3, 0, 0, DOWN, k);
|
|
|
|
CODE_ENEMY_H1L:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 1, 0, 0, 0, LEFT, k);
|
|
|
|
CODE_ENEMY_H2L:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 2, 0, 0, 0, LEFT, k);
|
|
|
|
CODE_ENEMY_H3L:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 3, 0, 0, 0, LEFT, k);
|
|
|
|
CODE_ENEMY_H1R:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 1, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_H2R:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 2, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_H3R:
|
|
CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 3, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_W1L:
|
|
CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 1 * 16, 1, 0, 0, 0, LEFT, k);
|
|
|
|
CODE_ENEMY_W2L:
|
|
CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 1 * 16, 2, 0, 0, 0, LEFT, k);
|
|
|
|
CODE_ENEMY_W3L:
|
|
CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 1 * 16, 3, 0, 0, 0, LEFT, k);
|
|
|
|
CODE_ENEMY_W1R:
|
|
CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 0 * 16, 1, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_W2R:
|
|
CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 0 * 16, 2, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_W3R:
|
|
CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 0 * 16, 3, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_SPL:
|
|
CreateActor(actor[k], KIND_SPEED_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 3 * 16, 1, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_SPR:
|
|
CreateActor(actor[k], KIND_SPEED_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 2 * 16, 1, 0, 0, 0, RIGHT, k);
|
|
|
|
CODE_ENEMY_DRP:
|
|
CreateActor(actor[k], KIND_DROP_GENERATOR, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 10 * 16, 0, 0, DROP_TIMER, 0, NONE, k);
|
|
|
|
CODE_COIN:
|
|
CreateActor(actor[k], KIND_COIN, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 12 * 16, 0, 0, 0, 0, NONE, k);
|
|
|
|
CODE_HEART:
|
|
CreateActor(actor[k], KIND_HEART, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 13 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_KEY_RED:
|
|
CreateActor(actor[k], KIND_KEY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 14 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_LOCK_RED:
|
|
CreateActor(actor[k], KIND_LOCK, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 15 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_KEY_BLUE:
|
|
CreateActor(actor[k], KIND_KEY, 1, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 1 * 16, 14 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_LOCK_BLUE:
|
|
CreateActor(actor[k], KIND_LOCK, 1, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 1 * 16, 15 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_KEY_GREEN:
|
|
CreateActor(actor[k], KIND_KEY, 2, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 2 * 16, 14 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_LOCK_GREEN:
|
|
CreateActor(actor[k], KIND_LOCK, 2, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 2 * 16, 15 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_KEY_YELLOW:
|
|
CreateActor(actor[k], KIND_KEY, 3, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 3 * 16, 14 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
CODE_LOCK_YELLOW:
|
|
CreateActor(actor[k], KIND_LOCK, 3, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 3 * 16, 15 * 16, 1, 0, 0, 0, NONE, k);
|
|
|
|
else
|
|
dec(k);
|
|
end;
|
|
inc(k);
|
|
end;
|
|
end;
|
|
|
|
procedure IniMenu();
|
|
begin
|
|
menu.enabled := TRUE;
|
|
menu.section := MENU_SECTION_ANIMATION;
|
|
|
|
menu.music := Mix_LoadMUS(FILE_MUSIC_MENU);
|
|
menu.sound_logo := Mix_LoadWAV(FILE_SOUND_MENU_LOGO);
|
|
menu.sound_start := Mix_LoadWAV(FILE_SOUND_MENU_START);
|
|
|
|
menu.sprite := OpenPicture(FILE_MENU);
|
|
menu.frame := 0;
|
|
menu.timer := 200;
|
|
|
|
// Fondo
|
|
menu.src_rect_fondo.x := 0;
|
|
menu.src_rect_fondo.y := 0;
|
|
menu.src_rect_fondo.w := 320;
|
|
menu.src_rect_fondo.h := 240;
|
|
|
|
menu.dst_rect_fondo.x := 0;
|
|
menu.dst_rect_fondo.y := 0;
|
|
menu.dst_rect_fondo.w := 320;
|
|
menu.dst_rect_fondo.h := 240;
|
|
|
|
// Logo
|
|
menu.src_rect_logo.x := 0;
|
|
menu.src_rect_logo.y := 240;
|
|
menu.src_rect_logo.w := 260;
|
|
menu.src_rect_logo.h := 154;
|
|
|
|
menu.dst_rect_logo.x := 30;
|
|
menu.dst_rect_logo.y := 30;
|
|
menu.dst_rect_logo.w := 260;
|
|
menu.dst_rect_logo.h := 154;
|
|
|
|
menu.dst_rect_logo_zoom.x := 0;
|
|
menu.dst_rect_logo_zoom.y := 0;
|
|
menu.dst_rect_logo_zoom.w := 0;
|
|
menu.dst_rect_logo_zoom.h := 0;
|
|
|
|
// PRESS RETURN TO START
|
|
menu.src_rect_text.x := 0;
|
|
menu.src_rect_text.y := 394;
|
|
menu.src_rect_text.w := 125;
|
|
menu.src_rect_text.h := 7;
|
|
|
|
menu.dst_rect_text.x := (320 - 125) div 2;
|
|
menu.dst_rect_text.y := 195;
|
|
menu.dst_rect_text.w := 125;
|
|
menu.dst_rect_text.h := 7;
|
|
|
|
// JAILGAMES 2016
|
|
menu.src_rect_text2.x := 0;
|
|
menu.src_rect_text2.y := 394+7;
|
|
menu.src_rect_text2.w := 55;
|
|
menu.src_rect_text2.h := 5;
|
|
|
|
menu.dst_rect_text2.x := (320 - 55) div 2;
|
|
menu.dst_rect_text2.y := 210;
|
|
menu.dst_rect_text2.w := 55;
|
|
menu.dst_rect_text2.h := 5;
|
|
|
|
// Animació
|
|
menu.sprite_animation := OpenPicture(FILE_MENU_ANIMATION);
|
|
|
|
menu.src_rect_animation.x := 0;
|
|
menu.src_rect_animation.y := 0;
|
|
menu.src_rect_animation.w := 320;
|
|
menu.src_rect_animation.h := 240;
|
|
|
|
menu.dst_rect_animation.x := 0;
|
|
menu.dst_rect_animation.y := 0;
|
|
menu.dst_rect_animation.w := 320;
|
|
menu.dst_rect_animation.h := 240;
|
|
|
|
menu.animation[0].num_frames := 29;
|
|
menu.animation[0].index := 0;
|
|
menu.animation[0].timer := 0;
|
|
menu.animation[0].speed := 9;
|
|
menu.animation[0].loops := FALSE;
|
|
|
|
menu.animation[0].frame[ 0] := 0;
|
|
menu.animation[0].frame[ 1] := 1;
|
|
menu.animation[0].frame[ 2] := 0;
|
|
menu.animation[0].frame[ 3] := 1;
|
|
menu.animation[0].frame[ 4] := 2;
|
|
menu.animation[0].frame[ 5] := 3;
|
|
menu.animation[0].frame[ 6] := 4;
|
|
menu.animation[0].frame[ 7] := 5;
|
|
menu.animation[0].frame[ 8] := 6;
|
|
menu.animation[0].frame[ 9] := 7;
|
|
menu.animation[0].frame[10] := 8;
|
|
menu.animation[0].frame[11] := 9;
|
|
menu.animation[0].frame[12] := 10;
|
|
menu.animation[0].frame[13] := 11;
|
|
menu.animation[0].frame[14] := 12;
|
|
menu.animation[0].frame[15] := 13;
|
|
menu.animation[0].frame[16] := 14;
|
|
menu.animation[0].frame[17] := 15;
|
|
menu.animation[0].frame[18] := 16;
|
|
menu.animation[0].frame[19] := 17;
|
|
menu.animation[0].frame[20] := 18;
|
|
menu.animation[0].frame[21] := 19;
|
|
menu.animation[0].frame[22] := 20;
|
|
menu.animation[0].frame[23] := 21;
|
|
menu.animation[0].frame[24] := 22;
|
|
menu.animation[0].frame[25] := 23;
|
|
menu.animation[0].frame[26] := 24;
|
|
menu.animation[0].frame[27] := 25;
|
|
menu.animation[0].frame[28] := 26;
|
|
|
|
menu.animation[1].num_frames := 23;
|
|
menu.animation[1].index := 0;
|
|
menu.animation[1].timer := 0;
|
|
menu.animation[1].speed := 9;
|
|
menu.animation[1].loops := FALSE;
|
|
|
|
menu.animation[1].frame[ 0] := 18;
|
|
menu.animation[1].frame[ 1] := 26;
|
|
menu.animation[1].frame[ 2] := 18;
|
|
menu.animation[1].frame[ 3] := 26;
|
|
menu.animation[1].frame[ 4] := 18;
|
|
menu.animation[1].frame[ 5] := 26;
|
|
menu.animation[1].frame[ 6] := 18;
|
|
menu.animation[1].frame[ 7] := 26;
|
|
menu.animation[1].frame[ 8] := 18;
|
|
menu.animation[1].frame[ 9] := 26;
|
|
menu.animation[1].frame[10] := 18;
|
|
menu.animation[1].frame[11] := 26;
|
|
menu.animation[1].frame[12] := 18;
|
|
menu.animation[1].frame[13] := 26;
|
|
menu.animation[1].frame[14] := 18;
|
|
menu.animation[1].frame[15] := 19;
|
|
menu.animation[1].frame[16] := 20;
|
|
menu.animation[1].frame[17] := 21;
|
|
menu.animation[1].frame[18] := 22;
|
|
menu.animation[1].frame[19] := 23;
|
|
menu.animation[1].frame[20] := 24;
|
|
menu.animation[1].frame[21] := 25;
|
|
menu.animation[1].frame[22] := 26;
|
|
end;
|
|
|
|
procedure EndMenu();
|
|
begin
|
|
CloseSound(menu.sound_logo);
|
|
CloseSound(menu.sound_start);
|
|
CloseMusic(menu.music);
|
|
ClosePicture(menu.sprite);
|
|
ClosePicture(menu.sprite_animation);
|
|
menu.enabled:= FALSE;
|
|
end;
|
|
|
|
procedure IniActors();
|
|
var
|
|
i: byte;
|
|
begin
|
|
for i:=0 to MAX_ACTORS - 1 do
|
|
actor[i].enabled := FALSE;
|
|
map.sprite_actor := OpenPicture(FILE_ACTORS);
|
|
end;
|
|
|
|
procedure IniAnimatedTiles();
|
|
var
|
|
i: byte;
|
|
begin
|
|
for i:=0 to MAX_ANIMATED_TILES - 1 do
|
|
animated_tile[i].enabled := FALSE;
|
|
end;
|
|
|
|
procedure IniMap();
|
|
begin
|
|
map.src_rect.x := 0;
|
|
map.src_rect.y := 0;
|
|
map.src_rect.w := 320;
|
|
map.src_rect.h := 240;
|
|
|
|
map.dst_rect.x := 0;
|
|
map.dst_rect.y := 0;
|
|
map.dst_rect.w := 320;
|
|
map.dst_rect.h := 240;
|
|
|
|
LoadMap(@map);
|
|
end;
|
|
|
|
procedure EndMap();
|
|
begin
|
|
ClosePicture(map.sprite_tile);
|
|
ClosePicture(map.sprite_actor);
|
|
ClosePicture(map.background);
|
|
end;
|
|
|
|
procedure IniPlayer();
|
|
var
|
|
i: byte;
|
|
begin
|
|
player.sprite := OpenPicture(FILE_PLAYER);
|
|
player.dst_rect.x := MAP_TILE_WIDTH * STARTING_PLAYER_TILE_X;
|
|
player.dst_rect.y := MAP_TILE_HEIGHT * STARTING_PLAYER_TILE_Y;
|
|
player.dst_rect.w := 16;
|
|
player.dst_rect.h := 24;
|
|
player.src_rect.x := 0;
|
|
player.src_rect.y := 0;
|
|
player.src_rect.w := player.dst_rect.w;
|
|
player.src_rect.h := player.dst_rect.h;
|
|
player.direction := RIGHT;
|
|
player.respawn_x := player.dst_rect.x;
|
|
player.respawn_y := player.dst_rect.y;
|
|
player.respawn_direction := player.direction;
|
|
player.speed_x := BASE_SPEED;
|
|
player.speed_y := 0;
|
|
player.can_jump := TRUE;
|
|
player.jump_pressed_now := FALSE;
|
|
player.jump_pressed_before := FALSE;
|
|
player.standing := TRUE;
|
|
player.jumpforce := 10;
|
|
player.active_animation := 0;
|
|
player.enabled := TRUE;
|
|
player.cooldown := 0;
|
|
player.lifes := 10;
|
|
player.coins := 0;
|
|
for i:=0 to 5 do player.key[i] := FALSE;
|
|
player.sound_jump := Mix_LoadWAV(FILE_SOUND_JUMP);
|
|
player.sound_death := Mix_LoadWAV(FILE_SOUND_DEATH);
|
|
player.sound_coin := Mix_LoadWAV(FILE_SOUND_COIN);
|
|
|
|
player.animation[0].num_frames := 33;
|
|
player.animation[0].index := 0;
|
|
player.animation[0].timer := 0;
|
|
player.animation[0].speed := 6;
|
|
player.animation[0].loops := FALSE;
|
|
player.animation[0].frame[ 0] := 0;
|
|
player.animation[0].frame[ 1] := 1;
|
|
player.animation[0].frame[ 2] := 2;
|
|
player.animation[0].frame[ 3] := 2;
|
|
player.animation[0].frame[ 4] := 1;
|
|
player.animation[0].frame[ 5] := 0;
|
|
player.animation[0].frame[ 6] := 0;
|
|
player.animation[0].frame[ 7] := 1;
|
|
player.animation[0].frame[ 8] := 2;
|
|
player.animation[0].frame[ 9] := 2;
|
|
player.animation[0].frame[10] := 1;
|
|
player.animation[0].frame[11] := 0;
|
|
player.animation[0].frame[12] := 0;
|
|
player.animation[0].frame[13] := 1;
|
|
player.animation[0].frame[14] := 2;
|
|
player.animation[0].frame[15] := 2;
|
|
player.animation[0].frame[16] := 1;
|
|
player.animation[0].frame[17] := 0;
|
|
player.animation[0].frame[18] := 0;
|
|
player.animation[0].frame[19] := 1;
|
|
player.animation[0].frame[20] := 2;
|
|
player.animation[0].frame[21] := 3;
|
|
player.animation[0].frame[22] := 4;
|
|
player.animation[0].frame[23] := 4;
|
|
player.animation[0].frame[24] := 5;
|
|
player.animation[0].frame[25] := 5;
|
|
player.animation[0].frame[26] := 4;
|
|
player.animation[0].frame[27] := 4;
|
|
player.animation[0].frame[28] := 5;
|
|
player.animation[0].frame[29] := 5;
|
|
player.animation[0].frame[30] := 6;
|
|
player.animation[0].frame[31] := 6;
|
|
player.animation[0].frame[32] := 7;
|
|
|
|
player.animation[1] := player.animation[0];
|
|
|
|
player.animation[2].num_frames := 8;
|
|
player.animation[2].index := 0;
|
|
player.animation[2].speed := 4;
|
|
player.animation[2].loops := FALSE;
|
|
player.animation[2].frame[ 0] := 0;
|
|
player.animation[2].frame[ 1] := 1;
|
|
player.animation[2].frame[ 2] := 2;
|
|
player.animation[2].frame[ 3] := 3;
|
|
player.animation[2].frame[ 4] := 4;
|
|
player.animation[2].frame[ 5] := 5;
|
|
player.animation[2].frame[ 6] := 6;
|
|
player.animation[2].frame[ 7] := 7;
|
|
|
|
player.animation[3] := player.animation[2];
|
|
player.animation[4] := player.animation[2];
|
|
player.animation[5] := player.animation[2];
|
|
|
|
player.animation[6].num_frames := 20;
|
|
player.animation[6].index := 0;
|
|
player.animation[6].speed := 6;
|
|
player.animation[6].loops := FALSE;
|
|
player.animation[6].frame[ 0] := 0;
|
|
player.animation[6].frame[ 1] := 1;
|
|
player.animation[6].frame[ 2] := 2;
|
|
player.animation[6].frame[ 3] := 3;
|
|
player.animation[6].frame[ 4] := 4;
|
|
player.animation[6].frame[ 5] := 5;
|
|
player.animation[6].frame[ 6] := 6;
|
|
player.animation[6].frame[ 7] := 7;
|
|
player.animation[6].frame[ 8] := 7;
|
|
player.animation[6].frame[ 9] := 7;
|
|
player.animation[6].frame[10] := 7;
|
|
player.animation[6].frame[11] := 7;
|
|
player.animation[6].frame[12] := 7;
|
|
player.animation[6].frame[13] := 7;
|
|
player.animation[6].frame[14] := 7;
|
|
player.animation[6].frame[15] := 7;
|
|
player.animation[6].frame[16] := 7;
|
|
player.animation[6].frame[17] := 7;
|
|
player.animation[6].frame[18] := 7;
|
|
player.animation[6].frame[19] := 7;
|
|
|
|
player.animation[7] := player.animation[6];
|
|
end;
|
|
|
|
procedure EndPlayer();
|
|
begin
|
|
ClosePicture(player.sprite);
|
|
CloseSound(player.sound_jump);
|
|
CloseSound(player.sound_death);
|
|
CloseSound(player.sound_coin);
|
|
end;
|
|
|
|
procedure IniHud();
|
|
begin
|
|
hud.sprite := OpenPicture(FILE_HUD);
|
|
hud.src_rect.x := 0;
|
|
hud.src_rect.y := 0;
|
|
hud.src_rect.w := 320;
|
|
hud.src_rect.h := 16;
|
|
|
|
hud.dst_rect.x := 0;
|
|
hud.dst_rect.y := 224;
|
|
hud.dst_rect.w := 320;
|
|
hud.dst_rect.h := 16;
|
|
|
|
hud.num_src_rect.x := 0;
|
|
hud.num_src_rect.y := 16;
|
|
hud.num_src_rect.w := 5;
|
|
hud.num_src_rect.h := 5;
|
|
|
|
hud.num_dst_rect.x := 0;
|
|
hud.num_dst_rect.y := 16;
|
|
hud.num_dst_rect.w := 5;
|
|
hud.num_dst_rect.h := 5;
|
|
|
|
hud.bignum_src_rect.x := 0;
|
|
hud.bignum_src_rect.y := 21;
|
|
hud.bignum_src_rect.w := 7;
|
|
hud.bignum_src_rect.h := 7;
|
|
|
|
hud.bignum_dst_rect.x := 0;
|
|
hud.bignum_dst_rect.y := 21;
|
|
hud.bignum_dst_rect.w := 7;
|
|
hud.bignum_dst_rect.h := 7;
|
|
end;
|
|
|
|
procedure EndHud();
|
|
begin
|
|
ClosePicture(hud.sprite);
|
|
end;
|
|
|
|
procedure IniGame(zone: byte);
|
|
begin
|
|
game.sound_drop_enemy := Mix_LoadWAV(FILE_SOUND_DROP_ENEMY);
|
|
game.sound_drop_splat := Mix_LoadWAV(FILE_SOUND_DROP_SPLAT);
|
|
game.enabled := TRUE;
|
|
game.zone := zone;
|
|
|
|
// Inicialitzar jugador
|
|
IniPlayer();
|
|
|
|
// Inicialitza hud
|
|
IniHud();
|
|
|
|
// Establir el color d'esborrat
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
|
|
|
// Inicialitza actors
|
|
IniActors();
|
|
|
|
// Inicialitza tiles animats
|
|
IniAnimatedTiles();
|
|
|
|
// Inicialitza mapa
|
|
IniMap();
|
|
SetMapGFX(zone);
|
|
SetMapMusic(zone);
|
|
end;
|
|
|
|
procedure EndGame();
|
|
begin
|
|
EndPlayer();
|
|
EndHud();
|
|
EndMap();
|
|
CloseSound(game.sound_drop_enemy);
|
|
CloseSound(game.sound_drop_splat);
|
|
CloseMusic(game.music);
|
|
game.enabled := FALSE;
|
|
end;
|
|
|
|
procedure KillPlayer();
|
|
begin
|
|
player.enabled := FALSE;
|
|
player.cooldown := COOLDOWN_TIME;
|
|
|
|
// Establir animació de mort
|
|
if (player.direction = LEFT) then
|
|
SetPlayerAnimation(PLAYER_ANIMATION_DYING_LEFT)
|
|
else
|
|
SetPlayerAnimation(PLAYER_ANIMATION_DYING_RIGHT);
|
|
|
|
|
|
Mix_PlayChannel(-1, player.sound_death, 0);
|
|
end;
|
|
|
|
function OnFloor():boolean;
|
|
//[27/08/2016] [DOC] [BEGIN]
|
|
var
|
|
tile_on_right_foot, tile_on_left_foot,
|
|
tile_under_right_foot, tile_under_left_foot : byte;
|
|
|
|
i_am_above_platform, i_am_above_travesable,
|
|
i_am_on_background : boolean;
|
|
begin
|
|
tile_under_left_foot := ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT);
|
|
tile_under_right_foot := ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT);
|
|
|
|
i_am_above_platform := (tile_under_left_foot = TILE_PLATFORM) or (tile_under_right_foot = TILE_PLATFORM);
|
|
i_am_above_travesable := (tile_under_left_foot = TILE_TRAVESABLE_PLATFORM) or (tile_under_right_foot = TILE_TRAVESABLE_PLATFORM);
|
|
|
|
tile_on_left_foot := ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h-1) div MAP_TILE_HEIGHT);
|
|
tile_on_right_foot := ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h-1) div MAP_TILE_HEIGHT);
|
|
|
|
i_am_on_background := (tile_on_left_foot = TILE_BACKGROUND) and (tile_on_right_foot = TILE_BACKGROUND);
|
|
|
|
if ( ( i_am_above_platform or i_am_above_travesable ) and i_am_on_background ) then
|
|
OnFloor := TRUE
|
|
else
|
|
OnFloor := FALSE;
|
|
//[27/08/2016] [DOC] [END]
|
|
|
|
{if (ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM) then
|
|
OnFloor := TRUE
|
|
else
|
|
OnFloor := FALSE;}
|
|
end;
|
|
|
|
procedure MoveActors();
|
|
var
|
|
i, k: byte;
|
|
begin
|
|
for i:=0 to MAX_ACTORS - 1 do
|
|
if actor[i].enabled then
|
|
case actor[i].kind of
|
|
KIND_FLYING_ENEMY:
|
|
begin
|
|
case actor[i].direction of
|
|
RIGHT:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then
|
|
actor[i].direction := LEFT;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH);
|
|
actor[i].direction := LEFT;
|
|
end;
|
|
end;
|
|
|
|
LEFT:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x) < 0 then
|
|
actor[i].direction := RIGHT;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH));
|
|
actor[i].direction := RIGHT;
|
|
end;
|
|
end;
|
|
|
|
DOWN:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y + actor[i].speed_y;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.y + actor[i].dst_rect.h > GAME_WINDOW_HEIGHT) then
|
|
actor[i].direction := UP;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y - ((actor[i].dst_rect.y + actor[i].dst_rect.h) mod MAP_TILE_WIDTH);
|
|
actor[i].direction := UP;
|
|
end;
|
|
end;
|
|
|
|
UP:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y - actor[i].speed_y;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.y < 0) then
|
|
actor[i].direction := DOWN;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y + (MAP_TILE_WIDTH - (actor[i].dst_rect.y mod MAP_TILE_WIDTH));
|
|
actor[i].direction := DOWN;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
actor[i].frame := (actor[i].frame + 1) mod 24;
|
|
if (actor[i].direction = UP) then
|
|
actor[i].src_rect.y := 4 * 16;
|
|
if (actor[i].direction = DOWN) then
|
|
actor[i].src_rect.y := 5 * 16;
|
|
if (actor[i].direction = LEFT) then
|
|
actor[i].src_rect.y := 7 * 16;
|
|
if (actor[i].direction = RIGHT) then
|
|
actor[i].src_rect.y := 6 * 16;
|
|
actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_WALKING_ENEMY:
|
|
begin
|
|
case actor[i].direction of
|
|
RIGHT:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then
|
|
actor[i].direction := LEFT;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH);
|
|
actor[i].direction := LEFT;
|
|
end;
|
|
|
|
// Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then
|
|
actor[i].direction := LEFT;
|
|
end;
|
|
|
|
LEFT:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x) < 0 then
|
|
actor[i].direction := RIGHT;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH));
|
|
actor[i].direction := RIGHT;
|
|
end;
|
|
|
|
// Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then
|
|
actor[i].direction := RIGHT;
|
|
end;
|
|
end;
|
|
|
|
// Animacio
|
|
actor[i].frame := (actor[i].frame + 1) mod 48;
|
|
if (actor[i].direction = LEFT) then
|
|
actor[i].src_rect.y := 1 * 16
|
|
else
|
|
actor[i].src_rect.y := 0 * 16;
|
|
actor[i].src_rect.x := (actor[i].frame div 8) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_SPEED_ENEMY:
|
|
begin
|
|
case actor[i].direction of
|
|
RIGHT:
|
|
begin
|
|
// Mirem si estem en la mateixa altura que el jugador i fem que es meneje més ràpid
|
|
if (actor[i].dst_rect.y + 8 > player.dst_rect.y)
|
|
and (actor[i].dst_rect.y + 8 < player.dst_rect.y + player.dst_rect.h - 1)
|
|
and (player.can_jump) then
|
|
actor[i].speed_x := 3
|
|
else
|
|
actor[i].speed_x := 1;
|
|
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then
|
|
actor[i].direction := LEFT;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH);
|
|
actor[i].direction := LEFT;
|
|
end;
|
|
|
|
// Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then
|
|
actor[i].direction := LEFT;
|
|
end;
|
|
|
|
LEFT:
|
|
begin
|
|
// Mirem si estem en la mateixa altura que el jugador i fem que es meneje més ràpid
|
|
if (actor[i].dst_rect.y + 8 > player.dst_rect.y)
|
|
and (actor[i].dst_rect.y + 8 < player.dst_rect.y + player.dst_rect.h - 1)
|
|
and (player.can_jump) then
|
|
actor[i].speed_x := 3
|
|
else
|
|
actor[i].speed_x := 1;
|
|
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x) < 0 then
|
|
actor[i].direction := RIGHT;
|
|
|
|
// Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH));
|
|
actor[i].direction := RIGHT;
|
|
end;
|
|
|
|
// Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then
|
|
actor[i].direction := RIGHT;
|
|
end;
|
|
end;
|
|
|
|
// Animacio
|
|
actor[i].frame := (actor[i].frame + 1) mod 48;
|
|
if (actor[i].direction = LEFT) then
|
|
actor[i].src_rect.y := 2 * 16
|
|
else
|
|
actor[i].src_rect.y := 3 * 16;
|
|
actor[i].src_rect.x := (actor[i].frame div 8) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_MOBILE_PLATFORM:
|
|
begin
|
|
case actor[i].direction of
|
|
RIGHT:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then
|
|
actor[i].direction := LEFT;
|
|
|
|
// Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH);
|
|
actor[i].direction := LEFT;
|
|
end;
|
|
end;
|
|
|
|
LEFT:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.x < 0) then
|
|
actor[i].direction := RIGHT;
|
|
|
|
// Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH));
|
|
actor[i].direction := RIGHT;
|
|
end;
|
|
end;
|
|
|
|
DOWN:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y + actor[i].speed_y;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.y + actor[i].dst_rect.h > GAME_WINDOW_HEIGHT) then
|
|
actor[i].direction := UP;
|
|
|
|
// Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y - ((actor[i].dst_rect.y + actor[i].dst_rect.h) mod MAP_TILE_WIDTH);
|
|
actor[i].direction := UP;
|
|
end;
|
|
end;
|
|
|
|
UP:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y - actor[i].speed_y;
|
|
|
|
// Si eix per la vora, canvi de sentit
|
|
if (actor[i].dst_rect.y < 0) then
|
|
actor[i].direction := DOWN;
|
|
|
|
// Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y + (MAP_TILE_WIDTH - (actor[i].dst_rect.y mod MAP_TILE_WIDTH));
|
|
actor[i].direction := DOWN;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
KIND_DROP_GENERATOR:
|
|
begin
|
|
if (actor[i].timer > 0) then
|
|
dec(actor[i].timer)
|
|
else
|
|
// Si el contador arriba a 0, creem un actor KIND_DROP_ENEMY
|
|
begin
|
|
actor[i].timer := 32000;
|
|
k := 0;
|
|
while (actor[k].enabled) do inc(k);
|
|
CreateActor(actor[k], KIND_DROP_ENEMY, 0, actor[i].dst_rect.x, actor[i].dst_rect.y, 16, 16, 0, 8 * 16, 0, 2, 0, 0, DOWN, i);
|
|
Mix_PlayChannel(-1, game.sound_drop_enemy, 0);
|
|
end;
|
|
|
|
// Animacio
|
|
actor[i].frame := (actor[i].frame + 1) mod 24;
|
|
if (actor[i].timer > (DROP_TIMER - 25)) then
|
|
// no el pintem. Posem el frame 6 que està buit
|
|
actor[i].src_rect.x := (6 * actor[i].dst_rect.w)
|
|
else
|
|
actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_DROP_ENEMY:
|
|
begin
|
|
// Calculem la nova posició
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y + actor[i].speed_y;
|
|
|
|
// Si eix per la vora, adios i avisa al pare
|
|
if (actor[i].dst_rect.y + actor[i].dst_rect.h > GAME_WINDOW_HEIGHT) then
|
|
begin
|
|
actor[i].enabled := FALSE;
|
|
actor[actor[i].parent].timer := DROP_TIMER;
|
|
end;
|
|
|
|
// Colisió amb el mapa, correcció al ultim pixel bo, transforma en KIND_DROP_SPLAT
|
|
if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND)
|
|
or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then
|
|
begin
|
|
actor[i].dst_rect.y := actor[i].dst_rect.y - ((actor[i].dst_rect.y + actor[i].dst_rect.h) mod MAP_TILE_WIDTH);
|
|
actor[i].kind := KIND_DROP_SPLAT;
|
|
actor[i].frame := 0;
|
|
actor[i].timer := 30;
|
|
actor[i].src_rect.y := 11 * 16;
|
|
Mix_PlayChannel(-1, game.sound_drop_splat, 0);
|
|
end;
|
|
|
|
// Animacio
|
|
actor[i].frame := (actor[i].frame + 1) mod 24;
|
|
actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_DROP_SPLAT:
|
|
begin
|
|
//if (actor[i].timer > 0) then
|
|
if (actor[i].frame < 23) then
|
|
// Si encara te temps, pintem la animació
|
|
begin
|
|
dec(actor[i].timer);
|
|
actor[i].frame := (actor[i].frame + 1) mod 24;
|
|
actor[i].src_rect.x := ((actor[i].frame div 4) + 0) * actor[i].dst_rect.w;
|
|
end
|
|
else
|
|
begin
|
|
actor[i].enabled := FALSE;
|
|
actor[actor[i].parent].timer := DROP_TIMER;
|
|
end;
|
|
end;
|
|
|
|
KIND_COIN:
|
|
begin
|
|
actor[i].frame := (actor[i].frame + 1) mod 32;
|
|
actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_HEART:
|
|
begin
|
|
actor[i].frame := (actor[i].frame + 1) mod 32;
|
|
actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_KEY:
|
|
begin
|
|
//actor[i].frame := (actor[i].frame + 1) mod 32;
|
|
//actor[i].src_rect.x := (actor[i].frame div 32) * actor[i].dst_rect.w;
|
|
end;
|
|
|
|
KIND_LOCK:
|
|
begin
|
|
//actor[i].frame := (actor[i].frame + 1) mod 32;
|
|
//actor[i].src_rect.x := (actor[i].frame div 32) * actor[i].dst_rect.w;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure SetPlayerDirection(direction: integer);
|
|
begin
|
|
if (direction <> player.direction) then
|
|
begin
|
|
player.direction := direction;
|
|
player.speed_x := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure MovePlayer(direction: integer);
|
|
begin
|
|
case direction of
|
|
UP:
|
|
begin
|
|
// Si pot saltar, aleshores
|
|
if (OnFloor and player.can_jump) then
|
|
begin
|
|
// Salta i ja no pot saltar (fins que toque terra i/o soltes el botó)
|
|
player.can_jump := FALSE;
|
|
|
|
// No estem quets
|
|
player.standing := FALSE;
|
|
|
|
// Pilla velocitat negativa per a pujar cap amunt
|
|
player.speed_y := -(player.jumpforce);
|
|
|
|
// Calculem la nova posició
|
|
player.dst_rect.y := player.dst_rect.y + player.speed_y;
|
|
|
|
// Soroll de saltar
|
|
Mix_PlayChannel(-1, player.sound_jump, 0);
|
|
end;
|
|
|
|
// Nou frame d'animació
|
|
if (player.direction = LEFT) then
|
|
SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_LEFT)
|
|
else
|
|
if (player.direction = RIGHT) then
|
|
SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_RIGHT);
|
|
end;
|
|
|
|
RIGHT:
|
|
begin
|
|
// Per a poder dibuixar el bot en el sentit que toca
|
|
SetPlayerDirection(RIGHT);
|
|
|
|
// No estem quets
|
|
player.standing := FALSE;
|
|
|
|
// Incrementem la velocitat horitzontal
|
|
player.speed_x := min(player.speed_x + 1, MAX_SPEED);
|
|
|
|
// Calculem la nova posició
|
|
player.dst_rect.x := player.dst_rect.x + ((player.speed_x div RATIO_SPEED) + 1);
|
|
|
|
// Selecció de l'animació
|
|
if (player.speed_y = 0) then
|
|
// Animació de caminar
|
|
SetPlayerAnimation(PLAYER_ANIMATION_WALKING_RIGHT)
|
|
else
|
|
// Animació de saltar
|
|
SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_RIGHT);
|
|
end;
|
|
|
|
LEFT :
|
|
begin
|
|
// Per a poder dibuixar el bot en el sentit que toca
|
|
SetPlayerDirection(LEFT);
|
|
|
|
// No estem quets
|
|
player.standing := FALSE;
|
|
|
|
// Incrementem la velocitat horitzontal
|
|
player.speed_x := min(player.speed_x + 1, MAX_SPEED);
|
|
|
|
// Calculem la nova posició
|
|
player.dst_rect.x := player.dst_rect.x - ((player.speed_x div RATIO_SPEED) + 1);
|
|
|
|
// Selecció de l'animació
|
|
if (player.speed_y = 0) then
|
|
// Animació de caminar
|
|
SetPlayerAnimation(PLAYER_ANIMATION_WALKING_LEFT)
|
|
else
|
|
// Animació de saltar
|
|
SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_LEFT);
|
|
end;
|
|
end;
|
|
|
|
// Calcul del frame d'animació
|
|
Animate(player.animation[player.active_animation], player.src_rect);
|
|
end;
|
|
|
|
procedure ApplyGravity();
|
|
begin
|
|
// Si toca piso aleshores
|
|
if (OnFloor) then
|
|
begin
|
|
// Totes les forces verticals paren
|
|
player.speed_y := 0;
|
|
// Podem saltar
|
|
player.can_jump := TRUE;
|
|
end
|
|
else
|
|
begin
|
|
// Si no toca piso aleshores s'incrementa la velocitat vertical
|
|
player.speed_y := player.speed_y + GRAVITY;
|
|
|
|
// La velocitat no pot ser mai superior a la altura d'un tile del mapa, per a que no els atravesse
|
|
//player.speed_y := max(min(player.speed_y, MAX_SPEED_Y), -(MAX_SPEED_Y));
|
|
player.speed_y := min(player.speed_y, MAX_SPEED_Y);
|
|
|
|
// Calculem la nova posició
|
|
player.dst_rect.y := player.dst_rect.y + player.speed_y;
|
|
end;
|
|
end;
|
|
|
|
procedure DrawSprite (sprite:PSDL_Texture; src_rect, dst_rect: TSDL_Rect);
|
|
begin
|
|
SDL_RenderCopy(renderer, sprite, @src_rect, @dst_rect);
|
|
end;
|
|
|
|
procedure DrawMap(map:Tmap);
|
|
var
|
|
i, j: byte;
|
|
src_rect1: TSDL_Rect;
|
|
dst_rect1: TSDL_Rect;
|
|
begin
|
|
src_rect1.w := MAP_TILE_WIDTH;
|
|
src_rect1.h := MAP_TILE_HEIGHT;
|
|
dst_rect1.w := MAP_TILE_WIDTH;
|
|
dst_rect1.h := MAP_TILE_HEIGHT;
|
|
|
|
for i:=0 to (ROOM_WIDTH_IN_TILES - 1) do
|
|
for j:=0 to (ROOM_HEIGHT_IN_TILES - 1) do
|
|
begin
|
|
src_rect1.x := (GetTile(i, j) mod 16) * MAP_TILE_WIDTH;
|
|
src_rect1.y := (GetTile(i, j) div 16) * MAP_TILE_HEIGHT;
|
|
dst_rect1.x := i * MAP_TILE_WIDTH;
|
|
dst_rect1.y := j * MAP_TILE_HEIGHT;
|
|
SDL_RenderCopy(renderer, map.sprite_tile, @src_rect1, @dst_rect1);
|
|
end;
|
|
|
|
i := 0;
|
|
while animated_tile[i].enabled do
|
|
begin
|
|
src_rect1.x := ((animated_tile[i].index mod 16) * MAP_TILE_WIDTH) + ((animated_tile[i].frame div 8) * MAP_TILE_WIDTH);
|
|
src_rect1.y := (animated_tile[i].index div 16) * MAP_TILE_HEIGHT;
|
|
dst_rect1.x := animated_tile[i].x;
|
|
dst_rect1.y := animated_tile[i].y;
|
|
animated_tile[i].frame := (animated_tile[i].frame + 1) mod 16;
|
|
SDL_RenderCopy(renderer, map.sprite_tile, @src_rect1, @dst_rect1);
|
|
inc(i);
|
|
end;
|
|
end;
|
|
|
|
procedure DrawHud();
|
|
begin
|
|
// Pinta el fondo del marcador
|
|
DrawSprite(hud.sprite, hud.src_rect, hud.dst_rect);
|
|
|
|
// Pinta el numero de vides
|
|
hud.bignum_src_rect.x := ((player.lifes mod 100) div 10) * hud.bignum_src_rect.w;
|
|
hud.bignum_dst_rect.y := 229;
|
|
hud.bignum_dst_rect.x := 88;
|
|
DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect);
|
|
|
|
hud.bignum_src_rect.x := (player.lifes mod 10) * hud.bignum_src_rect.w;
|
|
hud.bignum_dst_rect.x := 96;
|
|
DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect);
|
|
|
|
// Pinta el numero de monedes
|
|
hud.bignum_src_rect.x := (player.coins div 100) * hud.bignum_src_rect.w;
|
|
hud.bignum_dst_rect.y := 229;
|
|
hud.bignum_dst_rect.x := 258;
|
|
DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect);
|
|
|
|
hud.bignum_src_rect.x := ((player.coins mod 100) div 10) * hud.bignum_src_rect.w;
|
|
hud.bignum_dst_rect.x := 258+8;
|
|
DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect);
|
|
|
|
hud.bignum_src_rect.x := (player.coins mod 10) * hud.bignum_src_rect.w;
|
|
hud.bignum_dst_rect.x := 258+16;
|
|
DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect);
|
|
|
|
if prog.debug then
|
|
begin
|
|
// Pinta el valor x,y del jugador
|
|
hud.num_src_rect.x := (player.dst_rect.x div 100) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.y := 1;
|
|
hud.num_dst_rect.x := 1;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := ((player.dst_rect.x mod 100) div 10) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 5;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := (player.dst_rect.x mod 10) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 9;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := (player.dst_rect.y div 100) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 17;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := ((player.dst_rect.y mod 100) div 10) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 21;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := (player.dst_rect.y mod 10) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 25;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
// Pinta el valor de onfloor
|
|
if (OnFloor) then
|
|
hud.num_src_rect.x := 1 * hud.num_src_rect.w
|
|
else
|
|
hud.num_src_rect.x := 0 * hud.num_src_rect.w;
|
|
hud.num_dst_rect.y := 1;
|
|
hud.num_dst_rect.x := 33;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT)) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 37;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT)) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 41;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
// Pinta el numero d'habitació
|
|
hud.num_src_rect.x := (map.room div 100) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.y := 1;
|
|
hud.num_dst_rect.x := 49;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := ((map.room mod 100) div 10) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 53;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
|
|
hud.num_src_rect.x := (map.room mod 10) * hud.num_src_rect.w;
|
|
hud.num_dst_rect.x := 57;
|
|
DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect);
|
|
end;
|
|
end;
|
|
|
|
procedure CheckPlayerCollisionWithMap();
|
|
var
|
|
tile_on_left_foot, tile_on_right_foot : byte; // [27/05/2016] [DOC]
|
|
i_am_on_platform, i_am_on_travesable : boolean; // [27/05/2016] [DOC]
|
|
begin
|
|
// Si eix per baix, recalcula posició i canvi de pantalla
|
|
if (player.dst_rect.y > GAME_WINDOW_HEIGHT) then
|
|
begin
|
|
// Coloquem al jugador dalt de tot
|
|
player.dst_rect.y := 1;
|
|
|
|
// Canvi de pantalla
|
|
LoadRoom(map.room + 12);
|
|
end;
|
|
|
|
// Si eix per dalt, recalcula posició i canvi de pantalla
|
|
if ((player.dst_rect.y + player.dst_rect.h - 1) < 0) then
|
|
begin
|
|
// Recoloca el personat
|
|
player.dst_rect.y := GAME_WINDOW_HEIGHT - player.dst_rect.h;
|
|
|
|
// Canvi de pantalla
|
|
LoadRoom(map.room - 12);
|
|
end;
|
|
|
|
// Si eix per la vora, recalcula posició i canvi de pantalla
|
|
if (player.dst_rect.x > GAME_WINDOW_WIDTH) then
|
|
begin
|
|
// Coloquem al jugador en la entrada de la nova pantalla
|
|
player.dst_rect.x := 0;
|
|
|
|
// Canvi de pantalla
|
|
LoadRoom(map.room + 1);
|
|
end;
|
|
|
|
// Si eix per la vora, recalcula posició i canvi de pantalla
|
|
if ((player.dst_rect.x + player.dst_rect.w - 1) < 0) then
|
|
begin
|
|
// El posem al borde dret
|
|
player.dst_rect.x := GAME_WINDOW_WIDTH - player.dst_rect.w;
|
|
|
|
// Canvi de pantalla
|
|
LoadRoom(map.room - 1);
|
|
end;
|
|
|
|
// Mirem si colisionem cap avall i corregim
|
|
//[27/05/2016] [DOC] [BEGIN]
|
|
tile_on_left_foot := ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT);
|
|
tile_on_right_foot := ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT);
|
|
|
|
i_am_on_platform := (tile_on_left_foot = TILE_PLATFORM) or (tile_on_right_foot = TILE_PLATFORM);
|
|
i_am_on_travesable := (tile_on_left_foot = TILE_TRAVESABLE_PLATFORM) or (tile_on_right_foot = TILE_TRAVESABLE_PLATFORM);
|
|
|
|
if ( (player.was_on_background) and (player.speed_y > 0) and ( i_am_on_platform or i_am_on_travesable ) ) then
|
|
begin
|
|
// Corregim la posicio
|
|
player.dst_rect.y := player.dst_rect.y - ((player.dst_rect.y + player.dst_rect.h - 1) mod MAP_TILE_HEIGHT) - 1;
|
|
|
|
// Ja podem saltar
|
|
player.can_jump := TRUE;
|
|
end;
|
|
|
|
player.was_on_background := (tile_on_left_foot = TILE_BACKGROUND) and (tile_on_right_foot = TILE_BACKGROUND);
|
|
//[27/05/2016] [DOC] [END]
|
|
|
|
{if player.speed_y > 0 then
|
|
if (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM) then
|
|
begin
|
|
// Corregim la posicio
|
|
player.dst_rect.y := player.dst_rect.y - ((player.dst_rect.y + player.dst_rect.h - 1) mod MAP_TILE_HEIGHT) - 1;
|
|
|
|
// Ja podem saltar
|
|
player.can_jump := TRUE;
|
|
end;
|
|
|
|
if (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM) then
|
|
begin
|
|
// Corregim la posicio
|
|
player.dst_rect.y := player.dst_rect.y - ((player.dst_rect.y + player.dst_rect.h - 1) mod MAP_TILE_HEIGHT) - 1;
|
|
|
|
// Ja podem saltar
|
|
player.can_jump := TRUE;
|
|
end;}
|
|
|
|
// Mirem si colisionem cap amunt i corregim
|
|
if (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM) then
|
|
// Corregim la posicio
|
|
player.dst_rect.y := player.dst_rect.y + (MAP_TILE_HEIGHT - (player.dst_rect.y mod MAP_TILE_HEIGHT));
|
|
|
|
// Una vegada em permes la colisió amunt o avall, al haver un marge de 3 pixels pot ser que estiguem dins d'una paret. S'ha de corregir aquest offset
|
|
// Mirem les colisions laterals
|
|
if (ReadMapTile(player.dst_rect.x div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile(player.dst_rect.x div MAP_TILE_WIDTH, (player.dst_rect.y + (player.dst_rect.h div 2)) div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile(player.dst_rect.x div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM) then
|
|
player.dst_rect.x := player.dst_rect.x + (MAP_TILE_WIDTH - (player.dst_rect.x mod MAP_TILE_WIDTH));
|
|
|
|
if (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 1) div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 1) div MAP_TILE_WIDTH, (player.dst_rect.y + (player.dst_rect.h div 2)) div MAP_TILE_HEIGHT) = TILE_PLATFORM)
|
|
or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 1) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM) then
|
|
player.dst_rect.x := player.dst_rect.x - ((player.dst_rect.x + player.dst_rect.w) mod MAP_TILE_WIDTH);
|
|
|
|
// Comprovar si toca alguna part del mapa de les que maten
|
|
if (ReadMapTile((player.dst_rect.x + 8) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 12) div MAP_TILE_HEIGHT) = TILE_KILLING_PLATFORM) then
|
|
if player.enabled then
|
|
KillPlayer();
|
|
end;
|
|
|
|
{procedure CheckPlayerCollisionWithActors();
|
|
var
|
|
i, collision: byte;
|
|
//collision_top, collision_bottom, collision_left, collision_right: boolean;
|
|
begin
|
|
for i:=0 to MAX_ACTORS - 1 do
|
|
if actor[i].enabled then
|
|
begin
|
|
collision := NO_COLLISION;
|
|
if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
collision := LEFT_COLLISION;
|
|
|
|
if((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
collision := RIGHT_COLLISION;
|
|
|
|
if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
collision := LEFT_COLLISION;
|
|
|
|
if ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
collision := RIGHT_COLLISION;
|
|
|
|
if (collision <> NO_COLLISION) then
|
|
case actor[i].kind of
|
|
KIND_FLYING_ENEMY, KIND_WALKING_ENEMY, KIND_DROP_ENEMY, KIND_SPEED_ENEMY:
|
|
begin
|
|
if (player.enabled) then
|
|
KillPlayer();
|
|
end;
|
|
|
|
KIND_COIN:
|
|
begin
|
|
inc(player.coins);
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0);
|
|
Mix_PlayChannel(-1, player.sound_coin, 0);
|
|
end;
|
|
|
|
KIND_HEART:
|
|
begin
|
|
inc(player.lifes);
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0);
|
|
Mix_PlayChannel(-1, player.sound_coin, 0);
|
|
end;
|
|
|
|
KIND_KEY:
|
|
begin
|
|
player.key[0] := TRUE;;
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0);
|
|
Mix_PlayChannel(-1, player.sound_coin, 0);
|
|
end;
|
|
|
|
KIND_LOCK:
|
|
begin
|
|
// Si tenim clau
|
|
if (player.key[0]) then
|
|
begin
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div MAP_TILE_WIDTH), (actor[i].dst_rect.y div MAP_TILE_HEIGHT), 0);
|
|
end
|
|
else
|
|
begin
|
|
if collision = LEFT_COLLISION then
|
|
begin
|
|
player.dst_rect.x := player.dst_rect.x + (MAP_TILE_WIDTH - (player.dst_rect.x mod MAP_TILE_WIDTH));
|
|
end
|
|
else
|
|
begin
|
|
player.dst_rect.x := player.dst_rect.x - ((player.dst_rect.x + player.dst_rect.w) mod MAP_TILE_WIDTH);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;}
|
|
|
|
procedure CheckPlayerCollisionWithActors();
|
|
var
|
|
i: byte;
|
|
begin
|
|
for i:=0 to MAX_ACTORS - 1 do
|
|
if actor[i].enabled then
|
|
case actor[i].kind of
|
|
KIND_FLYING_ENEMY, KIND_WALKING_ENEMY, KIND_DROP_ENEMY, KIND_SPEED_ENEMY:
|
|
begin
|
|
if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
if (player.enabled) then
|
|
KillPlayer();
|
|
end;
|
|
|
|
KIND_COIN:
|
|
begin
|
|
if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
begin
|
|
inc(player.coins);
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0);
|
|
Mix_PlayChannel(-1, player.sound_coin, 0);
|
|
end;
|
|
end;
|
|
|
|
KIND_HEART:
|
|
begin
|
|
if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
begin
|
|
inc(player.lifes);
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0);
|
|
Mix_PlayChannel(-1, player.sound_coin, 0);
|
|
end;
|
|
end;
|
|
|
|
KIND_KEY:
|
|
begin
|
|
if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then
|
|
begin
|
|
player.key[actor[i].id] := TRUE;;
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0);
|
|
Mix_PlayChannel(-1, player.sound_coin, 0);
|
|
end;
|
|
end;
|
|
|
|
KIND_LOCK:
|
|
// Les colisions amb aquest actor no tenen en compte el ENEMY_HITBOX_REDUCTION
|
|
begin
|
|
// El jugador colisiona amb el actor per l'esquerra del jugador
|
|
if ((actor[i].dst_rect.x + actor[i].dst_rect.w > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x + actor[i].dst_rect.w > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y > player.dst_rect.y) and (actor[i].dst_rect.y < player.dst_rect.y + player.dst_rect.h)) then
|
|
// Si tenim clau
|
|
if (player.key[actor[i].id]) then
|
|
begin
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div MAP_TILE_WIDTH), (actor[i].dst_rect.y div MAP_TILE_HEIGHT), 0);
|
|
end
|
|
// Si no tenim clau
|
|
else
|
|
begin
|
|
player.dst_rect.x := player.dst_rect.x + (MAP_TILE_WIDTH - (player.dst_rect.x mod MAP_TILE_WIDTH));
|
|
end;
|
|
|
|
// El jugador colisiona amb el actor per la dreta del jugador
|
|
if ((actor[i].dst_rect.x > player.dst_rect.x) and (actor[i].dst_rect.x < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y + actor[i].dst_rect.h > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h < player.dst_rect.y + player.dst_rect.h))
|
|
or
|
|
((actor[i].dst_rect.x > player.dst_rect.x) and (actor[i].dst_rect.x < player.dst_rect.x + player.dst_rect.w) and
|
|
(actor[i].dst_rect.y > player.dst_rect.y) and (actor[i].dst_rect.y < player.dst_rect.y + player.dst_rect.h)) then
|
|
// Si tenim clau
|
|
if (player.key[actor[i].id]) then
|
|
begin
|
|
actor[i].enabled := FALSE;
|
|
SetActor((actor[i].dst_rect.x div MAP_TILE_WIDTH), (actor[i].dst_rect.y div MAP_TILE_HEIGHT), 0);
|
|
end
|
|
// Si no tenim clau
|
|
else
|
|
begin
|
|
player.dst_rect.x := player.dst_rect.x - ((player.dst_rect.x + player.dst_rect.w) mod MAP_TILE_WIDTH);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure SetProgSection(section:byte);
|
|
begin
|
|
case section of
|
|
SECTION_MENU:
|
|
begin
|
|
prog.section := SECTION_MENU;
|
|
IniMenu();
|
|
EndGame();
|
|
end;
|
|
|
|
SECTION_GAME:
|
|
begin
|
|
prog.section := SECTION_GAME;
|
|
IniGame(ZONE_VOLCANO);
|
|
EndMenu;
|
|
end;
|
|
|
|
SECTION_QUIT:
|
|
begin
|
|
prog.section := SECTION_QUIT;
|
|
EndGame;
|
|
EndMenu;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure IniProgram();
|
|
begin
|
|
prog.music_enabled := TRUE;
|
|
prog.filter := TRUE;
|
|
SetProgSection(SECTION_MENU);
|
|
prog.debug := FALSE;
|
|
|
|
if (prog.music_enabled) then
|
|
Mix_VolumeMusic(100)
|
|
else
|
|
Mix_VolumeMusic(0);
|
|
|
|
prog.sprite := OpenPicture(FILE_FILTER);
|
|
|
|
prog.src_rect.x := 0;
|
|
prog.src_rect.y := 0;
|
|
prog.src_rect.w := 640;
|
|
prog.src_rect.h := 480;
|
|
|
|
prog.dst_rect.x := 0;
|
|
prog.dst_rect.y := 0;
|
|
prog.dst_rect.w := 640;
|
|
prog.dst_rect.h := 480;
|
|
end;
|
|
|
|
procedure EndProgram();
|
|
begin
|
|
ClosePicture(prog.sprite);
|
|
EndGame();
|
|
EndMenu();
|
|
end;
|
|
|
|
begin
|
|
// Inicialitzar SDL en general i el video en particular
|
|
fullscreen := false;
|
|
SDL_Init(SDL_INIT_EVERYTHING);
|
|
window := SDL_CreateWindow(WINDOW_TITLE + BUILD, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
|
|
renderer := SDL_CreateRenderer(window, -1, 0);
|
|
SDL_RenderSetLogicalSize(renderer, 320, 240);
|
|
|
|
// Inicialitzar SDL_Image (càrrega de PNGs)
|
|
IMG_Init(IMG_INIT_PNG);
|
|
|
|
// Inicialitzar audio
|
|
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
|
|
Mix_AllocateChannels(8);
|
|
|
|
// Inicialitzar el programa
|
|
IniProgram();
|
|
|
|
// Establir el color d'esborrat
|
|
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
|
|
|
// Inicialitza variables generals
|
|
quit := false;
|
|
delta_time := SDL_GetTicks();
|
|
|
|
// Bucle de programa
|
|
while not quit do
|
|
begin
|
|
case prog.section of
|
|
SECTION_GAME:
|
|
begin
|
|
// Inicialitza habitació
|
|
LoadRoom(STARTING_ROOM);
|
|
|
|
// Conecta la musica
|
|
Mix_PlayMusic(game.music, -1);
|
|
|
|
// Bucle de joc
|
|
while game.enabled do
|
|
begin
|
|
while SDL_PollEvent(@e) > 0 do
|
|
begin
|
|
// Si arriva el event de tancar la aplicació, eixim del bucle
|
|
if (e.type_ = SDL_QUITEV) then
|
|
begin
|
|
quit := true;
|
|
SetProgSection(SECTION_MENU);
|
|
break;
|
|
end
|
|
else
|
|
if ((e.type_ = SDL_KEYDOWN) and (e.key._repeat = 0)) then
|
|
case e.key.keysym.scancode of
|
|
SDL_SCANCODE_ESCAPE:
|
|
begin
|
|
SetProgSection(SECTION_MENU);
|
|
end;
|
|
|
|
SDL_SCANCODE_F:
|
|
begin
|
|
if ( fullscreen ) then
|
|
begin
|
|
SDL_SetWindowFullscreen(window, 0);
|
|
SDL_ShowCursor(1);
|
|
fullscreen := false;
|
|
end
|
|
else
|
|
begin
|
|
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
|
SDL_ShowCursor(0);
|
|
fullscreen := true;
|
|
end;
|
|
end;
|
|
|
|
SDL_SCANCODE_W:
|
|
begin
|
|
LoadRoom(map.room - 12);
|
|
end;
|
|
|
|
SDL_SCANCODE_A:
|
|
begin
|
|
LoadRoom(map.room - 1);
|
|
end;
|
|
|
|
SDL_SCANCODE_S:
|
|
begin
|
|
LoadRoom(map.room + 12);
|
|
end;
|
|
|
|
SDL_SCANCODE_D:
|
|
begin
|
|
LoadRoom(map.room + 1);
|
|
end;
|
|
|
|
SDL_SCANCODE_G:
|
|
begin
|
|
player.lifes := 255;
|
|
end;
|
|
|
|
SDL_SCANCODE_M:
|
|
begin
|
|
prog.music_enabled := not(prog.music_enabled);
|
|
if (prog.music_enabled) then
|
|
Mix_VolumeMusic(100)
|
|
else
|
|
Mix_VolumeMusic(0);
|
|
end;
|
|
|
|
SDL_SCANCODE_T:
|
|
begin
|
|
IniPlayer();
|
|
LoadRoom(TEST_ROOM);
|
|
end;
|
|
|
|
SDL_SCANCODE_F1:
|
|
begin
|
|
prog.debug := not(prog.debug);
|
|
end;
|
|
|
|
SDL_SCANCODE_F2:
|
|
begin
|
|
prog.filter := not(prog.filter);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if ((SDL_GetTicks() - delta_time) > GAME_SPEED) then
|
|
begin
|
|
// Agafar el array de tecles
|
|
keys := SDL_GetKeyboardState(nil);
|
|
|
|
// Mirem si esta apretant el botó de saltar. Per tal d'evitar repeticions en aquest boto
|
|
if (keys[SDL_SCANCODE_UP] = 0) then
|
|
player.jump_pressed_now := FALSE
|
|
else
|
|
player.jump_pressed_now := TRUE;
|
|
|
|
// Si el jugador està deshabilitat, anem reduint el temps d'espera i canviant el frame de la animació de mort
|
|
if not(player.enabled) then
|
|
if (player.cooldown > 0) then
|
|
begin
|
|
dec(player.cooldown);
|
|
Animate(player.animation[player.active_animation], player.src_rect);
|
|
end
|
|
else
|
|
// Ha acabat el temps d'estar mort. Revivim al jugador
|
|
begin
|
|
player.enabled := TRUE;
|
|
|
|
// Coloquem al jugador en el sentit que tenia quan va entrar a la habitació
|
|
if (player.respawn_direction = LEFT) then
|
|
begin
|
|
SetPlayerAnimation(PLAYER_ANIMATION_STANDING_LEFT);
|
|
player.direction := LEFT;
|
|
end;
|
|
if (player.respawn_direction = RIGHT) then
|
|
begin
|
|
SetPlayerAnimation(PLAYER_ANIMATION_STANDING_RIGHT);
|
|
player.direction := RIGHT;
|
|
end;
|
|
|
|
// Coloquem al jugador en les coordenades per on va entrar
|
|
player.dst_rect.x := min(player.respawn_x, GAME_WINDOW_WIDTH - player.dst_rect.w);
|
|
player.dst_rect.y := player.respawn_y;
|
|
|
|
// Recarreguem la habitació
|
|
LoadRoom(map.room);
|
|
|
|
if (player.lifes > 0) then
|
|
// Descontem una vida
|
|
dec(player.lifes)
|
|
else
|
|
// Si no li queden vides, eixim al menu
|
|
SetProgSection(SECTION_MENU);
|
|
end;
|
|
|
|
// Comprovem les tecles que ens interesen i actuem en consequència
|
|
if (keys[SDL_SCANCODE_RIGHT] = 1) and (player.enabled) then
|
|
MovePlayer(RIGHT);
|
|
if (keys[SDL_SCANCODE_LEFT] = 1) and (keys[SDL_SCANCODE_RIGHT] = 0) and (player.enabled) then
|
|
MovePlayer(LEFT);
|
|
if (keys[SDL_SCANCODE_UP] = 1) and (player.enabled) and not(player.jump_pressed_before) then
|
|
MovePlayer(UP);
|
|
player.jump_pressed_before := player.jump_pressed_now;
|
|
|
|
// Mirem si no estem fent cap a cap costat i reduim la velocitat horitzontal
|
|
if ((keys[SDL_SCANCODE_RIGHT] = 0) and (keys[SDL_SCANCODE_LEFT] = 0) and (player.enabled)) then
|
|
begin
|
|
player.speed_x := 0;
|
|
|
|
// Estem quets
|
|
player.standing := TRUE;
|
|
|
|
// Posem la animació d'estar quet si no estem saltant
|
|
//if (player.speed_y = 0) then
|
|
if (player.can_jump) then
|
|
begin
|
|
if (player.direction = LEFT) then
|
|
SetPlayerAnimation(PLAYER_ANIMATION_STANDING_LEFT)
|
|
else
|
|
if (player.direction = RIGHT) then
|
|
SetPlayerAnimation(PLAYER_ANIMATION_STANDING_RIGHT);
|
|
Animate(player.animation[player.active_animation], player.src_rect);
|
|
end;
|
|
end;
|
|
|
|
// Moure els actors
|
|
MoveActors();
|
|
|
|
// Apliquem la gravetat
|
|
if (player.enabled) then ApplyGravity();
|
|
|
|
// Comprovar colisions amb els actors
|
|
if (player.enabled) then CheckPlayerCollisionWithActors();
|
|
|
|
// Comprovar colisions amb el mapejat
|
|
CheckPlayerCollisionWithMap();
|
|
|
|
SDL_RenderSetLogicalSize(renderer, 320, 240);
|
|
|
|
// Borrem pantalla
|
|
SDL_RenderClear(renderer);
|
|
|
|
// Pintem el fondo
|
|
DrawSprite(map.background, map.src_rect, map.dst_rect);
|
|
|
|
// Pinta el mapa
|
|
DrawMap(map);
|
|
|
|
// Pintem el jugador
|
|
DrawSprite(player.sprite, player.src_rect, player.dst_rect);
|
|
|
|
// Pintem els actors
|
|
for i:=0 to MAX_ACTORS - 1 do
|
|
if (actor[i].enabled) then
|
|
DrawSprite(map.sprite_actor, actor[i].src_rect, actor[i].dst_rect);
|
|
|
|
// Pintem el marcador
|
|
DrawHud();
|
|
|
|
// Posem el filtro de pantalla
|
|
if prog.filter then
|
|
begin
|
|
SDL_RenderSetLogicalSize(renderer, 640, 480);
|
|
DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect);
|
|
end;
|
|
|
|
// Mostrem la pantalla
|
|
SDL_RenderPresent(renderer);
|
|
|
|
delta_time := SDL_GetTicks();
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
SECTION_MENU:
|
|
begin
|
|
// Establir el color d'esborrat
|
|
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
|
|
|
// Apaga la musica
|
|
Mix_HaltMusic();
|
|
|
|
while menu.enabled do
|
|
begin
|
|
// Bucle del menu
|
|
while SDL_PollEvent(@e) > 0 do
|
|
begin
|
|
// Si arriva el event de tancar la aplicació, eixim del bucle
|
|
if (e.type_ = SDL_QUITEV) then
|
|
begin
|
|
quit := true;
|
|
menu.enabled := FALSE;
|
|
break;
|
|
end
|
|
else
|
|
if ((e.type_ = SDL_KEYDOWN) and (e.key._repeat = 0)) then
|
|
case e.key.keysym.scancode of
|
|
SDL_SCANCODE_ESCAPE:
|
|
begin
|
|
quit := true;
|
|
SetProgSection(SECTION_QUIT);
|
|
break;
|
|
end;
|
|
|
|
// (Des)Activa el mode de pantalla completa
|
|
SDL_SCANCODE_F:
|
|
begin
|
|
if ( fullscreen ) then
|
|
begin
|
|
SDL_SetWindowFullscreen(window, 0);
|
|
SDL_ShowCursor(1);
|
|
fullscreen := false;
|
|
end
|
|
else
|
|
begin
|
|
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
|
SDL_ShowCursor(0);
|
|
fullscreen := true;
|
|
end;
|
|
end;
|
|
|
|
// (Des)Activa la musica
|
|
SDL_SCANCODE_M:
|
|
begin
|
|
prog.music_enabled := not(prog.music_enabled);
|
|
if (prog.music_enabled) then
|
|
Mix_VolumeMusic(100)
|
|
else
|
|
Mix_VolumeMusic(0);
|
|
end;
|
|
|
|
// (Des)Activa les scanlines
|
|
SDL_SCANCODE_F2:
|
|
begin
|
|
prog.filter := not(prog.filter);
|
|
end;
|
|
|
|
// Inicia el joc
|
|
SDL_SCANCODE_RETURN:
|
|
begin
|
|
if (menu.timer > 99) then
|
|
begin
|
|
menu.timer := 99;
|
|
Mix_HaltMusic();
|
|
Mix_HaltChannel(-1);
|
|
Mix_PlayChannel(-1, menu.sound_start, 0);
|
|
menu.frame := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if ((SDL_GetTicks() - delta_time) > GAME_SPEED) then
|
|
begin
|
|
case menu.section of
|
|
{MENU_SECTION_MAIN:
|
|
begin
|
|
if menu.timer > 100 then
|
|
// Menu normal
|
|
begin
|
|
menu.frame := (menu.frame + 1) mod 30000;
|
|
|
|
SDL_RenderSetLogicalSize(renderer, 320, 240);
|
|
// Borrem pantalla
|
|
SDL_RenderClear(renderer);
|
|
|
|
// Pintem el fondo del menu
|
|
//DrawSprite(menu.sprite, menu.src_rect_fondo, menu.dst_rect_fondo);
|
|
|
|
// Pintem el logo DESPLEGA
|
|
menu.dst_rect_logo_zoom.w := menu.dst_rect_logo.w;
|
|
menu.dst_rect_logo_zoom.h := min(menu.dst_rect_logo_zoom.h + 4, menu.dst_rect_logo.h);
|
|
menu.dst_rect_logo_zoom.x := menu.dst_rect_logo.x;
|
|
menu.dst_rect_logo_zoom.y := menu.dst_rect_logo.y;
|
|
|
|
DrawSprite(menu.sprite, menu.src_rect_logo, menu.dst_rect_logo_zoom);
|
|
|
|
if menu.frame = (154 div 4) then
|
|
Mix_PlayChannel(-1, menu.sound_logo, 0);
|
|
if menu.frame = (300 div 4) then
|
|
// Conecta la musica
|
|
Mix_PlayMusic(menu.music, -1);
|
|
|
|
if menu.frame > (300 div 4) then
|
|
begin
|
|
// Pintem el text: PRESS RETURN TO START
|
|
if ((menu.frame mod 64) < 32) then
|
|
DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text);
|
|
|
|
// Pintem el text: JAILGAMES 2016
|
|
DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2);
|
|
end;
|
|
end
|
|
else
|
|
// Menu havent apretat START/RETURN
|
|
begin
|
|
dec(menu.timer);
|
|
menu.frame := (menu.frame + 1) mod 30000;
|
|
|
|
// Borrem pantalla
|
|
SDL_RenderSetLogicalSize(renderer, 320, 240);
|
|
SDL_RenderClear(renderer);
|
|
|
|
// Pintem el fondo del menu
|
|
//DrawSprite(menu.sprite, menu.src_rect_fondo, menu.dst_rect_fondo);
|
|
|
|
// Pintem el logo
|
|
DrawSprite(menu.sprite, menu.src_rect_logo, menu.dst_rect_logo);
|
|
|
|
// Pintem el text: PRESS RETURN TO START
|
|
if ((menu.frame mod 8) < 4) then
|
|
DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text);
|
|
|
|
// Pintem el text: JAILGAMES 2016
|
|
DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2);
|
|
|
|
if menu.timer = 0 then
|
|
begin
|
|
//prog.section := SECTION_GAME;
|
|
//menu.enabled := FALSE;
|
|
//game.enabled := TRUE;
|
|
//menu.section := MENU_SECTION_ANIMATION;
|
|
//menu.timer := 100
|
|
end;
|
|
end;
|
|
|
|
// Posem el filtro de pantalla
|
|
if prog.filter then
|
|
begin
|
|
SDL_RenderSetLogicalSize(renderer, 640, 480);
|
|
DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect);
|
|
end;
|
|
|
|
// Mostrem la pantalla
|
|
SDL_RenderPresent(renderer);
|
|
|
|
delta_time := SDL_GetTicks();
|
|
end;}
|
|
|
|
MENU_SECTION_ANIMATION:
|
|
begin
|
|
// No hem pulsat el botó d'start
|
|
if menu.timer > 100 then
|
|
// Animació inicial
|
|
if not(menu.animation[0].loops) then
|
|
begin
|
|
// Borrem pantalla
|
|
SDL_RenderSetLogicalSize(renderer, 320, 240);
|
|
SDL_RenderClear(renderer);
|
|
|
|
AnimateIntroMenu(menu.animation[0], menu.src_rect_animation);
|
|
|
|
// Pintem la animacio
|
|
DrawSprite(menu.sprite_animation, menu.src_rect_animation, menu.dst_rect_animation);
|
|
|
|
// Posem el filtro de pantalla
|
|
if prog.filter then
|
|
begin
|
|
SDL_RenderSetLogicalSize(renderer, 640, 480);
|
|
DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect);
|
|
end;
|
|
|
|
// Mostrem la pantalla
|
|
SDL_RenderPresent(renderer);
|
|
|
|
delta_time := SDL_GetTicks();
|
|
end
|
|
else
|
|
// Animació segona en loop
|
|
begin
|
|
if Mix_PlayingMusic() = 0 then
|
|
Mix_PlayMusic(menu.music, -1);
|
|
|
|
// Borrem pantalla
|
|
SDL_RenderSetLogicalSize(renderer, 320, 240);
|
|
SDL_RenderClear(renderer);
|
|
|
|
AnimateIntroMenu(menu.animation[1], menu.src_rect_animation);
|
|
|
|
// Pintem la animacio
|
|
DrawSprite(menu.sprite_animation, menu.src_rect_animation, menu.dst_rect_animation);
|
|
|
|
// Pintem el text: PRESS RETURN TO START
|
|
if ((menu.animation[1].timer mod 64) < 32) then
|
|
DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text);
|
|
|
|
// Pintem el text: JAILGAMES 2016
|
|
DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2);
|
|
|
|
// Posem el filtro de pantalla
|
|
if prog.filter then
|
|
begin
|
|
SDL_RenderSetLogicalSize(renderer, 640, 480);
|
|
DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect);
|
|
end;
|
|
|
|
// Mostrem la pantalla
|
|
SDL_RenderPresent(renderer);
|
|
|
|
delta_time := SDL_GetTicks();
|
|
end
|
|
else
|
|
// Hem pulsat el botó d'start
|
|
begin
|
|
Mix_HaltMusic();
|
|
|
|
// Borrem pantalla
|
|
SDL_RenderSetLogicalSize(renderer, 320, 240);
|
|
SDL_RenderClear(renderer);
|
|
|
|
AnimateIntroMenu(menu.animation[1], menu.src_rect_animation);
|
|
|
|
// Pintem la animacio
|
|
DrawSprite(menu.sprite_animation, menu.src_rect_animation, menu.dst_rect_animation);
|
|
|
|
// Pintem el text: PRESS RETURN TO START
|
|
if ((menu.animation[1].timer mod 8) < 4) then
|
|
DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text);
|
|
|
|
// Pintem el text: JAILGAMES 2016
|
|
DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2);
|
|
|
|
// Posem el filtro de pantalla
|
|
if prog.filter then
|
|
begin
|
|
SDL_RenderSetLogicalSize(renderer, 640, 480);
|
|
DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect);
|
|
end;
|
|
|
|
// Mostrem la pantalla
|
|
SDL_RenderPresent(renderer);
|
|
|
|
delta_time := SDL_GetTicks();
|
|
|
|
dec(menu.timer);
|
|
if menu.timer = 0 then
|
|
begin
|
|
SetProgSection(SECTION_GAME);
|
|
menu.timer := 200;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// Finalitzar la música, els samples i el audio
|
|
CloseSound(player.sound_jump);
|
|
CloseSound(player.sound_death);
|
|
CloseSound(player.sound_coin);
|
|
CloseSound(menu.sound_logo);
|
|
CloseSound(menu.sound_start);
|
|
CloseSound(game.sound_drop_enemy);
|
|
CloseSound(game.sound_drop_splat);
|
|
|
|
Mix_HaltMusic();
|
|
|
|
CloseMusic(game.music);
|
|
CloseMusic(menu.music);
|
|
|
|
Mix_CloseAudio();
|
|
|
|
EndProgram();
|
|
|
|
// Finalitzar SDL_Image
|
|
IMG_Quit();
|
|
|
|
// Destruir els sprites
|
|
ClosePicture(prog.sprite);
|
|
ClosePicture(player.sprite);
|
|
ClosePicture(map.sprite_tile);
|
|
ClosePicture(map.sprite_actor);
|
|
ClosePicture(map.background);
|
|
ClosePicture(menu.sprite);
|
|
ClosePicture(menu.sprite_animation);
|
|
ClosePicture(hud.sprite);
|
|
|
|
// Destruir la finestra
|
|
SDL_DestroyWindow(window);
|
|
|
|
// Finalitzar SDL
|
|
SDL_Quit();
|
|
end.
|