|
|
Line 1: |
Line 1: |
− | Good to see a taelnt at work. I can't match that.
| + | A wonderful job. Super heplufl information. |
− | | + | |
− | ==Basics of Danmaku==
| + | |
− | Here is a quick example of a very simple bullet engine.
| + | |
− | Some notes on variables:
| + | |
− | * bullet->xinc, bullet->yinc - these values are added to x or y each frame and control the speed of bullet, ie: x+=xinc;
| + | |
− | * bullet->realx, bullet->realy - position of the bullet in screen pixels (0~255, 0~192 representing NDS screen for instance)
| + | |
− | * bullet->x, bullet->y - subpixel x,y values.. each frame bullet->x+=bullet->xinc. Values range from 0~255*255, 0~192*256 and must be divided by 256 (or shifted right by 8 bits >>8) to represent actual screen pixel values
| + | |
− | | + | |
− | | + | |
− | <source lang="c">
| + | |
− | //Bullet callback prototype
| + | |
− | typedef void(*_bullFunc)(struct _bullet_t *);
| + | |
− | | + | |
− | typedef struct _bullet_t {
| + | |
− | int x;
| + | |
− | int y;
| + | |
− | int xinc;
| + | |
− | int yinc;
| + | |
− | int realx;
| + | |
− | int realy;
| + | |
− | bool active;
| + | |
− | _bullFunc *func;
| + | |
− | } bullet_t;
| + | |
− | | + | |
− | #define MAXBULLETS 400
| + | |
− | | + | |
− | bullet_t bullets[MAXBULLETS];
| + | |
− | | + | |
− | void bulletsInit(void) {
| + | |
− | int c=0;
| + | |
− | do {
| + | |
− | bullets[c].active=false;
| + | |
− | bullets[c].func=NULL;
| + | |
− | } while(++c<MAXBULLETS);
| + | |
− | }
| + | |
− | | + | |
− | void bulletsUpdate(void) {
| + | |
− | int c;
| + | |
− | c=0;
| + | |
− | do {
| + | |
− | if(bullets[c].active==true) {
| + | |
− | bullets[c].x+=bullets[c].xinc; //screen coords in subpixels.. each 256 == 1 pixel
| + | |
− | bullets[c].y+=bullets[c].yinc;
| + | |
− | bullets[c].realx+=bullets[c].x>>8; //these are the ACTUAL screen coords in pixels
| + | |
− | bullets[c].realt+=bullets[c].y>>8;
| + | |
− | if(bullets[c].func) {
| + | |
− | ((_bullFunc)bullets[c].func)(&bullets[c]); //call callback function if availible
| + | |
− | }
| + | |
− | //Here you may want to check if the bullets are off the screen and if so delete them, for instance...
| + | |
− | if((bullets[c].x>256)||(bullets[c].y>192)||(bullets[c].x<0)||(bullets[c].y<0)) {
| + | |
− | bullets[c].active=false;
| + | |
− | }
| + | |
− | | + | |
− | //Here is where you add code to actuall draw and/or update screen
| + | |
− | ...
| + | |
− | //
| + | |
− | | + | |
− | }
| + | |
− | } while(++c<MAXBULLETS);
| + | |
− | | + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | A simple working example can be found [http://svn.blea.ch/thdslib/trunk/thdslib/examples/thsprite/source/main.c here]. | + | |
− | | + | |
− | Heckuva good job. I sure aprpceitae it.
| + | |
− | | + | |
− | ==2D homing==
| + | |
− | This bullet callback function will slowly seek towards a target. homeparams needs to be sent in 'extra' param.
| + | |
− | | + | |
− | The inner and outer parameters define a doughnut shaped area of around the target object within which the bullet object is influenced.
| + | |
− | <source lang="c">
| + | |
− | //Specifys behavior of homing function
| + | |
− | typedef struct _homeparams {
| + | |
− | int inner; //squared inner distance squared
| + | |
− | int outer; //squared outer distance squared
| + | |
− | int speed; //speed (note, speed will increase based on distance to target getting faster as it approaches. similar to a gravity effect)
| + | |
− | } homeparams;
| + | |
− | | + | |
− | //For example, the values i used here are:
| + | |
− | homeparams defualthp={
| + | |
− | 50*50, //inner distance squared
| + | |
− | 100*100, //outter distance squared
| + | |
− | 675 //speed
| + | |
− | };
| + | |
− | | + | |
− | //Home in on ppl (set homeparams for inner,outer,speed params!)
| + | |
− | void thSpellsBulletHomeCallback(t_bullets *bullet, int who, void *extra) {
| + | |
− | int c;
| + | |
− | int closestent;
| + | |
− | int closest;
| + | |
− | int dist;
| + | |
− | int xc,yc;
| + | |
− | homeparams *hp=(homeparams*)extra;
| + | |
− | closest=0xffff; //something very far far away
| + | |
− | closestent=-1;
| + | |
− | | + | |
− | if(who==PLAYER) { //Firstly find closest player or enemy depending on what u are (dont home on yerself >_>)
| + | |
− | c=1;
| + | |
− | do {
| + | |
− | if(entities[c].flags!=0) {
| + | |
− | if(c>PLAYER) { //an enemy(>0) dont wanna home on bonus boxes etc (<0)
| + | |
− | xc=bulletsGetRealX(entities[c].bullet);
| + | |
− | yc=bulletsGetRealY(entities[c].bullet);
| + | |
− | dist=thDistance(xc,yc,bulletsGetRealX(bullet),bulletsGetRealY(bullet));
| + | |
− | if(dist<closest) {
| + | |
− | closest=dist;
| + | |
− | closestent=c;
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | } while(++c<MAXENTITIES);
| + | |
− | } else {
| + | |
− | xc=bulletsGetRealX(entities[PLAYER].bullet);
| + | |
− | yc=bulletsGetRealY(entities[PLAYER].bullet);
| + | |
− | closest=thDistance(xc,yc,bulletsGetRealX(bullet),bulletsGetRealY(bullet));
| + | |
− | closestent=0;
| + | |
− | }
| + | |
− | if((closestent!=-1)&&(closest>hp->inner)&&(closest<hp->outer)) {
| + | |
− | xc=bulletsGetRealX(entities[closestent].bullet);
| + | |
− | yc=bulletsGetRealY(entities[closestent].bullet);
| + | |
− | //this block from bulletsSeek but modded
| + | |
− | int dx, dy, mx, my;
| + | |
− | int speed;
| + | |
− | speed=hp->speed;
| + | |
− | int mod;
| + | |
− | dx=xc-bullet->realx;
| + | |
− | dy=yc-bullet->realy;
| + | |
− | if(abs(dx)>abs(dy)) {
| + | |
− | if(dx!=0)
| + | |
− | my=abs((dy<<8)/dx);
| + | |
− | else
| + | |
− | my=0;
| + | |
− | mod=speed-abs(dx)*4; //change the 4 here and below to change how distance affects 'gravity'
| + | |
− | if(dx>0)
| + | |
− | bullet->xinc=speed;
| + | |
− | else
| + | |
− | bullet->xinc=-speed;
| + | |
− | if(dy>0)
| + | |
− | bullet->yinc=(my*mod)>>8;
| + | |
− | else
| + | |
− | bullet->yinc=-((my*mod)>>8);
| + | |
− | } else {
| + | |
− | if(dy!=0)
| + | |
− | mx=abs((dx<<8)/dy);
| + | |
− | else
| + | |
− | mx=0;
| + | |
− | mod=speed-abs(dy)*4;
| + | |
− | if(dy>0)
| + | |
− | bullet->yinc=speed;
| + | |
− | else
| + | |
− | bullet->yinc=-speed;
| + | |
− | if(dx>0)
| + | |
− | bullet->xinc=(mx*mod)>>8;
| + | |
− | else
| + | |
− | bullet->xinc=-((mx*mod)>>8);
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | This has made my day. I wish all postngis were this good.
| + | |
A wonderful job. Super heplufl information.