Project1

标题: 启动画面(弹出窗口,RGE最适合) [打印本页]

作者: 一箭烂YiJL    时间: 2011-10-10 19:58
标题: 启动画面(弹出窗口,RGE最适合)
本帖最后由 一箭烂YiJL 于 2011-10-12 22:03 编辑

0.序
这个是我的"伪 3D Map"在 v0.4 阶段的东西,如果认为不适合在这里发布,版主请移至 RGE 专区。
主要功能:弹出一个启动画面窗口(无框边位图,透明度)
支援格式:bmp,而且不能透明背景(VX/XP 可以先加载至 Bitmap 类,再存为 bmp 或者制作 hBitmap 结构)
(RGE 最适合使用)

1.开始
图(伪3D Map):

经过序的介绍后,就要说如何应用。专门给脚本加载过长的游戏使用。
RGE:在 main RGE.init (生成主窗口)的游戏,在最前放进脚本页。
VX/XP:先要给 Game.exe 去掉 ShowWindow(反汇编),然后在最前放进脚本页,以及自己在 main 调用ShowWindow。ps2:XP 请有心人帮助弄范例(而且尤其关注 XP 编码(转换))。
ps3:请放置 Splash.bmp!
在每一个加载阶段也可以切换窗口文字(内容),例如脚本页:
Splash (启动画面脚本)
操作:Splash.redraw("正在就加载精灵类")

▼ Sprite
。。。。。。(精灵类父类)
操作:Splash.redraw("正在就加载游戏物件")

▼ 游戏物件
。。。。。。(游戏物件)
操作:Splash.release(结束启动画面)
mian


2.脚本

  1. #==============================================================================
  2. # ■ Splash by YiJL
  3. #------------------------------------------------------------------------------
  4. #  启动画面。
  5. #   
  6. #   - Splash.init
  7. #     初始化
  8. #
  9. #   - Splash.redraw(str)
  10. #     改变显示文字
  11. #
  12. #   - Splash.release
  13. #     释放窗口
  14. #
  15. #==============================================================================

  16. module Splash
  17.   #--------------------------------------------------------------------------
  18.   # ● Win32API
  19.   #--------------------------------------------------------------------------
  20.   M2W = Win32API.new("kernel32", "MultiByteToWideChar",  "ilpipi" , "i")
  21.   CreateWindowEx = Win32API.new("user32", "CreateWindowExW", "lpplllllllll", "l")
  22.   ShowWindow = Win32API.new("user32", "ShowWindow", "ll", "l")
  23.   LoadImage = Win32API.new("user32", "LoadImageW", "lpllll", "l")
  24.   GetCurrentProcess = Win32API.new("kernel32", "GetCurrentProcess", "v", "l")
  25.   SelectObject = Win32API.new("gdi32", "SelectObject", "ll", "l")
  26.   DeleteObject = Win32API.new("gdi32", "DeleteObject", "l", "l")
  27.   GetDC = Win32API.new("user32", "GetDC", "l", "l")
  28.   ReleaseDC = Win32API.new("user32", "ReleaseDC", "ll", "l")
  29.   DestroyWindow = Win32API.new("user32", "DestroyWindow", "l", "l")
  30.   GetSystemMetrics = Win32API.new("user32", "GetSystemMetrics", "l", "l")
  31.   TextOut = Win32API.new("gdi32", "TextOutW", "lllpl", "l")
  32.   CreatePatternBrush = Win32API.new("gdi32", "CreatePatternBrush", "l", "l")
  33.   CreateFont = Win32API.new("gdi32", "CreateFontW", "lllllllllllllp", "l")
  34.   FillRect = Win32API.new("user32", "FillRect", "lpl", "l")
  35.   SetBkMode = Win32API.new("gdi32", "SetBkMode", "ll", "l")
  36.   Sleep = Win32API.new("kernel32", "Sleep", "l", "v")
  37.   SetLWndAttri = Win32API.new("user32", "SetLayeredWindowAttributes", "llll", "l")
  38.   PeekMessage = Win32API.new("user32", "PeekMessageW", "pllll", "l")
  39.   #--------------------------------------------------------------------------
  40.   # ● 常量
  41.   #--------------------------------------------------------------------------
  42.   BMPW = 600                 # 位图长度
  43.   BMPH = 360                 # 位图高度
  44.   BMPP = "Splash.bmp"        # 位图路径
  45.   FONT = "Microsoft YaHei"   # 显示字体
  46.   WAIT = 1                   # 等待时间(s)
  47.   TXTX = 30                  # 字体显示 x 坐标
  48.   TXTY = 210                 # 字体显示 y 坐标
  49.   FNTS = 24                  # 字体大小
  50.   #--------------------------------------------------------------------------
  51.   # ● 初始化
  52.   #--------------------------------------------------------------------------
  53.   def self.init
  54.     if @hSplashWnd.nil?
  55.       hInstance = GetCurrentProcess.call
  56.       @hSplashWnd = CreateWindowEx.call(0x80000, wchar("#32771"), wchar("Splash"),
  57.       0x80000000, (GetSystemMetrics.call(0) - BMPW) / 2,
  58.       (GetSystemMetrics.call(1) - BMPH) / 2, BMPW, BMPH, 0, 0, hInstance, 0)
  59.       ShowWindow.call(@hSplashWnd, 1)
  60.       SetLWndAttri.call(@hSplashWnd, 0, 220, 2)
  61.       hDC = GetDC.call(@hSplashWnd)
  62.       @hBitmap = LoadImage.call(hInstance, wchar(BMPP), 0, BMPW, BMPH, 0x10)
  63.       @hFont = CreateFont.call(FNTS, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, wchar(FONT))
  64.       @hBrush = CreatePatternBrush.call(@hBitmap)
  65.       FillRect.call(hDC, [0, 0, BMPW, BMPH].pack("l*"), @hBrush)
  66.       SetBkMode.call(hDC, 1)
  67.       SelectObject.call(hDC, @hFont)
  68.       str = " "
  69.       TextOut.call(hDC, TXTX, TXTY, wchar(str), str.split(//u).size)
  70.       ReleaseDC.call(@hSplashWnd, hDC)
  71.       msg = " " * 28
  72.       time = Time.now
  73.       while Time.now - time < WAIT
  74.         # 防止无响应
  75.         PeekMessage.call(msg, @hSplashWnd, 0, 0, 0)
  76.         Sleep.call(500)
  77.       end
  78.     end
  79.   end
  80.   #--------------------------------------------------------------------------
  81.   # ● 重画
  82.   #--------------------------------------------------------------------------
  83.   def self.redraw(str)
  84.     unless @hSplashWnd.nil?
  85.       hDC = GetDC.call(@hSplashWnd)
  86.       FillRect.call(hDC, [0, 0, BMPW, BMPH].pack("l*"), @hBrush)
  87.       SetBkMode.call(hDC, 1)
  88.       SelectObject.call(hDC, @hFont)
  89.       TextOut.call(hDC, TXTX, TXTY, wchar(str), str.split(//u).size)
  90.       ReleaseDC.call(@hSplashWnd, hDC)
  91.       msg = " " * 28
  92.       time = Time.now
  93.       while Time.now - time < WAIT
  94.         # 防止无响应
  95.         PeekMessage.call(msg, @hSplashWnd, 0, 0, 0)
  96.         Sleep.call(500)
  97.       end
  98.     end
  99.   end
  100.   #--------------------------------------------------------------------------
  101.   # ● 释放
  102.   #--------------------------------------------------------------------------
  103.   def self.release
  104.     unless @hSplashWnd.nil?
  105.       DeleteObject.call(@hFont)
  106.       DeleteObject.call(@hBitmap)
  107.       DeleteObject.call(@hBrush)
  108.       DestroyWindow.call(@hSplashWnd)
  109.       hSplashWnd = nil
  110.     end
  111.   end
  112.   #--------------------------------------------------------------------------
  113.   # ● unicode 编码
  114.   #--------------------------------------------------------------------------
  115.   def self.wchar(str)
  116.     length = M2W.call(65001, 0, str, -1, 0, 0) << 1
  117.     buffer = " " * length
  118.     M2W.call(65001, 0, str, -1, buffer, length)
  119.     return buffer
  120.   end
  121. end

  122. Splash.init
复制代码
3.范例
VX: 启动画面.zip (948.11 KB, 下载次数: 2152) 感谢月夜神音的编辑支援
XP:waiting for 有心人中。。

作者: 七千    时间: 2011-10-10 21:45
各种V5~抢占沙发
作者: fux2    时间: 2011-10-11 00:03
看到那陀api才刚学的我表示蛋疼。
作者: tamashii    时间: 2011-10-11 00:40
Fake...
Fake / Stray Night...........
Unlicensed bread works...
作者: 月夜神音    时间: 2011-10-11 05:41
本帖最后由 月夜神音 于 2011-10-18 18:21 编辑

剑兰前辈回来了吗~~!前辈的东西不能不支持~~
VX范例: 启动画面VX.rar (836.06 KB, 下载次数: 111)
作者: DeathKing    时间: 2011-10-11 12:56
JUI套件啊啊啊啊啊啊啊………………
作者: 七千    时间: 2011-10-11 22:54
其实这个账号哦不是马甲呢
作者: 各种压力的猫君    时间: 2011-10-11 23:01
求验证:
这个脚本能不能解决WIN7打开RM游戏假死的问题
(就是说把假死的那段换成这个加载图……)
作者: 一箭烂YiJL    时间: 2011-10-12 20:49
本帖最后由 一箭烂YiJL 于 2011-10-12 21:53 编辑
各种压力的猫君 发表于 2011-10-11 23:01
求验证:
这个脚本能不能解决WIN7打开RM游戏假死的问题
(就是说把假死的那段换成这个加载图……) ...

Win7 有关?
不了解什么状况。

RM 游戏假死是指:

1.XP 10s bug?
紫苏有帖子解决。一般脚本中 XP 应该要加 Graphics.update。

2.VX 加载过慢假死?
外加用那些 API 封装好的 dll,在反遍汇删 ShowWindow 的同一个地方,调用之。
并且要在 main 之前 ShowWindow 。

回复 月夜神音 的帖子
非常感谢提供范例!你所说的问题就是忘了 Splash.release。
现在并且会显示加载项目,我会在主楼放置 VX 的范例。
(VX 有 RTPSETUP.exe。)
作者: 退屈£无聊    时间: 2011-10-14 20:06
翻着手册勉强看懂了一点点- -……
API的DC是我永远的伤……
作者: yangff    时间: 2011-10-14 20:22
不建议用这个api
LZ可以去看看UpdateLayeredWindow这个API我相信效果会比LZ现在用的好很多
作者: 一箭烂YiJL    时间: 2011-10-14 22:04
yangff 发表于 2011-10-14 20:22
不建议用这个api
LZ可以去看看UpdateLayeredWindow这个API我相信效果会比LZ现在用的好很多 ...
不建议用这个api

是指 SetLayeredWindowAttributes ?

UpdateLayeredWindow 我试过的,但我怀疑半透明问题和能在 HBITMAP ->(CreatePatternBrush) HBRUSH ->(FillRect) HDC 其中。(另外你说的 UpdateLayeredWindow 是要有 GDI+ 支持的那个么?)
作者: yangff    时间: 2011-10-14 22:32
一箭烂YiJL 发表于 2011-10-14 22:04
是指 SetLayeredWindowAttributes ?

UpdateLayeredWindow 我试过的,但我怀疑半透明问题和能在 HBITMA ...


UpdateLayeredWindow 没有任何问题……WIN2000确实不支持=v=
效果比SetLayeredWindowAttributes 好。
支持半透明,可以传递Png,实现简单,就是不能用WM_PAINT这个比较讨厌……
带上WS_EX_LAYERED样式实现比较简单的说……
  1.         public void SetBits(Bitmap bitmap)
  2.         {
  3.             //if (!haveHandle) return;
  4.             if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat))
  5.                 throw new ApplicationException("图片必须是32位带Alhpa通道的图片。");
  6.             IntPtr oldBits = IntPtr.Zero;
  7.             IntPtr screenDC = Win32.GetDC(IntPtr.Zero);
  8.             IntPtr hBitmap = IntPtr.Zero;
  9.             IntPtr memDc = Win32.CreateCompatibleDC(screenDC);
  10.             try {
  11.                 Win32.Point topLoc = new Win32.Point(Left, Top);
  12.                 Win32.Size bitMapSize = new Win32.Size(bitmap.Width, bitmap.Height);
  13.                 Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION();
  14.                 Win32.Point srcLoc = new Win32.Point(0, 0);
  15.                 hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
  16.                 oldBits = Win32.SelectObject(memDc, hBitmap);
  17.                 blendFunc.BlendOp = Win32.AC_SRC_OVER;
  18.                 blendFunc.SourceConstantAlpha = 255;
  19.                 blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA;
  20.                 blendFunc.BlendFlags = 0;
  21.                 Win32.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA);
  22.             }
  23.             finally
  24.             {
  25.                 if (hBitmap != IntPtr.Zero)
  26.                 {
  27.                     Win32.SelectObject(memDc, oldBits);
  28.                     Win32.DeleteObject(hBitmap);
  29.                 }
  30.                 Win32.ReleaseDC(IntPtr.Zero, screenDC);
  31.                 Win32.DeleteDC(memDc);
  32.             }
  33.         }
复制代码

作者: 一箭烂YiJL    时间: 2011-10-14 22:46
yangff 发表于 2011-10-14 22:32

UpdateLayeredWindow 没有任何问题……WIN2000确实不支持=v=
效果比SetLayeredWindowAttributes 好。

果然-v-(尤其是支持 PNG),自 XP 引入了 GDI+ ,Win2000 用户的话要自己装咯。
嗯,最初写这个脚本的时候考虑到这个函数的兼容问题= =....
似乎我还真不该用 CreatePatternBrush 和 FillRect。
VX 和 XP 要做 png 加载做 tagBITMAP 还算容易,RGE 在 init 之前就麻烦了,
或许还需要外加一个图像格式转换插件。
作者: yangff    时间: 2011-10-14 23:37
一箭烂YiJL 发表于 2011-10-14 22:46
果然-v-(尤其是支持 PNG),自 XP 引入了 GDI+ ,Win2000 用户的话要自己装咯。
嗯,最初写这个脚本的时 ...

libPng=v=
或者自行静态反汇编RGE的dll
作者: poiuy12348609    时间: 2012-4-17 18:17
請問va支持嗎?
作者: Front    时间: 2012-10-8 19:41
VX 用的话~会和Game.exe一起显示出来.
作者: Front    时间: 2012-10-12 10:38
仔细一看是我没有把ShowWindow去掉...求箭烂大叔反汇编软件...Explorer不好用




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1