拜托各位兄弟,怎么用c做顺畅的动画?

freedolphin 2003-01-09 08:32:05
putimage和getimage做动画太慢了,闪得厉害,有什么好办法吗?大哥帮忙啦
...全文
90 45 打赏 收藏 转发到动态 举报
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
maltose 2003-02-11
  • 打赏
  • 举报
回复
好长时间没来了,看了楼主的回帖,
感到被人理解是一件很重要的事情对我来说。

好了,我领分去了,谢谢。
freedolphin 2003-01-29
  • 打赏
  • 举报
回复
多谢麦芽糖,不管要不要分,我很感激。
至于要不要分,我想其实不很重要,要分并没错啊,只是大家在这里切磋,希望的是共同进步,至于分数嘛,把那样的心血拿出来,当然要多拿点啦。
我想麻烦麦芽糖到我的新问题里发个贴,我想给他一些分,虽然我可以给的分数不多。
maltose 2003-01-20
  • 打赏
  • 举报
回复
程序我已经给楼主发出去。

注:运行环境为TurboC2.0,

Tc的目录是d:\tc\th,

(th的意思是“天惑”)

我完全仿造“天惑”而做的,
所有的图形资源都是。

我的程序可以运行比较短的时间,
因为只做了开头的部分(基础都打好了,
XMS、图形的调用、内存的分配等等),
但是由于当时没有买到关于双缓冲的资料,
只用了putimage和getimage实现,稍稍有
点闪烁。
只是因为最后一学期开学,没有全部完成,
后期的工作只是向其中添加东西即可。

由于我的工作十分忙,
没有多余的时间,所以不能负责程序的
解释工作。所以只负责楼主的程序到
可以运行为止。

运行结果是纵版射击游戏。

程序很大,源程序可能有13个文件,
无法一一贴出。

另外,楼主可以把这个程序分给其他人
(当然也包括那些骂我小气的人,
我当然不能和他们一般见识),
通过mail或者其他的方式均可,
我放弃所有版权,凝结了我的很多天
心血和购买书籍,电脑的money的
程序,我对待他就像对待我的
baby一样,你说我多要点分
有错吗?我在卖自己的血和孩子呀!!

明天有一个很大的项目我要作,
所以这一段时间回帖有一定困难,
不过我也会抽空来一趟。

楼主可以用mail联系我。

最后要告诉“毒药”的一些人,
随着时间的过去,
人会越来越现实,
为了钱和其他的一些东西,
棱角会越来越少。
当初我为了游戏的痴狂劲
和狂傲不羁的性格带给我
工作上的非常大的被动,
所以我希望通过我的
亲身经历告诉大家:
在csdn上为了分,
也是一种活法!!


如果没有其他事情的话,
(不包括楼主程序运行问题)
我不会回贴的。

maltose

20030120
2608 2003-01-19
  • 打赏
  • 举报
回复
一些说明:砖块采用数组加链表的结构方式,还有一个bug,一次连续打掉三块以上的的砖块后,会有一些鼓励语句,但是这些语句会一直显示,我还没有来得及做消除的语句。
NVIDIATi4600 2003-01-18
  • 打赏
  • 举报
回复
扯淡,基础这么差,不自己用功看书,光在这论坛上问这个问那个的,问到的也是些半瓶子醋,能学到什么东西?回头一看人家DX编的程序,喝,这个漂亮,我学这个得了!再回头一看,操,什么也没学到。这种人多了去了,甭理他。他要真想学,就不上这来了。google上一搜,什么没有?
loveghb 2003-01-18
  • 打赏
  • 举报
回复
(吹牛大王)说的有道理,但是我们这些菜鸟讨论讨论还是有好处的,可以打发无聊的时间,交一些朋友的,你说是吗?:)
2608 2003-01-18
  • 打赏
  • 举报
回复
void moveBall(BALL_INFOR *ball_ptr,char *circleBuffer)
{
putimage((*ball_ptr).block_left,(*ball_ptr).block_top,circleBuffer,AND_PUT);

(*ball_ptr).centre_x+=X_movedir*CIRCLE_RADIUS;
(*ball_ptr).centre_y+=Y_movedir*CIRCLE_RADIUS;

(*ball_ptr).block_left=(*ball_ptr).centre_x-CIRCLE_RADIUS;
(*ball_ptr).block_top=(*ball_ptr).centre_y-CIRCLE_RADIUS;

circle((*ball_ptr).centre_x,(*ball_ptr).centre_y,CIRCLE_RADIUS);
floodfill((*ball_ptr).centre_x,(*ball_ptr).centre_y,WHITE);
}

void reboundBall (BALL_INFOR ball_struct)
{
if ((ball_struct.centre_y+CIRCLE_RADIUS >= bar_top)
&& (ball_struct.centre_y+CIRCLE_RADIUS <= bar_top + 5)
&& (bar_left < ball_struct.centre_x)
&& (ball_struct.centre_x < bar_left+BAR_WIDTH))
{
Y_movedir*=-1;
consecutive_hit=0;
}

/* judge if the ball in range */
if (ball_struct.block_top-2*CIRCLE_RADIUS < Y_MOVE_RANGE_UP)
Y_movedir*=-1;

if (ball_struct.centre_x+3*CIRCLE_RADIUS > X_MOVE_RANGE_RIGHT)
X_movedir*=-1;

if (ball_struct.block_left-2*CIRCLE_RADIUS < X_MOVE_RANGE_LEFT)
X_movedir*=-1;
}

void isLoss(int ball_centre_y,
char *circleBuffer,char *barBuffer,char *brickBuffer)
{
if (ball_centre_y+CIRCLE_RADIUS > Y_MOVE_RANGE_DOWN)
{

outtextxy(230,240,"YOU LOSE!!");
outtextxy(150,280,"press any key to quit");
getch();

dispose_brick();

free(circleBuffer);
free(barBuffer);
free (brickBuffer);

closegraph();
exit(0);
}
}

void moveBar(unsigned int moveDir,char * barBuffer)
{
putimage(bar_left,bar_top,barBuffer,AND_PUT);

switch (moveDir) {
case BAR_LEFT_MOVE :
if (bar_left > X_MOVE_RANGE_LEFT+10)
bar_left-=10;
break;
case BAR_RIGHT_MOVE:
if (bar_left+BAR_WIDTH < X_MOVE_RANGE_RIGHT-10)
bar_left+=10;
break;
case BAR_UP_MOVE:
if (bar_top-10 >= 200)
bar_top-=10;
break;
case BAR_DOWN_MOVE:
if (bar_top+10 <= 445)
bar_top+=10;
break;
default:
break;
}

bar(bar_left,bar_top,bar_left+BAR_WIDTH,bar_top+BAR_HIGH);
}

void drawBrick(void)
{
int line,column,brick_left,brick_top;

BRICK_INFOR_PTR
brick_line_new_ptr;

for (line=0;line<4;line++)
{
/* set information of the first brick in a brick line */
brick_left=60; brick_top=30+(line+1)*20;

brick_line_first_ptr[line]=(BRICK_INFOR_PTR)malloc(sizeof(brick_infor));
brick_line_first_ptr[line]->pre=NULL;
brick_line_first_ptr[line]->left=brick_left;
brick_line_first_ptr[line]->top=brick_top;
brick_line_first_ptr[line]->next=NULL;

brick_line_last_ptr[line]=brick_line_first_ptr[line];

bar(brick_left,brick_top,brick_left+BRICK_WIDTH,brick_top+BRICK_HIGH);

for (column=2;column<=21;column++)
{
brick_left+=25; /* 5 is granularity of bricks */
brick_line_new_ptr=malloc(sizeof(brick_infor));
brick_line_new_ptr->pre=brick_line_last_ptr[line];
brick_line_new_ptr->pre->next=brick_line_new_ptr;
brick_line_new_ptr->left=brick_left;
brick_line_new_ptr->top=brick_top;
brick_line_new_ptr->next=NULL;

brick_line_last_ptr[line]=brick_line_new_ptr;

bar(brick_left,brick_top,brick_left+BRICK_WIDTH,brick_top+BRICK_HIGH);
}
}
}

int isFinish(void)
{
int i;

for (i=0;i<4;i++)
if (brick_line_first_ptr[i])
return 1;

return 0;
}

int impactLine(int leftTop_y)
{
int line;

/* get brick line number which ball is in */
if ( 50<=leftTop_y && leftTop_y<= 55)
line=1;
if ( 70<=leftTop_y && leftTop_y<= 75)
line=2;
if ( 90<=leftTop_y && leftTop_y<= 95)
line=3;
if ( 110<=leftTop_y && leftTop_y<= 115)
line=4;

return line;
}

BRICK_INFOR_PTR findBrcik_JudgeImpactDir
(int ball_centre_x,int ball_centre_y,
int *impact_dir,int *Line)

{
int isfind=0,impactDir_x,whichLine;

BRICK_INFOR_PTR
check_ptr=NULL;

whichLine=impactLine(ball_centre_y+Y_movedir*5);
if (whichLine)
check_ptr=brick_line_first_ptr[whichLine-1];

impactDir_x=ball_centre_x+X_movedir*CIRCLE_RADIUS;

while (check_ptr && !isfind)
{
/* side impact */
if ((impactDir_x==check_ptr->left && ball_centre_x < check_ptr->left)
||
(impactDir_x==check_ptr->left+20 && ball_centre_x > check_ptr->left+20))
{ *impact_dir=2; isfind=1; }

/* directly impact */
if (!isfind)
if ((check_ptr->left <= impactDir_x && ball_centre_x <= check_ptr->left+20)
||
(check_ptr->left <= ball_centre_x && impactDir_x <= check_ptr->left+20))
{ *impact_dir=1; isfind=1; }

if (isfind==0)
check_ptr=check_ptr->next;
}
*Line=whichLine-1;
return check_ptr;
}

void hitBrick(int ball_centre_x,int ball_centre_y,char *brickBuffer)

{
int impactDir=0,Line;


BRICK_INFOR_PTR
beHitted_brick=NULL;

beHitted_brick=
findBrcik_JudgeImpactDir(ball_centre_x,ball_centre_y,&impactDir,&Line);

if (beHitted_brick)
{
if (beHitted_brick->next && beHitted_brick->pre)
{
beHitted_brick->pre->next=beHitted_brick->next;
beHitted_brick->next->pre=beHitted_brick->pre;
}
else
if (beHitted_brick->pre && !beHitted_brick->next)
{
beHitted_brick->pre->next=NULL; /* if the brick is the last one */
brick_line_last_ptr[Line]=brick_line_last_ptr[Line]->pre;
}
else
if (!beHitted_brick->pre && beHitted_brick->next)
{
beHitted_brick->next->pre=NULL; /* if the brick is the first one */
brick_line_first_ptr[Line]=brick_line_first_ptr[Line]->next;
}
else
brick_line_first_ptr[Line]=NULL;

putimage(beHitted_brick->left,beHitted_brick->top,brickBuffer,AND_PUT);
free(beHitted_brick);

consecutive_hit+=1;
if (consecutive_hit>=3)
show_hortative_words(&consecutive_hit);

if (impactDir==1)
Y_movedir*=-1;
if (impactDir==2)
X_movedir*=-1;
}
}

void dispose_brick(void)
{
BRICK_INFOR_PTR
temp_brick_ptr;
int i;

for (i=0;i<4;i++)
while (brick_line_first_ptr[i])
{
temp_brick_ptr=brick_line_first_ptr[i];
brick_line_first_ptr[i]=brick_line_first_ptr[i]->next;
free(temp_brick_ptr);
}
}

void show_hortative_words(int *hitNumber)
{
int textCoordinate_top,textCoordinate_Right;
char text[20]="",number;

if (*hitNumber<10)
{
text[0]=*hitNumber+48;
sprintf (text,"%c hit GOOD!!",*hitNumber+48);
outtextxy(200,15,text);
}
else
{
text[0]=*hitNumber/10+48; text[1]=*hitNumber%10+48;
sprintf (text+2," hit PERFECT!!");
outtextxy(200,15,text);
}
}

void initialize_graphic()
{
int graphdriver=VGA,graphmode=VGAHI;

registerbgidriver(EGAVGA_driver);
initgraph(&graphdriver,&graphmode,"");

setfillstyle(1,YELLOW);
setbkcolor (BLUE);

circle_size=imagesize(0,0,2*CIRCLE_RADIUS,2*CIRCLE_RADIUS);
bar_size=imagesize(bar_left,bar_top,bar_left+BAR_WIDTH,bar_top+BAR_HIGH);

circleBuffer=malloc(circle_size);
barBuffer=malloc(bar_size);

getimage(0,0,2*CIRCLE_RADIUS,2*CIRCLE_RADIUS,circleBuffer);
getimage(bar_left,bar_top,bar_left+BAR_WIDTH,bar_top+BAR_HIGH,barBuffer);

brick_size=imagesize(0,0,20,5);
brickBuffer=malloc(brick_size);
getimage(0,0,20,5,brickBuffer);
}
2608 2003-01-18
  • 打赏
  • 举报
回复
我自己做的打砖块游戏,图形方式,用了很多的putimage和getimage函数,
希望会对你游戏帮助

#include <stdlib.h>
#include <graphics.h>
#include <bios.h>
#include <conio.h>

#define X_MOVE_RANGE_LEFT 30
#define X_MOVE_RANGE_RIGHT getmaxx()-30
#define Y_MOVE_RANGE_UP 30
#define Y_MOVE_RANGE_DOWN getmaxy()-30

#define CIRCLE_RADIUS 5

#define BAR_WIDTH 40
#define BAR_HIGH 5

#define BRICK_WIDTH 20
#define BRICK_HIGH 5

#define BAR_LEFT_MOVE 0x4b00
#define BAR_RIGHT_MOVE 0x4d00
#define BAR_UP_MOVE 0x4800
#define BAR_DOWN_MOVE 0x5000

struct brick_information
{
struct brick_information *pre;
int left;
int top;
struct brick_information *next;
};
typedef struct brick_information brick_infor;
typedef brick_infor *BRICK_INFOR_PTR;

BRICK_INFOR_PTR
brick_line_first_ptr[4],brick_line_last_ptr[4];

struct ball_information
{
int centre_x;
int centre_y;
int block_left; /* the coordinate of block which ball is in */
int block_top;
};
typedef struct ball_information BALL_INFOR;

BALL_INFOR
ball_infor={270,240,270-CIRCLE_RADIUS,240-CIRCLE_RADIUS};


/* sub functions */

void initialize_graphic();
void drawBrick(void);
void reboundBall(BALL_INFOR );
void moveBall(BALL_INFOR *,char *);
void isLoss(int,char *,char *,char *);
void moveBar(unsigned int,char *);
int impactDirection(int bar_left,int bar_top,int ball_left,int ball_top);
int isFinish(void);
void hitBrick(int,int,char *);
BRICK_INFOR_PTR findBrcik_JudgeImpactDir(int,int,int *,int *);
int impactLine(int );
void dispose_brick(void);
void show_hortative_words (int *);

int
bar_movedir, bar_left=40, bar_top=440, /* bar's coordinates */

/*
move direction: left&up left&down right&up right&down

X_movedir -1 -1 1 1
Y_movedir -1 1 -1 1
*/
X_movedir=-1,Y_movedir=-1;

char
*circleBuffer=NULL,
*barBuffer=NULL,
*brickBuffer=NULL;

unsigned int
circle_size=0,
bar_size=0,
brick_size=0;

int
consecutive_hit=0;/* the number of consecutive impact */

main()
{
int
impactDir_y; /* record left or right side of block of ball impacts brick */

initialize_graphic();

#if 1

drawBrick();

/* set the move range of ball (30,30,600,450) */
rectangle(X_MOVE_RANGE_LEFT,Y_MOVE_RANGE_UP,
X_MOVE_RANGE_RIGHT,Y_MOVE_RANGE_DOWN);

bar(bar_left,bar_top,bar_left+BAR_WIDTH,bar_top+BAR_HIGH);

circle(ball_infor.centre_x,ball_infor.centre_y,CIRCLE_RADIUS);
floodfill(ball_infor.centre_x,ball_infor.centre_y,WHITE);

settextstyle(TRIPLEX_FONT,HORIZ_DIR,4);


while (isFinish())
{
moveBall(&(ball_infor),circleBuffer);

/* use bar to rebound ball */
reboundBall(ball_infor);

/* if the ball is out rebound of range,then quit */
isLoss(ball_infor.centre_y,circleBuffer,barBuffer,brickBuffer);

delay(10000);

/* if (kbhit()) */
moveBar(bioskey(0),barBuffer);

/*50-110 is range of brick line in*/
impactDir_y=ball_infor.centre_y+Y_movedir*CIRCLE_RADIUS;
if (impactDir_y >= 50 && impactDir_y <= 115)
hitBrick(ball_infor.centre_x,ball_infor.centre_y,brickBuffer);

} /* end rebound loop */
#endif
} /* end main program */
HITGB 2003-01-18
  • 打赏
  • 举报
回复
建议用FLASH!:)
sinan 2003-01-18
  • 打赏
  • 举报
回复
loveghb(毒药),谢了,一开始我想应用到直接在屏幕上画图,看样双缓冲是没什么用了
jackie168 2003-01-18
  • 打赏
  • 举报
回复
可否這樣想:
先畫幾張圖片....
然後用計時器把它們播放出來....
就產生了動畫效果 //比較簡單的想法
loveghb 2003-01-17
  • 打赏
  • 举报
回复
哈哈,画的时候当然是看不到,但是程序员你自己要知道的呀。例如在DOS的13H模式下,是320*200的分辨率,256色的,正好用8位表示,也就是 1个
unsigned char,那么屏幕大小的内存要 320*200个字节了。大约64K吧,实际上多数是申请不到的。(要么少申请点,那要牺牲你的屏幕大小了,或者用EMS、XMS技术,要么就用32位编译器。:(,可惜我英文太差了,下载了一个DJGPP,但是可能缺东西,无法用。大家干脆学VC算了)在内存中画其实和在显存中画是没什么区别的,只是画在内存中的东西要你自己“贴”到显存中去。
你可以看一些资料,网上很多的。在这里要象麦芽糖学习,他是我们的前辈,比我们懂的多。大家多多请教他,特别是XMS、EMS技术。
sinan 2003-01-16
  • 打赏
  • 举报
回复
loveghb(毒药),我不明白你的意思“在内存中画你的东西”,根本看不到怎么画啊,再就是分配一段屏幕大小的内存,哪要多大啊,用imagesize只能到0xFFFF,根本分不到啊???
sanfenqian 2003-01-16
  • 打赏
  • 举报
回复
看来不要分都不行了, loveghb(毒药) 就是厉害呀!哈哈
freedolphin 2003-01-16
  • 打赏
  • 举报
回复
怎么加分啊?
loveghb 2003-01-15
  • 打赏
  • 举报
回复
双缓冲其实很简单的,开辟一段屏幕大小的内存,然后在内存中画你的东西,画好后再以下子复制到显存中。好处就是避免在用户面前画,因为显示器的刷新率在70左右,但是你不可能这么快的画好整个画面,就会产生闪烁,画面效果就打折扣了。但是双缓冲会简慢你的速度,在类似DX—BALL这种弹球游戏中可以不用全屏幕刷新的,因为在动的东西不多的。
大家都去用32位的编译器吧,那就不用EMS和XMS技术了。32位编译器可以调到大内存了!
Robin 2003-01-15
  • 打赏
  • 举报
回复
强烈建议把分给毒药!
langziji 2003-01-14
  • 打赏
  • 举报
回复
人活在世上为钱,我活在CSDN上是为分呀,不骗你们,真的。
maltose 2003-01-14
  • 打赏
  • 举报
回复
to loveghb(毒药) :

完了。看见你的帖子后的第一感觉就是
--你小子好厉害!

我一时的英名就毁在你的手中。

你的话让我无地自容。

就像把地缝里的“小我”给挖出来晒太阳一样。

我输给你了。

不过对于“毒药”对于我的“教训”,
我作如下决定:
把源代码免费给freedolphin (阿蓝) 楼主,

楼主,请留下你的email !
sinan 2003-01-14
  • 打赏
  • 举报
回复
问一下,双缓冲是怎么实现的啊???
加载更多回复(25)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧