博文
我的零八愿望结局(2008-3-4 20:24:00)
以前跟人说过,我希望我的零八愿望能在新的一年里实现…
那是元旦的前一天晚上,听完新年的音乐会,我不懂艺术,可怜的那些人算是对牛弹琴了吧,我很开心地望着天空说,我希望我在零八年里过掉六级,考上研究生,
然后很执著的傻笑的那种,呵呵…
有个人很开心的咯咯的笑我…因为我六级算上这次考了已经四次,
"你六级要考六次才能过",呵呵,可爱的神奇咒语…
我这次六级没过,413分,…,有点失望,因为有希望才会有失望,
希望的越多,失望才越多~
回想我的六级历程,…,346,383,413,每次其实我都在很努力,
我也知道我英语烂,要比别人付出的多…
也怪不了谁,谁让自己大学里不好好学英语呢~
跟自己说,下次我一定可以,再接再厉……呵呵…
幸运的是我的另一个愿望应该是可以实现的吧,初试成绩也出来了,
402,比较意外,也很开心,呵呵,大概是因为上帝不会同时关上两扇门吧……

大学,我得到了什么?(2007-12-14 16:49:00)
昨天考完了《微波》,大学里最后一次必修课考试。辅导员也意思就是,选完毕设题和照完毕业照的没其它事的可以回家了,而我就是属于那种“有其它事的”,考研。
大学实质上已经上完了,过去的三年多里我都得到了些啥呢?有快乐的,有无措的,更多的是迷茫与激情的交织。
大
一刚来的时候,什么都不懂,就是土包子,发现很多新奇的东西。电子方面最让我着迷,倒不是爱玩游戏。我就成天在那琢磨,电脑这个冷冰冰的东西是怎么运转起
来的呢?那硬盘的磁头是怎么读写信息的呢?显示器上的点都是怎么描绘出来的呢?刚来没电脑,成天泡图书馆,吃完饭有时候回宿舍都省了,直接奔图书馆。把能
看懂的看不懂的计算机硬件方面的书几乎全部给看了个遍。想来,求知若渴的感觉大概就是那样吧。计算机体系结构,硬件方面的知识大概就那时建立起来的。那时
的我大概是我大学中进步最快的一段时间吧。
而接下的路我确实走错了,大一下买了个电脑,说要DIY自己装机,到电脑城里东买个CPU,西买个显
卡,回来兴奋得不行,当然了,机器是很容易装的,很快就装好了,立马装了个XP,点来点去地也不知道要干嘛,最热心的东西就是咋样咋样优化它了,使它启动
时间更短,跑得更快。这时期我也看书,不过不泡图书馆了,都是借了书出来读。而我竟然读得是应用软件方面的书,学过3DMAX,ACDSEE,MAYA,
FRONTPAGE…这学期开了C语言,我很上心,学得还过得去,这学期我的收获大概就是学了C…还学了点WINDOWS编程,做了几个画图程序。虽然当
时有点小成就感,马上就开始感到,真TDM无聊,全是函数调用来调用去地,谁能告诉我它的来龙去脉,其实我那时连自己想知道什么都不知道…
大二我认识了UNIX,我意外的发现这世界上原来除了WINDOWS还有其它的操作系统,我喜欢新鲜的东西,而我恰恰又犯了一个现今大学生的通病,浮躁…
我
几乎把大部分的LINUX发行版全体验了个遍,还把BSD的三分支给装了通,Solairs因为下不回来没装过。那时最热心的东西就是咋样把这系统的字体
显示得好看点呢?咋样让它编译得更适合我的机器,让它跑得更快呢?这段时期就学到了UNIX的体系结构和基本概念和一些常用的命令,基本是浮躁当头,有时
候一个版本还没装热立马换掉,浪费了N多N多(N>半年左右)时间,能说什么呢,过去的事情了,后悔也没用。这期间我也在编程,我不用再像以前写程
序一样调用那继承了N道又重载的函数了,看到MFC我就晕,可我发现我还是得调用函数,最起码操作系统内核的接口你还是必须得调用。我很郁闷,也很迷茫,
自己编程算个鸟呀,自己写的几句全是没一点有思考性的东西,老在调用函数,无聊地呀。
大概不知道什么时候了,我学习了数据结构和算法,我才发现这
才叫有点思考性的东西嘛,原来程序并不总是这么无聊地调用别人的东西,我去北大ACM网上做程序题,解决了问题我会很开心,比那做什么画图有意思多了。这
期间我感兴趣的东西太多了,图形学,操作系统,编译原理,汇编,计算机体系结构,算法,协议栈…。我好像同时在学本专业通信和计算机两专业的课程。每次放长假回家我都会带N多大砖块书回去看,而我在家里也确实
是没日没夜地看书,像一天看七八个小时的书的时候很多,过年除了走亲访友其它时候也不例外。而就算这样,我也感觉不到我的进步,我发现我更无知了,不知道
的东西更多了,我迷茫了…
我开始不知道我要干什么了,什么东西好像都知道,而又好像不知道,有时候静也静不下来,有时候卯足了劲却又不知道要干嘛,我迷失了…在
这个迷失的时期我认识了篮子,呵呵,一可爱的小女子,很有激情的,我看到了以前的我。可我的激情现要从何而来呢?我到底要干什么呢?苦笑…我开始胡逛网
了,以前基本不会去逛网的,以前逛网就是打开GOOGLE搜索我想知道的东西。在天涯社区里我遇到了很多人,有学生,有老板,有技术员,有销售兵,我的茫
然也在他们当中绝大多数中得到了体现,现今一个浮躁的社会…
我走上了考研路,可就是这难得的静下心来的时间却让我体会到了我以前从未想到过的东
西。你还在天天换LINUX发行版或汉化你的LINUX吗?你还会认为改注册表,编辑音频,使用黑客软件啥地很牛B么?你还在那因为看到每天蹦出来的高新
技术名词而激动不已,进而想要投身进去当做你的终身职业么?这都是因为浮躁而做得些SB事情,当然了,以前的我占了八成。我现只想告诫我自己几条,静下心
来拒绝浮躁,电脑只是工具,没必要重新发明轮子,学好自己的本专业分清主次,在技术和销售两分的转型期中国学好技术是必要的但技术不是全部。你说呢?
我现其实也只是刚刚从迷失中走出的小P孩,我走出了茫然,走出了浮躁,我也走完了大学…
不过,没关系,这只是新的开始…
阅读全文(1163) | 评论:14 | 复制链接
Tortoise And Rose(2007-10-25 13:09:00)
小乌龟的那只腿还是断的,
不想人为地粘起来,
附加的结合玷污心中的纯洁。
残缺也是一种美。
正儿八经地折过几朵纸玫瑰,
只有这朵最好,一直放在抽屉,
总会在打开抽屉时不经意地看到。
没有玫瑰的清香扑鼻,
也没有玫瑰的娇艳多姿,
只是安然地躺在抽屉的角落,
尘封心的气息。
有个人说,小乌龟像我,傻愣愣地~
我想永远是这只傻不啦叽地断腿小乌龟。
我们每个人都是只有一只翅膀的天使,
只有互相拥抱才会飞翔。

Only you can see...
SDL在WINDOWS环境下的设置(DevCpp)(2007-10-23 10:35:00)
好多人问关于SDL在WINDOWS环境下的编译环境设置,
最近我有点“功课”,也必须在WINODWS下编译SDL程序,
有点心得,致那些热心于SDL 的朋友们。
以下是在DevCpp环境下的SDL设置(至于VC环境,没有实践,就不敢写了):
1.下载http://www.libsdl.org/release/SDL-1.2.12-win32.zip运行库,
运行SDL程序时压缩包里的sdl.dll要和程序在同一目录下。
2.下载http://www.libsdl.org/release/SDL-devel-1.2.12-mingw32.tar.gz开发库,
将解压后的SDL-1.2.xx目录下的include\SDL文件夹,及lib\*.*(下的所有文件)
分别拷到C:\devcpp(假设DevCPP装在C盘)文件夹下的include,lib文件夹下。
3.设置下DevCpp的连接器,写入 -lmingw32 -lSDLmain -lSDL -mwindows
就可以编译运行SDL程序了,头文件包含应该是<SDL/SDL.h>。
阅读全文(1691) | 评论:4 | 复制链接
单词表逆序程序(2007-6-13 20:15:00)
以前地ACM同胞现全有自己地事去了,继续搞ACM的现当然几乎成领军人物了,只有我这烂人还在这准备考研地说,正经程序就再没写几个,方便背单词的小程序倒自己写了N(N>10)个……哈哈,都笑我没品位呀……,其实都是些自己实用的程序,这个逆序程序好像还比较有用的……,背单词换个口味呢……
#include <iostream>
#include <string.h>
using namespace std;
const int N=8000; //偶最多也只背这么多个
int cmp(char *a,char *b)
{
char ta,tb;
int la=0,lb=0;
while(a[la]!='\0' && a[la]!=9 && a[la]!=' ' && a[la]!=','
&& a[la]!='(' && a[la]!= '[' && a[la]!='/' && a[la]!='.')
la++;
while(b[lb]!='\0' && b[lb]!=9 && b[lb]!= ' ' && b[lb]!=','
&& b[lb]!='(' && b[lb]!= '[' && b[lb]!='/' && b[lb]!='.')
lb++;
la--;
lb--;
while(la!=-1 || lb !=-1)
{
if(a[la]>='A' && a[la]<='Z')
ta=a[la]+32;
else ta=a[la];
if(b[lb]>='A' && b[lb]<='Z')
tb=b[lb]+32;
else tb=b[lb];
if(ta>tb)
return 1;
else if(ta<tb)
return -1;
else
{
la--;
lb--;
}
}
}
int main()
{
FILE *fp;
int i,j,p=0,min;
char ch[N][100]={0};
char tmp[100];
if((fp=fopen("in.csv","r"))==NULL)
{
cout << "read error" <<endl;
return 1;
}
while(!feof(fp))
{
i=0;
while( !feof(fp)
&& (ch[p][i++]=fgetc(fp))!='\n');
ch[p][i-1]='\0';
p++;
}
p--;
for (i=0;i<p;i++)
{
min = i;
for (j=i+1;j<p;j++)
{
if(cmp(ch[j],ch[min])<0)
min=j;
}
if(min != i)
{
strcpy(tmp,ch[min]);
strcpy(ch[min],ch[i]);
strcpy(ch[i],tmp);
}
}
fclose(fp);
fp=fopen("out.csv","w+");
for (i=0;i<p;i++)
{
fprintf(fp,"%s\n",ch[i]);
}
fclose(fp);
}
阅读全文(1610) | 评论:2 | 复制链接
GBK点阵字体的显示(2007-1-18 20:17:00)
下文转自SOHU论坛 , 软件开发 -> C/C++版原著者为该版副版主 爱在远方
一、汉字在计算机中的编码形式
我们都知道,在计算机中英文字符是用一个字节的ASCII码表示,该字节最高位一般用做奇偶校验,故实际是用7位码来代表128个字符的,但是对于众多的汉字,只有用两个字节才能表示,这样用两个字节来表示一个汉字的体制,国家制定了统一的标准,称为国标码。国标码规定,组成两个汉字代码的各字节最高位为0,这和英文字符表示方法相同,这就有可能把汉字的国标码看作两个ASCII码,为此又规定在计算机里表示汉字时,把最高位置1,表示该码是汉字,这种最高位为1的代码称为机器内的汉字代码,简称内码。计算机里汉字就是用内码表示的。
例如:“大”这个汉字,
国标码 3473 00110100 01110011
内码 B4F3 10110100 11110011
知道汉字在计算机里是用内码表示的以后,还需要知道具体汉字的结构。我国在1981年公布了《通讯用汉字字符集及其交换码标准》GB2312-80方案,里面规定了高频字、常用字、次常用字集合成汉字基本字符集(共6763个),再加上一些西文字母,希腊字母、日文字符、图形符号等一共700个。国家标准的汉字字符集在汉字操作系统中是以汉字库的形式提供的。汉字库规定,把字库分为94个区(区号),每个区有94个汉字(位号),这就是所谓的区位码(区位码第一字节是区号,第二字节是位号,因为知道了区位码就等于知道了该汉字在字库中的位置)。每个汉字在字库中是以点阵字模形式存储的,如一般采用16*16点阵形式,这样就需要32字节。在16*16点阵里,存1的点在显示时为一个亮点,存0的点不显示,这样汉字就显示出来了。简单写一下“大”这个字的字模:
0000001100000000
0000001100000000
0000001100000000
0000001100000010
1111111111111110
0000001100000000
0000001100000000
0000001100000000
0000001100000000
0000001110000000
0000011001000000
0000110000100000
0001100000010000
0001000000011000
0010000000001110
1100000000000100
这样当需要显示“大”这个汉字时,首先把这个字模取出,然后逐位显示,1显示0不显示,屏幕上就会出现“大”这个汉字。
那么我们怎么知道汉字的区位码呢?前面说了,汉字在计算机里是用内码存储的。内码和区位码的转换关系是(还以“大”为例):
区号:B4-A0 位号:F3-A0
也就是说,把内码减去A0就是区位码,那么“大”这个汉字的区位码就出来了,是在14H区53H号,也就是第20区第83号。那么由于每个区有94个汉字,“大”这个字应该就是在汉字库的第(20-1)*94+(83-1)个汉字位置(每个汉字字模占32字节)。那么现在又要问了,内码又是怎样得到的呢?看下面的程序:
main()
{
unsigned char *s="大";
printf("%x,%x\n",s[0],s[1]);
getch();
}
运行程序发现,输出就是b4,f3。
二、西文方式下显示中文
说到这儿,大家应该有个思路了吧。要想显示汉字:
(1) 获得汉字内码
(2) 换算成区位码
(3) 在字库中取出该汉字的字模(共32字节)
(4) 1显示0不显示
以下为自己写的小程序:
#include <iostream>
#include <SDL/SDL.h>
using namespace std;
char shape[32], in[256] = "中华人民共和国";
SDL_Surface *screen;
FILE *fp;
void
putpixel (SDL_Surface * img, int x, int y, Uint32 pixel)
{
int bpp = img->format->BytesPerPixel;
Uint8 *p = (Uint8 *) img->pixels + y * img->pitch + x * bpp;
switch (bpp)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *) p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *) p = pixel;
break;
};
}
void
PutShape (unsigned char left, unsigned char right, int x, int y)
{
unsigned char bits[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
int pos = 32 * ((left - 161) * 94 + (right - 161)), i, j;
Uint32 pixel = SDL_MapRGB (screen->format, 255, 255, 255);
fseek (fp, pos, SEEK_SET);
fread (shape, 32, 1, fp);
for (i = 0; i < 16; i++)
for (j = 0; j < 8; j++)
{
if (shape[2 * i] & bits[j])
putpixel (screen, x + j, i + y, pixel);
if (shape[2 * i + 1] & bits[j])
putpixel (screen, x + j + 8, i + y, pixel);
}
}
void
PutStr (int x, int y)
{
int length = strlen (in), i;
for (i = 0; i < length; i += 2)
{
PutShape (in[i], in[i + 1], x, y);
x += 16;
if (x > 640)
{
x = 0;
y += 16;
}
}
}
void
loop ()
{
SDL_Event event;
int running = 1;
while (running)
{
SDL_Delay (50);
while (SDL_PollEvent (&event))
{
switch (event.type)
{
case SDL_QUIT:
running = 0;
break;
};
}
SDL_UpdateRect (screen, 0, 0, 0, 0);
}
}
int
main ()
{
if (SDL_Init (SDL_INIT_VIDEO) < 0)
fprintf (stderr, "init error\n");
if ((screen =
SDL_SetVideoMode (640, 480, 32,
SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
fprintf (stderr, "setvideomode error\n");
if ((fp = fopen ("HZK16", "r")) == NULL)
fprintf (stderr, "open HZK16 error\n");
atexit (SDL_Quit);
PutStr (32, 2);
loop ();
fclose (fp);
return 0;
}
阅读全文(2146) | 评论:2 | 复制链接
SDL版本的扫雷程序(2007-1-1 23:53:00)
元旦才刚放假,说实话,我很闲……
所以又写了个扫雷,这个扫雷程序其实真要算是“初学者”级的了……
里面就用到了一个比较像样的算法,…
就是点一个空的时候把邻近的所有连通的空格全部显出……
其实聪明人一下子就知道是搜索了,深搜广搜都可以了……我用的是深搜……
呵呵,程序很简单,但我还是写了这么长,不知怎么搞地……
可能很多地方还可以精简吧……我没刻意去怎么精简它……
因为反正是好玩呀……呵呵,关键的深搜算法写得好一点就差不多了……
正好温习一下落了些时日的算法了……
程序运行状态:

源程序:bomb.cc
/***************************************************************************
* bomb.cc
* 扫雷
* Mon Jan 1 15:29:38 2007
* Copyright 2007 HuYinLin
* Email huyinlin@126.com
****************************************************************************/
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <iostream>
using namespace std;
#define FrameW 3 //边框厚
#define BASE_W 20 //小方块大小
#define LINE 16 //行数
#define COL 30 //列数
#define BOMB_NUM 80 //雷数
#define UP 30 //上方还有的其它东东
#define HW FrameW*2+COL*BASE_W //屏幕宽
#define HH FrameW+LINE*BASE_W+UP //屏幕高
#define FontW 10 //字体高度和宽度
#define FontH 18
int bomb[LINE][COL] = { };
int temp[LINE][COL] = { };
int frame[8][2] = {
-1, 0, 1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, 1, 1, -1
};
int alive = 0, TIME;
SDL_Surface *screen, //屏幕
*nobomb, //没有雷的区域
*font, //字体
*dead, //雷
*flag, //旗帜
*error, //错误标志
*newgame, //新游戏
*back, //小背景
*cover; //默认的图
SDL_Surface *
LoadIMG (const char *name)
{
SDL_Surface *tmp, *final;
if ((tmp = IMG_Load (name)) == NULL)
fprintf (stderr, "load %s error\n", name);
final = SDL_DisplayFormat (tmp);
SDL_FreeSurface (tmp);
SDL_SetColorKey (final, SDL_SRCCOLORKEY | SDL_RLEACCEL,
*(Uint32 *) final->pixels);
return final;
}
void
LoadData ()
{
nobomb = LoadIMG ("nobomb.png");
font = LoadIMG ("font.gif");
dead = LoadIMG ("dead.png");
cover = LoadIMG ("cover.gif");
error = LoadIMG ("error.png");
flag = LoadIMG ("flag.png");
newgame = LoadIMG ("new.jpg");
back = LoadIMG ("back.png");
}
int
over (int x, int y) //测试是否超出边界
{
if (x < 0 || x >= LINE || y < 0 || y >= COL)
return 1;
else
return 0;
}
int
gameover ()
{
int flag = 1;
for (int i = 0; i < LINE; i++)
for (int j = 0; j < COL; j++)
if (bomb[i][j] == -1 && temp[i][j] != 1)
flag = 0;
return flag;
}
void
drawnum (int num) //显示时间
{
SDL_Rect dst, src;
dst.x = FrameW, dst.y = FrameW;
dst.w = FontW;
dst.h = FontH;
src.w = FontW;
src.h = FontH;
src.y = 0;
int s[3] = { }, i = 2;
while (num)
{
s[i--] = num % 10;
num /= 10;
}
for (i = 0; i < 3; i++)
{
src.x = s[i] * FontW;
SDL_BlitSurface (back, &src, screen, &dst);
SDL_BlitSurface (font, &src, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
dst.x += FontW;
}
}
void
creatbomb () //绘制雷区
{
TIME = 0;
drawnum (0);
alive = 1;
int i, j, x, y, num, k;
for (i = 0; i < LINE; i++)
for (j = 0; j < COL; j++)
{
bomb[i][j] = 0;
temp[i][j] = 0;
}
for (i = 0; i < BOMB_NUM; i++)
{
x = rand () % LINE;
y = rand () % COL;
bomb[x][y] = -1; //-1表示此地有雷
}
for (i = 0; i < LINE; i++) //填其它的数
for (j = 0; j < COL; j++)
if (bomb[i][j] != -1)
{
num = 0;
for (k = 0; k < 8; k++)
{
x = i + frame[k][0];
y = j + frame[k][1];
if (!over (x, y) && bomb[x][y] == -1)
num -= bomb[x][y];
}
bomb[i][j] = num;
}
}
void
initdraw () //初始时的画片
{
int i, j;
SDL_Rect src, dst;
src.x = src.y = 0;
src.w = back->w;
src.h = UP;
dst.y = dst.x = 0;
dst.w = back->w;
dst.h = UP;
for (i = FrameW; i < HW; i += back->w)
{
SDL_BlitSurface (back, &src, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
dst.x += back->w;
}
dst.x = (HW - newgame->w) / 2;
dst.y = (UP - newgame->h) / 2;
dst.w = newgame->w;
dst.h = newgame->h;
SDL_BlitSurface (newgame, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
dst.w = dst.h = BASE_W;
for (i = FrameW; i < HW - FrameW; i += BASE_W)
for (j = UP; j < HH - FrameW; j += BASE_W)
{
dst.x = i;
dst.y = j;
SDL_BlitSurface (cover, NULL, screen, &dst);
}
SDL_UpdateRect (screen, FrameW, UP, COL * BASE_W, LINE * BASE_W);
}
void
FreeData ()
{
SDL_FreeSurface (nobomb);
SDL_FreeSurface (font);
SDL_FreeSurface (dead);
SDL_FreeSurface (cover);
SDL_FreeSurface (flag);
SDL_FreeSurface (error);
SDL_FreeSurface (newgame);
SDL_FreeSurface (back);
}
void
init ()
{
if ((SDL_Init (SDL_INIT_AUDIO | SDL_INIT_VIDEO)) < 0)
fprintf (stderr, "init error\n");
if ((screen =
SDL_SetVideoMode (HW, HH, 32,
SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
fprintf (stderr, "set video mode error\n");
atexit (SDL_Quit);
SDL_WM_SetCaption ("hard bomble", "");
LoadData ();
initdraw ();
srand (time (NULL));
}
int
returnx (int a) //真实坐标到数组坐标
{
if (a < FrameW)
return -1;
return (a - FrameW) / BASE_W;
}
int
returny (int b)
{
if (b < UP)
return -1;
return (b - UP) / BASE_W;
}
void
drawsurface (SDL_Surface * img, int x, int y)
{
SDL_Rect dst;
dst.x = y * BASE_W + FrameW;
dst.y = x * BASE_W + UP;
dst.w = img->w;
dst.h = img->h;
SDL_BlitSurface (img, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
void
Bomb () //碰到雷了
{
int i, j;
alive = 0;
SDL_Rect dst;
dst.w = dst.h = BASE_W;
for (i = 0; i < LINE; i++)
for (j = 0; j < COL; j++)
{
if (temp[i][j] == 1 && bomb[i][j] != -1)
{
drawsurface (nobomb, i, j);
drawsurface (error, i, j);
}
if (bomb[i][j] == -1)
{
dst.x = j * BASE_W + FrameW;
dst.y = UP + i * BASE_W;
drawsurface (nobomb, i, j);
SDL_BlitSurface (dead, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
}
}
void
drawchar (int num, int x, int y) //在图片上画雷的个数
{
temp[x][y] = -1;
SDL_Rect src, dst;
src.w = FontW;
src.h = FontH;
src.x = num * FontW;
src.y = 0;
dst.w = FontW;
dst.h = FontH;
dst.x = y * BASE_W + FrameW + (BASE_W - FontW) / 2;
dst.y = UP + x * BASE_W + (BASE_W - FontH) / 2;
drawsurface (nobomb, x, y);
SDL_BlitSurface (font, &src, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
void
testvast (int x, int y) //对一个非雷区进行递归搜索
{
SDL_Rect dst;
int a, b, k;
dst.w = dst.h = BASE_W;
dst.x = y * BASE_W + FrameW;
dst.y = UP + x * BASE_W;
SDL_BlitSurface (nobomb, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
bomb[x][y] = 10;
for (k = 0; k < 4; k++)
{
a = x + frame[k][0];
b = y + frame[k][1];
if (!over (a, b) && temp[a][b] == 0)
{
if (bomb[a][b] == 0)
testvast (a, b);
else if (bomb[a][b] != -1)
drawchar (bomb[a][b], a, b);
}
}
}
/* type=-1 左键
type=0 中键
type=1 右键
*/
void
handleevent (int type, int x, int y)
{
if (alive)
{
switch (type)
{
case -1:
if (temp[x][y] == 0)
{
if (bomb[x][y] == -1)
Bomb ();
else if (bomb[x][y] != 0)
drawchar (bomb[x][y], x, y);
else if (bomb[x][y] == 0)
testvast (x, y);
}
break;
case 0:
if (bomb[x][y] != 0 && bomb[x][y] != -1
&& temp[x][y] == -1)
{
int k, num = 0, a, b;
for (k = 0; k < 8; k++)
{
a = x + frame[k][0];
b = y + frame[k][1];
if (!over (a, b) && temp[a][b] == 1)
num++;
}
if (num == bomb[x][y])
{
for (k = 0; k < 8; k++)
{
a = x + frame[k][0];
b = y + frame[k][1];
if (!over (a, b))
{
if (temp[a][b] != 1)
handleevent
(-1,
a,
b);
}
}
}
}
break;
case 1:
if (temp[x][y] == 1)
{
drawsurface (cover, x, y);
temp[x][y] = 0;
}
else if (temp[x][y] == 0)
{
drawsurface (flag, x, y);
temp[x][y] = 1;
if (gameover ())
{
alive = 0;
for (int i = 0; i < LINE; i++)
for (int j = 0; j < COL; j++)
{
if (bomb[i][j] == 0
&& temp[i][j] !=
10)
handleevent
(-1,
i,
j);
else if (bomb[i][j] !=
-1
&& temp[i][j]
!= -1)
drawchar (bomb
[i]
[j],
i,
j);
}
}
}
break;
};
}
}
int
pointatnew (int x, int y) //sdl坐标
{
if (x < (HW - newgame->w) / 2
|| x > (HW - newgame->w) / 2 + newgame->w
|| y < (UP - newgame->h) / 2
|| y > (UP - newgame->h) / 2 + newgame->h)
return 0;
else
return 1;
}
void
wait ()
{
SDL_Delay (50);
}
void
rungame ()
{
SDL_Event event;
int timeisok = 0;
Uint32 thistime, nexttime = 0;
int run = 1, x, y;
drawnum (0);
while (run)
{
wait ();
if (alive)
{
thistime = SDL_GetTicks ();
if (thistime >= nexttime)
{
timeisok = 1;
nexttime = thistime + 1000;
}
if (timeisok)
{
drawnum (TIME++);
timeisok = 0;
}
}
while (SDL_PollEvent (&event))
{
switch (event.type)
{
case SDL_QUIT:
run = 0;
break;
case SDL_MOUSEBUTTONDOWN:
x = returny (event.button.y);
y = returnx (event.button.x);
if (!over (x, y))
{
switch (event.button.button)
{
case SDL_BUTTON_LEFT:
handleevent (-1, x, y);
break;
case SDL_BUTTON_RIGHT:
handleevent (1, x, y);
break;
case SDL_BUTTON_MIDDLE:
handleevent (0, x, y);
break;
};
}
else if (pointatnew
(event.button.x, event.button.y))
{
creatbomb ();
initdraw ();
}
}
}
}
}
int
main ()
{
init ();
rungame ();
FreeData ();
}
阅读全文(2400) | 评论:3 | 复制链接
SDL版本的俄罗斯方块程序(2007-1-1 0:49:00)
放元旦了……三天假,很闲……
其实要做的事实很多,都快期末考试了,可看着教材就不想看……
就花了点时间写了个俄罗斯方块程序了……
听有人说俄罗斯方块是初学程序设计语言去写的样本例子……
我真惭愧呀……我还花了两个下午来研究这个“初学者”级的程序……==||
不知道是那们人太牛了,还是我太逊了……
程序运行状态:

程序:tetris.cc
程序写得乱,我也懒得写注解了……因为总感觉人太逊了……
写得注解更要误导别人了……
可能受了那“牛人“打击了……
/***************************************************************************
* tetris.cc
*
* Sat Dec 30 19:31:35 2006
* Copyright 2006 HuYinLin
* Email huyinlin@126.com
****************************************************************************/
//俄罗斯方块程序
#include <SDL/SDL.h>
#include <iostream>
#include <SDL/SDL_image.h>
#include <SDL/SDL_mixer.h>
using namespace std;
#define HW 512
#define HH 704
#define BLOCK_W 32 //象素值
#define BLOCK_H 32
#define GAME_W 10 //BLOCK值
#define GAME_H 22
#define MAXUPDATES 8*GAME_W+4*4
#define FPS 40
#define MAXINT 999999999
#define FONT_WIDTH 16
#define FONT_HIGHT 16
SDL_Surface *screen, *back, *block, *frame, *font, *up, *bottom;
int gamestate[GAME_W + 2][GAME_H + 1] = { };
int score;
typedef struct
{
int coor[4][2]; //相对坐标
int rotate_next;
} shape;
typedef struct
{
int x, y; //block坐标
int type; //形状
SDL_Surface *img;
} object;
enum
{
BOTTOM_WAV,
EXPLODE_WAV,
EXCELLENT_WAV,
NUM_WAVES
};
Mix_Chunk *sounds[NUM_WAVES];
object current, next;
int speed = 10;
SDL_Rect src[MAXUPDATES];
SDL_Rect dst[MAXUPDATES];
int numupdates;
typedef struct
{
SDL_Rect *src, *dst;
SDL_Surface *img;
} Blit;
Blit blits[MAXUPDATES];
shape SP[19] = {
{0, 0, 1, 0, 0, 1, 0, 2, 1},
{-1, 0, -1, 1, 0, 1, 1, 1, 2},
{0, 2, 1, 2, 1, 1, 1, 0, 3},
{-1, 1, 0, 1, 1, 1, 1, 2, 0},
{0, 0, 0, 1, 0, 2, 1, 2, 5},
{-1, 1, 0, 1, 1, 1, 1, 0, 6},
{0, 0, 1, 0, 1, 1, 1, 2, 7},
{0, 2, 0, 1, 1, 1, 2, 1, 4},
{0, 0, -1, 0, 1, 0, 0, 1, 9},
{0, 0, 0, 1, 0, 2, 1, 1, 10},
{-1, 1, 0, 1, 1, 1, 0, 0, 11},
{0, 0, 0, 1, 0, 2, -1, 1, 8},
{0, 0, -1, 0, 0, 1, 1, 1, 13},
{0, 1, 0, 2, 1, 1, 1, 0, 12},
{0, 0, 0, 1, 1, 0, -1, 1, 15},
{0, 0, 0, 1, 1, 1, 1, 2, 14},
{0, 0, 0, 1, 0, 2, 0, 3, 17},
{-1, 1, 0, 1, 1, 1, 2, 1, 16},
{0, 0, 0, 1, 1, 1, 1, 0, 18}
};
void
drawobject (object sprite)
{
Blit *update;
for (int i = 0; i < 4; i++)
{
update = &blits[numupdates++];
update->img = sprite.img;
update->src->x = update->src->y = 0;
update->src->w = BLOCK_W;
update->src->h = BLOCK_H;
update->dst->x =
(sprite.x + SP[sprite.type].coor[i][0]) * BLOCK_W -
frame->w;
update->dst->y =
(sprite.y - SP[sprite.type].coor[i][1]) * BLOCK_H -
frame->h;
update->dst->w = BLOCK_W;
update->dst->h = BLOCK_H;
}
}
void
eraseobject (object sprite)
{
Blit *update;
for (int i = 0; i < 4; i++)
{
update = &blits[numupdates++];
update->img = back;
update->src->x =
(sprite.x + SP[sprite.type].coor[i][0]) * BLOCK_W -
frame->w;
update->src->y =
(sprite.y - SP[sprite.type].coor[i][1]) * BLOCK_H -
frame->h;
update->src->w = BLOCK_W;
update->src->h = BLOCK_H;
update->dst->x =
(sprite.x + SP[sprite.type].coor[i][0]) * BLOCK_W -
frame->w;
update->dst->y =
(sprite.y - SP[sprite.type].coor[i][1]) * BLOCK_H -
frame->h;
update->dst->w = BLOCK_W;
update->dst->h = BLOCK_H;
}
}
void
updatescene ()
{
for (int i = 0; i < numupdates; i++)
SDL_BlitSurface (blits[i].img, blits[i].src, screen,
blits[i].dst);
SDL_UpdateRects (screen, numupdates, dst);
numupdates = 0;
}
void
Rotate ()
{
int i, x, y;
int type = SP[current.type].rotate_next;
for (i = 0; i < 4; i++)
{
x = current.x + SP[type].coor[i][0];
y = current.y + SP[type].coor[i][1];
if (gamestate[x][y] != 0)
break;
}
if (i == 4)
current.type = type;
else
return;
}
void
drawframe ()
{
int i = 0, j = 0, flag = 0;
int down[4];
for (i = 0; i < 4; i++)
down[j++] = current.x + SP[current.type].coor[i][0];
SDL_Rect dst;
dst.w = frame->w;
dst.h = frame->h;
for (i = 0; i < HH; i += frame->h)
{
dst.x = 0;
dst.y = i;
SDL_BlitSurface (frame, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
dst.x = frame->w + GAME_W * BLOCK_W;
SDL_BlitSurface (frame, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
for (i = 0; i < frame->w + GAME_W * BLOCK_W; i += frame->w)
{
dst.y = HH - frame->h;
dst.x = i;
flag = 0;
for (j = 0; j < 4; j++)
{
if (dst.x == (down[j] * BLOCK_H) - frame->w)
{
SDL_BlitSurface (bottom, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
i += frame->w;
dst.x = i;
SDL_BlitSurface (bottom, NULL, screen, &dst);
flag = 1;
}
}
if (!flag)
SDL_BlitSurface (frame, NULL, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
}
void
init ()
{
int i;
if (SDL_Init (SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0)
fprintf (stderr, "init error\n");
if ((screen =
SDL_SetVideoMode (HW, HH, 32,
SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
fprintf (stderr, "set video mode error\n");
srand (time (NULL));
atexit (SDL_Quit);
SDL_WM_SetCaption ("tetris", "");
for (i = 0; i < MAXUPDATES; i++) //更新矩阵进行锁定
{
blits[i].src = &src[i];
blits[i].dst = &dst[i];
}
for (i = 0; i < GAME_W + 2; i++) //设置底线
gamestate[i][GAME_H] = 1;
for (i = 0; i < GAME_H; i++)
gamestate[0][i] = gamestate[GAME_W + 1][i] = 1;
next.x = 13;
next.y = 10;
if (Mix_OpenAudio (22050, AUDIO_U16, 1, 512) < 0)
{
fprintf (stderr,
"Warning: Couldn't set 22050 Hz 16-bit audio\n- Reason: %s\n",
SDL_GetError ());
}
}
SDL_Surface *
LoadIMG (const char *name)
{
SDL_Surface *tmp, *ok;
if ((tmp = IMG_Load (name)) == NULL)
{
fprintf (stderr, "load %s error\n", name);
return NULL;
}
ok = SDL_DisplayFormat (tmp);
SDL_FreeSurface (tmp);
SDL_SetColorKey (ok, SDL_SRCCOLORKEY | SDL_RLEACCEL,
*(Uint32 *) ok->pixels);
return ok;
}
void
showstring (int x, int y, const char *string)
{
int length = strlen (string), i;
SDL_Rect src, dst;
dst.y = y;
src.w = FONT_WIDTH;
src.h = FONT_HIGHT;
for (i = 0; i < length; i++)
{
dst.x = x + i * FONT_WIDTH;
if (string[i] >= 'a' && string[i] <= 'o')
{
src.x = (string[i] - 'a' + 1) * FONT_WIDTH;
src.y = 2 * FONT_HIGHT;
}
else
{
src.x = (string[i] - 'p') * FONT_WIDTH;
src.y = 3 * FONT_HIGHT;
}
SDL_BlitSurface (font, &src, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
}
void
LoadData ()
{
block = LoadIMG ("element.gif");
back = LoadIMG ("back.jpg");
frame = LoadIMG ("frame.gif");
font = LoadIMG ("glassfont.png");
up = LoadIMG ("up.gif");
bottom = LoadIMG ("bottom.gif");
sounds[BOTTOM_WAV] = Mix_LoadWAV ("bottom.wav");
sounds[EXPLODE_WAV] = Mix_LoadWAV ("explosion.wav");
sounds[EXCELLENT_WAV] = Mix_LoadWAV ("excellent.wav");
}
int
moveable (int faceing)
{
int x, y, i;
switch (faceing)
{
case -1:
for (i = 0; i < 4; i++)
{
x = current.x + SP[current.type].coor[i][0] - 1;
y = current.y - SP[current.type].coor[i][1];
if (gamestate[x][y] != 0)
break;
}
if (i == 4)
return 1;
else
return 0;
case 0:
for (i = 0; i < 4; i++)
{
x = current.x + SP[current.type].coor[i][0];
y = current.y - SP[current.type].coor[i][1] + 1;
if (gamestate[x][y] != 0)
break;
}
if (i == 4)
return 1;
else
return 0;
case 1:
for (i = 0; i < 4; i++)
{
x = current.x + SP[current.type].coor[i][0] + 1;
y = current.y - SP[current.type].coor[i][1];
if (gamestate[x][y] != 0)
break;
}
if (i == 4)
return 1;
else
return 0;
default:
return 0;
}
}
int
atbottom ()
{
if (moveable (0))
return 0;
else
return 1;
}
int
over ()
{
int y, i;
for (i = 0; i < 4; i++)
{
y = current.y - SP[current.type].coor[i][1];
if (y < 4)
break;
}
if (i == 4)
return 0;
else
return 1;
}
void
FreeData ()
{
SDL_FreeSurface (block);
SDL_FreeSurface (back);
SDL_FreeSurface (frame);
SDL_FreeSurface (font);
SDL_FreeSurface (up);
SDL_FreeSurface (bottom);
Mix_CloseAudio ();
}
void
drawupline ()
{
SDL_Rect src, dst;
dst.y = 4 * BLOCK_H;
dst.x = 2 * frame->w + (GAME_W - 2) * BLOCK_W;
dst.w = up->w;
dst.h = up->h;
src.x = src.y = 0;
src.h = up->h;
src.w = 2 * BLOCK_W;
SDL_BlitSurface (up, &src, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
void
creatblock ()
{
int type = rand () % 19;
next.type = type;
next.img = block;
current.x = GAME_W / 2;
current.y = 4;
}
void
moveblock (int faceing)
{
int can = moveable (faceing);
if (can)
{
switch (faceing)
{
case -1:
current.x--;
break;
case 0:
current.y++;
break;
case 1:
current.x++;
break;
};
}
}
void
wait ()
{
Uint32 this_tick;
static Uint32 next_tick = 0;
this_tick = SDL_GetTicks ();
if (next_tick > this_tick)
SDL_Delay (next_tick - this_tick);
next_tick = this_tick + 1000 / FPS;
}
void
addscore (int num)
{
switch (num) //消掉的行数
{
case 1:
score += 100;
break;
case 2:
score += 300;
break;
case 3:
score += 700;
break;
case 4:
score += 1500;
break;
default:
break;
};
if (num >= 3)
Mix_PlayChannel (EXCELLENT_WAV, sounds[EXCELLENT_WAV], 0);
else
Mix_PlayChannel (EXPLODE_WAV, sounds[EXPLODE_WAV], 0);
}
void
shownum (int x, int y, int num_char, int num)
{
int a, i = num_char - 1;
int S[10] = { };
while (num != 0)
{
a = num % 10;
S[i--] = a;
num /= 10;
}
SDL_Rect src, dst;
for (i = 0; i < num_char; i++)
{
src.x = S[i] * FONT_WIDTH;
src.y = 1 * FONT_HIGHT;
src.w = FONT_WIDTH;
src.h = FONT_HIGHT;
dst.x = x + i * FONT_WIDTH;
dst.y = y;
dst.w = FONT_WIDTH;
dst.h = FONT_HIGHT;
SDL_BlitSurface (back, &dst, screen, &dst);
SDL_BlitSurface (font, &src, screen, &dst);
SDL_UpdateRects (screen, 1, &dst);
}
}
void
eraseline (int line)
{
int i, j;
for (j = line - 1; j > 0; j--)
for (i = 1; i < GAME_W + 1; i++)
gamestate[i][j + 1] = gamestate[i][j];
}
void
collision ()
{
int num = 0, i, j;
for (j = GAME_H - 1; j > 0; j--)
{
for (i = 1; i < GAME_W + 1; i++)
{
if (gamestate[i][j] == 0)
break;
}
if (i == GAME_W + 1)
{
num++;
eraseline (j++);
}
}
if (num != 0)
addscore (num);
}
void
rungame ()
{
SDL_Event event;
int point = 0;
Uint8 *key;
int run = 1, i, j, x, y, w = 0, s = 0;
int up = 0, left = 0, right = 0, tr = 10, tl = 10;
numupdates = 0;
score = 0;
drawframe ();
creatblock ();
current.type = next.type;
current.img = next.img;
creatblock ();
drawobject (next);
x = frame->w * 4 + GAME_W * BLOCK_W;
y = BLOCK_H * (GAME_H - 8);
showstring (x, y, "speed");
y = BLOCK_H * (GAME_H - 7);
shownum (x, y, 1, 11 - speed);
x = frame->w * 4 + GAME_W * BLOCK_W;
y = BLOCK_H * (GAME_H - 3);
showstring (x, y, "score");
x = frame->w * 4 + GAME_W * BLOCK_W;
y = 6 * BLOCK_H;
showstring (x, y, "next");
x = 2 * frame->w + GAME_W * BLOCK_W;
y = 4 * BLOCK_H;
showstring (x, y, "upper line");
x = frame->w * 4 + GAME_W * BLOCK_W;
y = BLOCK_H * (GAME_H - 2);
shownum (x, y, 6, score);
while (run)
{
wait ();
eraseobject (current);
drawframe ();
drawupline ();
point++;
if (point % (speed * (FPS / 10)) == 0)
moveblock (0);
if (point > MAXINT)
point -= MAXINT;
while (SDL_PollEvent (&event))
{
switch (event.type)
{
case SDL_QUIT:
return;
};
}
key = SDL_GetKeyState (NULL);
if (!w && key[SDLK_w])
speed--;
if (speed < 1)
speed = 1;
w = key[SDLK_w];
if (!s && key[SDLK_s])
speed++;
if (speed > 10)
speed = 10;
s = key[SDLK_s];
//
if (key[SDLK_LEFT])
tl--;
else
tl = 10;
if (tl <= 0 && key[SDLK_LEFT])
moveblock (-1);
if (tl > 0 && !left && key[SDLK_LEFT])
moveblock (-1);
left = key[SDLK_LEFT];
//
if (key[SDLK_RIGHT])
tr--;
else
tr = 10;
if (tr <= 0 && key[SDLK_RIGHT])
moveblock (1);
if (tr > 0 && !right && key[SDLK_RIGHT])
moveblock (1);
right = key[SDLK_RIGHT];
//
if (key[SDLK_SPACE])
moveblock (0);
//
if (!up && key[SDLK_UP])
Rotate ();
up = key[SDLK_UP];
//
drawobject (current);
updatescene ();
speed -= score / 10000;
if (speed < 1)
speed = 1;
else if (speed > 10)
speed = 10;
shownum (frame->w * 4 + GAME_W * BLOCK_W,
BLOCK_H * (GAME_H - 7), 2, 11 - speed);
if (atbottom ())
{
if (over ())
return;
Mix_PlayChannel (BOTTOM_WAV, sounds[BOTTOM_WAV], 0);
eraseobject (next);
for (i = 0; i < 4; i++)
{
x = current.x + SP[current.type].coor[i][0];
y = current.y - SP[current.type].coor[i][1];
gamestate[x][y] = 1;
}
collision ();
shownum (frame->w * 4 + GAME_W * BLOCK_W,
BLOCK_H * (GAME_H - 2), 6, score);
eraseobject (current);
updatescene ();
SDL_Rect dst;
for (j = GAME_H - 1; j > 0; j--)
for (i = 1; i < GAME_W + 1; i++)
{
dst.x = i * BLOCK_W - frame->w;
dst.y = j * BLOCK_H - frame->h;
if (gamestate[i][j])
{
SDL_BlitSurface
(block,
NULL, screen, &dst);
}
else
{
SDL_BlitSurface
(back,
&dst, screen, &dst);
}
SDL_UpdateRects (screen, 1, &dst);
}
current.type = next.type;
current.img = next.img;
creatblock ();
drawobject (next);
}
updatescene ();
}
}
int
main ()
{
init ();
LoadData ();
SDL_BlitSurface (back, NULL, screen, NULL);
SDL_Flip (screen);
numupdates = 0;
rungame ();
FreeData ();
}
阅读全文(2519) | 评论:9 | 复制链接
光栅图形显示模拟(2006-12-29 18:11:00)
为了学图形学方便,用SDL写了个光栅显示的模拟,
还花了几个下午来研究了下,主要就是坐标之间的
转换着实让人烦,开始写的一个因为烦透了,删了又重写过……
这个写得还算满意了,坐标之间的转换关系蛮方便地,
也可以从象素级别上刷写一张图象,作一堆杂七杂八的变换,
达到什么效果就看自己写的程序了……
这只是个学习的工具,自己写的图形程序可以直接用来试验,
没什么其它功能,就一个操作伪象素有点用……
呵呵,模拟的就是伪象素嘛……
//raster.h头文件
#include <SDL/SDL.h>
#include <stdlib.h>
#include <iostream>
#define SetR 100
#define SetG 255
#define SetB 255
#define FrameR 255
#define FrameG 0
#define FrameB 0
void init ();
void loop ();
void drawjay ();
void setpixel (int x, int y, Uint8 R = SetR, Uint8 G = SetG, Uint8 B = SetB);
void setpixel (int x, int y, Uint32 pixel);
void drawframe (int x, int y, Uint8 R = FrameR, Uint8 G = FrameG, Uint8 B =
FrameB);
void drawframe (int x, int y, Uint32 pixel);
int maxx ();
int minx ();
int maxy ();
int miny ();
//raster.cc程序文件
#include "raster.h"
#define HW 800 //hardware width
#define HH 600 //hardware hight
#define PIXEL_H 4 //minimum
#define PIXEL_W 4
#define OO 1 //是否用一到四象限坐标
#define CUTR 255 //切割颜色
#define CUTG 255
#define CUTB 255
#define OOR 255 //坐标线颜色
#define OOG 0
#define OOB 0
SDL_Surface *screen, *jay;
//对屏幕的象素级操作
void
putpixel (SDL_Surface * img, int x, int y, Uint32 pixel)
{
int bpp = img->format->BytesPerPixel;
Uint8 *p = (Uint8 *) img->pixels + y * img->pitch + x * bpp;
switch (bpp)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *) p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *) p = pixel;
break;
};
}
Uint32
returnpixel (SDL_Surface * img, int x, int y)
{
int bpp = img->format->BytesPerPixel;
Uint8 *p = (Uint8 *) img->pixels + y * img->pitch + x * bpp;
switch (bpp)
{
case 1:
return *p;
case 2:
return *(Uint16 *) p;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *) p;
default:
return 0;
};
}
void
drawooline () //画十字线坐标,只有打开四个象限(OO)才用到,
{
if (OO)
{
Uint32 pixel = SDL_MapRGB (screen->format, OOR,
OOG, OOB);
int i;
for (i = 0; i < HW; i++)
putpixel (screen, i, HH / 2, pixel);
for (i = 0; i < HH; i++)
putpixel (screen, HW / 2, i, pixel);
SDL_UpdateRect (screen, 0, HH / 2, HW, 1);
SDL_UpdateRect (screen, HW / 2, 0, 1, HH);
}
}
void
drawcut () //画屏幕切割线,如果只用到第一象限就不画十字线坐标了
{
int i, j;
Uint32 pixel = SDL_MapRGB (screen->format, CUTR,
CUTG, CUTB);
for (i = 0; i < HH; i++)
for (j = 0; j < HW; j++)
{
if (i % PIXEL_H != 0 && j % PIXEL_W == 0)
putpixel (screen, j, i, pixel);
else if (i % PIXEL_H == 0)
putpixel (screen, j, i, pixel);
}
SDL_ShowCursor (0);
SDL_WM_SetCaption ("Computer raster display emulation", "");
if (OO)
drawooline ();
SDL_Flip (screen);
}
void
init ()
{
if ((SDL_Init (SDL_INIT_VIDEO)) < 0)
fprintf (stderr, "init error\n");
atexit (SDL_Quit);
if ((screen =
SDL_SetVideoMode (HW, HH, 32,
SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
fprintf (stderr, "set video mode error\n");
drawcut ();
if ((jay = SDL_LoadBMP ("jay.bmp")) == NULL)
fprintf (stderr, "load jay error\n");
}
void
drawjay () //画图片(jay)
{
int i, j;
if (OO)
{
int mx = minx (), my = miny ();
for (i = mx; i <= maxx (); i++)
for (j = my; j <= maxy (); j++)
setpixel (i, maxy () - j - abs (my),
returnpixel (jay, i + abs (mx),
j + abs (my)));
}
else
{
for (i = minx (); i <= maxx (); i++)
for (j = miny (); j <= maxy (); j++)
setpixel (i, maxy () - j,
returnpixel (jay, i, j));
}
}
int
maxx () //伪象素系统的最大的X值,
{
if (OO)
return (HW - 1) / PIXEL_W - HW / 2 / PIXEL_W;
else
return (HW - 1) / PIXEL_W;
}
int
minx ()
{
if (OO)
return -HW / 2 / PIXEL_W;
else
return 0;
}
int
maxy ()
{
if (OO)
return (HH - 1) / PIXEL_H - HH / 2 / PIXEL_H;
else
return (HH - 1) / PIXEL_H;
}
int
miny ()
{
if (OO)
return -HH / 2 / PIXEL_H;
else
return 0;
}
//真实坐标系统到伪象素系统的坐标转换
void
changecoor (int a, int b, int &x, int &y)
{
if (a < 0 || a >= HW || b < 0 || b >= HH)
return;
if (OO)
{
int ox = HW / 2;
int oy = HH / 2;
x = a / PIXEL_W - ox / PIXEL_W;
y = (HH - 1 - b) / PIXEL_H - oy / PIXEL_H;
}
else
{
x = a / PIXEL_W;
y = (HH - 1 - b) / PIXEL_H;
}
}
//伪象素坐标系统到真实坐标的坐标转换
void
changebackcoor (int x, int y, int &a, int &b) //oo to sdl
{
if (x > maxx () || x < minx () || y > maxy () || y < miny ())
return;
if (OO)
{
a = HW / 2 + x * PIXEL_W;
b = HH / 2 - y * PIXEL_H;
}
else
{
a = x * PIXEL_W;
b = HH - y * PIXEL_H;
}
}
//画一个伪象素点的边框,鼠标移动到一个伪象素点上时有用
void
drawframe (int x, int y, Uint8 R, Uint8 G, Uint8 B) //oo坐标
{
if (x > maxx () || x < minx () || y > maxy () || y < miny ())
return;
Uint32 pixel = SDL_MapRGB (screen->format, R, G, B);
changebackcoor (x, y, x, y);
int i;
for (i = 1; i < PIXEL_W; i++)
{
putpixel (screen, x + i, y - 1, pixel);
putpixel (screen, x + i, y - PIXEL_H + 1, pixel);
}
for (i = 1; i < PIXEL_H; i++)
{
putpixel (screen, x + 1, y - i, pixel);
putpixel (screen, x + PIXEL_W - 1, y - i, pixel);
}
SDL_UpdateRect (screen, x + 1, y - PIXEL_H + 1, PIXEL_W - 1,
PIXEL_H - 1);
}
//重载一下
void
drawframe (int x, int y, Uint32 pixel)
{
if (x > maxx () || x < minx () || y > maxy () || y < miny ())
return;
changebackcoor (x, y, x, y);
int i;
for (i = 1; i < PIXEL_W; i++)
{
putpixel (screen, x + i, y - 1, pixel);
putpixel (screen, x + i, y - PIXEL_H + 1, pixel);
}
for (i = 1; i < PIXEL_H; i++)
{
putpixel (screen, x + 1, y - i, pixel);
putpixel (screen, x + PIXEL_W - 1, y - i, pixel);
}
SDL_UpdateRect (screen, x + 1, y - PIXEL_H + 1, PIXEL_W - 1,
PIXEL_H - 1);
}
//主loop
void
loop ()
{
SDL_Event event;
Uint32 oldpixel = SDL_MapRGB (screen->format, 0, 0, 0);
int run = 1, bx, by, oldx = minx () - 1, oldy = miny () - 1, x, y;
int tmpx, tmpy;
while (run)
{
SDL_Delay (50);
while (SDL_PollEvent (&event))
{
switch (event.type)
{
case SDL_QUIT:
run = 0;
break;
case SDL_MOUSEBUTTONDOWN:
changecoor (event.
button.x, event.button.y, bx, by);
fprintf (stdout, "X:%d\tY:%d\n", bx, by);
break;
};
}
SDL_GetMouseState (&x, &y);
changecoor (x, y, x, y);
if (oldx != x || oldy != y) //鼠标移动后的还原
drawframe (oldx, oldy, oldpixel);
changebackcoor (x, y, tmpx, tmpy);
oldpixel = returnpixel (screen, tmpx + 2, tmpy - 2);
drawframe (x, y);
oldx = x;
oldy = y;
}
}
//操作伪象素点
void
setpixel (int x, int y, Uint8 R, Uint8 G, Uint8 B)
{
if (x > maxx () || x < minx () || y > maxy () || y < miny ())
return;
changebackcoor (x, y, x, y);
Uint32 pixel = SDL_MapRGB (screen->format, R, G, B);
int i, j;
for (i = 1; i < PIXEL_W; i++)
for (j = 1; j < PIXEL_H; j++)
putpixel (screen, x + i, y - j, pixel);
SDL_UpdateRect (screen, x + 1, y - PIXEL_H + 1, PIXEL_W - 1,
PIXEL_H - 1);
}
void
setpixel (int x, int y, Uint32 pixel)
{
if (x > maxx () || x < minx () || y > maxy () || y < miny ())
return;
changebackcoor (x, y, x, y);
int i, j;
for (i = 1; i < PIXEL_W; i++)
for (j = 1; j < PIXEL_H; j++)
putpixel (screen, x + i, y - j, pixel);
SDL_UpdateRect (screen, x + 1, y - PIXEL_H + 1, PIXEL_W - 1,
PIXEL_H - 1);
}
阅读全文(1963) | 评论:2 | 复制链接
SDL 入门试验(2006-12-27 13:08:00)
一直想写图形方面的程序,又不想写窗口方面的,那种全是拖拉式控件,没什么
特别好玩地……,偶然间发现了SDL(Simple Directmedia Library)发现真是是我
想要地,呵呵,不像DirectX那样基于COM技术,我可不想为了写几个小程序就去
搞清烦透了的COM,最重要的是,我是LINUX系统,学COM没用场,呵呵……
最让人激动的是SDL竟然是跨平台的,WIN32下也可以用,这样,我在我的Gentoo
下写的程序完全就可以让别人在WIN32下编译运行了,真是PERFECT……
SDL是完全是C库,感觉蛮小地,很快就学会了……
只要会C,几乎一下午就可以写你自己的小游戏了(虽然这样,SDL算起来还是一个比较底层的库,你要自己控制所有的东西,一帧一帧的东西,你要全部自己来实现)……
虽然它是一个C库,但其它语言完全可以调用它……
下面是我在SDL网站上下的ALIENS游戏的自己重写,说我抄也无所谓了,
因为只要自己明白了其中的道理,都一样了(至少还花了一下午的写程序时间呀)……
算是SDL入门作品了(程序在Gentoo Linux 2006.1下SDL1.2.9编译运行通过,WIN32下没试,
没功夫去配置WIN下的SDL环境,网上很多这样的东西)
/***************************************************************************
* Copyright (C) 2006 by xhh *
* huyinlin@XHH *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/*对ALIENS游戏的重写--初学SDL*/
#include <iostream>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h> //不是SDL标准包,但可很方便地操纵声频,几乎快成标准包了
using namespace std;
const int MAXALIENS = 50;
const int MAXSHOTS = 4;
const int MAXUPDATES = 2 * (MAXSHOTS + MAXALIENS + 1);
const int FPS = 25; //帧速
const int PLAYER_SPEED = 5;
const int SHOT_SPEED = 8;
const int ALIEN_SPEED = 8;
const int EXPLODE_TIME = 4;
enum
{
MUSIC_WAV,
SHOT_WAV,
EXPLODE_WAV,
NUM_WAVES
};
Mix_Chunk *sounds[NUM_WAVES]; //让枚举成为Index
SDL_Surface *screen, *back; //屏幕和背景
typedef struct
{
int x, y; //横纵坐标
int alive; //生存状态
int faceing; //方向
SDL_Surface *img;
} object;
object me; //玩家
object aliens[MAXALIENS]; //目标
object shots[MAXSHOTS]; //子弹
object explosion[MAXALIENS + 1];
SDL_Rect src[MAXUPDATES], dst[MAXUPDATES];
//各个分散的要更新的区域
int numupdates; //要更新的区域数目
int reloading;
typedef struct
{
SDL_Surface *img;
SDL_Rect *src, *dst;
} blit;
//为了Blit方便,把源,目的都打在一个结构中
blit blits[MAXUPDATES];
SDL_Surface *
LoadImg (const char *name) //装入图象
{
SDL_Surface *tmp, *ok;
if ((tmp = SDL_LoadBMP (name)) == NULL)
{
fprintf (stderr, "load %s error", name);
return NULL;
}
SDL_SetColorKey (tmp, SDL_SRCCOLORKEY | SDL_RLEACCEL,
*(Uint8 *) tmp->pixels);
//让边上透明,图象就不会是一块块的了
ok = SDL_DisplayFormat (tmp);
SDL_FreeSurface (tmp);
return ok;
}
void
LoadData ()
{
int i;
me.img = LoadImg ("player.bmp");
aliens[0].img = LoadImg ("alien.bmp");
shots[0].img = LoadImg ("shot.bmp");
explosion[0].img = LoadImg ("explosion.bmp");
back = LoadImg ("back.bmp");
sounds[MUSIC_WAV] = Mix_LoadWAV ("music.wav");
sounds[SHOT_WAV] = Mix_LoadWAV ("shot.wav");
sounds[EXPLODE_WAV] = Mix_LoadWAV ("explode.wav");
for (i = 1; i < MAXALIENS; i++) //所用的图片一样地
{
aliens[i].img = aliens[0].img;
}
for (i = 1; i < MAXSHOTS; i++)
{
shots[i].img = shots[0].img;
}
for (i = 1; i < MAXALIENS + 1; i++)
{
explosion[i].img = explosion[0].img;
}
for (i = 0; i < MAXUPDATES; i++) //Blit梆定
{
blits[i].src = &src[i];
blits[i].dst = &dst[i];
}
}
void
FreeData ()
{
SDL_FreeSurface (me.img);
SDL_FreeSurface (aliens[0].img);
SDL_FreeSurface (shots[0].img);
SDL_FreeSurface (explosion[0].img);
}
void
drawobject (object * sprite)
//只是给出了要画物体的坐标,图象信息,真正的BLIT在Updatesene()中
{
blit *update;
update = &blits[numupdates++]; //之后交给Updatescene()去Blit;
update->img = sprite->img;
update->src->x = update->src->y = 0;
update->src->w = sprite->img->w;
update->src->h = sprite->img->h;
update->dst->x = sprite->x;
update->dst->y = sprite->y;
//这两行其实只有UpdateRect才用到;Blit无用
update->dst->w = sprite->img->w;
update->dst->h = sprite->img->h;
}
void
eraseobject (object * sprite) //用背景盖掉object
{
blit *update;
update = &blits[numupdates++];
update->img = back;
update->src->x = sprite->x;
update->src->y = sprite->y;
update->src->w = sprite->img->w;
update->src->h = sprite->img->h;
update->dst->x = sprite->x;
update->dst->y = sprite->y;
update->dst->w = sprite->img->w;
update->dst->h = sprite->img->h;
}
void
wait ()
{
static Uint32 next_tick = 0;
Uint32 this_tick;
this_tick = SDL_GetTicks ();
if (this_tick < next_tick)
SDL_Delay (next_tick - this_tick);
next_tick = this_tick + 1000 / FPS;
}
void
Updatescene ()
{
int i;
for (i = 0; i < numupdates; i++)
{
SDL_BlitSurface (blits[i].img, blits[i].src, screen,
blits[i].dst);
}
SDL_UpdateRects (screen, numupdates, dst);
//BLit后的更新屏幕
numupdates = 0; //全部更新完毕,重新计数
}
void
creatalien ()
{
int i = 0;
for (i = 0; i < MAXALIENS; i++)
{
if (!aliens[i].alive)
break;
}
if (i == MAXALIENS)
return;
do
{
aliens[i].faceing = (rand () % 3) - 1;
}
while (aliens[i].faceing == 0); //方向就只有 1 和-1了
aliens[i].y = 0;
if (aliens[i].faceing < 0)
aliens[i].x = screen->w - aliens[i].img->w - 1;
else
aliens[i].x = 0;
aliens[i].alive = 1;
}
bool
collision (object * sprite1, object * sprite2) //测试碰撞
{
if ((sprite1->y >= (sprite2->y + sprite2->img->h)) ||
(sprite1->x >= (sprite2->x + sprite2->img->w)) ||
(sprite2->y >= (sprite1->y + sprite1->img->h)) ||
(sprite2->x >= (sprite1->x + sprite1->img->w)))
{
return (false);
}
return (true);
}
void
rungame ()
{
int j, i;
SDL_Event event;
Uint8 *keys;
numupdates = 0;
SDL_BlitSurface (back, NULL, screen, NULL);
SDL_UpdateRect (screen, 0, 0, 0, 0);
me.x = (screen->w - me.img->w) / 2;
me.y = (screen->h - me.img->h) - 1;
me.alive = 1;
me.faceing = 0;
for (i = 0; i < MAXALIENS; i++)
aliens[i].alive = 0;
for (i = 0; i < MAXSHOTS; i++)
shots[i].alive = 0;
drawobject (&me);
creatalien ();
drawobject (&aliens[0]);
Updatescene ();
while (me.alive)
{
wait (); //一帧一帧地运行
while (SDL_PollEvent (&event))
if (event.type == SDL_QUIT)
return;
keys = SDL_GetKeyState (NULL);
if (keys[SDLK_ESCAPE])
return;
//在一帧里全部要更新
for (i = 0; i < MAXALIENS; i++)
if (aliens[i].alive)
eraseobject (&aliens[i]);
for (i = 0; i < MAXSHOTS; i++)
if (shots[i].alive)
eraseobject (&shots[i]);
for (i = 0; i < MAXALIENS + 1; i++)
if (explosion[i].alive)
eraseobject (&explosion[i]);
eraseobject (&me);
//explosion计时
for (i = 0; i < MAXALIENS + 1; i++)
{
if (explosion[i].alive)
explosion[i].alive--;
}
//新产生一个aliens
if ((rand () % FPS) == 0) //大约过FPS帧才产生一个,即一秒一个
creatalien ();
//产生shot
if (!reloading)
{
if (keys[SDLK_SPACE] == SDL_PRESSED)
{
for (i = 0; i < MAXSHOTS; i++)
if (!shots[i].alive)
break;
if (i != MAXSHOTS)
{
shots[i].x =
me.x + (me.img->w -
shots[i].img->w) / 2;
shots[i].y = me.y - shots[i].img->h;
shots[i].alive = 1;
Mix_PlayChannel (SHOT_WAV,
sounds[SHOT_WAV], 0);
}
}
}
reloading = (keys[SDLK_SPACE] == SDL_PRESSED);
//移动自己
me.faceing = 0;
if (keys[SDLK_RIGHT])
me.faceing++;
if (keys[SDLK_LEFT])
me.faceing--;
me.x += me.faceing * PLAYER_SPEED;
if (me.x < 0)
me.x = 0;
if (me.x > screen->w - me.img->w)
me.x = screen->w - me.img->w - 1;
//移动aliens
for (i = 0; i < MAXALIENS; i++)
{
if (aliens[i].alive)
{
aliens[i].x +=
aliens[i].faceing * ALIEN_SPEED;
if (aliens[i].x < 0)
{
aliens[i].x = 0;
aliens[i].faceing = 1;
aliens[i].y += aliens[i].img->h;
}
if (aliens[i].x >=
screen->w - aliens[i].img->w)
{
aliens[i].x =
screen->w - aliens[i].img->w -
1;
aliens[i].faceing = -1;
aliens[i].y += aliens[i].img->h;
}
}
}
//移动shot
for (i = 0; i < MAXSHOTS; i++)
{
if (shots[i].alive)
{
shots[i].y -= SHOT_SPEED;
if (shots[i].y < 0)
shots[i].alive = 0;
}
}
//测试碰撞
for (i = 0; i < MAXSHOTS; i++)
for (j = 0; j < MAXALIENS; j++)
{
if (shots[i].alive && aliens[j].alive
&& collision (&shots[i], &aliens[j]))
{
shots[i].alive = 0;
aliens[j].alive = 0;
explosion[j].x = aliens[j].x;
explosion[j].y = aliens[j].y;
explosion[j].alive = EXPLODE_TIME;
Mix_PlayChannel (EXPLODE_WAV,
sounds[EXPLODE_WAV],
0);
}
}
for (i = 0; i < MAXALIENS; i++)
{
if (aliens[i].alive && me.alive
&& collision (&me, &aliens[i]))
{
aliens[i].alive = 0;
me.alive = 0;
explosion[i].x = aliens[i].x;
explosion[i].y = aliens[i].y;
explosion[i].alive = EXPLODE_TIME;
explosion[MAXALIENS].x = me.x;
explosion[MAXALIENS].y = me.y;
explosion[MAXALIENS].alive = EXPLODE_TIME;
Mix_PlayChannel (EXPLODE_WAV,
sounds[EXPLODE_WAV], 0);
}
}
//draw所有的东东
if (me.alive)
drawobject (&me);
for (i = 0; i < MAXALIENS; i++)
if (aliens[i].alive)
drawobject (&aliens[i]);
for (i = 0; i < MAXSHOTS; i++)
if (shots[i].alive)
drawobject (&shots[i]);
for (i = 0; i < MAXALIENS + 1; i++)
if (explosion[i].alive)
drawobject (&explosion[i]);
Updatescene ();
}
while (Mix_Playing (EXPLODE_WAV))
wait ();
Mix_HaltChannel (-1);
}
int
main (int argc, char *argv[])
{
if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) //初始化
cout << "init error" << endl;
atexit (SDL_Quit);
if ((screen =
SDL_SetVideoMode (640, 480, 32,
SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
cout << "init video mode error" << endl;
SDL_WM_SetCaption ("aliens", "aliens");
/* 找开音频 */
if (Mix_OpenAudio (11025, AUDIO_U8, 1, 512) < 0)
{
fprintf (stderr,
"Warning: Couldn't set 11025 Hz 8-bit audio\n- Reason: %s\n",
SDL_GetError ());
}
srand (time (NULL));
LoadData ();
rungame ();
FreeData ();
Mix_CloseAudio ();
}
程序效果:
阅读全文(2336) | 评论:3 | 复制链接




最新评论