好天气看好电影

魔戒台词:刚铎和洛汉的好男儿,我的好兄弟;我在你们眼中...,看到了我心中也感受到的恐惧;有一天人类将失去勇气...,我们将众叛亲离,一败涂地;但不是今天;有一天邪将胜正,人类的世界也会完全毁灭;但不是今天;今天我们要誓死奋战。为了你们在世上所珍惜的一切...,一定要奋战到底
free hit counter

统计

最新评论

  • 1. re: Invoke and BeginInvoke
  • 哥们,写得太好了,真正的为我解惑了,看了好多文章都云里雾里的,今天终于明白了!
  • --拼命郎
  • 2. re: 三聚氰胺算法
  • @丁学首先说明,我没有造任何谣言。第四题弄错了,1楼纠正了一下,我非常感谢。其它数据都是从网络上取下来,对一个养牛的奶农来说, 就像1楼算出的3吨,或者说1吨有什么区别? 你觉得奶农会一年买几吨或者买...
  • --信息加油站义工
  • 3. re: Invoke and BeginInvoke
  • 受益匪浅
  • --清清爽爽
  • 4. re: 对.net事件的看法
  • 嗯,受教了,不错师傅!
  • --清清爽爽
  • 5. re: 三聚氰胺算法
  • @信息加油站义工
    但是你觉得使用“造谣”的方式对一个中国企业落井下石很好吗?
  • --丁学

2d游戏斜视角地图的实现

2d游戏斜视角地图的实现
本文例子代码下载(radasm工程文件)

说明:



 一、本程序是一个斜视角地图的滚屏演示。本程序在实现的时候并没有考虑屏幕渲染效率和内存空间的节省问题。所以地图绘制函数并没有对不可视的图块部分进行排除。本程序的实现完全采用了win32汇编语言,因此采用gdi接口也能获得较好的帧速。

 

二、本程序反映了2d游戏地图的控制思路。即,核心问题是几个坐标变换问题,解决了坐标变换就可以了。
 
    1、保存地图的一维数据索引。需要把这个一维数组索引转变成地图坐标,即(列号,行号)。 完成这一步以后,绘图程序才能遍历整个一维数组,就象遍历
       一个二维的地图块数组一样。即通过数组索引确定它是在地图上的坐标。

    2、地图坐标----图块列号、行号。地图坐标转变成屏幕贴图坐标。因为地图坐标是(列号、行号),所以必须要通过地图坐标求解出地图块左上角的像素坐标,即贴图坐标。

    3、进行视变换。即,地图很大的时候,把视口举行在地图上进行平移就可以实现地图的滚动,看到不同的部分。所以,一旦视口的左上角在地图上的绝对坐标确定下来,那么一个地图 块在视口内部的相对坐标------最终的窗口客户区贴图坐标就可以求出。

    4、经过上面几步变换,一个地图块就真正的可以被绘制到窗口里面。

三、帧速控制:

  a、用变量timeOld记录上次计算帧速结束的时间。
  b、变量timeNew记录当前时间。
  c、用变量frameCount记录从timeOld到timeNew的间隔里一共播放的帧数。

  d、每次获取当前时间timeNew以后,求自从
     上次计算帧速结束到现在一共有多少时间(ms):timeNew - timeOld

   当这个时间间隔大于1秒,就进行一次帧速计算,并且令
   timeOld = timeNew,frameCount也归零,准备从现在重新记录
     帧播放,以备在下一秒进行计算。

  e、用timeCur进行时间跟踪,以便帧速控制。
   timeCur记录上次播放一帧结束的时间。timeNew - timeCur表示
     自从上次播放一帧到现在经过了多少时间。
   所以如果每次当 timeNew - timeCur > 10的时候才进行一帧的
      播放,然后令timeCur = timeNew,以便进行下一帧播放时间间隔的
      控制。这样我们就可以控制在每个10ms内最多播放一帧,即对帧速进行
      了控制。

代码说明:

本例子主要的代码是地图绘制函数,地图绘制函数实现了几个坐标变换。

DrawMap proc hdc1:HDC
 LOCAL i:DWORD
 LOCAL row:DWORD
 LOCAL col:DWORD
 LOCAL xAbs:DWORD
 LOCAL yAbs:DWORD
 LOCAL vx:DWORD
 LOCAL vy:DWORD
 LOCAL vp:POINT
 
 invoke BitBlt,buffer,0,0,640,480,bgDC,0,0,SRCCOPY
 mov i,0 
 .repeat
  ;把数组索引转变成地图坐标
  xor edx,edx
  mov eax,i
  mov ebx,20
  div ebx
  mov row,edx
  mov col,eax  
  ;把地图坐标转变成贴图坐标(绝对坐标)
  mov eax,row
  mov ebx,64/2
  mul ebx
  mov xAbs,eax
  mov eax,col
  mul ebx
  sub xAbs,eax
  mov eax,xstart
  add xAbs,eax
  
  mov eax,col
  mov ebx,32/2
  mul ebx
  mov yAbs,eax
  mov eax,row
  mul ebx
  add yAbs,eax
  mov eax,ystart
  add yAbs,eax
  ;根据视口坐标,把贴图坐标转变成窗口(视口)坐标
  mov eax,xAbs
  sub eax,viewRect.left
  mov vx,eax
  mov eax,yAbs
  sub eax,viewRect.top
  mov vy,eax
  ;进行屏幕贴图
  mov eax,i
  .if mapInfo[eax]==0
   invoke BitBlt,buffer,vx,vy,64,32,tile0,64,0,SRCAND
   invoke BitBlt,buffer,vx,vy,64,32,tile0,0,0,SRCPAINT
  .elseif mapInfo[eax]==1
   invoke BitBlt,buffer,vx,vy,64,32,tile1,64,0,SRCAND
   invoke BitBlt,buffer,vx,vy,64,32,tile1,0,0,SRCPAINT
  .elseif mapInfo[eax]==2
   invoke BitBlt,buffer,vx,vy,64,32,tile2,64,0,SRCAND
   invoke BitBlt,buffer,vx,vy,64,32,tile2,0,0,SRCPAINT
  .else
   invoke BitBlt,buffer,vx,vy,64,32,tile3,64,0,SRCAND
   invoke BitBlt,buffer,vx,vy,64,32,tile3,0,0,SRCPAINT
  .endif
  ;
  add i,1
 .until i==400
 
 ; 处理景物
 mov i,0 
 .repeat
  ;把数组索引转变成地图坐标
  xor edx,edx
  mov eax,i
  mov ebx,20
  div ebx
  mov row,edx
  mov col,eax  
  ;把地图坐标转变成贴图坐标(绝对坐标)
  mov eax,row
  mov ebx,64/2
  mul ebx
  mov xAbs,eax
  mov eax,col
  mul ebx
  sub xAbs,eax
  mov eax,xstart
  add xAbs,eax
  
  mov eax,col
  mov ebx,32/2
  mul ebx
  mov yAbs,eax
  mov eax,row
  mul ebx
  add yAbs,eax
  mov eax,ystart
  add yAbs,eax
  ;根据视口坐标,把贴图坐标转变成窗口(视口)坐标
  mov eax,xAbs
  sub eax,viewRect.left
  mov vx,eax
  mov eax,yAbs
  sub eax,viewRect.top
  mov vy,eax
  ;进行屏幕贴图
  mov eax,i
  .if sceneInfo[eax]==1
   add vx,7
   sub vy,44
   invoke BitBlt,buffer,vx,vy,50,60,scene1,50,0,SRCAND
   invoke BitBlt,buffer,vx,vy,50,60,scene1,0,0,SRCPAINT
  .elseif sceneInfo[eax]==2
   add vx,7
   sub vy,30
   invoke BitBlt,buffer,vx,vy,50,60,scene2,50,0,SRCAND
   invoke BitBlt,buffer,vx,vy,50,60,scene2,0,0,SRCPAINT
  .endif
  ;
  add i,1
 .until i==400
 
 ;<<<<<<<<<<<<<<<<<<处理精灵<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 mov eax,viewRect.left
 mov vp.x,eax
 mov eax,viewRect.top
 mov vp.y,eax
 invoke GetStatus
 .if eax==0
  invoke SetDir
 .endif
 invoke DrawSprite,buffer,vp
  ; 打印程序信息  
  invoke SetBkMode,buffer,TRANSPARENT
  invoke TextOut,buffer,50,300,addr frameInfo,28
  invoke TextOut,buffer, 50,350,addr appInfo,sizeof appInfo - 1
  invoke TextOut,buffer,55, 400,addr authInfo,sizeof authInfo - 1
  invoke SetBkMode,buffer,OPAQUE
  invoke BitBlt,hdc1,0,0,640,480,buffer,0,0,SRCCOPY
 ret

DrawMap endp





posted on 2008-06-05 17:02 信息加油站义工 阅读(2677) 评论(17)  编辑 收藏 所属分类: 8. 信息技术2. c++与汇编4. 游戏编程

评论

#1楼  2008-06-05 17:22 kkun      

汇编写游戏,
  回复  引用  查看    

#2楼  2008-06-05 17:29 wfa [未注册用户]

主要的功能还是调用库函数的,你看看,一大堆Invoke。   回复  引用    

#3楼  2008-06-05 17:48 大石头      

郁闷,还真是用汇编来写游戏……为了更好的性能??还是为了别的什么?   回复  引用  查看    

#4楼  2008-06-05 17:52 红尘中迷茫      

。。。改写成C#如何?   回复  引用  查看    

#5楼  2008-06-05 20:54 Phinecos(洞庭散人)      

win32汇编,一堆windows API,不过真有必要这么干么?呵呵   回复  引用  查看    

#6楼  2008-06-05 22:25 BAsil      

厉害,不懂   回复  引用  查看    

#7楼  2008-06-05 22:48 曲滨*銘龘鶽      

那里有哪么多API?
不多不多,cnblogs 改成多语言的博客了?
真的吗?   回复  引用  查看    

#8楼  2008-06-06 00:21 簡簡單單..      

建议转C#..   回复  引用  查看    

#9楼  2008-06-06 00:46 Cat Chen      

其实用XNA写不就好了嘛,简单易懂。   回复  引用  查看    

#10楼  2008-06-06 07:34 wuya2 [未注册用户]

我觉得图形绘制部分用DirectX也许比调用GDI API效率更高;
而一般的地方用不用汇编差异不大,不如用C#之类的来得直观。   回复  引用    

#11楼  2008-06-06 08:31 1-2-3      

女性霸王龙?狂晕啊。不过真的很可爱。   回复  引用  查看    

#12楼  2008-06-06 10:17 gillspent      

用汇编运行效率相对来说,要比其他的高,但是编写起来是要花点力气   回复  引用  查看    

#13楼  2008-06-06 13:19 ! [未注册用户]

@1-2-3
哇,你都看到性别了,真是非凡啊   回复  引用    

#14楼  2008-06-06 15:09 HedgeHog      

最近在做网页游戏,不过是用 asp.net 写,帮顶了   回复  引用  查看    

#15楼  2008-06-06 15:10 HedgeHog      

最近 cnblogs 上,越来越多各种语言的作品   回复  引用  查看    

#16楼  2008-06-06 17:27 狼Robot      

强.   回复  引用  查看    

#17楼  2008-06-06 23:26 蜀山雪狼      

一看到radasm头都大了。
楼主真强。   回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-06-09 19:39 编辑过


相关链接: