Compare commits

...

8 Commits

Author SHA1 Message Date
Milang b6ae4b8cc9 plante piranha completée 2020-03-10 19:34:09 +01:00
Milang eb1e3e1fc6 completing piranha plants 2020-03-10 19:20:06 +01:00
Milang 9476c81e50 level changes
currently adding plants (part 1)
2020-03-07 15:22:39 +01:00
Milang 35c1214270 Fixed camera 2020-03-07 15:22:07 +01:00
Milang 23b98fd3d4 fix minor camera "bugs"
&correct error provided by previour commit
2020-03-04 15:08:35 +01:00
milang 13872b3dcb reduce koopa code
merge code from KOOPA_V & KOOPA_R
2020-02-29 19:15:09 +01:00
milang 5f9791f6aa optimized ennemi behaviour (to be tested)
replace ennemies specific behaviours by a switch => means less duplicated code
2020-02-29 19:01:17 +01:00
milang 1b3acce432 update ennemi functions
use `ennemi_t const * ` instead of `ennemi_t *` in display methods
2020-02-29 18:24:33 +01:00
13 changed files with 201 additions and 199 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 B

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -24,9 +24,11 @@ extern const int ennemi_heights[NOMBRE_ENNEMIS];
#define KOOPA_R(x,y,dir) {KOOPA_R_ID,{x,y,ennemi_widths[KOOPA_R_ID],ennemi_heights[KOOPA_R_ID],dir,0,0,1},ALIVE,0,dir}
#define PLANTE(x,y) {PLANTE_ID,{x,y,ennemi_widths[PLANTE_ID],ennemi_heights[PLANTE_ID],0,0,0,0},ALIVE,0,0}
// pour plante ID, ymin est associé à p1=0
// Dimensions pr les boites
#define PLANTE_NLAPS 99
typedef struct
@ -38,14 +40,16 @@ typedef struct
int p1 :14;
} ennemi_t;
void ennemiDisplay(ennemi_t * e);
void ennemiDisplay(ennemi_t const * e);
extern ennemi_t * ennemis_global;
extern int ennemis_global_size;
void ennemiesDisplay();
void ennemiMove(ennemi_t *e);
void ennemiMove(ennemi_t * e);
void ennemiesInit(ennemi_t * table, int s);
void plante_tour(ennemi_t *e);
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -23,7 +23,7 @@ mario_start = (108, 81, 47)
nuage = (127, 127, 127)
arbre_tronc = (74,35,18)
arbre_feuilles = (0,86,0)
plante = (102,0,127)
def color_compare(color1, color2):
if color1[0] == color2[0] and color1[1] == color2[1] and color1[2] == color2[2]:
@ -54,19 +54,19 @@ pixels = img.load()
for x in range(0,img.size[0]):
for i in range(0, img.size[1]):
y=img.size[1]-i-1
if color_compare(pixels[x,y],empty):
code += write_char(0)
elif color_compare(pixels[x,y], pierre):
code += write_char(1)
elif color_compare(pixels[x,y], piece):
code += write_char(2)
elif color_compare(pixels[x,y], brique):
code += write_char(3)
elif color_compare(pixels[x,y],brique_piece):
code += write_char(4)
@ -75,7 +75,7 @@ for x in range(0,img.size[0]):
elif color_compare(pixels[x,y],boite_champi):
code += write_char(6)
elif color_compare(pixels[x,y],beton):
code += write_char(7)
@ -109,8 +109,12 @@ for x in range(0,img.size[0]):
elif color_compare(pixels[x,y], arbre_feuilles):
code += write_char(17)
elif color_compare(pixels[x,y], plante):
code += write_char(18)
else:
code += write_char(0)
print("Warning: unknown type at", x, y, "with pixel color: ", pixels[x,y])
f = open("../assets-fx/bin/lvl_"+filename, 'wb')

View File

@ -16,13 +16,13 @@ int cameraY() {return max(max(y-32,0)-delta_y,0);}
void cameraMove() // only vertical movement
{
if (MKB_getKeyState(MK_UP) && abs(delta_y)<24) delta_y-=4;
if (MKB_getKeyState(MK_DOWN) && abs(delta_y)<24) delta_y+=4;
static int camera_vy=0;
if (MKB_getKeyState(MK_UP) && (abs(delta_y)<20 || delta_y>=0)) { delta_y-=4;}
if (MKB_getKeyState(MK_DOWN) && (abs(delta_y)<20 || delta_y<=0)) { delta_y+=4;}
if (!MKB_getKeyState(MK_DOWN) && !MKB_getKeyState(MK_UP)) delta_y-=4*sgn(delta_y);
static int camera_vy=0;
if (mario.p.y==last_vy) // mario arrêté
immobile++;
if (mario.p.y==last_vy) immobile++;
else
{
last_vy=mario.p.y;
@ -30,26 +30,20 @@ void cameraMove() // only vertical movement
}
if (mario.p.y-cameraY()-mario.p.h<16 || mario.p.y-cameraY()>54)
{
y+=5*sgn(mario.p.y-y);
y+=4*sgn(mario.p.y-y);
}
if (immobile>=2)
{
//y+=(mario.p.y-y)/3;
if (camera_vy==0)
{
distance=2*(mario.p.y-y)*sgn(mario.p.y-y);
}
if (camera_vy==0) distance=2*(mario.p.y-y)*sgn(mario.p.y-y);
//décéleration après avoir parvouru la moitié de la distance, sinon acceleration
if (camera_vy*(camera_vy+1)>distance)
camera_vy--;
else
camera_vy++;
if (camera_vy*(camera_vy+1)>distance) camera_vy--;
else camera_vy++;
//y++;
if (camera_vy<0)
camera_vy=0;
if (camera_vy<0) camera_vy=0;
if (((y+camera_vy*sgn(mario.p.y-y)/2)-(mario.p.y))*sgn(mario.p.y-y)>0)
{

View File

@ -16,24 +16,10 @@ const int ennemi_widths [NOMBRE_ENNEMIS] = {0, 8, 8, 8, 8 , 8, 8};
//const int ennemi_heights[NOMBRE_ENNEMIS] = {0, 8, 12, 9, 12, 9, 8};
const int ennemi_heights[NOMBRE_ENNEMIS] = {0, 8, 8, 8, 8, 8, 8};
void ennemiDisplay(ennemi_t * e)
void ennemiDisplay(ennemi_t const * e)
{
if (e->life==0 && e->type!=NONE)
{
if (e->p1==0)
{
e->b.vx*=-1;
e->b.vy=5;
}
e->p1++;
e->b.vy--;
e->b.y+=e->b.vy;
e->b.x+=e->b.vx;
if (e->p1>=30) e->type=NONE; // died 1.5 sec before
}
if (e->type==NONE) return;
if (e->b.x<=cameraX(0)-e->b.w || e->b.x>=cameraX(0)+127) return; // do not draw if out of the screen
else e->discovered=1; // for security, tag as discover all drawed ennemies
{// draw
int tx=0, ty=0, dsx=0, dsy=0;
@ -86,13 +72,36 @@ void ennemiDisplay(ennemi_t * e)
{
extern image_t img_plante;
t.sheet=&img_plante;
// TODO tx ty tsx,tsy
t.width*=2;
dsx=-4;
}
}
tileDraw(e->b.x-cameraX(0)+dsx, e->b.y-cameraY(mario.p.y)+dsy, &t, tx, ty);
}
}
void plante_tour(ennemi_t *e)
{
if (e->type==PLANTE_ID)
{
e->p1++;
e->p1%=PLANTE_NLAPS;
if (0<=e->p1 && e->p1<35) // (plante en bas, en attente)
{
if (abs(mario.p.x-e->b.x)<15) e->p1=0;
}
if (35<=e->p1 && e->p1<58)
{
if ((e->p1+1)%3==0) e->b.y++;
}
if (58<=e->p1 && e->p1<75){} // plante en attente en haut
if (75<=e->p1 && e->p1<98)
{
if (e->p1%3==0) e->b.y--;
}
}
}
bool ennemi_check_collision(ennemi_t *e) { return (boxContact(&e->b, &mario.p)); }
void hurtMario()
@ -104,6 +113,21 @@ void hurtMario()
void ennemiMove(ennemi_t *e)
{
if (!(e->b.x<=cameraX(0)-e->b.w || e->b.x>=cameraX(0)+127)) e->discovered=1; // for security, tag as discover all drawed ennemies
if (e->life==DEAD && e->type!=NONE) // dying animation
{
if (e->p1==0)
{
e->b.vx=2*sgn(e->b.vx);
e->b.vy=5;
}
e->p1++;
e->b.vy--;
e->b.y+=e->b.vy;
e->b.x+=e->b.vx;
if (e->p1>=30) e->type=NONE; // died 1.5 sec before
}
if (e->b.x<cameraX()+128+30 && e->b.x>cameraX()-30)
e->discovered=1;
@ -126,7 +150,7 @@ void ennemiMove(ennemi_t *e)
return;
}
for (int i=0; i<ennemis_global_size; i++)
for (int i=0; i<ennemis_global_size; i++) // physique des carapaces (collisions avec les autres)
{
ennemi_t* t=&ennemis_global[i];
if (t->type!=NONE)
@ -158,148 +182,52 @@ void ennemiMove(ennemi_t *e)
}
}
}
int previous_case=-5;
for (int j=0; j<e->b.h; j++)
{
if ((e->b.x+j)/8!=previous_case)
{
previous_case=(e->b.x+j)/8;
gift_t * c=(gift_t*)worldGetCell(e->b.x+j ,e->b.y-1);
gift_t * c=(gift_t *)worldGetCell(e->b.x+j, e->b.y-1);
if ((c->type==GIFT || c->type==BRICK) && (c->time_hit_id || c->state) && e->life!=DEAD)
{
e->life=DEAD;
e->p1=0;
e->life=e->p1=DEAD;
scoreAdd(KILL_ENNEMI);
break;
}
}
}
if (e->b.y<0) e->type=NONE;
const bool mario_fatal_hit = (mario.p.last_vy<=-2 || mario.p.vy<=-2);
if (e->type==GOOMBA_ID)
switch (e->type) // move
{
case KOOPA_R_ID:
boxMove(&e->b);
if (e->b.vx==0)
{
if (e->p1==0)
{
e->b.vx=-1;
e->p1=-1;
}
else
{
e->p1*=-1;
e->b.vx=e->p1;
}
}
if (e->b.y<0)
e->type=NONE;
if (e_hitMario)
{
if (mario_fatal_hit)
{
e->life=DEAD;
e->p1=0;
scoreAdd(KILL_ENNEMI);
mario.p.vy=4;
mario.p.y=e->b.y+ennemi_heights[GOOMBA_ID]+1;
}
else
hurtMario();
}
return;
}
if (e->type==KOOPA_V_ID)
{
boxMove(&e->b);
if (e->b.vx==0)
{
if (e->p1==0)
{
e->b.vx=-1;
e->p1=-1;
}
else
{
e->p1*=-1;
e->b.vx=e->p1;
}
}
if (e->b.y<0)
e->type=NONE;
if (e_hitMario)
{
if (mario_fatal_hit)
{
e->type=CARAPACE_VERTE;
e->b.h=ennemi_heights[CARAPACE_VERTE];
e->p1=2;
e->b.vx=0;
scoreAdd(KILL_ENNEMI);
mario.p.vy=4;
mario.p.y=e->b.y+ennemi_heights[CARAPACE_VERTE]+1;
}
else
hurtMario();
}
return;
}
if (e->type==KOOPA_R_ID)
{
boxMove(&e->b);
if (e->b.vx==0)
{
if (e->p1==0)
{
e->b.vx=-1;
e->p1=-1;
}
else
{
e->p1*=-1;
e->b.vx=e->p1;
}
}
else
{ // demi tour automatique
if (e->b.vx)
{ // demi tour si au dessus du vide
int s=-1;
if (e->b.vx>0)
s=e->b.w;
if (e->b.vx>0) s=e->b.w;
if (worldGetCellCategory(e->b.x+s, e->b.y-1)==CTG_EMPTY && sgn(e->b.vx)==sgn(s))
{
e->p1*=-1;
e->b.vx=e->p1;
}
if (worldGetCellCategory(e->b.x+s, e->b.y-1)==CTG_EMPTY && sgn(e->b.vx)==sgn(s)) e->b.vx=(e->p1*=-1);
}
if (e->b.y<0)
e->type=NONE;
if (e_hitMario)
// fall through
case GOOMBA_ID:
case KOOPA_V_ID:
if (e->type!=KOOPA_R_ID) boxMove(&e->b);
if (e->b.vx==0) // demi tour si mur
{
if (mario_fatal_hit)
{
e->type=CARAPACE_ROUGE;
e->b.h=ennemi_heights[CARAPACE_ROUGE];
e->p1=2;
e->b.vx=0;
scoreAdd(KILL_ENNEMI);
mario.p.vy=4;
mario.p.y=e->b.y+ennemi_heights[CARAPACE_ROUGE]+1;
}
else
hurtMario();
if (e->p1==0) e->b.vx=e->p1=-1;
else e->b.vx=(e->p1*=-1);
}
return;
}
break;
if (e->type==CARAPACE_VERTE || e->type==CARAPACE_ROUGE)
{
case CARAPACE_VERTE:
case CARAPACE_ROUGE:
boxMove(&e->b);
if (e->b.vx==0)
{
if (e->p1<2)
@ -308,54 +236,100 @@ void ennemiMove(ennemi_t *e)
e->b.vx=6*e->p1;
}
}
if (e->b.y<0) e->type=NONE;
if (e->p1>=2)
{
e->p1++;
if (e->p1==80)
if ((e->p1++)==80)
{ // transformation carapace->koopa
e->type--;
e->b.h=ennemi_heights[e->type];
e->p1=e->b.vx=0;
}
}
break;
if (e_hitMario)
{
if (e->p1==0 || e->p1>=2)
{
if (mario.p.x>=e->b.x)
e->p1=-1;
if (mario.p.x<=e->b.x)
e->p1=1;
e->b.vx=6*e->p1;
if (mario_fatal_hit)
{
mario.p.vy=4;
mario.p.y=e->b.y+ennemi_heights[CARAPACE_VERTE];
}
else
{ // mario bounce
if (mario.p.x>=e->b.x) mario.p.x=e->b.x+e->b.w;
if (mario.p.x<=e->b.x) mario.p.x=e->b.x-mario.p.w;
}
}
else
{
if (mario_fatal_hit)
{
e->p1=e->b.vx=0;
mario.p.vy=4;
mario.p.y=e->b.y+ennemi_heights[CARAPACE_VERTE]+1;
}
else hurtMario();
}
}
boxMove(&e->b);
return;
case PLANTE_ID:
plante_tour(e);
}
if (e_hitMario && mario_fatal_hit) switch (e->type) // mario attacks
{
case GOOMBA_ID:
e->life=DEAD;
e->p1=0;
scoreAdd(KILL_ENNEMI);
mario.p.vy=4;
mario.p.y=e->b.y+ennemi_heights[e->type]+1;
break;
case KOOPA_V_ID:
case KOOPA_R_ID:
e->type++;
e->b.h=ennemi_heights[e->type];
e->p1=2;
e->b.vx=0;
scoreAdd(KILL_ENNEMI);
mario.p.vy=6;
mario.p.y=e->b.y+ennemi_heights[e->type]+1;
break;
case CARAPACE_VERTE:
case CARAPACE_ROUGE:
if (e->p1==0 || e->p1>=2)
{
if (mario.p.x>=e->b.x) e->p1=-1;
if (mario.p.x<=e->b.x) e->p1=1;
e->b.vx=6*e->p1;
mario.p.vy=6;
mario.p.y=e->b.y+ennemi_heights[CARAPACE_VERTE];
}
else
{
e->p1=e->b.vx=mario.p.vx=0;
mario.p.vy=6;
mario.p.y=e->b.y+ennemi_heights[CARAPACE_VERTE]+1;
}
break;
case PLANTE_ID:
hurtMario();
break;
}
else if (e_hitMario) switch (e->type) // hurt mario
{
case GOOMBA_ID:
case KOOPA_V_ID:
case KOOPA_R_ID:
hurtMario();
break;
case CARAPACE_VERTE:
case CARAPACE_ROUGE:
if (e->p1==0 || e->p1>=2)
{
if (mario.p.x>=e->b.x) e->p1=-1;
else e->p1=1;
e->b.vx=6*e->p1;
if (mario_fatal_hit)
{
mario.p.vy=6;
mario.p.y=e->b.y+ennemi_heights[CARAPACE_VERTE];
}
else
{ // mario bounce
if (mario.p.x>=e->b.x) mario.p.x=e->b.x+e->b.w;
else mario.p.x=e->b.x-mario.p.w;
mario.p.vx=0;
}
}
else hurtMario();
break;
case PLANTE_ID:
hurtMario();
break;
}
}
// Global variables for ennemies
@ -371,7 +345,7 @@ void ennemiesDisplay()
void ennemiesInit(ennemi_t * table, int s)
{
if (ennemis_global)
freeProf(ennemis_global);
freeProf(ennemis_global);
ennemis_global_size=ennemis_global=0;
if (!s) return;
int size=sizeof(ennemi_t)*s;

View File

@ -34,6 +34,7 @@
#define PACKED_NUAGE 15
#define PACKED_ARBRE_TRONC 16
#define PACKED_ARBRE_FEUILLES 17
#define PACKED_PLANTE 18
void mallocError()
{
@ -85,7 +86,7 @@ static void unpackLevel(packed_level_t * p)
int sx=0, sy=p->height; // Mario start coords
ennemi_t ennemis[20]={0};
ennemi_t ennemis[30]={0};
int nombre_ennemis=0;
@ -318,6 +319,12 @@ static void unpackLevel(packed_level_t * p)
ennemis[nombre_ennemis]=e;
nombre_ennemis++;
}
else if (contents==PACKED_PLANTE)
{
ennemi_t e=PLANTE(8*x+4,8*y-8);
ennemis[nombre_ennemis]=e;
nombre_ennemis++;
}
if (contents==PACKED_MARIO_START)
{

View File

@ -46,7 +46,7 @@ extern image_t img_star;
const tileset_t mario_starman={&img_star, TILE_W, TILE_H, 0};
extern image_t img_fleur;
const tileset_t fleur={&img_fleur, TILE_W, TILE_H, 0};
const tileset_t fleur={&img_fleur, 2*TILE_W, TILE_H, 0};
extern image_t img_bullet;
const tileset_t bullet={&img_bullet, TILE_W/2, TILE_H/2, 1};

View File

@ -6,6 +6,7 @@
#include <camera.h>
#include <gint/std/string.h>
#include <base.h>
#include <ennemi.h>
static teleport_t teleporteurs[6]={0}; // 6 max
static int nombre_teleporteurs=0; // Nombre d'entités utilisés dans le niveau actuel
@ -55,6 +56,22 @@ void teleportersActive()
mario.p.x=t.tx*8+4; mario.p.y=t.ty*8; // Move Mario
mario.p.vx=0; mario.p.vy=0; // Disables every move of mario
cameraAdjust();
for (int j=0; j<ennemis_global_size; j++) if (ennemis_global[j].type==PLANTE_ID) for (int k=0; k<99; k++) plante_tour(&ennemis_global[j]);
const tuyau_t c = *((tuyau_t*)worldGetCell(mario.p.x, mario.p.y));
if (c.type==TUYAU && c.y==2) // animation de sortie
{
for (int j=0; j<8; j++)
{
dclear(C_WHITE); worldDraw(0,0); dupdate();
waitNextFrame(); waitNextFrame();
mario.p.y++;
}
}
}
}
}

View File

@ -166,6 +166,8 @@ void worldDraw()
// draw immunity remaining time [It's a progress bar on the left side of the screen]
if (mario_immunity) drect(0,64-MARIO_IMMUNITY_TIME+mario_immunity,2,64, C_BLACK);
}
void worldMove()