merged Slave and Fairy to Enemy

To create a slave, pass ENEMY_IMMUNE for hp in create_enemy(). tip: create_enemyg(...) is an abbreviation for create_enemy(&global.enemies, ...).
There is something like a super fancy event system for Enemies' logic rules now: logic_rule will be called with t = negative special values like EVENT_BIRTH or EVENT_DEATH on corresponding events. cool, isn't it? well those values have to be filtered out (like if(t < 0) return;) if you don't use them so they don't do strange things with your locus.
This commit is contained in:
laochailan 2011-04-26 12:04:45 +02:00
parent fbccb951c1
commit bdc0db9957
16 changed files with 215 additions and 304 deletions

View file

@ -30,5 +30,5 @@ void main(void)
pos1.y *= 2.0;
if(length(pos1) < rad)
gl_FragColor *= pow(vec4(0.1,0.2,0.3,1),3.0*(rad - length(pos1)));
gl_FragColor *= pow(vec4(0.1,0.2,0.3,1),vec4(3.0*(rad - length(pos1))));
}

View file

@ -5,10 +5,9 @@ set(SRCs
player.c
texture.c
projectile.c
enemy.c
animation.c
fairy.c
poweritem.c
slave.c
list.c
font.c
audio.c

104
src/enemy.c Normal file
View file

@ -0,0 +1,104 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include "enemy.h"
#include <stdlib.h>
#include <math.h>
#include "global.h"
#include "projectile.h"
#include "list.h"
void create_enemy(Enemy **enemies, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
complex pos, int hp, void *parent, complex args, ...) {
Enemy *e = (Enemy *)create_element((void **)enemies, sizeof(Enemy));
e->birthtime = global.frames;
e->pos = pos;
e->pos0 = pos;
e->hp = hp;
e->parent = parent;
e->logic_rule = logic_rule;
e->draw_rule = draw_rule;
va_list ap;
int i;
memset(e->args, 0, 4);
va_start(ap, args);
for(i = 0; i < 4 && args; i++) {
e->args[i++] = args;
args = va_arg(ap, complex);
}
va_end(ap);
e->logic_rule(e, EVENT_BIRTH);
}
void delete_enemy(Enemy **enemies, Enemy* enemy) {
enemy->logic_rule(enemy, EVENT_DEATH);
delete_element((void **)enemies, enemy);
}
void free_enemies(Enemy **enemies) {
delete_all_elements((void **)enemies);
}
void draw_enemies(Enemy *enemies) {
Enemy *e;
for(e = enemies; e; e = e->next)
e->draw_rule(e, global.frames - e->birthtime);
}
void Fairy(Enemy *e, int t) {
glEnable(GL_TEXTURE_2D);
float s = sin((float)(global.frames-e->birthtime)/10.f)/6 + 0.8;
glPushMatrix();
glTranslatef(creal(e->pos),cimag(e->pos),0);
glPushMatrix();
glRotatef(global.frames*10,0,0,1);
glScalef(s, s, s);
glColor3f(0.2,0.7,1);
draw_texture(0,0,"fairy_circle");
glPopMatrix();
glColor4f(1,1,1,1);
glPushMatrix();
if(e->dir) {
glCullFace(GL_FRONT);
glScalef(-1,1,1);
}
draw_animation(0, 0, e->moving, "fairy");
glPopMatrix();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
void process_enemies(Enemy **enemies) {
Enemy *enemy = *enemies, *del = NULL;
while(enemy != NULL) {
enemy->logic_rule(enemy, global.frames - enemy->birthtime);
if(enemy->hp != ENEMY_IMMUNE
&& (creal(enemy->pos) < -20 || creal(enemy->pos) > VIEWPORT_W + 20
|| cimag(enemy->pos) < -20 || cimag(enemy->pos) > VIEWPORT_H + 20
|| enemy->hp <= 0)) {
del = enemy;
enemy = enemy->next;
delete_enemy(enemies, del);
} else {
enemy = enemy->next;
}
}
}

54
src/enemy.h Normal file
View file

@ -0,0 +1,54 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#ifndef SLAVE_H
#define SLAVE_H
#include "animation.h"
#include <complex.h>
#include <stdarg.h>
struct Enemy;
typedef void (*EnemyLogicRule)(struct Enemy*, int t);
typedef EnemyLogicRule EnemyDrawRule;
enum {
ENEMY_IMMUNE = -9000,
};
typedef struct Enemy {
struct Enemy *next;
struct Enemy *prev;
long birthtime;
complex pos;
complex pos0;
int dir; // TODO: deprecate those
int moving;
EnemyLogicRule logic_rule;
EnemyDrawRule draw_rule;
int hp;
void *parent;
complex args[4];
} Enemy;
#define create_enemyg(drule, lrule, pos, hp, par, args) (create_enemy(&global.enemies, drule, lrule, pos, hp, par, args))
void create_enemy(Enemy **enemies, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
complex pos, int hp, void *parent, complex args, ...);
void delete_enemy(Enemy **enemies, Enemy* enemy);
void draw_enemies(Enemy *enemies);
void free_enemies(Enemy **enemies);
void process_enemies(Enemy **enemies);
void Fairy(Enemy*, int t);
#endif

View file

@ -1,114 +0,0 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include "fairy.h"
#include "global.h"
#include "list.h"
void create_fairy(complex pos, int hp, FairyRule rule, complex args, ...) {
Fairy *f = create_element((void **)&global.fairies, sizeof(Fairy));
f->pos0 = pos;
f->pos = pos;
f->rule = rule;
f->birthtime = global.frames;
f->moving = 0;
f->hp = hp;
f->dir = 0;
f->ani = get_ani("fairy");
va_list ap;
int i;
va_start(ap, args);
for(i = 0; i < 4 && args; i++) {
f->args[i] = args;
args = va_arg(ap, complex);
}
va_end(ap);
}
void delete_fairy(Fairy *fairy) {
if(global.plr.power < 6 && fairy->hp <= 0)
create_poweritem(fairy->pos, 6-15*I, Power);
delete_element((void **)&global.fairies, fairy);
}
void draw_fairies() {
glEnable(GL_TEXTURE_2D);
Texture *tex = get_tex("fairy_circle");
glBindTexture(GL_TEXTURE_2D, tex->gltex);
Fairy *f;
glPushMatrix();
float s = sin((float)global.frames/10.f)/6 + 0.8;
float wq = ((float)tex->w)/tex->truew;
float hq = ((float)tex->h)/tex->trueh;
glColor3f(0.2,0.7,1);
for(f = global.fairies; f; f = f->next) {
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(creal(f->pos),cimag(f->pos),0);
glRotatef(global.frames*10,0,0,1);
glScalef(tex->w/2,tex->h/2,1);
glScalef(s, s, s);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(-1, -1, 0);
glTexCoord2f(0,hq); glVertex3f(-1, 1, 0);
glTexCoord2f(wq,hq); glVertex3f(1, 1, 0);
glTexCoord2f(wq,0); glVertex3f(1, -1, 0);
glEnd();
glPopMatrix();
}
glPopMatrix();
glColor3f(1,1,1);
for(f = global.fairies; f; f = f->next) {
glPushMatrix();
glTranslatef(creal(f->pos),cimag(f->pos),0);
if(f->dir) {
glCullFace(GL_FRONT);
glScalef(-1,1,1);
}
draw_animation_p(0, 0, f->moving, f->ani);
glCullFace(GL_BACK);
glPopMatrix();
}
glColor3f(1,1,1);
glDisable(GL_TEXTURE_2D);
}
void free_fairies() {
delete_all_elements((void **)&global.fairies);
}
void process_fairies() {
Fairy *fairy = global.fairies, *del = NULL;
while(fairy != NULL) {
fairy->rule(fairy);
if(creal(fairy->pos) < -20 || creal(fairy->pos) > VIEWPORT_W + 20
|| cimag(fairy->pos) < -20 || cimag(fairy->pos) > VIEWPORT_H + 20 || fairy->hp <= 0) {
del = fairy;
fairy = fairy->next;
delete_fairy(del);
} else {
fairy = fairy->next;
}
}
}

View file

@ -1,43 +0,0 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#ifndef FAIRY_H
#define FAIRY_H
#include "animation.h"
#include <complex.h>
struct Fairy;
typedef void (*FairyRule)(struct Fairy*);
typedef struct Fairy {
struct Fairy *next;
struct Fairy *prev;
long birthtime;
int hp;
complex pos;
complex pos0;
char moving;
char dir;
Animation *ani;
FairyRule rule;
complex args[4];
} Fairy;
void create_fairy(complex pos, int hp, FairyRule rule, complex args, ...);
void delete_fairy(Fairy *fairy);
void draw_fairies();
void free_fairies();
void process_fairies();
#endif

View file

@ -11,7 +11,7 @@
#include <SDL/SDL.h>
#include "player.h"
#include "projectile.h"
#include "fairy.h"
#include "enemy.h"
#include "poweritem.h"
#include "audio.h"
#include "boss.h"
@ -31,6 +31,9 @@ enum {
SNDSRC_COUNT = 30,
EVENT_DEATH = -8999,
EVENT_BIRTH,
FPS = 60
};
@ -39,7 +42,7 @@ enum {
typedef struct {
Player plr;
Projectile *projs;
Fairy *fairies;
Enemy *enemies;
Poweritem *poweritems;
Laser *lasers;

View file

@ -41,7 +41,7 @@ void init_player(Player* plr, Character cha) {
}
void player_draw(Player* plr) {
draw_slaves(plr->slaves);
draw_enemies(plr->slaves);
glPushMatrix();
glTranslatef(creal(plr->pos), cimag(plr->pos), 0);
@ -87,7 +87,7 @@ void player_draw(Player* plr) {
}
void player_logic(Player* plr) {
process_slaves(plr->slaves);
process_enemies(&plr->slaves);
if(plr->fire && !(global.frames % 4)) {
create_projectile("youmu", plr->pos + 10 - I*20, ((Color){1,1,1}), linear, -20I)->type = PlrProj;
@ -105,14 +105,16 @@ void player_logic(Player* plr) {
plr->focus++;
if(plr->power >= 0 && plr->slaves == NULL)
create_slave(&plr->slaves, youmu_opposite_logic, youmu_opposite_draw, plr->pos, plr, 0);
create_enemy(&plr->slaves, youmu_opposite_draw, youmu_opposite_logic, plr->pos, ENEMY_IMMUNE, plr, 0);
}
void plr_bomb(Player *plr) {
if(global.frames - plr->recovery >= 0 && plr->bombs > 0) {
Fairy *f;
for(f = global.fairies; f; f = f->next)
f->hp = 0;
Enemy *e;
for(e = global.enemies; e; e = e->next)
if(e->hp != ENEMY_IMMUNE)
e->hp = 0;
free_projectiles();
play_sound("laser1");
@ -137,5 +139,5 @@ void plr_death(Player *plr) {
}
if(plr->slaves)
free_slaves(&plr->slaves);
free_enemies(&plr->slaves);
}

View file

@ -11,7 +11,7 @@
#include <complex.h>
#include "texture.h"
#include "animation.h"
#include "slave.h"
#include "enemy.h"
enum {
False = 0,
@ -43,7 +43,7 @@ typedef struct {
Character cha;
ShotMode shot;
Slave *slaves;
Enemy *slaves;
Animation *ani;
} Player;

View file

@ -9,24 +9,27 @@
#include "player.h"
#include "global.h"
void youmu_opposite_draw(Slave *s) {
complex pos = s->pos + ((Player *)s->parent)->pos;
void youmu_opposite_draw(Enemy *e, int t) {
complex pos = e->pos + ((Player *)e->parent)->pos;
draw_texture(creal(pos), cimag(pos), "items/power");
}
void youmu_opposite_logic(Slave *slave) {
Player *plr = (Player *)slave->parent;
void youmu_opposite_logic(Enemy *e, int t) {
if(t < 0)
return;
Player *plr = (Player *)e->parent;
if(plr->focus < 15) {
slave->args[1] = carg(plr->pos - slave->pos0);
slave->pos = slave->pos0 - plr->pos;
e->args[1] = carg(plr->pos - e->pos0);
e->pos = e->pos0 - plr->pos;
if(cabs(slave->pos) > 30)
slave->pos -= 5*cexp(I*carg(slave->pos));
if(cabs(e->pos) > 30)
e->pos -= 5*cexp(I*carg(e->pos));
}
if(plr->fire && !(global.frames % 4))
create_projectile("youmu", slave->pos + plr->pos, ((Color){1,1,1}), linear, -20*cexp(I*slave->args[1]))->type = PlrProj;
create_projectile("youmu", e->pos + plr->pos, ((Color){1,1,1}), linear, -20*cexp(I*e->args[1]))->type = PlrProj;
slave->pos0 = slave->pos + plr->pos;
e->pos0 = e->pos + plr->pos;
}

View file

@ -8,9 +8,9 @@
#ifndef PLRMODES_H
#define PLRMODES_H
#include "slave.h"
#include "enemy.h"
void youmu_opposite_draw(Slave *s);
void youmu_opposite_logic(Slave *slave);
void youmu_opposite_draw(Enemy *e, int t);
void youmu_opposite_logic(Enemy *e, int t);
#endif

View file

@ -58,15 +58,15 @@ int test_collision(Projectile *p) {
if(cabs(global.plr.pos - p->pos) < projr + 1)
return 1;
} else {
Fairy *f = global.fairies;
while(f != NULL) {
if(cabs(f->pos - p->pos) < 15) {
Enemy *e = global.enemies;
while(e != NULL) {
if(e->hp != ENEMY_IMMUNE && cabs(e->pos - p->pos) < 15) {
global.points += 100;
f->hp--;
e->hp--;
play_sound("hit");
return 2;
}
f = f->next;
e = e->next;
}
if(global.boss != NULL && cabs(global.boss->pos - p->pos) < 15) {

View file

@ -1,58 +0,0 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include "slave.h"
#include <stdlib.h>
#include <math.h>
#include "global.h"
#include "projectile.h"
#include "list.h"
void create_slave(Slave **slaves, SlaveRule logic_rule, SlaveRule draw_rule, complex pos, void *parent, complex args, ...) {
Slave *s = (Slave *)create_element((void **)slaves, sizeof(Slave));
s->birthtime = global.frames;
s->pos = pos;
s->pos0 = pos;
s->parent = parent;
s->logic_rule = logic_rule;
s->draw_rule = draw_rule;
va_list ap;
int i;
memset(s->args, 0, 4);
va_start(ap, args);
for(i = 0; i < 4 && args; i++) {
s->args[i++] = args;
args = va_arg(ap, complex);
}
va_end(ap);
}
void delete_slave(Slave **slaves, Slave* slave) {
delete_element((void **)&slaves, slave);
}
void free_slaves(Slave **slaves) {
delete_all_elements((void **)slaves);
}
void draw_slaves(Slave *slaves) {
Slave *s;
for(s = slaves; s; s = s->next)
s->draw_rule(s);
}
void process_slaves(Slave *slaves) {
Slave *slave;
for(slave = slaves; slave; slave = slave->next)
slave->logic_rule(slave);
}

View file

@ -1,45 +0,0 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#ifndef SLAVE_H
#define SLAVE_H
#include "animation.h"
#include <complex.h>
#include <stdarg.h>
struct Slave;
typedef void (*SlaveRule)(struct Slave*);
typedef struct Slave {
struct Slave *next;
struct Slave *prev;
long birthtime;
complex pos;
complex pos0;
SlaveRule logic_rule;
SlaveRule draw_rule;
Animation *ani;
void *parent;
complex args[4];
} Slave;
void load_slave();
void create_slave(Slave **slaves, SlaveRule logic_rule, SlaveRule draw_rule, complex pos, void *parent, complex args, ...);
void delete_slave(Slave **slaves, Slave* slave);
void draw_slaves(Slave *slaves);
void free_slaves(Slave **slaves);
void process_slaves(Slave *slaves);
//void linear(complex *pos, complex pos0, float *angle, int time, complex* args);
#endif

View file

@ -90,7 +90,7 @@ void stage_draw() {
player_draw(&global.plr);
draw_projectiles();
draw_fairies();
draw_enemies(global.enemies);
draw_poweritems();
draw_lasers();
@ -130,7 +130,7 @@ void apply_bg_shaders() {
GLuint shader = get_shader("boss_zoom");
glUseProgram(shader);
complex pos = global.boss->pos + 10*cexp(I*global.frames/5.0);
complex pos = global.boss->pos + 15*cexp(I*global.frames/5.0);
complex fpos = global.boss->pos;
glUniform2f(glGetUniformLocation(shader, "blur_orig"),
@ -160,7 +160,7 @@ void apply_bg_shaders() {
void stage_logic() {
player_logic(&global.plr);
process_fairies();
process_enemies(&global.enemies);
process_projectiles();
process_poweritems();
process_lasers();
@ -185,7 +185,7 @@ void stage_logic() {
void stage_end() {
free_projectiles();
free_fairies();
free_enemies(&global.enemies);
free_poweritems();
global.frames = 0;
}

View file

@ -11,15 +11,21 @@
#include "../stage.h"
#include "../global.h"
void simpleFairy(Fairy *f) {
if(!((global.frames - f->birthtime) % 50))
create_projectile("rice", f->pos, ((Color){0,0,1}), linear,3 + 2I);
void simpleEnemy(Enemy *e, int t) {
if(t == EVENT_DEATH && global.plr.power < 6) {
create_poweritem(e->pos, 6-15*I, Power);
return;
} else if(t < 0) {
return;
}
f->moving = 1;
f->dir = creal(f->args[0]) < 0;
if(!((global.frames - e->birthtime) % 50))
create_projectile("rice", e->pos, ((Color){0,0,1}), linear,3 + 2I);
int t = global.frames - f->birthtime;
f->pos = f->pos0 + f->args[0]*t + I*sin((global.frames - f->birthtime)/10.0f)*20; // TODO: do this way cooler.
e->moving = 1;
e->dir = creal(e->args[0]) < 0;
e->pos = e->pos0 + e->args[0]*t + I*sin((global.frames - e->birthtime)/10.0f)*20; // TODO: do this way cooler.
}
void stage0_draw() {
@ -136,7 +142,7 @@ Boss *create_cirno() {
void stage0_events() {
if(global.frames == 300 )
global.boss = create_cirno();
if(global.boss == NULL && !(global.frames % 100)) create_fairy(0 + I*100, 3, simpleFairy, 2);
if(global.boss == NULL && !(global.frames % 100)) create_enemy(&global.enemies, Fairy, simpleEnemy, 0 + I*100, 3, NULL, 2);
// if(!(global.frames % 100))
// create_laser(LaserCurve, 300, 300, 60, 500, ((ColorA){0.6,0.6,1,0.4}), lolsin, 0);