Thds/Bullet code bits
From ProjectWiki
(Difference between revisions)
(→2D Aiming) |
(→Fast then slow home) |
||
Line 161: | Line 161: | ||
</source> | </source> | ||
− | + | This has made my day. I wish all postngis were this good. | |
− | This | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + |
Revision as of 02:01, 23 July 2011
Good to see a taelnt at work. I can't match that.
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
//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); }
A simple working example can be found 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.
//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); } } }
This has made my day. I wish all postngis were this good.