Thds/Bullet code bits

From ProjectWiki
(Difference between revisions)
Jump to: navigation, search
(Fast then slow home)
(SNirvpXuyg)
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.
+

Revision as of 08:19, 23 July 2011

A wonderful job. Super heplufl information.

Personal tools
irssi scripts
eggdrop scripts