⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 digger.c

📁 经典的老游戏digger的源代码.提起digger相信很多人会回忆起曾经为了它挑灯夜战的时光
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Digger Remastered
   Copyright (c) Andrew Jenner 1998-2004 */

#include "def.h"
#include "sprite.h"
#include "input.h"
#include "hardware.h"
#include "digger.h"
#include "drawing.h"
#include "main.h"
#include "sound.h"
#include "monster.h"
#include "scores.h"
#include "bags.h"

#ifdef _WINDOWS
#include "win_dig.h"
#endif

struct digger
{
  Sint4 x,y,h,v,rx,ry,mdir,dir,bagtime,rechargetime,fx,fy,fdir,expsn,
        deathstage,deathbag,deathani,deathtime,emocttime,emn,msc,lives,ivt;
  bool notfiring,alive,firepressed,dead,levdone,invin;
} digdat[DIGGERS];

Sint4 startbonustimeleft=0,bonustimeleft;

Sint4 emmask=0;

Sint3 emfield[MSIZE];

bool bonusvisible=FALSE,bonusmode=FALSE,digvisible;

void updatedigger(int n);
void diggerdie(int n);
void initbonusmode(void);
void endbonusmode(void);
bool getfirepflag(int n);
void drawdig(int n,int d,int x,int y,bool f);

void initdigger(void)
{
  int dig;
  for (dig=curplayer;dig<diggers+curplayer;dig++) {
    if (digdat[dig].lives==0)
      continue;
    digdat[dig].v=9;
    digdat[dig].mdir=4;
    digdat[dig].h=(diggers==1) ? 7 : (8-dig*2);
    digdat[dig].x=digdat[dig].h*20+12;
    digdat[dig].dir=(dig==0) ? DIR_RIGHT : DIR_LEFT;
    digdat[dig].rx=0;
    digdat[dig].ry=0;
    digdat[dig].bagtime=0;
    digdat[dig].alive=TRUE;
    digdat[dig].dead=FALSE; /* alive !=> !dead but dead => !alive */
    digdat[dig].invin=FALSE;
    digdat[dig].ivt=0;
    digdat[dig].deathstage=1;
    digdat[dig].y=digdat[dig].v*18+18;
    movedrawspr(dig+FIRSTDIGGER-curplayer,digdat[dig].x,digdat[dig].y);
    digdat[dig].notfiring=TRUE;
    digdat[dig].emocttime=0;
    digdat[dig].firepressed=FALSE;
    digdat[dig].expsn=0;
    digdat[dig].rechargetime=0;
    digdat[dig].emn=0;
    digdat[dig].msc=1;
  }
  digvisible=TRUE;
  bonusvisible=bonusmode=FALSE;
}

Uint5 curtime,ftime;

#ifdef INTDRF
Uint5 frame;
#endif

void newframe(void)
{

#ifndef ARM

  Uint5 t;
  if (synchvid) {
    for (;curtime<ftime;curtime+=17094) { /* 17094 = ticks in a refresh */
      do_windows_events();
      fillbuffer();
      gretrace();
      checkkeyb();
    }
    curtime-=ftime;
    fillbuffer();
  }
  else {
    do {
#ifdef _WINDOWS
      do_windows_events();
#endif
      fillbuffer();             /* Idle time */
      t=gethrt();
      checkkeyb();
#ifdef _WINDOWS
      if (suspend_game)
        continue;
      if ( ( (unsigned long double)curtime + (unsigned long double)ftime ) <= (unsigned long double)t )
        break;
      if ((unsigned long double)t < (unsigned long double) curtime)
        break;

    } while (TRUE);
//    } while ((((unsigned long double)t<((unsigned long double)curtime+(unsigned long double)ftime)) && ((unsigned long double)t>=(unsigned long double) curtime)) || suspend_game);
#else
    } while (curtime+ftime>t && t>curtime);
#endif
    curtime=t;
  }

#else

  for (;curtime<ftime;curtime+=15000) {
    fillbuffer();
    gretrace();
    soundint();
    checkkeyb();
  }
  curtime-=ftime;

#endif

#ifdef INTDRF
  frame++;
#endif

}

Uint5 cgtime;

void drawdig(int n,int d,int x,int y,bool f)
{
  drawdigger(n-curplayer,d,x,y,f);
  if (digdat[n].invin) {
    digdat[n].ivt--;
    if (digdat[n].ivt==0)
      digdat[n].invin=FALSE;
    else
      if (digdat[n].ivt%10<5)
        erasespr(FIRSTDIGGER+n-curplayer);
  }
}

void dodigger(void)
{
  int n;
  newframe();
  if (gauntlet) {
    drawlives();
    if (cgtime<ftime)
      timeout=TRUE;
    cgtime-=ftime;
  }
  for (n=curplayer;n<diggers+curplayer;n++) {
    if (digdat[n].expsn!=0)
      drawexplosion(n);
    else
      updatefire(n);
    if (digvisible)
      if (digdat[n].alive)
        if (digdat[n].bagtime!=0) {
          drawdig(n,digdat[n].mdir,digdat[n].x,digdat[n].y,
                  digdat[n].notfiring && digdat[n].rechargetime==0);
          incpenalty();
          digdat[n].bagtime--;
        }
        else
          updatedigger(n);
      else
        diggerdie(n);
    if (digdat[n].emocttime>0)
      digdat[n].emocttime--;
  }
  if (bonusmode && isalive()) {
    if (bonustimeleft!=0) {
      bonustimeleft--;
      if (startbonustimeleft!=0 || bonustimeleft<20) {
        startbonustimeleft--;
        if (bonustimeleft&1) {
          ginten(0);
          soundbonus();
        }
        else {
          ginten(1);
          soundbonus();
        }
        if (startbonustimeleft==0) {
          music(0);
          soundbonusoff();
          ginten(1);
        }
      }
    }
    else {
      endbonusmode();
      soundbonusoff();
      music(1);
    }
  }
  if (bonusmode && !isalive()) {
    endbonusmode();
    soundbonusoff();
    music(1);
  }
}

void updatefire(int n)
{
  Sint4 pix;
  int clfirst[TYPES],clcoll[SPRITES],i;
  bool clflag;
  if (digdat[n].notfiring) {
    if (digdat[n].rechargetime!=0)
      digdat[n].rechargetime--;
    else
      if (getfirepflag(n-curplayer))
        if (digdat[n].alive) {
          digdat[n].rechargetime=levof10()*3+60;
          digdat[n].notfiring=FALSE;
          switch (digdat[n].dir) {
            case DIR_RIGHT:
              digdat[n].fx=digdat[n].x+8;
              digdat[n].fy=digdat[n].y+4;
              break;
            case DIR_UP:
              digdat[n].fx=digdat[n].x+4;
              digdat[n].fy=digdat[n].y;
              break;
            case DIR_LEFT:
              digdat[n].fx=digdat[n].x;
              digdat[n].fy=digdat[n].y+4;
              break;
            case DIR_DOWN:
              digdat[n].fx=digdat[n].x+4;
              digdat[n].fy=digdat[n].y+8;
          }
          digdat[n].fdir=digdat[n].dir;
          movedrawspr(FIRSTFIREBALL+n-curplayer,digdat[n].fx,digdat[n].fy);
          soundfire(n);
        }
  }
  else {
    switch (digdat[n].fdir) {
      case DIR_RIGHT:
        digdat[n].fx+=8;
        pix=ggetpix(digdat[n].fx,digdat[n].fy+4)|
            ggetpix(digdat[n].fx+4,digdat[n].fy+4);
        break;
      case DIR_UP:
        digdat[n].fy-=7;
        pix=0;
        for (i=0;i<7;i++)
          pix|=ggetpix(digdat[n].fx+4,digdat[n].fy+i);
        pix&=0xc0;
        break;
      case DIR_LEFT:
        digdat[n].fx-=8;
        pix=ggetpix(digdat[n].fx,digdat[n].fy+4)|
            ggetpix(digdat[n].fx+4,digdat[n].fy+4);
        break;
      case DIR_DOWN:
        digdat[n].fy+=7;
        pix=0;
        for (i=0;i<7;i++)
          pix|=ggetpix(digdat[n].fx,digdat[n].fy+i);
        pix&=0x3;
        break;
    }
    drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
    for (i=0;i<TYPES;i++)
      clfirst[i]=first[i];
    for (i=0;i<SPRITES;i++)
      clcoll[i]=coll[i];
    incpenalty();
    i=clfirst[2];
    while (i!=-1) {
      killmon(i-FIRSTMONSTER);
      scorekill(n);
      digdat[n].expsn=1;
      i=clcoll[i];
    }
    i=clfirst[4];
    while (i!=-1) {
      if (i-FIRSTDIGGER+curplayer!=n && !digdat[i-FIRSTDIGGER+curplayer].invin
          && digdat[i-FIRSTDIGGER+curplayer].alive) {
        killdigger(i-FIRSTDIGGER+curplayer,3,0);
        digdat[n].expsn=1;
      }
      i=clcoll[i];
    }
    if (clfirst[0]!=-1 || clfirst[1]!=-1 || clfirst[2]!=-1 || clfirst[3]!=-1 ||
        clfirst[4]!=-1)
      clflag=TRUE;
    else
      clflag=FALSE;
    if (clfirst[0]!=-1 || clfirst[1]!=-1 || clfirst[3]!=-1) {
      digdat[n].expsn=1;
      i=clfirst[3];
      while (i!=-1) {
        if (digdat[i-FIRSTFIREBALL+curplayer].expsn==0)
          digdat[i-FIRSTFIREBALL+curplayer].expsn=1;
        i=clcoll[i];
      }
    }
    switch (digdat[n].fdir) {
      case DIR_RIGHT:
        if (digdat[n].fx>296)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fx-=8;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
        break;
      case DIR_UP:
        if (digdat[n].fy<15)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fy+=7;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
        break;
      case DIR_LEFT:
        if (digdat[n].fx<16)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fx+=8;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
        break;
      case DIR_DOWN:
        if (digdat[n].fy>183)
          digdat[n].expsn=1;
        else
          if (pix!=0 && !clflag) {
            digdat[n].expsn=1;
            digdat[n].fy-=7;
            drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,0);
          }
    }
  }
}

void erasediggers(void)
{
  int i;
  for (i=0;i<diggers;i++)
    erasespr(FIRSTDIGGER+i);
  digvisible=FALSE;
}

void drawexplosion(int n)
{
  switch (digdat[n].expsn) {
    case 1:
      soundexplode(n);
    case 2:
    case 3:
      drawfire(n-curplayer,digdat[n].fx,digdat[n].fy,digdat[n].expsn);
      incpenalty();
      digdat[n].expsn++;
      break;
    default:
      killfire(n);
      digdat[n].expsn=0;
  }
}

void killfire(int n)
{
  if (!digdat[n].notfiring) {
    digdat[n].notfiring=TRUE;
    erasespr(FIRSTFIREBALL+n-curplayer);
    soundfireoff(n);
  }
}

void updatedigger(int n)
{
  Sint4 dir,ddir,diggerox,diggeroy,nmon;
  bool push=TRUE,bagf;
  int clfirst[TYPES],clcoll[SPRITES],i;
  readdir(n-curplayer);
  dir=getdir(n-curplayer);
  if (dir==DIR_RIGHT || dir==DIR_UP || dir==DIR_LEFT || dir==DIR_DOWN)
    ddir=dir;
  else
    ddir=DIR_NONE;
  if (digdat[n].rx==0 && (ddir==DIR_UP || ddir==DIR_DOWN))
    digdat[n].dir=digdat[n].mdir=ddir;
  if (digdat[n].ry==0 && (ddir==DIR_RIGHT || ddir==DIR_LEFT))
    digdat[n].dir=digdat[n].mdir=ddir;
  if (dir==DIR_NONE)
    digdat[n].mdir=DIR_NONE;
  else
    digdat[n].mdir=digdat[n].dir;
  if ((digdat[n].x==292 && digdat[n].mdir==DIR_RIGHT) ||
      (digdat[n].x==12 && digdat[n].mdir==DIR_LEFT) ||
      (digdat[n].y==180 && digdat[n].mdir==DIR_DOWN) ||
      (digdat[n].y==18 && digdat[n].mdir==DIR_UP))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -