铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 4841|回复: 18

[其他] 达摩堂迎新春活动——“大家都是伸手党”

[复制链接]
发表于 2010-2-12 13:29 | 显示全部楼层 |阅读模式

马上注册,结交更多侠友!

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x
活动时间:即日起至正月十五(2010年2月28日)
活动细则:参与者可以针对金群任一MOD平台编写事件、脚本或源码提供任何一个他人可以直接使用的小系统、小功能、小指令并给出用法。不求技术高深,但求有一定实用性。
本活动贴禁水,凡回复中未提供事件、脚本或源码者一律视为灌水,所有灌水贴均删帖处理,情节恶劣者扣分。
活动奖励:凡按要求参与活动者均可得到至少10积分的参与分,功能强大、算法先进及构思巧妙者均可有额外的加分。
请大家踊跃参加,谢谢!
示例(作者黄顺坤):

;Kdefnum=1118
  0                              ;  0(0)::空语句(清屏)
  50 5 0 0 0 0 0 0               ;  50(32):全部变量清零
  50 0 0 0 0 0 0 0               ;  50(32):变量赋值 [X0]=0
  50 0 1 100 0 0 0 0             ;  50(32):变量赋值 [X1]=100
  50 8 0 3270 100 0 0 0          ;  50(32):读对话到字符串  Str[X100]=talk(3270) [这里改成你的问话Y/N]
;:Label0
  50 32 0 1 6 0 0 0              ;  50(32):修改下一条指令 下一条指令参数6=[X1]
  50 25 3 0 -30601 5 100 0       ;  50(32):保存给定地址数据 [5-8877+[X0]]=[X100](Int)
  50 3 0 0 0 0 2 0               ;  50(32):四则运算 [X0]=[X0]+2
  50 3 0 0 1 1 1 0               ;  50(32):四则运算 [X1]=[X1]+1
  50 4 0 0 0 21 0 0              ;  50(32):变量判断 If[X0]<21 then JMP=0 else JMP=1
  36 256 -44 0                   ;  36(24):跳转变量JMP是否为0是则跳转到:Label0
  11 1 0                         ;  11(B):是否住宿是则跳转到:Label1
  0                              ;  0(0)::空语句(清屏)
;:Label1
  -1                             ;  -1(FFFF):事件结束
使用说明:在对话3270(使用者可以自行修改事件中的对话编号)内保存一句问话,限11个汉字或全角字符(多余的字符将被舍去),使用后游戏中的是否住宿文字将被对话3270中设置的文字替代,本事件仅适用于DOS版。


[发帖际遇]: 凶神恶煞看到神仙姐姐玉像,叩了一千个响头,蒲团被磕破了,发现里面有银两2。
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 14:28 | 显示全部楼层
  1. function magic212(bnum, mnum, i, level: integer): boolean;
  2. var
  3.   power: array[0..9] of integer;
  4.   rnum, jiji, a, rnum2, b, c, d: integer;
  5.   str: widestring;
  6. begin
  7.   rnum := brole[bnum].rnum;
  8.   jiji := 0;
  9.   for a := 0 to 9 do
  10.     begin
  11.       power[a] := jiji;
  12.       jiji := jiji + 10;
  13.     end;
  14.   calcanselect(bnum, 1);
  15.   if selectaim(bnum, 1) then
  16.     begin
  17.       for a := 0 to broleamount - 1 do
  18.         begin
  19.           if (brole[a].X = ax) and (brole[a].Y = ay) and (brole[a].Team <>
  20.             brole[bnum].Team) and (brole[a].Dead = 0) then
  21.             begin
  22.               Rrole[rnum].MagLevel[i] := Rrole[rnum].MagLevel[i] + random(2) +
  23.                 1;
  24.               SetAminationPosition(Rmagic[mnum].AttAreaType,
  25.                 Rmagic[mnum].AttDistance[level - 1]);
  26.               if Rrole[rnum].MagLevel[i] > 999 then
  27.                 Rrole[rnum].MagLevel[i] := 999;
  28.               ShowMagicName(mnum);
  29.               instruct_1(11796, rnum, 0);
  30.               instruct_0;
  31.               PlayActionAmination(bnum, Rmagic[mnum].MagicType);
  32.               PlayMagicAmination(bnum, Rmagic[mnum].AmiNum);
  33.               c := 0;
  34.               jiji := random(100);
  35.               if jiji < power[level - 1] then
  36.                 begin
  37.                   rnum2 := brole[a].rnum;
  38.                   for b := 0 to 3 do
  39.                     begin
  40.                       if rrole[rnum2].TakingItemAmount[b] >= 0 then
  41.                         c := c + 1;
  42.                     end;
  43.                   if c >= 1 then
  44.                     begin
  45.                       jiji := random(c);
  46.                       d := rrole[rnum2].TakingItem[c];
  47.                       rrole[rnum2].TakingItemAmount[c] :=
  48.                         rrole[rnum2].TakingItemAmount[c]
  49.                         - 1;
  50.                       str := ' 偷竊成功';
  51.                       drawtextwithrect(@str[1], 80, 30, 205, colcolor($66),
  52.                         colcolor($64));
  53.                       waitanykey;
  54.                       redraw;
  55.                       instruct_2(d, 1);
  56.                     end
  57.                   else
  58.                     begin
  59.                       str := ' 無物可偷';
  60.                       drawtextwithrect(@str[1], 80, 30, 205, colcolor($66),
  61.                         colcolor($64));
  62.                       waitanykey;
  63.                       redraw;
  64.                     end;
  65.                 end
  66.               else
  67.                 begin
  68.                   str := ' 偷窃失败';
  69.                   drawtextwithrect(@str[1], 80, 30, 205, colcolor($66),
  70.                     colcolor($64));
  71.                   waitanykey;
  72.                   redraw;
  73.                 end;
  74.               result := true;
  75.               exit;
  76.             end;
  77.         end;
  78.     end;
  79.   result := false;
  80. end;
复制代码
我看了看手边也没有什么好的事件了。(原因:从有了复刻版后再没碰过50指令了。)
也只好把我做的偷东西武功贴上来了,并不像乱来大师写的可以偷装备,我本身认为头装备太逆天了。
我的技术不好,请大家不要鄙视我。

p/s:只为了参与活动,别无他求。

评分

参与人数 1声望 +20 收起 理由
凶神恶煞 + 20 第一个响应活动的!

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 16:12 | 显示全部楼层
支持下凶神

--[[走路时,遇到障碍物会自动拐弯]]--
前些天晚老dos游戏发现,这游戏人物行走时,遇到障碍物人物会拐弯,所以也给金群做了个
将以下代码复制进jymodify.lua
然后修改一下jymain里的Game_SMap()和Game_MMap()
修改的内容很简单,都是在读键值后加上一句direct=newdirect(direct)即可
  1. function newdirect(oldd)
  2.         if oldd==-1 then
  3.                 return -1
  4.         end
  5.         local x,y
  6.         if JY.Status==GAME_SMAP then
  7.                 x,y=JY.Base["人X1"],JY.Base["人Y1"]
  8.         elseif JY.Status~=GAME_MMAP then
  9.                 x,y=JY.Base["人X"],JY.Base["人Y"]
  10.         else
  11.                 return -1
  12.         end
  13.         local function CanMove(od1,od2)  --判断某点是否可以到达,od1
  14.                 local nx,ny
  15.                 nx=x+CC.DirectX[od1+1]
  16.                 ny=y+CC.DirectY[od1+1]
  17.                 if od2~=nil then
  18.                         nx=nx+CC.DirectX[od2+1]
  19.                         ny=ny+CC.DirectY[od2+1]
  20.                 end
  21.                 if JY.Status==GAME_SMAP then
  22.                         if SceneCanPass(nx,ny) then
  23.                                 return true
  24.                         end
  25.                 else
  26.                         if (lib.GetMMap(nx,ny,3)==0 and lib.GetMMap(nx,ny,4)==0) or CanEnterScene(nx,ny)~=-1 then
  27.                                 return true
  28.                         end
  29.                 end
  30.                 return false
  31.         end
  32.         local d1,d2,d3
  33.         d1=oldd
  34.         if oldd==0 then
  35.                 d2=1
  36.                 d3=2
  37.         elseif oldd==1 then
  38.                 d2=3
  39.                 d3=0
  40.         elseif oldd==2 then
  41.                 d2=0
  42.                 d3=3
  43.         elseif oldd==3 then
  44.                 d2=2
  45.                 d3=1
  46.         end
  47.         if CanMove(d1) then
  48.                 return d1
  49.         elseif CanMove(d2) and CanMove(d1,d2) then--左边以前左前方点
  50.                 return d2
  51.         elseif CanMove(d3) and CanMove(d1,d3) then--右边以及右前方点
  52.                 return d3
  53.         else
  54.                 return d1
  55.         end
  56. end
复制代码
[发帖际遇]: jy02785317卖下一个mod的制作人绝密采访稿,狂赚银两18。

评分

参与人数 1声望 +20 收起 理由
凶神恶煞 + 20 通用性很强,赞!

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 16:16 | 显示全部楼层

战斗地图使用当前场景地图

战斗地图使用当前场景地图

在指令
  1.     WarLoadMap(WAR.Data["地图"]);       --加载战斗地图
复制代码
后加上以下代码
  1.         for i=0,63 do
  2.                 for j=0,63 do
  3.                         lib.SetWarMap(i,j,0,lib.GetS(JY.SubScene,i,j,0))
  4.                         lib.SetWarMap(i,j,1,lib.GetS(JY.SubScene,i,j,1))
  5.                 end
  6.         end
复制代码
这样就可以了
当然还会有一些几个问题
1少贴图,smp和wmp的贴图不一致
2战斗场景无法显示出建筑层海拔,所以有些显示不正确,不过在一些海拔不明显的场景,倒是没什么问题

评分

参与人数 1声望 +12 收起 理由
凶神恶煞 + 12 想法很好,现在的做法貌似都是复制贴图

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 16:22 | 显示全部楼层

将smp的贴图复制到wmp

这个工具是为了解决上楼的问题而写的
早就写了,不过因为被某人bs一直没有发
确实,很简单的工具啦,希望有人能制作更好的,我这个也只能将就着用

需要提供smp,sdx,wmp,wdx
然后输入起始贴图编号和结束贴图编号
如果是从smp到wmp的话,建议起始编号0,结束编号2499(?这个想不起来了,也或许是2500)

当然你可以从从其他文件复制贴图到其他文件里,不一定非要是smp wmp  当然格式必须是一样的

[发帖际遇]: jy02785317偷看武当弟子练功,习得梯云纵,增加声望1。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 1声望 +20 收起 理由
凶神恶煞 + 20 感谢分享!

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 17:28 | 显示全部楼层
老衲也骗骗分~~

这个是战斗中选择目标功能的修改

新增功能:
移动上下左右经过某人物,自动显示其简单状态(不需按回车等)
移动到屏幕边沿时(一定格数,超出视野时),自动调整战场,也就是说只要范围够大,现在可以看遍整个战场了~

应该是大众功能~
  1. //选择目标

  2. function SelectAim(bnum, step: integer): boolean;
  3. var
  4.   Axp, Ayp, i: integer;
  5. begin
  6.   result := false;
  7.   SDL_EnableKeyRepeat(50, 30);
  8.   Ax := Bx;
  9.   Ay := By;
  10.   DrawBFieldWithCursor(step);
  11.   if (bfield[2, Ax, Ay] >= 0) then     //坐标上人物非空,显示其状态
  12.     ShowSimpleStatus(Brole[bfield[2, Ax, Ay]].rnum,30,30);

  13.   sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  14.   while (SDL_WaitEvent(@event) >= 0) do
  15.   begin
  16.     case event.type_ of
  17.       SDL_QUITEV:

  18.         if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then Quit;
  19.       SDL_KEYDOWN:
  20.         begin
  21.           if (event.key.keysym.sym = sdlk_left) then
  22.           begin
  23.             Ay := Ay - 1;
  24.             if Ay < 0 then Ay := 0;
  25.             if (abs(Ax - Bx) + abs(Ay - By) > step) or (Bfield[3, Ax, Ay] <> 0) then Ay := Ay + 1;
  26.             if (abs(Ax - Bx) + abs(Ay - By) > 10) then
  27.             begin
  28.               By := By-1;
  29.               if By < 0 then
  30.                 By := 0;
  31.             end;
  32.             DrawBFieldWithCursor(step);
  33.             if (bfield[2, Ax, Ay] >= 0) then     //坐标上人物非空,显示其状态
  34.               ShowSimpleStatus(Brole[bfield[2, Ax, Ay]].rnum, 30, 30);
  35.             sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  36.           end;
  37.           if (event.key.keysym.sym = sdlk_right) then
  38.           begin
  39.             Ay := Ay + 1;
  40.             if Ay > 63 then Ay := 63;
  41.             if (abs(Ax - Bx) + abs(Ay - By) > step) or (Bfield[3, Ax, Ay] <> 0) then Ay := Ay - 1;
  42.             if (abs(Ax - Bx) + abs(Ay - By) > 10) then By := By+1;
  43.             DrawBFieldWithCursor(step);
  44.             if (bfield[2, Ax, Ay] >= 0) then     //坐标上人物非空,显示其状态
  45.               ShowSimpleStatus(Brole[bfield[2, Ax, Ay]].rnum, 30, 30);
  46.             sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  47.           end;
  48.           if (event.key.keysym.sym = sdlk_down) then
  49.           begin
  50.             Ax := Ax + 1;
  51.             if Ax > 63 then Ax := 63;
  52.             if (abs(Ax - Bx) + abs(Ay - By) > step) or (Bfield[3, Ax, Ay] <> 0) then Ax := Ax - 1;
  53.             if (abs(Ax - Bx) + abs(Ay - By) > 10) then Bx := Bx+1;
  54.             DrawBFieldWithCursor(step);
  55.             if (bfield[2, Ax, Ay] >= 0) then     //坐标上人物非空,显示其状态
  56.               ShowSimpleStatus(Brole[bfield[2, Ax, Ay]].rnum, 30, 30);
  57.             sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  58.           end;
  59.           if (event.key.keysym.sym = sdlk_up) then
  60.           begin
  61.             Ax := Ax - 1;
  62.             if Ax < 0 then Ax := 0;
  63.             if (abs(Ax - Bx) + abs(Ay - By) > step) or (Bfield[3, Ax, Ay] <> 0) then Ax := Ax + 1;
  64.             if (abs(Ax - Bx) + abs(Ay - By) > 10) then Bx := Bx-1;
  65.             DrawBFieldWithCursor(step);
  66.             if (bfield[2, Ax, Ay] >= 0) then     //坐标上人物非空,显示其状态
  67.               ShowSimpleStatus(Brole[bfield[2, Ax, Ay]].rnum, 30, 30);
  68.             sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  69.           end;
  70.         end;
  71.       SDL_KEYUP:
  72.         begin
  73.           if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
  74.           begin
  75.             result := true;
  76.             x50[28927] := 1;
  77.             break;
  78.           end;
  79.           if (event.key.keysym.sym = sdlk_escape) then
  80.           begin
  81.             result := false;
  82.             x50[28927] := 0;
  83.             break;
  84.           end;
  85.         end;
  86.       SDL_MOUSEBUTTONUP:
  87.         begin
  88.           if (event.button.button = sdl_button_left) then
  89.           begin
  90.             result := true;
  91.             break;
  92.           end;
  93.           if (event.button.button = sdl_button_right) then
  94.           begin
  95.             result := false;
  96.             break;
  97.           end;
  98.         end;
  99.       SDL_MOUSEMOTION:
  100.         begin
  101.           Axp := (-event.button.x + CENTER_x + 2 * event.button.y - 2 * CENTER_y + 36) div 72 + Bx;
  102.           Ayp := (event.button.x - CENTER_x + 2 * event.button.y - 2 * CENTER_y + 36) div 72 + By;
  103.           if (abs(Axp - Bx) + abs(Ayp - By) <= step) and (Bfield[3, Axp, Ayp] = 0) then
  104.           begin
  105.             Ax := Axp;
  106.             Ay := Ayp;
  107.             //if (abs(Axp - Bx) > 10) then Bx = Bx+1;  or
  108.             //(abs(Ayp - By) > 10)
  109.             DrawBFieldWithCursor(step);
  110.             if (bfield[2, Ax, Ay] >= 0) then     //坐标上人物非空,显示其状态
  111.               ShowSimpleStatus(Brole[bfield[2, Ax, Ay]].rnum, 30, 30);
  112.             sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  113.           end;
  114.         end;
  115.     end; //end case
  116.     SDL_Delay(20);
  117.     event.key.keysym.sym := 0;
  118.   end;   //end while
  119.   Bx := brole[bnum].X;
  120.   By := brole[bnum].Y;


  121. end;
复制代码
[发帖际遇]: 老衲法号乱来跟踪成昆进入明教密道,结果:奋勇救小昭脱险,得到小昭感谢银两5。


[ 本帖最后由 老衲法号乱来 于 2010-2-12 17:34 编辑 ]

评分

参与人数 1声望 +25 收起 理由
凶神恶煞 + 25 甚为人性化,实用!

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 17:51 | 显示全部楼层
画带半透明的rle8图像,其他子程对此封装

要玩半透明图像显示的请拿去~由于要计算,效率肯定比原来要低的~~供有需要的朋友使用
  1. //画带alphe的rle8图象

  2. procedure DrawRLE8WithAlphe(num, px, py: integer; Pidx: Pinteger; Ppic: PByte; RectArea: TRect; Image: PChar; alphe, shadow: integer);
  3. var
  4.   w, h, xs, ys: smallint;
  5.   offset, length, p: integer;
  6.   l, l1, ix, iy: smallint;
  7.   i1, i2: integer;
  8.   pix, pix1, pix2, pix3, pix4, color1, color2, color3, color4, colorin: Uint32;
  9. begin

  10.   if num = 0 then
  11.     offset := 0
  12.   else
  13.   begin
  14.     inc(Pidx, num - 1);
  15.     offset := Pidx^;
  16.   end;

  17.   Inc(Ppic, offset);
  18.   w := Psmallint((Ppic))^;
  19.   Inc(Ppic, 2);
  20.   h := Psmallint((Ppic))^;
  21.   Inc(Ppic, 2);
  22.   xs := Psmallint((Ppic))^;
  23.   Inc(Ppic, 2);
  24.   ys := Psmallint((Ppic))^;
  25.   Inc(Ppic, 2);
  26.   if JudgeInScreen(px, py, w, h, xs, ys, RectArea.x, RectArea.y, RectArea.w, RectArea.h) then
  27.   begin
  28.     for iy := 1 to h do
  29.     begin
  30.       l := Ppic^;
  31.       inc(Ppic, 1);
  32.       w := 1;
  33.       p := 0;
  34.       for ix := 1 to l do
  35.       begin
  36.         l1 := Ppic^;
  37.         inc(Ppic);
  38.         if p = 0 then
  39.         begin
  40.           w := w + l1;
  41.           p := 1;
  42.         end
  43.         else if p = 1 then
  44.         begin
  45.           p := 2 + l1;
  46.         end
  47.         else if p > 2 then
  48.         begin
  49.           p := p - 1;
  50.           if (w - xs + px >= RectArea.x) and (iy - ys + py >= RectArea.y) and (w - xs + px < RectArea.x + RectArea.w) and (iy - ys + py < RectArea.y + RectArea.h) then
  51.           begin
  52.             if image = nil then
  53.             begin
  54.               pix := getpixel(screen, w - xs + px, iy - ys + py);
  55.               colorin := sdl_maprgb(screen.format, ACol[l1 * 3] * (4 + shadow), ACol[l1 * 3 + 1] * (4 + shadow), ACol[l1 * 3 + 2] * (4 + shadow));
  56.               pix1 := pix and $FF;
  57.               color1 := colorin and $FF;
  58.               pix2 := pix shr 8 and $FF;
  59.               color2 := colorin shr 8 and $FF;
  60.               pix3 := pix shr 16 and $FF;
  61.               color3 := colorin shr 16 and $FF;
  62.               pix4 := pix shr 24 and $FF;
  63.               color4 := colorin shr 24 and $FF;
  64.               pix1 := (alphe * color1 + (100 - alphe) * pix1) div 100;
  65.               pix2 := (alphe * color2 + (100 - alphe) * pix2) div 100;
  66.               pix3 := (alphe * color3 + (100 - alphe) * pix3) div 100;
  67.               pix4 := (alphe * color4 + (100 - alphe) * pix4) div 100;
  68.               pix := pix1 + pix2 shl 8 + pix3 shl 16 + pix4 shl 24;
  69.               putpixel(screen, w - xs + px, iy - ys + py, pix);
  70.             end
  71.             else
  72.               Pint(image + ((w - xs + px) * 1152 + (iy - ys + py)) * 4)^ := sdl_maprgb(screen.format, ACol[l1 * 3] * (4 + shadow), ACol[l1 * 3 + 1] * (4 + shadow), ACol[l1 * 3 + 2] * (4 + shadow));
  73.           end;
  74.           w := w + 1;
  75.           if p = 2 then
  76.           begin
  77.             p := 0;
  78.           end;
  79.         end;
  80.       end;
  81.     end;
  82.   end;

  83. end;
复制代码

[发帖际遇]: winson7891投石杀死蒙古大汗蒙哥,天下闻名,增加声望5。

评分

参与人数 1声望 +25 收起 理由
凶神恶煞 + 25 原创精品

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 18:10 | 显示全部楼层
我们经常会看到场景地图的边沿上面,包含着上一幅地图的贴图,边沿非常“肮脏”

其实只要在初始化场景时加一句话,就能解决这个情况~

FillChar(BFieldImg,SizeOf(BFieldImg),#0);

这个是战场的例子,fillchar这个系统功能效率比较可靠,所以放心使用~

//初始化战场映像
  1. //初始化战场映像

  2. procedure InitialWholeBField;
  3. var
  4.   i1, i2, j1, j2, x, y: integer;
  5. begin
  6.   FillChar(BFieldImg,SizeOf(BFieldImg),#0);
  7.   for i1 := 0 to 63 do
  8.     for i2 := 0 to 63 do
  9.     begin
  10.       x := -i1 * 36 + i2 * 36 + 2302;
  11.       y := i1 * 18 + i2 * 18 + 18;
  12.       if (i1 < 0) or (i2 < 0) or (i1 > 63) or (i2 > 63) then
  13.         InitialBPic(0, x, y)
  14.       else
  15.       begin
  16.         InitialBPic(bfield[0, i1, i2] div 2, x, y);
  17.         if (bfield[1, i1, i2] > 0) then
  18.           InitialBPic(bfield[1, i1, i2] div 2, x, y)
  19.       end;
  20.     end;

  21. end;
复制代码
从此以后,场景不再肮脏了~~

[发帖际遇]: winson7891在黑龙潭边拣到一个手帕,经验证是瑛姑绣的四张机手帕,转手卖得银两10。

评分

参与人数 1声望 +20 收起 理由
凶神恶煞 + 20 超有用!

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 18:11 | 显示全部楼层
字幕指令,用法同新对话指令
^^改变文字颜色
## 延时
**换行
@@等待击键
&&显示姓名
%%显示名
$$显示姓
  1. procedure ShowTitle(talknum, color: integer);
  2. var
  3.   newcolor, alen, x1, y1, ch, color1, color2, c1, r1, n, namelen, i, t1, grp, idx, offset, len, i1, i2, face, c, x, y, w, h, cell, row: integer;
  4.   np3, np1, np2, tp, p1, ap: pchar;
  5.   actorarray, name1, name2, talkarray: array of byte;
  6.   pword: array[0..1] of Uint16;
  7.   wd, str: string;
  8.   temp2: widestring;
  9. begin
  10.   pword[1] := 0;
  11.   color1 := color and $FF;
  12.   color2 := (color shr 8) and $FF;
  13.   x := 0;
  14.   y := 30;
  15.   w := 640;
  16.   h := 109;
  17.   row := 5;
  18.   cell := 25;
  19.   //read talk
  20.   idx := fileopen('\resource\TALK.IDX', fmopenread);
  21.   grp := fileopen('\resource\TALK.GRP', fmopenread);
  22.   if talknum = 0 then
  23.   begin
  24.     offset := 0;
  25.     fileread(idx, len, 4);
  26.   end
  27.   else
  28.   begin
  29.     fileseek(idx, (talknum - 1) * 4, 0);
  30.     fileread(idx, offset, 4);
  31.     fileread(idx, len, 4);
  32.   end;
  33.   len := (len - offset);
  34.   setlength(talkarray, len + 1);
  35.   fileseek(grp, offset, 0);
  36.   fileread(grp, talkarray[0], len);
  37.   fileclose(idx);
  38.   fileclose(grp);
  39.   for i := 0 to len - 1 do
  40.   begin
  41.     talkarray[ i ] := talkarray[ i ] xor $FF;
  42.     if (talkarray[ i ] = $FF) then
  43.       talkarray[ i ] := 0;
  44.   end;
  45.   talkarray[len] := byte(0);
  46.   tp := @talkarray[0];

  47.   if length(tp) > cell * 2 then
  48.   begin
  49.     x1 := 300 - cell * 10;
  50.   end
  51.   else x1 := 300 - length(tp) * 5;

  52.   if ((length(tp) div 2) > cell * row) then
  53.   begin
  54.     y1 := y + (h div 2) - 50
  55.   end
  56.   else y1 := y + (h div 2) - 10 - ((length(tp) div 2) div cell) * 10;

  57.   p1 := @Rrole[0].Name;
  58.   alen := length(p1) + 2;
  59.   setlength(actorarray, alen);
  60.   ap := @actorarray[0];
  61.   for n := 0 to alen - 1 do
  62.   begin
  63.     (ap + n)^ := (p1 + n)^;
  64.     if (p1 + n)^ = char(0) then break;
  65.   end;
  66.   (ap + n)^ := char($0);
  67.   (ap + n + 1)^ := char(0);

  68.   if alen = 6 then
  69.   begin
  70.     setlength(name1, 4);
  71.     np1 := @name1[0];
  72.     np1^ := ap^;
  73.     (np1 + 1)^ := (ap + 1)^;
  74.     (np1 + 2)^ := char(0);
  75.     (np1 + 3)^ := char(0);
  76.     setlength(name2, 4);
  77.     np2 := @name2[0];
  78.     np2^ := ap^;
  79.     for i := 0 to length(name2) - 1 do
  80.       (np2 + i)^ := (ap + i + 2)^;
  81.   end
  82.   else if alen > 8 then
  83.   begin
  84.     setlength(name1, 6);
  85.     np1 := @name1[0];
  86.     np1^ := ap^;
  87.     (np1 + 1)^ := (ap + 1)^;
  88.     (np1 + 2)^ := (ap + 2)^;
  89.     (np1 + 3)^ := (ap + 3)^;
  90.     (np1 + 4)^ := char(0);
  91.     (np1 + 5)^ := char(0);
  92.     setlength(name2, 6);
  93.     np2 := @name2[0];
  94.     for i := 0 to length(name2) - 1 do
  95.       (np2 + i)^ := (ap + i + 4)^;
  96.   end
  97.   else if alen = 8 then
  98.   begin
  99.     if ((puint16(ap)^ = $6EAB) and ((puint16(ap + 2)^ = $63AE))) or
  100.       ((puint16(ap)^ = $E8A6) and ((puint16(ap + 2)^ = $F9AA))) or
  101.       ((puint16(ap)^ = $46AA) and ((puint16(ap + 2)^ = $E8A4))) or
  102.       ((puint16(ap)^ = $4FA5) and ((puint16(ap + 2)^ = $B0AA))) or
  103.       ((puint16(ap)^ = $7DBC) and ((puint16(ap + 2)^ = $65AE))) or
  104.       ((puint16(ap)^ = $71A5) and ((puint16(ap + 2)^ = $A8B0))) or
  105.       ((puint16(ap)^ = $D1BD) and ((puint16(ap + 2)^ = $AFB8))) or
  106.       ((puint16(ap)^ = $71A5) and ((puint16(ap + 2)^ = $C5AA))) or
  107.       ((puint16(ap)^ = $D3A4) and ((puint16(ap + 2)^ = $76A5))) or
  108.       ((puint16(ap)^ = $BDA4) and ((puint16(ap + 2)^ = $5DAE))) or
  109.       ((puint16(ap)^ = $DABC) and ((puint16(ap + 2)^ = $A7B6))) or
  110.       ((puint16(ap)^ = $43AD) and ((puint16(ap + 2)^ = $DFAB))) or
  111.       ((puint16(ap)^ = $71A5) and ((puint16(ap + 2)^ = $7BAE))) or
  112.       ((puint16(ap)^ = $B9A7) and ((puint16(ap + 2)^ = $43C3))) or
  113.       ((puint16(ap)^ = $61B0) and ((puint16(ap + 2)^ = $D5C1))) or
  114.       ((puint16(ap)^ = $74A6) and ((puint16(ap + 2)^ = $E5A4))) or
  115.       ((puint16(ap)^ = $DDA9) and ((puint16(ap + 2)^ = $5BB6))) then
  116.     begin
  117.       setlength(name1, 6);
  118.       np1 := @name1[0];
  119.       np1^ := ap^;
  120.       (np1 + 1)^ := (ap + 1)^;
  121.       (np1 + 2)^ := (ap + 2)^;
  122.       (np1 + 3)^ := (ap + 3)^;
  123.       (np1 + 4)^ := char(0);
  124.       (np1 + 5)^ := char(0);
  125.       setlength(name2, 4);
  126.       np2 := @name2[0];
  127.       for i := 0 to length(name2) - 1 do
  128.         (np2 + i)^ := (ap + i + 4)^;
  129.     end
  130.     else
  131.     begin
  132.       setlength(name1, 4);
  133.       np1 := @name1[0];
  134.       np1^ := ap^;
  135.       (np1 + 1)^ := (ap + 1)^;
  136.       (np1 + 2)^ := char(0);
  137.       (np1 + 3)^ := char(0);
  138.       setlength(name2, 6);
  139.       np2 := @name2[0];
  140.       for i := 0 to length(name2) - 1 do
  141.         (np2 + i)^ := (ap + i + 2)^;
  142.     end;
  143.   end;
  144.   temp2 := big5tounicode(tp);

  145.   str := unicodetobig5(@temp2[1]);

  146.   setlength(wd, 0);
  147.   i := 0;
  148.   while i < length(str) do
  149.   begin
  150.     setlength(wd, length(wd) + 1);
  151.     wd[length(wd) - 1] := str[ i ];
  152.     if (integer(str[ i ]) in [$81..$FE]) and (integer(str[i + 1]) <> $7E) then
  153.     begin
  154.       setlength(wd, length(wd) + 1);
  155.       wd[length(wd) - 1] := str[i + 1];
  156.       wd[length(wd) - 2] := str[ i ];
  157.       inc(i, 2);
  158.       continue
  159.     end;
  160.     if (str[ i ] = #$0D) and (str[i + 1] = #$0A) then
  161.     begin
  162.       setlength(wd, length(wd) + 1);
  163.       wd[length(wd) - 1] := '*';
  164.       wd[length(wd) - 2] := '*';
  165.       inc(i, 2);
  166.       continue;
  167.     end;
  168.     if (integer(str[ i ]) in [$20..$7F]) then
  169.     begin
  170.       if str[ i ] = '^' then
  171.       begin
  172.         if (integer(str[i + 1]) in [$30..$39]) or (str[i + 1] = '^') then
  173.         begin
  174.           setlength(wd, length(wd) + 1);
  175.           wd[length(wd) - 1] := str[i + 1];
  176.           inc(i, 2);
  177.           continue;
  178.         end;
  179.       end
  180.       else if (str[ i ] = '*') and (str[i + 1] = '*') then
  181.       begin
  182.         setlength(wd, length(wd) + 1);
  183.         wd[length(wd) - 1] := str[i + 1];
  184.         inc(i, 2);
  185.         continue;
  186.       end
  187.       else if (str[ i ] = '&') and (str[i + 1] = '&') then
  188.       begin
  189.         setlength(wd, length(wd) + 1);
  190.         wd[length(wd) - 1] := str[i + 1];
  191.         inc(i, 2);
  192.         continue;
  193.       end
  194.       else if (str[ i ] = '#') and (str[i + 1] = '#') then
  195.       begin
  196.         setlength(wd, length(wd) + 1);
  197.         wd[length(wd) - 1] := str[i + 1];
  198.         inc(i, 2);
  199.         continue;
  200.       end
  201.       else if (str[ i ] = '@') and (str[i + 1] = '@') then
  202.       begin
  203.         setlength(wd, length(wd) + 1);
  204.         wd[length(wd) - 1] := str[i + 1];
  205.         inc(i, 2);
  206.         continue;
  207.       end
  208.       else if (str[ i ] = '$') and (str[i + 1] = '$') then
  209.       begin
  210.         setlength(wd, length(wd) + 1);
  211.         wd[length(wd) - 1] := str[i + 1];
  212.         inc(i, 2);
  213.         continue;
  214.       end
  215.       else if (str[ i ] = '%') and (str[i + 1] = '%') then
  216.       begin
  217.         setlength(wd, length(wd) + 1);
  218.         wd[length(wd) - 1] := str[i + 1];
  219.         inc(i, 2);
  220.         continue;
  221.       end;
  222.       setlength(wd, length(wd) + 1);
  223.       wd[length(wd) - 1] := char($A0 + (smallint(str[ i ]) - 32));
  224.       wd[length(wd) - 2] := char($A3);
  225.     end;
  226.     inc(i);
  227.   end;
  228.   tp := @wd[3];

  229.   ch := 0;

  230.   while ((puint16(tp + ch))^ shl 8 <> 0) and ((puint16(tp + ch))^ shr 8 <> 0) do
  231.   begin
  232.     redraw;
  233.     c1 := 0;
  234.     r1 := 0;
  235.     DrawRectangleWithoutFrame(x, y, w, h, 0, 40);
  236.     while r1 < row do
  237.     begin
  238.       pword[0] := (puint16(tp + ch))^;
  239.       if (pword[0] shr 8 <> 0) and (pword[0] shl 8 <> 0) then
  240.       begin
  241.         ch := ch + 2;
  242.         if (pword[0] and $FF) = $5E then //^^改变文字颜色
  243.         begin
  244.           case smallint((pword[0] and $FF00) shr 8) - $30 of
  245.             0: newcolor := 28515;
  246.             1: newcolor := 28421;
  247.             2: newcolor := 28435;
  248.             3: newcolor := 28563;
  249.             4: newcolor := 28466;
  250.             5: newcolor := 28450;
  251.             64: newcolor := color;
  252.           else newcolor := color;
  253.           end;
  254.           color1 := newcolor and $FF;
  255.           color2 := (newcolor shr 8) and $FF;
  256.         end
  257.         else if pword[0] = $2323 then //## 延时
  258.         begin
  259.           sdl_delay(500);
  260.         end
  261.         else if pword[0] = $2A2A then //**换行
  262.         begin
  263.           if c1 > 0 then
  264.           begin
  265.             inc(r1);
  266.             DrawRectangleWithoutFrame(x, y + h + 11 * (r1 - 1) + 1, w, 10, 0, 40);
  267.           end;
  268.           c1 := 0;
  269.         end
  270.         else if pword[0] = $4040 then //@@等待击键
  271.         begin
  272.           sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  273.           n := waitanykey;
  274.           while (n = sdlk_up) or
  275.             (n = sdlk_down) or
  276.             (n = sdlk_right) or
  277.             (n = sdlk_left) do
  278.             n := waitanykey;

  279.         end
  280.         else if (pword[0] = $2626) or (pword[0] = $2525) or (pword[0] = $2424) then
  281.         begin
  282.           case pword[0] of
  283.             $2626: np3 := ap; //&&显示姓名
  284.             $2525: np3 := np2; //%%显示名
  285.             $2424: np3 := np1; //$$显示姓
  286.           end;
  287.           i := 0;
  288.           while (puint16(np3 + i)^ shr 8 <> 0) and (puint16(np3 + i)^ shl 8 <> 0) do
  289.           begin
  290.             pword[0] := puint16(np3 + i)^;
  291.             i := i + 2;
  292.             DrawBig5ShadowText(@pword[0], x1 + CHINESE_FONT_SIZE * c1, y1 + CHINESE_FONT_SIZE * r1, colcolor( color1), colcolor( color2));
  293.             inc(c1);
  294.             if c1 = cell then
  295.             begin
  296.               c1 := 0;
  297.               inc(r1);
  298.               DrawRectangleWithoutFrame(x, y + h + 11 * (r1 - 1) + 1, w, 10, 0, 40);
  299.               if r1 = row then
  300.               begin
  301.                 redraw;
  302.                 c1 := 0;
  303.                 r1 := 0;
  304.                 DrawRectangleWithoutFrame(x, y, w, h, 0, 40);
  305.               end;
  306.             end;
  307.           end;
  308.         end
  309.         else //显示文字
  310.         begin
  311.           Drawbig5ShadowText(@pword, x1 + CHINESE_FONT_SIZE * c1, y1 + CHINESE_FONT_SIZE * r1, colcolor( color1), colcolor(color2));
  312.           inc(c1);
  313.           if c1 = cell then
  314.           begin
  315.             c1 := 0;
  316.             inc(r1);
  317.             DrawRectangleWithoutFrame(x, y + h + 11 * (r1 - 1) + 1, w, 10, 0, 40);
  318.           end;
  319.         end;
  320.       end
  321.       else break;
  322.     end;
  323.     sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  324.     n := waitanykey;
  325.     while (n = sdlk_up) or
  326.       (n = sdlk_down) or
  327.       (n = sdlk_right) or
  328.       (n = sdlk_left) do
  329.       n := waitanykey;
  330.     if (pword[0] and $FF = 0) or (pword[0] and $FF00 = 0) then break;
  331.   end;
  332.   redraw;
  333.   //DrawBig5ShadowText(@pword, x1 + CHINESE_FONT_SIZE * c1, y1 + CHINESE_FONT_SIZE * r1, colcolor(0, color1), colcolor(0, color2));

  334.   setlength(wd, 0);
  335.   setlength(str, 0);
  336.   setlength(temp2, 0);
  337. end;
复制代码

[ 本帖最后由 KG 于 2010-2-13 20:20 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 1声望 +25 收起 理由
凶神恶煞 + 25 好贴奖励

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-12 23:41 | 显示全部楼层
某超傻的指令
我是来骗分的
希望ls几位大大不要嘲笑~
  1. //增加某属性数值
  2. procedure unknownewintruct(rnum, kind, addnum: integer);
  3. var
  4.   word: widestring;
  5. begin

  6.   case kind of
  7.   0:
  8.   begin
  9.   RRole[rnum].Defence := RRole[rnum].Defence + addnum;
  10.   word :=' 防御增加';
  11.   if RRole[rnum].Defence > 500 then RRole[rnum].Defence := 500
  12.   end;
  13.   1:
  14.   begin
  15.   RRole[rnum].Speed := RRole[rnum].Speed + addnum;
  16.   word :=' 轻功增加';
  17.   if RRole[rnum].Speed > 500 then RRole[rnum].Speed := 500
  18.   end;
  19.   2:
  20.   begin
  21.   RRole[rnum].Fist := RRole[rnum].Fist + addnum;
  22.   word :=' 拳掌增加';
  23.   if RRole[rnum].Fist > 999 then RRole[rnum].Fist := 999
  24.   end;
  25.   3:
  26.   begin
  27.   RRole[rnum].Sword := RRole[rnum].Sword + addnum;
  28.   word := '御剑增加';
  29.   if RRole[rnum].Sword > 999 then RRole[rnum].Sword := 999
  30.   end;
  31.   4:
  32.   begin
  33.   RRole[rnum].Knife := RRole[rnum].Knife + addnum;
  34.   word := '耍刀增加';
  35.   if RRole[rnum].Knife > 999 then RRole[rnum].Knife := 999
  36.   end;
  37.   5:
  38.   begin
  39.   RRole[rnum]. Unusual := RRole[rnum].Unusual + addnum;
  40.   word := '特殊增加';
  41.   if RRole[rnum].Unusual > 999 then RRole[rnum].Unusual := 999
  42.   end;
  43.   end;
  44.   DrawRectangle(CENTER_X - 75, 98, 145, 51, 0, colcolor(255), 30);
  45.   drawshadowtext(@word[1], CENTER_X - 90, 125, colcolor($7), colcolor($5));
  46.   drawbig5shadowtext(@rrole[rnum].Name, CENTER_X - 90, 100, colcolor($23), colcolor($21));
  47.   word := format('%4d', [addnum]);
  48.   drawengshadowtext(@word[1], CENTER_X + 20, 125, colcolor($66), colcolor($64));
  49.   sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  50.   waitanykey;
  51.   redraw;
  52. end;
复制代码
ps:lx那个比我的高明多了

[ 本帖最后由 killer_zingy 于 2010-2-13 06:45 编辑 ]

评分

参与人数 1声望 +12 收起 理由
凶神恶煞 + 12 添补业界指令空白O(∩_∩)O

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-13 06:42 | 显示全部楼层
看到kz贴了这个,我也把我的贴出来了。
注:kz别嘲笑我。

这是效果图。
  1. procedure addanyulike(rnum, kind, addnum, show: integer);
  2. var
  3.   str: array[0..7] of widestring;
  4.   addtarget: array[0..7] of integer;
  5.   word: widestring;
  6. begin
  7.   addtarget[0] := 43;
  8.   addtarget[1] := 45;
  9.   addtarget[2] := 44;
  10.   addtarget[3] := 50;
  11.   addtarget[4] := 51;
  12.   addtarget[5] := 52;
  13.   addtarget[6] := 53;
  14.   addtarget[7] := 54;
  15.   str[0] := ' 攻擊增加';
  16.   str[1] := ' 防禦增加';
  17.   str[2] := ' 輕功增加';
  18.   str[3] := ' 拳掌增加';
  19.   str[4] := ' 禦劍增加';
  20.   str[5] := ' 耍刀增加';
  21.   str[6] := ' 特殊增加';
  22.   str[7] := ' 暗器增加';
  23.   rrole[rnum].Data[addtarget[kind]] := rrole[rnum].data[addtarget[kind]] +
  24.     addnum;
  25.   if rrole[rnum].Data[addtarget[kind]] > maxprolist[addtarget[kind]] then
  26.     rrole[rnum].Data[addtarget[kind]] := maxprolist[addtarget[kind]];
  27.   if show = 0 then
  28.   begin
  29.     word := str[kind];
  30.     DrawRectangle(CENTER_X - 75, 98, 145, 51, 0, colcolor(255), 30);
  31.     drawshadowtext(@word[1], CENTER_X - 90, 125, colcolor($7),
  32.       colcolor($5));
  33.     drawbig5shadowtext(@rrole[rnum].Name, CENTER_X - 90, 100,
  34.       colcolor($23),
  35.       colcolor($21));
  36.     word := format('%4d', [addnum]);
  37.     drawengshadowtext(@word[1], CENTER_X + 20, 125, colcolor($66),
  38.       colcolor($64));
  39.     sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  40.     waitanykey;
  41.     redraw;
  42.   end;
  43. end;
复制代码
[发帖际遇]: 轩辕夏禹为救乔峰,聚贤庄大战群侠后身负重伤,花费银两25治伤。


ps:kz你就别取笑我了,我也是依样画葫芦写出来的,可以说是抄袭你。

[ 本帖最后由 轩辕夏禹 于 2010-2-13 07:01 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 1声望 +12 收起 理由
凶神恶煞 + 12 支持互相讨论研究

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-13 14:49 | 显示全部楼层
写一个实时缩放RLE8图片的代码,重载原来的DrawRLE8pic。
使用前需要定义一个新的record:
  1. type
  2.   
  3.   TRLE8zoompixel = record
  4.     alpha: boolean;
  5.     red: byte;
  6.     green: byte;
  7.     blue: byte;
  8.   end;
复制代码
定义后可以把以下代码加入到Engine.pas里面。在原来的DrawRLE8pic过程后面写上 “overload;”。引用此过程只需在原过程参数后面新加入一个倍数的参数,一般参数在0.5倍到3倍之间时,效果应该都还算可以接受。效率一般,如果缩放图片过多,可能较慢。
  1. procedure DrawRLE8pic(num, px, py: integer; Pidx: pinteger; Ppic: Pbyte; RectArea: TRect; Image: PChar; shadow: integer; MULT: single); overload;
  2. var
  3.   RLE8zoompixel: array of array of TRLE8zoompixel;
  4.   nowpixel : TRLE8zoompixel;
  5.   newwidth, newheight, offset, oldwidth, oldheight, xs, ys, nowdata, iy, ix, xpos, i, datalen, drawstate, i2: integer;
  6.   drawx, drawy, parameter : integer;
  7.   f_drawx, f_drawy, f_x, f_y, nowred, nowgreen, nowblue: Extended;
  8.   coefficient: array[0..3] of Extended;
  9. begin
  10.   if num = 0 then
  11.     offset := 0
  12.   else
  13.   begin
  14.     inc(Pidx, num - 1);
  15.     offset := Pidx^;
  16.   end;

  17.   Inc(Ppic, offset);
  18.   oldwidth := Psmallint((Ppic))^;
  19.   Inc(Ppic, 2);
  20.   oldheight := Psmallint((Ppic))^;
  21.   Inc(Ppic, 2);
  22.   xs := Psmallint((Ppic))^;
  23.   Inc(Ppic, 2);
  24.   ys := Psmallint((Ppic))^;
  25.   Inc(Ppic, 2);

  26.   setlength(RLE8zoompixel, oldwidth, oldheight);

  27.   for iy := 0 to oldheight - 1 do
  28.   begin
  29.     datalen := Ppic^;
  30.     drawstate := 0;
  31.     xpos := 0;
  32.     for ix := 0 to datalen do
  33.     begin
  34.       inc(Ppic);
  35.       nowdata := Ppic^;

  36.       if ix = datalen then
  37.       begin
  38.         if oldwidth > xpos then
  39.         begin
  40.           i := xpos;
  41.           for xpos := i to oldwidth - 1 do
  42.           begin
  43.             RLE8zoompixel[xpos][iy].alpha := true;
  44.           end;
  45.           drawstate := 0;
  46.         end;
  47.       end
  48.       else if drawstate = 0 then
  49.       begin
  50.         i := xpos;
  51.         for xpos := i to nowdata + i - 1 do
  52.         begin
  53.           RLE8zoompixel[xpos][iy].alpha := true;
  54.         end;
  55.         drawstate := 1;
  56.       end

  57.       else if drawstate = 1 then
  58.       begin
  59.         drawstate := nowdata + 2;
  60.       end

  61.       else if drawstate > 2 then
  62.       begin
  63.         RLE8zoompixel[xpos][iy].alpha := false;
  64.         RLE8zoompixel[xpos][iy].red := ACol[nowdata * 3];
  65.         RLE8zoompixel[xpos][iy].green := ACol[nowdata * 3 + 1];
  66.         RLE8zoompixel[xpos][iy].blue := ACol[nowdata * 3 + 2];
  67.         dec(drawstate);
  68.         inc(xpos);
  69.         if drawstate = 2 then
  70.           drawstate := 0;
  71.       end;

  72.     end;

  73.   end;

  74.   newwidth := Round(MULT * oldwidth);
  75.   newheight := Round(MULT * oldheight);

  76.   if JudgeInScreen(px, py, newwidth, newheight, xs, ys, RectArea.x, RectArea.y, RectArea.w, RectArea.h) then
  77.   begin
  78.     for ix := 0 to newheight - 1 do
  79.     begin
  80.       for iy := 0 to newwidth - 1 do
  81.       begin
  82.         f_drawx := ix / MULT;
  83.         f_drawy := iy / MULT;
  84.         drawx := Trunc(f_drawx);
  85.         drawy := Trunc(f_drawy);
  86.         f_x := f_drawx - drawx;
  87.         f_y := f_drawy - drawy;
  88.         coefficient[0] := (1 - f_y) * (1 - f_x);
  89.         coefficient[1] := (1 - f_y) * f_x;
  90.         coefficient[2] := (1 - f_x) * f_y;
  91.         coefficient[3] := f_x * f_y;
  92.         parameter := 4;

  93.         nowred := 0;
  94.         nowgreen := 0;
  95.         nowblue := 0;

  96.         for i := 0 to 1 do
  97.           for i2 := 0 to 1 do
  98.           begin
  99.             if (drawx + i >= oldwidth) or (drawy + i2 >= oldheight) or (RLE8zoompixel[drawx + i][drawy + i2].alpha) then
  100.               dec(parameter)
  101.             else
  102.             begin
  103.               nowred := nowred + coefficient[i + 2 * i2] * RLE8zoompixel[drawx + i][drawy + i2].red;
  104.               nowgreen := nowgreen + coefficient[i + 2 * i2] * RLE8zoompixel[drawx + i][drawy + i2].green;
  105.               nowblue := nowblue + coefficient[i + 2 * i2] * RLE8zoompixel[drawx + i][drawy + i2].blue;
  106.             end;
  107.           end;

  108.         if parameter = 0 then
  109.           nowpixel.alpha := true
  110.         else
  111.         begin
  112.           nowpixel.alpha := false;
  113.           nowpixel.red := Round(nowred);
  114.           nowpixel.green := Round(nowgreen);
  115.           nowpixel.blue := Round(nowblue);
  116.         end;
  117.         if (ix - xs + px >= RectArea.x) and (iy - ys + py >= RectArea.y) and (ix - xs + px < RectArea.x + RectArea.w) and (iy - ys + py < RectArea.y + RectArea.h) then
  118.           if not(nowpixel.alpha) then
  119.             if image = nil then
  120.               putpixel(screen, ix - xs + px, iy - ys + py, sdl_maprgb(screen.format, nowpixel.red * (4 + shadow), nowpixel.green * (4 + shadow), nowpixel.blue * (4 + shadow)))
  121.             else
  122.               Pint(image + ((ix - xs + px) * 1152 + (iy - ys + py)) * 4)^ := sdl_maprgb(screen.format, nowpixel.red * (4 + shadow), nowpixel.green * (4 + shadow), nowpixel.blue * (4 + shadow));
  123.       end;
  124.     end;
  125.   end;
  126. end;
复制代码
效果图见附件

[发帖际遇]: 真正的强强在丐帮大会揭露何师我的真正面目,得郭靖称赞,增加声望2。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 2声望 +30 收起 理由
凶神恶煞 + 16 很强大!
黄顺坤 + 14 囧。。加到最多了。凶神大大继续。。

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-13 15:44 | 显示全部楼层
写那个RLE8图片缩放的时候,我忘了RLE8格式,所以又看了下论坛的资料,但是觉得这个格式并不算太好,因为有大小限制,前一段研究了一下金山公司剑侠情缘系列游戏的图片格式,它是没有大小限制的。写出来与大家分享一下,如果觉得好,可以写一个格式转换的程序,把金庸图片转成剑侠情缘的图片格式。

在文件头部有一个头结构
  1.   TMPCHead = record
  2.     Headchar: array[0..15] of byte;  //这里标记“MPC File ver2.0”
  3.     Headnull: array[0..11] of integer; //null
  4.     Filedatalen: integer;   //不含头长度
  5.     MaxWide: integer; // 所含图片最大宽度     
  6.     MaxHeight: integer;  //最大高度
  7.     PicAmount: integer;  //图片数量
  8.     PicBitCount: integer;  //这个是位数么? 一般都是8
  9.     PaletteLen: integer;  //调色板长度
  10.     Xs: integer;  //偏移??是否所有图片用此一个偏移??
  11.     Ys: integer;  //??
  12.     Endnull: array[0..7] of integer; //null
  13.   end;
复制代码
接下来是调色板信息。调色板结构是
  1.   TMPCpalette = record
  2.     bule: byte;
  3.     green: byte;
  4.     red: byte;
  5.     alpha: byte; //透明度??这里好像并没有用到
  6.   end;
复制代码
接下来是每张图片的偏移(第一张是0),每个四字节。

再后面是每个图片的数据,数据前也有个头结构。
  1.   TMPCpichead = record
  2.     picDataLen: integer; //图片数据长度,含此头结构
  3.     Wide: integer;   //宽度
  4.     Height: integer;  //高度
  5.     Endnull: array[0..1] of integer;  //无用。也许以后可以自己改造成每个图片的偏移
  6.   end;
复制代码
然后就是真正的图片数据。
这有一段数据。

E1 02 1B 1B E1 E0 03 1B 09 07 E1 E0 04 44 3B 3B

第一个数是E1,当这个数大于80H(十进制的128)时,它先要减掉80H,所得到的就是指透明像素的个数,所以有97个透明像素。
接下来是02,他小于80H,表示接下来有2个颜色点,分别是1B,1B,所以颜色信息在对应的MPCpalette[$1B]中,再接下来又是E1,所以又有97个透明像素。这时此行的像素已经有了196个,而此段数据所表示图像的宽度是C4(此数在这段数据中并未给出),也就是196,此时应该换行。再接下来道理都是相同的。

这种图片格式消除了图片大小的限制,但也不一定适合金庸,只是拿出来参考一下。

附件打包一个查看这种图片的小程序和源码,还有两个这种格式的图片文件。

[发帖际遇]: 真正的强强听说关外有“闯王宝藏”,跟随田归农等人去寻宝,用光了盘缠才发现是假消息,共计损失银两16两。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 2声望 +24 收起 理由
凶神恶煞 + 10 追加!
黄顺坤 + 14 啊。。很不错啊。。||= =。。凶神继续加。。 ...

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-13 16:06 | 显示全部楼层
没想到大家都留了那么多手啊口胡。。

初始设置的时候。。
DOS选DOS,复刻的选kys
图片结构目前统一选grp



不拿点东西粗来实在说不过去了(1L的那个我花了5分钟写的那个示范。。表提了。。完全没啥水平囧)

sfe0.72.20sp1扯神纪念特别版

14:16 2010-2-12
1.增加动态战斗编辑,可以参照右边的缩略图编辑,缩略图可以放大缩小
2.增加导入导出excel模块
3.去掉mb.dat,改用api
4.怀念扯神大大,.20推出特别版扯神图标版

[发帖际遇]: 黄顺坤拍丁春秋的马屁结果拍到马腿上,被丁春秋打伤,失去医疗费银两7两。


[ 本帖最后由 黄顺坤 于 2010-2-13 16:11 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 1声望 +20 收起 理由
凶神恶煞 + 20 扯神我要看事件!

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-14 06:50 | 显示全部楼层
减体力, 继续骗分:
  1. procedure CalHurtRole(bnum, mnum, level: integer);
  2. var
  3.   i, rnum, hurt, addpoi, mp: integer;
  4. begin
  5.   rnum := brole[bnum].rnum;
  6.   rrole[rnum].PhyPower := rrole[rnum].PhyPower - 3;
  7.   if RRole[rnum].CurrentMP < rmagic[mnum].NeedMP * ((level + 1) div 2) then level := RRole[rnum].CurrentMP div rmagic[mnum].NeedMP * 2;
  8.   if level > 10 then level := 10;
  9.   RRole[rnum].CurrentMP := RRole[rnum].CurrentMP - rmagic[mnum].NeedMP * ((level + 1) div 2);
  10.   for i := 0 to broleamount - 1 do
  11.   begin
  12.     Brole.ShowNumber := -1;
  13.     if (Bfield[4, Brole.X, Brole.Y] <> 0) and (Brole[bnum].Team <> Brole.Team) and (Brole.Dead = 0) then
  14.     begin
  15.       //生命伤害
  16.       if (rmagic[mnum].HurtType = 0) then
  17.       begin
  18.         hurt := CalHurtValue(bnum, i, mnum, level);
  19.         Brole.ShowNumber := hurt;
  20.         //受伤
  21.         Rrole[Brole.rnum].CurrentHP := Rrole[Brole.rnum].CurrentHP - hurt;
  22.         Rrole[Brole.rnum].Hurt := Rrole[Brole.rnum].Hurt + hurt div LIFE_HURT;
  23.         if Rrole[Brole.rnum].Hurt > 99 then Rrole[Brole.rnum].Hurt := 99;
  24.         Brole[bnum].ExpGot := Brole[bnum].ExpGot + hurt div 2;
  25.         if Rrole[Brole.rnum].CurrentHP <= 0 then Brole[bnum].ExpGot := Brole[bnum].ExpGot + hurt div 2;
  26.       end;
  27.       //内力伤害
  28.       if (rmagic[mnum].HurtType = 1) then
  29.       begin
  30.         hurt := rmagic[mnum].HurtMP[level - 1] + random(5) - random(5);
  31.         Brole.ShowNumber := hurt;
  32.         Rrole[Brole.rnum].CurrentMP := Rrole[Brole.rnum].CurrentMP - hurt;
  33.         if Rrole[Brole.rnum].CurrentMP <= 0 then Rrole[Brole.rnum].CurrentMP := 0;
  34.         //增加己方内力及最大值
  35.         RRole[rnum].CurrentMP := RRole[rnum].CurrentMP + hurt;
  36.         RRole[rnum].MaxMP := RRole[rnum].MaxMP + random(hurt div 2);
  37.         if RRole[rnum].MaxMP > MAX_MP then RRole[rnum].MaxMP := MAX_MP;
  38.         if RRole[rnum].CurrentMP > RRole[rnum].MaxMP then RRole[rnum].CurrentMP := RRole[rnum].MaxMP;
  39.       end;

  40.       //体力伤害
  41.        if (rmagic[mnum].HurtType = 5) then
  42.        begin
  43.         hurt := rmagic[mnum].HurtMP[level - 1] + random(5) - random(5);
  44.         Brole.ShowNumber := hurt;
  45.         Rrole[Brole.rnum].PhyPower := Rrole[Brole.rnum].PhyPower - hurt;
  46.         if Rrole[Brole.rnum].PhyPower <= 0 then Rrole[Brole.rnum].PhyPower := 0;
  47.         end;
  48.       //中毒
  49.       addpoi := rrole[rnum].AttPoi div 5 + rmagic[mnum].Poision * level div 2 - rrole[Brole.rnum].DefPoi;
  50.       if addpoi + rrole[Brole.rnum].Poision > 99 then addpoi := 99 - rrole[Brole.rnum].Poision;
  51.       if addpoi < 0 then addpoi := 0;
  52.       if rrole[Brole.rnum].DefPoi >= 99 then addpoi := 0;
  53.       rrole[Brole.rnum].Poision := rrole[Brole.rnum].Poision + addpoi;
  54.     end;
  55.   end;

  56. end;
复制代码

顺便在复制在showhurtvalue里面多加一个5和颜色以及减号.


[ 本帖最后由 killer_zingy 于 2010-2-15 00:16 编辑 ]

评分

参与人数 1声望 +20 收起 理由
凶神恶煞 + 20 好贴奖励

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-16 06:16 | 显示全部楼层
为什么武功都要弄的那么麻烦呢?
直接判断一下类型不是更好?
在加一个群疗(也可以线疗, 十字疗)
  1. //医疗武功
  2. if (rmagic[mnum].HurtType = 6) then
  3.   hurt := Rrole[rnum].Medcine;
  4. begin
  5.   for i1 := 0 to 63 do
  6.     for i2 := 0 to 63 do
  7.     begin
  8.       if bfield[4, i1, i2] >= 1 then
  9.       begin
  10.         bnum := bfield[2, i1, i2];
  11.         if brole[bnum].Team = 0 then
  12.         begin
  13.           rrole[brole[bnum].rnum].CurrentHP := rrole[brole[bnum].rnum].CurrentHP
  14.             + hurt;
  15.           if Rrole[Brole[i].rnum].CurrentHP > Rrole[Brole[i].rnum].MaxHP then
  16.             Rrole[Brole[i].rnum].CurrentHP := Rrole[Brole[i].rnum].MaxHP;
  17.           brole[bnum].ShowNumber := hurt;
  18.         end;
  19.       end;
  20.     end;
  21. end;
复制代码
[发帖际遇]: killer_zingy偷得祖千秋八杯,被老头子祖千秋追杀打伤,医疗费银两18两。


[ 本帖最后由 killer_zingy 于 2010-2-16 10:00 编辑 ]

评分

参与人数 1声望 +12 收起 理由
凶神恶煞 + 12 貌似没有动画效果……

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-16 10:36 | 显示全部楼层
貌似这个帖快要被活埋了,只靠kz一个人在独力撑着。
我也发我的吧,是类似召唤幻兽的。
在武功里面的声音编号里输入你要召唤的人物编号就行了。
反正复刻版里的人物动作都没声音的,不知道是不是bt大偷懒。
  1. procedure callmonster(bnum, mnum, i, level: integer);
  2. var
  3.   o1, o2, dd, oo, rnum: integer;
  4. begin
  5.   for o1 := 0 to 63 do
  6.     for o2 := 0 to 63 do
  7.     begin
  8.       if bfield[4, o1, o2] >= 1 then
  9.       begin
  10.         if bfield[2, o1, o2] < 0 then
  11.         begin
  12.           dd := broleamount - 1;
  13.           rnum := brole[dd].rnum;
  14.           rrole[rnum].CurrentHP := rrole[rnum].MaxHP;
  15.           rrole[rnum].CurrentMP := rrole[rnum].MaxMP;
  16.           rrole[rnum].Poision := 0;
  17.           rrole[rnum].Hurt := 0;
  18.           rrole[rnum].PhyPower := 100;
  19.           broleamount := broleamount + 1;
  20.           bfield[2, o1, o2] := broleamount - 1;
  21.           brole[dd].rnum := rmagic[mnum].SoundNum;
  22.           brole[dd].Team := brole[bnum].Team;
  23.           brole[dd].X := o1;
  24.           brole[dd].Y := o2;
  25.           brole[dd].Face := 0;
  26.           brole[dd].Dead := 0;
  27.           brole[dd].Acted := 1;
  28.         end;
  29.       end;
  30.     end;
  31.   if brole[bnum].Team = 0 then
  32.     showmagicname(mnum);
  33.   rnum := brole[bnum].rnum;
  34.   for oo := 0 to 4 do
  35.   begin
  36.     if rrole[rnum].Data[25 + oo] >= 1 then
  37.       break;
  38.   end;
  39.   PlayActionAmination(bnum, oo); //
  40.   PlayMagicAmination(bnum, Rmagic[mnum].AmiNum);
  41. end;
复制代码
[发帖际遇]: 轩辕夏禹在佛山巧遇钟阿四一家被凤天南强逼,出手打趴凤天南,凤天南奉上银两25。


p/s:里面加入了敌我判断,是因为我的mod里敌方使用武功时是不显示武功名字的,就酱。
顺带一提,很想看看凶神大写的战斗指令啊,我看了那个凶神大的贴了,真是让我叹为观止。

[ 本帖最后由 轩辕夏禹 于 2010-2-16 10:41 编辑 ]

评分

参与人数 1声望 +15 收起 理由
凶神恶煞 + 15 有如场景有围墙的话,貌似人物会在墙外

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-16 16:18 | 显示全部楼层
不知道大家注意到没,复刻版有个小毛病,就是在事件中播放动画的时候,如果点击几下鼠标或按几下键盘的话,动画后面的几句对话就会跳过去。比如游戏开始事件中在播放软体娃娃动画的时候点了两下鼠标,那么动画结束后的两句对话就不会"WaitAnyKey",而会直接跳过了。这是因为消息队列中已经存在了两个点击鼠标的事件。所以,如果想改掉这个小毛病,需要修改一下WaitAnyKey这个函数。很简单,只要加入这句:  while(SDL_PollEvent(@event) > 0) do;  就可以了。

修改后的WaitAnyKey函数如下:
  1. function WaitAnyKey: integer;
  2. var
  3.   enum: integer;
  4. begin

  5.   event.key.keysym.sym := 0;
  6.   event.button.button := 0;

  7.   while(SDL_PollEvent(@event) > 0) do;   //清空消息队列
  8.   
  9.   while (SDL_WaitEvent(@event) >= 0) do
  10.   begin
  11.     if (event.type_ = SDL_QUITEV) then
  12.       if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
  13.         Quit;

  14.     if (event.type_ = SDL_KEYUP) or (event.type_ = SDL_mousebuttonUP) then
  15.       if (event.key.keysym.sym <> 0) or (event.button.button <> 0) then
  16.         break;
  17.   end;
  18.   result := event.key.keysym.sym;
  19.   event.key.keysym.sym := 0;
  20.   event.button.button := 0;
  21. end;
复制代码

[发帖际遇]: 真正的强强发现石破天准备用银票擦屁股,赶紧送上两卷草纸,换回一张银票,兑换银两17。

评分

参与人数 1声望 +20 收起 理由
凶神恶煞 + 20 超级实用,复刻必用!

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2010-2-16 17:41 | 显示全部楼层

绘制自己的鼠标

现有的复刻版的鼠标图像基本都是SDL自带的,就是那个黑乎乎的东西,其实我们完全可以绘制自己的鼠标。
如果用鼠标玩游戏的话,基本上鼠标都是一直在移动的,如果把鼠标和其它图像一起绘制的话,可能会很觉得鼠标的移动是一顿一顿的感觉,所以我选择使用多线程。在这里我没有用Delphi的TThread类,而是选择了windowsAPI的CreateThread函数。
在代码中,我们首先要隐藏SDL自带的鼠标,调用SDL_showcursor(0); 然后用CreateThread新建一个线程。如下:
  1. procedure newthread;
  2. var
  3.   CThread: Thandle;//声明一个句柄
  4.   Tid:DWord;
  5. begin
  6.   SDL_showcursor(0);
  7.   CThread := CreateThread(nil,0,@drawmouse,nil,0,Tid);
  8. end;
复制代码
在CreateThread的参数中,第三个就是线程函数的指针。

在代码开头,新定义了一个var: Buffer:PSDL_surface; 作为一个缓冲。
初始化Screen之后,也需要对Buffer设置一下,调用
Buffer := SDL_CreateRGBSurface(SDL_HWSURFACE, Screen.w, Screen.h, Screen.format.BitsPerPixel, Screen.format.RMask, Screen.format.GMask, Screen.format.BMask, Screen.format.AMask);

说一下这两个PSDL_Surface的作用,我设想的是,把原来代码里面所有绘图函数中的Screen替换为Buffer,也就是说先把图像绘制到Buffer上,然后在绘制鼠标的线程函数中调用SDL_BlitSurface(Buffer, nil, Screen, @dest);把Buffer绘制到Screen中,这样屏幕上就不会残留上次画的鼠标图像了。

下面说说线程函数 Drawmouse。直接看看我的代码。
  1. procedure drawmouse;
  2. var
  3.   image: PSDL_surface;
  4.   dest: TSDL_rect;
  5.   x, y: word;
  6. begin
  7.   image := IMG_Load('resource\mouse.png');
  8.   while (true) do
  9.   begin
  10.     if ethread then
  11.       break;

  12.     dest.x := 0;
  13.     dest.y := 0;
  14.     dest.w := Screen.w;
  15.     dest.h := Screen.h;
  16.     SDL_BlitSurface(Buffer, nil, Screen, @dest);
  17.    
  18.     if (event.motion.x > 0) and (event.motion.y > 0) and (event.motion.x <Screen.w) and (event.motion.y < Screen.h) then
  19.     begin
  20.       x := event.motion.x;
  21.       y := event.motion.y;
  22.     end;

  23.     dest.x := x;
  24.     dest.y := y;
  25.     SDL_updaterect(Screen, 0, 0, Screen.w, Screen.h)   
  26.   end;
  27. end;
复制代码
我的鼠标图片是resource\mouse.png,在函数开头读取到image。
接下来的代码是while循环画鼠标。
然后是我定义的一个全局变量eThread(布尔型),因为我尝试在退出时调用EndThread函数似乎有些错误,只好是通过改变这个变量来控制线程的结束,在游戏开始时把他设置为false,退出时是TRUE。
接下来的代码很简单了,就是分别把游戏图像和鼠标图像先后拷贝到Screen上。

但是现在并不是很完美,游戏中,我们会看到明显的闪烁现象。先解释一下出现闪烁的原因,因为绘制鼠标的线程函数用了While循环,每次绘制较快,而很可能在某次绘制中,主线程也在绘制地图,但是主线程绘制的东西较多,速度较慢,很可能只绘制到地面层,而没有建筑层。等到下次绘制鼠标时,主线程已经绘制完了建筑层,这时候,几次绘制中间因为SDL_updaterect了一次地面层的图像,所以会出现闪烁现象。
对于这个问题,我原先设想的是在所有复刻绘图代码中加入以下代码:
if (SDL_MustLock(screen)) then
begin
  SDL_LockSurface(screen);
end;

if (SDL_MustLock(screen)) then
begin
  SDL_UnlockSurface(screen);
end;

但是后来发现似乎锁定只能防止其他线程修改,并不能防止拷贝,所以,再定义一个全局变量screenchanged(Boolean型)。当绘图开始时赋值false,结束后赋值true。而我又定义了一个Buffer2作为第二缓冲。

修改后的代码如下:
  1. procedure drawmouse;
  2. var
  3.   image: PSDL_surface;
  4.   dest: TSDL_rect;
  5.   now, next: Uint32;
  6.   x, y: word;
  7. begin
  8.   image := IMG_Load('resource\mouse.png');
  9.   while (true) do
  10.   begin
  11.     if ethread then
  12.       break;

  13.     dest.x := 0;
  14.     dest.y := 0;
  15.     dest.w := Buffer.w;
  16.     dest.h := Buffer.h;

  17.     if (screenchanged) then
  18.       SDL_BlitSurface(Buffer, nil, Buffer2, @dest); //在Buffer不在绘制的时候,把Buffer拷贝到Buffer2.
  19.     SDL_BlitSurface(Buffer2, nil, Screen, @dest);  //把Buffer2拷贝到屏幕
  20.     if (event.button.x > 0) and (event.button.y > 0) and (event.button.x <Screen.w) and (event.button.y < Screen.h) then
  21.     begin
  22.       x := event.button.x;
  23.       y := event.button.y;
  24.     end;

  25.     dest.x := x;
  26.     dest.y := y;
  27.     SDL_BlitSurface(image, nil, Screen, @dest);
  28.     //drawheadpic(0, event.motion.x, event.motion.y);
  29.     SDL_updaterect(Screen, 0, 0, Screen.w, Screen.h);
  30.    
  31.   end;
  32. end;
复制代码
这时候会发现,闪烁已经消失了。

对这段代码简单的修改,也可以实现动态鼠标效果。

因为需要修改的代码很多,作者本人也未全部修改完成,不知道是否存在未知的bug。

附件是一个简单的效果图。

[发帖际遇]: 真正的强强在海边沙滩上捡到一支圣火令,当废铜卖了,获得银两2。


[ 本帖最后由 真正的强强 于 2010-2-16 18:37 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 1声望 +16 收起 理由
凶神恶煞 + 16 源码很强,不过,好大的指针……

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-5-16 21:05

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表