游戏中不可缺少动画. 在之前的图形界面实现中, 程序是基于用户输入事件驱动的, 除非使用单独的线程, 否则无法实现动画. 所以, 把程序改为基于时间驱动, 并使用精灵(Sprite)的概念. 精灵包含一个或者多个图像资源(帧), 以及其它状态信息. 这时, 使用C++来开发会更接近这种抽象.
主循环每隔一个时钟周期轮询所有的精灵, 获取它们的当前图像帧, 并blit到屏幕上页面. 也可以让它们自己blit到屏幕上面.
这就要求, 所有的逻辑处理都必须由开发者分解成流水线, 流水线的每一个片段都能在一个时钟周期内完成, 而且所有逻辑的流水线也必须能在一个时钟周期内完成.
while(1){
foreach(sprites as s){
s->tick();
}
others->tick();
sleep();
}
Written by benegg
at 2009-06-03 17:31:44 | tags: 游戏开发, 连连看开发实践
在前一篇日志(连连看游戏开发实践(1) - 算法)中, 已经做了一个命令行下的文字界面的连连看. 这一回, 我要给它加一个图形界面外壳, 将数字转换为图片显示, 用鼠标点击代替输入文字坐标.
程序运行界面如下:

Continue reading »
Written by benegg
at 2009-06-01 22:57:22 | tags: libsdl, SDL, 游戏开发, 连连看开发实践
从本篇文章开始, 我将写一序列游戏开发的文章, 讲述做一个连连看游戏的例子, 既锻炼自己, 也帮助别人. 最终, 游戏会加上网络功能.
连连看算法

如图, 为了找出A, B两点之间的连接路径, 首先过这两点作4条线段, 线段的两端便是地图边缘, 两条与横坐标轴平行, 另两条与纵坐标轴平行. 先考虑与横坐标轴平行的两条.
在两条线段上各取一点C和D, 此两点处在一条与纵坐标轴平行的直线上. 那么, ACDB这条路径便是一条可能的A, B两点的连通路径.
Continue reading »
Written by benegg
at 2009-05-31 13:41:30 | tags: 游戏开发, 连连看开发实践
SDL(Simple DirectMedia Layer)是一套很底层的图形API, 支持Linux, unix, *BSD, MacOS, Win32 and BeOS等平台. 由曾任暴雪公司lead software engineer的Sam Lantinga于1998年创建.
下面, 我在Linux用C语言和SDL编写一个移动图像的程序. 移动图像是2D游戏的基础. 因为SDL也支持Windows, 所以在cygwin下可直接编译运行.
首先. 你需要安装SDL, 也就是下面的包 libsdl, libsdl-dev, libsdl-image, libsdl-image-dev. libsdl-image是一套操作图形文件的的库, 使用它, 你只需要一个函数就能把png, jpg, bmp, gif等文件读入内存, 而且支持png的透明键.
下面是程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
| //author: ideawu.net
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#define TICK_INTERVAL 15
int main(int argc, char *argv[]){
SDL_Surface *screen;
SDL_Surface *image;
SDL_Event event;
SDL_Rect r = {0,0,0,0};
int x=0,y=0;
//使用的图像文件名, 放在当前目录下. 你可以使用png,jpg,bmp,等格式, SDL支持它们.
char *file_name = "fish.png";
int timepass=0, timeold=0;
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf("Could not initializing SDL: %s.\n",SDL_GetError());
exit(-1);
}
atexit(SDL_Quit);
screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
if(screen == NULL){
fprintf(stderr, "Couldn't set 800x600x32 video mode: %s\n", SDL_GetError());
exit(1);
}
image = IMG_Load(file_name);
if (image == NULL) {
fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());
return 1;
}
while(SDL_WaitEvent(&event) >= 0){
switch(event.type){
case SDL_MOUSEMOTION:
x = event.motion.x; y = event.motion.y;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym){
case SDLK_UP:
y -= 4;
break;
case SDLK_DOWN:
y += 4;
break;
case SDLK_LEFT:
x -= 4;
break;
case SDLK_RIGHT:
x += 4;
break;
}
break;
case SDL_QUIT:
exit(0);
break;
}
if(x < -image->w + 2) x = -image->w + 2;
if(y < -image->h + 2) y = -image->h + 2;
if(x > screen->w + image->w - 2) x = screen->w + image->w - 2;
if(y > screen->h + image->h - 2) y = screen->h + image->h - 2;
r.x = x;
r.y = y;
timeold = SDL_GetTicks();
SDL_FillRect(screen, NULL, 0);
if(SDL_BlitSurface(image, NULL, screen, &r) < 0)
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
SDL_Flip(screen);
timepass = SDL_GetTicks() - timeold;
//printf("%d ", timepass);
if(timepass < TICK_INTERVAL){
//ideawu.net: SDL_Delay(TICK_INTERVAL - timepass);
}
}
return 1;
} |
使用命令: gcc filename.c -lSDL_image -lSDL 编译. 然后 ./a.out 运行, 确保当前目录下有一个名为 fish.png的文件.
Written by benegg
at 2009-05-12 14:14:56 | tags: C语言, libsdl, SDL, 游戏编程
|
|
Recent Comments