设为首页收藏本站喵玉殿官方微博

 找回密码
 少女注册中
搜索
查看: 13888|回复: 19

[提问其他] 有自己做stg的前辈吗 想请教下弹幕的算法

  [复制链接]
发表于 2015-6-8 15:29:47 | 显示全部楼层 |阅读模式
用的是C++和DX9 (因为还是xp的系统 最高只能dx9了 然而大约不久后会换机子吧)
关于弹幕的移动 主要是考虑到弹幕并不一定是直线移动的(可能涉及奇怪的弧线或者中途变成狙之类的) 所以大概不大好用csv之类的记录一串数据直线移动就做出来
当前的做法是 弹幕的class里面有个函数指针成员pFunc 然后每次移动的时候如果pFunc==NULL 则当前的x和y坐标分别加上vx和vy 如果pFunc不是NULL则跑这个函数来改变弹幕的相应参数 这样就可以写各种不同的弹幕移动函数了

但是昨天在测试的时候试着写了个恋恋的本我(原作心弹素材 显示方面用的是sprite) 在全屏才100弹幕左右的时候就已经开始频繁的掉帧 而且我现在自机都没做 都是无判定弹幕 再加上弹幕判定可能会更卡
想请教下前辈们是怎么处理弹幕的算法的 谢谢大家
因为C++和DX9都是自学的 所以很多地方可能知识点有疏漏可能会有追问 或是问题表述不清楚还请见谅
发表于 2015-6-8 17:37:26 | 显示全部楼层
_(:з」∠)_真是厉害啊,【关注此问题←我也想知道(虽然我能撑几千弹幕才掉帧,,不过大概是电脑比较好的原因)

点评

soga 谢谢指导!  发表于 2015-6-9 04:12
这计算量其实是非常小的,一般没必要费心去优化这里。。。。还是看看楼下大神怎么说  发表于 2015-6-8 19:56
嗯嗯这个知道 我的意思是比如像沉静的月神这种卡 顶端的弹幕除非丧病的去合体擦弹 不然根本没可能碰到自机 就是觉得这种弹幕也加判定计算量太大了 但是又不能避免玩家跑顶上去  发表于 2015-6-8 18:47
我也记不清哪个帖子了,,反正大概就是勾股定理,然后自机是一个点,半径这个参数并不是真正的半径这样  发表于 2015-6-8 18:42
看到过前辈的关于辉针城巨型自机(划掉)巨型判定的帖子 是那个吗  发表于 2015-6-8 18:35
看一看我在百度贴吧发的帖子,可以参考一下神主是怎么进行的碰撞判定  发表于 2015-6-8 18:28
另外一个问题就是关于碰撞判定 我觉得每个子弹都每一帧判定一下与自机的距离这个计算量挺恐怖的 尤其是对于直线飞行的弹幕 加了碰撞计算量等于翻了一倍  发表于 2015-6-8 18:17
感觉还是我算法不到位 以前其实用地图编辑器在war3里做过神德和卫星向日葵 都是拿单位做的 神德同屏支持到1000+勉强不卡 war3里的单位都有很多一堆我不需要的参数 用来做弹幕其实浪费的资源比现在要多 然而并不很卡  发表于 2015-6-8 18:09
回复

使用道具 举报

发表于 2015-6-8 17:49:22 来自手机 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
回复

使用道具 举报

 楼主| 发表于 2015-6-8 18:01:59 | 显示全部楼层
song_5007 发表于 2015-6-8 17:37
_(:з」∠)_真是厉害啊,【关注此问题←我也想知道(虽然我能撑几千弹幕才掉帧,,不过大概是电脑比较好的原 ...

哇 几千弹幕很酷炫诶 请问前辈是什么做法

点评

不,,,仅仅是个弹幕乱飞的压力测试  发表于 2015-6-8 18:03
回复

使用道具 举报

 楼主| 发表于 2015-6-8 18:02:35 | 显示全部楼层
fancydz 发表于 2015-6-8 17:49
同关注此问题
因为找不到顺手的弹幕编写方式
所以一直处于半弃坑状态,一直在打别人家的飞机

我也在打别人的飞机(怎么听起来那么少儿不宜
回复

使用道具 举报

发表于 2015-6-8 21:29:12 | 显示全部楼层
你掉帧是用debug测的吗……
不论怎样,100弹就掉帧也太……

点评

诶 还有这个功能  发表于 2015-6-9 07:42
这个似乎不太好感觉……可以开个垂直同步然后一劳永逸……或者我在网上找到有个专门的类来解决这个问题  发表于 2015-6-9 07:27
啊 控帧是用的while(GetTickCount-time>fps)的循环 然后如果循环开始前就已经超过则显示一下 这样  发表于 2015-6-9 04:05
回复

使用道具 举报

发表于 2015-6-8 21:45:53 | 显示全部楼层
额这个。。。。我是用vb.net,大概2W之后才有比较明显掉帧。。。

点评

嗯……的确是在考虑改成这样的模式 一个函数然后里面跑循环  发表于 2015-6-9 07:32
嗯我看看……你需要用一个函数控制所有弹幕,比如你怎么用电脑绘制函数图像那样  发表于 2015-6-9 07:25
嗯 应该是我的算法问题吧  发表于 2015-6-9 04:06
回复

使用道具 举报

发表于 2015-6-9 00:55:19 | 显示全部楼层
刚刚看了一下,感觉本我[本能的释放]这张应该不难写,弹幕class里边存储几个简单数据即可:坐标,速度,角度,速度增量,角度增量。
放弹时以BOSS为坐标,有一定初速度,方向是圆形四周各个方向,速度增量设成负的,每次同方向发弹发两弹,然后把方向增量设成一正一副两个绝对值相等的数。最后在每帧处理的时候限定一下弹幕的最低速度就可以了。

这样就不用每个弹幕单跑一次函数了,只用作简单的加减法和三角函数计算就可以了。



这个效果其实不够好。

更可行的方法是弄个叫Anim的类,里边存储弹幕在不同时刻的数据。
在弹幕类里边声明anim为他的属性之一,平时可以空着,像这张卡的时候可以可以填上3个anim,
分别对应
1 弹幕开始发出时速度正常,只有一定角加速度的状态
2 弹幕转弯一段时间后减速,速度增量为负,角加速度随着减小的状态
3 弹幕不再减速后,只有速度和角度的状态

根据弹幕发出后的时间决定套用哪个anim的计算方式。
弹幕时间可以在每次帧处理时+1。


(以上均为口胡。)

点评

对于很特殊的子弹要不要用新的继承类(但是听说继承本身效率就不大好 不是很清楚底层实现)  发表于 2015-6-9 06:18
额 想了想 比如有那种 自机靠近会拐弯的子弹 这种子弹怎么用这个Anim类来实现?(如果不挂个函数在子弹类上的话)  发表于 2015-6-9 05:24
就是说用一个函数控制所有的弹幕怎么跑而不是每个弹幕挂钩一个函数么 Anim类这个主意不错 我晚点试试 谢谢指导!  发表于 2015-6-9 04:11
回复

使用道具 举报

发表于 2015-6-9 03:08:07 | 显示全部楼层
本帖最后由 krh 于 2015-6-8 14:11 编辑

100 确实太少了

是哪里搜索了 或者大量循环才会这样吧(看起来100*100 次计算距离比较符合计算机的速度

点评

估计就是每个弹幕都跑一个函数导致的 函数压入弹出的频率太高了  发表于 2015-6-9 04:11
回复

使用道具 举报

发表于 2015-6-9 09:29:48 | 显示全部楼层
  1. Public Class STG3D
  2.         ' STG相关的数据结构和函数
  3.         ' 此类不可实例化

  4.         Public Const DivideNum As Integer = 12

  5.         Public Const JUDGE_GRAZE As Integer = 1
  6.         Public Const JUDGE_MISS As Integer = 2
  7.         Public Const JUDGE_AWAY As Integer = 3

  8.         Public Const TEX_SPHERE As Integer = -2
  9.         Public Const TEX_CIRCLE As Integer = -1

  10.         Public Class Bullet
  11.             ' 抽象的弹幕类
  12.             ' 也可作为物体的基类

  13.             Private Position As Base.Point3D
  14.             Private Speed As Base.Point3D
  15.             Private Rotate As Base.Point3D
  16.             Private Scale As Base.Point3D
  17.             Private TexPtr As Integer
  18.             Private Texture As DxVB.DxImage
  19.             Public IsEnabled As Boolean
  20.             Public IsGrazed As Boolean

  21.             Public Sub New()
  22.                 Position.x = 0 : Position.y = 0 : Position.z = 0
  23.                 Speed.x = 0 : Speed.y = 0 : Speed.z = 0
  24.                 Rotate.x = 0 : Rotate.y = 0 : Rotate.z = 0
  25.                 Scale.x = 0 : Scale.y = 0 : Scale.z = 0
  26.                 TexPtr = 0 : IsEnabled = False : IsGrazed = True
  27.                 Texture = New DxVB.DxImage
  28.             End Sub

  29.             Public Sub New(ByVal Texture As DxVB.DxImage)
  30.                 Position.x = 0 : Position.y = 0 : Position.z = 0
  31.                 Speed.x = 0 : Speed.y = 0 : Speed.z = 0
  32.                 Rotate.x = 0 : Rotate.y = 0 : Rotate.z = 0
  33.                 Scale.x = 0 : Scale.y = 0 : Scale.z = 0
  34.                 TexPtr = Texture.Handle : IsEnabled = False : IsGrazed = True
  35.                 Me.Texture = Texture
  36.             End Sub

  37.             Public Sub SetTexture(ByVal Texture As DxVB.DxImage)
  38.                 TexPtr = Texture.Handle
  39.                 Me.Texture = Texture
  40.             End Sub

  41.             Public Function GetPosition() As Base.Point3D
  42.                 Return Position
  43.             End Function

  44.             Public Sub SetPosition(ByVal x As Double, ByVal y As Double, ByVal z As Double)
  45.                 Position.x = x : Position.y = y : Position.z = z
  46.             End Sub

  47.             Public Sub SetPosition(ByRef Point As Base.Point3D)
  48.                 Position = Point
  49.             End Sub

  50.             Public Function GetSpeed() As Base.Point3D
  51.                 Return Speed
  52.             End Function

  53.             Public Sub SetSpeed(ByVal x As Double, ByVal y As Double, ByVal z As Double)
  54.                 Speed.x = x : Speed.y = y : Speed.z = z
  55.             End Sub

  56.             Public Sub SetSpeed(ByRef Point As Base.Point3D)
  57.                 Speed = Point
  58.             End Sub

  59.             Public Sub SetRotate(ByVal x As Double, ByVal y As Double, ByVal z As Double)
  60.                 Rotate.x = x : Rotate.y = y : Rotate.z = z
  61.             End Sub

  62.             Public Sub SetScale(ByVal x As Double, ByVal y As Double, ByVal z As Double)
  63.                 Scale.x = x : Scale.y = y : Scale.z = z
  64.             End Sub

  65.             Public Function PreJudge(ByRef Point As Base.Point3D, ByVal Range As Double) As Boolean
  66.                 Return Math.Abs(Point.x - Position.x) < Range And Math.Abs(Point.y - Position.y) < Range And Math.Abs(Point.z - Position.z) < Range
  67.             End Function

  68.             Public Function PreJudge(ByRef Point As Base.Point3D, ByVal RangeX As Double, ByVal RangeY As Double, ByVal RangeZ As Double) As Boolean
  69.                 Return Math.Abs(Point.x - Position.x) < RangeX And Math.Abs(Point.y - Position.y) < RangeY And Math.Abs(Point.z - Position.z) < RangeZ
  70.             End Function

  71.             Public Function Judge(ByRef Point As Base.Point3D) As Integer
  72.                 If (Base.Distance3D(Point, Position) > Base.Average3D(Scale) * 1.5D) Then
  73.                     Return JUDGE_AWAY
  74.                 ElseIf (Base.Distance3D(Point, Position) > Base.Average3D(Scale)) Then
  75.                     Return JUDGE_GRAZE
  76.                 Else
  77.                     Return JUDGE_MISS
  78.                 End If
  79.             End Function

  80.             Public Function Distance(ByRef Bullet As Bullet) As Single
  81.                 Return Base.Distance3D(Position, Bullet.GetPosition())
  82.             End Function

  83.             Public Sub Draw()
  84.                 'If TexPtr = -2 Then DxVB.DrawSphere(Position.x, Position.y, Position.z, Base.Average3D(Scale), DivideNum, 255, 255, 255, 0, 0, 0, True)
  85.                 'If TexPtr = -1 Then DxVBDLL.DX.DrawCircle(Position.x, Position.z, Base.Average3D(Scale), DX.GetColor(255, 255, 255))
  86.                 'If TexPtr > 0 Then DxVB.DrawPic(Texture, Position.x, Position.z)
  87.                 If TexPtr = 0 Then DX.DrawPixel(Position.x, Position.z, &HFFFFFF)
  88.                 DxVB.DrawPic(Texture, Position.x, Position.z, Base.Average3D(Rotate))
  89.             End Sub
  90.         End Class

  91.         Public Class STGCore
  92.             ' STG的核心函数在这里
  93.             ' 包括绘制,判定和控制
  94.             ' 弹幕生成需要继承这个类
  95.             ' 此类需要实例化

  96.             Protected ArrayNumA As Integer
  97.             Protected ArrayNumB As Integer
  98.             Protected Bullets As Bullet(,)
  99.             Public Shared Player As Bullet
  100.             Protected Shared OriPlayer As Base.Point3D
  101.             Protected Shared GameCenter As Bullet
  102.             Protected CorePosition As Bullet
  103.             Protected Shared GameRange As Double
  104.             Protected Shared DefaultTex As Integer
  105.             Protected Shared Graze, Miss, Num As Integer
  106.             'Protected STGThread As Thread

  107.             Public Shared Sub InitShared(ByVal CenterX As Double, ByVal CenterY As Double, ByVal CenterZ As Double, ByVal Range As Double, _
  108.                             ByVal PlayerX As Double, ByVal PlayerY As Double, ByVal PlayerZ As Double, ByVal PlayerSize As Double, ByVal DefaultTexture As Integer)
  109.                 Player = New Bullet(New DxVB.DxImage)
  110.                 Player.SetPosition(PlayerX, PlayerY, PlayerZ)
  111.                 Player.SetScale(PlayerSize, PlayerSize, PlayerSize)
  112.                 Player.IsEnabled = True
  113.                 OriPlayer = Player.GetPosition()
  114.                 GameCenter = New Bullet()
  115.                 GameCenter.SetPosition(CenterX, CenterY, CenterZ)
  116.                 GameRange = Range : DefaultTex = DefaultTexture
  117.                 Graze = 0 : Miss = 0 : Num = 0
  118.             End Sub

  119.             Public Sub New(ByVal ArrayNum1 As Integer, ByVal ArrayNum2 As Integer, ByVal CenterX As Double, ByVal CenterY As Double, ByVal CenterZ As Double, ByVal Range As Double, _
  120.                             ByVal PlayerX As Double, ByVal PlayerY As Double, ByVal PlayerZ As Double, ByVal PlayerSize As Double, ByVal DefaultTexture As Integer)
  121.                 ArrayNumA = ArrayNum1
  122.                 ArrayNumB = ArrayNum2
  123.                 ReDim Bullets(ArrayNumA, ArrayNumB)
  124.                 InitBullet()
  125.                 Player = New Bullet(New DxVB.DxImage)
  126.                 Player.SetPosition(PlayerX, PlayerY, PlayerZ)
  127.                 Player.SetScale(PlayerSize, PlayerSize, PlayerSize)
  128.                 Player.IsEnabled = True
  129.                 OriPlayer = Player.GetPosition()
  130.                 GameCenter = New Bullet()
  131.                 GameCenter.SetPosition(CenterX, CenterY, CenterZ)
  132.                 CorePosition = New Bullet()
  133.                 CorePosition.SetPosition(CenterX, CenterY, CenterZ)
  134.                 GameRange = Range : DefaultTex = DefaultTexture
  135.                 'STGThread = New Thread(JudgeACtrl)
  136.             End Sub

  137.             Public Sub New(ByVal ArrayNum1 As Integer, ByVal ArrayNum2 As Integer, ByVal CenterX As Double, ByVal CenterY As Double, ByVal CenterZ As Double)
  138.                 ArrayNumA = ArrayNum1
  139.                 ArrayNumB = ArrayNum2
  140.                 ReDim Bullets(ArrayNumA, ArrayNumB)
  141.                 InitBullet()
  142.                 CorePosition = New Bullet()
  143.                 CorePosition.SetPosition(CenterX, CenterY, CenterZ)
  144.                 'STGThread = New Thread(JudgeACtrl)
  145.             End Sub

  146.             Public Sub Run()
  147.                 'STGThread.Start();
  148.             End Sub

  149.             Public Sub Close()
  150.                 'STGThread.Abort();
  151.             End Sub

  152.             Public Sub GetInfo(ByVal x As Single, ByVal y As Single)
  153.                 DxVB.DrawString("Graze: " + Graze.ToString(), x, y, 20)
  154.                 DxVB.DrawString("Miss:  " + Miss.ToString(), x, y + 25, 20)
  155.                 DxVB.DrawString("Num: " + Num.ToString(), x, y + 50, 20)
  156.             End Sub

  157.             Public Shared Sub GetInfo(ByRef Miss As Integer, ByRef Graze As Integer, ByRef Num As Integer)
  158.                 Miss = STGCore.Miss : Graze = STGCore.Graze : Num = STGCore.Num
  159.             End Sub

  160.             Public Function GetCenter() As Base.Point3D
  161.                 Return CorePosition.GetPosition()
  162.             End Function

  163.             Public Sub SetCenter(ByVal Point As Base.Point3D)
  164.                 CorePosition.SetPosition(Point)
  165.             End Sub

  166.             Private Sub InitBullet()
  167.                 For i = 0 To Bullets.GetUpperBound(0) Step 1
  168.                     For j = 0 To Bullets.GetUpperBound(1) Step 1
  169.                         Bullets(i, j) = New Bullet()
  170.                     Next j
  171.                 Next i
  172.             End Sub

  173.             Public Sub MainCircle()
  174.                 GenBullet()
  175.                 JudgeBullet()
  176.                 DrawBullet()
  177.             End Sub

  178.             Public Sub MainCircle(ByVal Time As Long, ByVal JmpRate As Integer)
  179.                 GenBullet()
  180.                 JudgeBullet()
  181.                 If Time Mod JmpRate = 0 Then DrawBullet()
  182.             End Sub

  183.             Protected Overridable Sub GenBullet()
  184.                 Dim TmpPoint As Base.Point3D
  185.                 For i = 0 To ArrayNumA - 1
  186.                     For j = 0 To ArrayNumB - 1
  187.                         If Not Bullets(i, j).IsEnabled Then
  188.                             TmpPoint.x = CorePosition.GetPosition().x
  189.                             TmpPoint.y = CorePosition.GetPosition().y
  190.                             TmpPoint.z = CorePosition.GetPosition().z
  191.                             Bullets(i, j).SetPosition(TmpPoint)
  192.                             Bullets(i, j).SetScale(20, 20, 20)
  193.                             Bullets(i, j).IsEnabled = True
  194.                         End If
  195.                         TmpPoint.x = 0
  196.                         TmpPoint.y = 0
  197.                         TmpPoint.z = 0
  198.                         TmpPoint.x = Bullets(i, j).GetPosition().x + TmpPoint.x
  199.                         TmpPoint.y = Bullets(i, j).GetPosition().y + TmpPoint.y
  200.                         TmpPoint.z = Bullets(i, j).GetPosition().z + TmpPoint.z
  201.                         If Base.Distance3D(Bullets(i, j).GetPosition(), GameCenter.GetPosition()) > GameRange Then
  202.                             Bullets(i, j) = New EngineCore.STG3D.Bullet()
  203.                         End If
  204.                     Next j
  205.                 Next i
  206.             End Sub

  207.             Protected Overridable Sub DrawBullet()
  208.                 For i = 0 To Bullets.GetUpperBound(0) Step 1
  209.                     For j = 0 To Bullets.GetUpperBound(1) Step 1
  210.                         If Bullets(i, j).IsEnabled Then Bullets(i, j).Draw()
  211.                     Next j
  212.                 Next i
  213.                 DrawPlayer()
  214.             End Sub

  215.             Protected Shared Sub DrawPlayer()
  216.                 Player.Draw()
  217.             End Sub

  218.             Protected Overridable Sub JudgeBullet()
  219.                 Num = 0
  220.                 For i = 0 To Bullets.GetUpperBound(0) Step 1
  221.                     For j = 0 To Bullets.GetUpperBound(1) Step 1
  222.                         If Bullets(i, j).IsEnabled Then
  223.                             If GameCenter.PreJudge(Bullets(i, j).GetPosition(), GameRange) Then
  224.                                 Num = Num + 1
  225.                             Else
  226.                                 Bullets(i, j) = New Bullet()
  227.                             End If
  228.                         End If
  229.                     Next j
  230.                 Next i

  231.                 For i = 0 To Bullets.GetUpperBound(0) Step 1
  232.                     For j = 0 To Bullets.GetUpperBound(1) Step 1
  233.                         If Bullets(i, j).IsEnabled Then
  234.                             If Bullets(i, j).IsEnabled And Player.PreJudge(Bullets(i, j).GetPosition(), GameRange) Then
  235.                                 If Player.Judge(Bullets(i, j).GetPosition()) = JUDGE_AWAY And Not Bullets(i, j).IsGrazed Then
  236.                                     Bullets(i, j).IsGrazed = True
  237.                                 End If
  238.                                 If Player.Judge(Bullets(i, j).GetPosition()) = JUDGE_GRAZE And Bullets(i, j).IsGrazed Then
  239.                                     Bullets(i, j).IsGrazed = False
  240.                                     Graze = Graze + 1
  241.                                 End If
  242.                                 If Player.Judge(Bullets(i, j).GetPosition()) = JUDGE_MISS Then
  243.                                     Bullets(i, j) = New Bullet()
  244.                                     Miss = Miss + 1
  245.                                     Player.SetPosition(OriPlayer)
  246.                                 End If
  247.                             End If
  248.                         End If
  249.                     Next j
  250.                 Next i
  251.             End Sub

  252.             Public Shared Sub Control()
  253.                 Dim TmpPos As Base.Point3D
  254.                 TmpPos = Player.GetPosition()
  255.                 If DefaultTex = TEX_SPHERE Then
  256.                     If Base.GetKey(Base.Keys.KeyLSHIFT) Or Base.GetKey(Base.Keys.KeyRSHIFT) Then
  257.                         If Base.GetKey(Base.Keys.KeyUP) Then
  258.                             TmpPos.z = TmpPos.z + 3
  259.                         End If
  260.                         If Base.GetKey(Base.Keys.KeyDOWN) Then
  261.                             TmpPos.z = TmpPos.z - 3
  262.                         End If
  263.                         If Base.GetKey(Base.Keys.KeyLEFT) Then
  264.                             TmpPos.x = TmpPos.x - 3
  265.                         End If
  266.                         If Base.GetKey(Base.Keys.KeyRIGHT) Then
  267.                             TmpPos.x = TmpPos.x + 3
  268.                         End If
  269.                     Else
  270.                         If Base.GetKey(Base.Keys.KeyUP) Then
  271.                             TmpPos.z = TmpPos.z + 5
  272.                         End If
  273.                         If Base.GetKey(Base.Keys.KeyDOWN) Then
  274.                             TmpPos.z = TmpPos.z - 5
  275.                         End If
  276.                         If Base.GetKey(Base.Keys.KeyLEFT) Then
  277.                             TmpPos.x = TmpPos.x - 5
  278.                         End If
  279.                         If Base.GetKey(Base.Keys.KeyRIGHT) Then
  280.                             TmpPos.x = TmpPos.x + 5
  281.                         End If
  282.                     End If
  283.                 Else
  284.                     If Base.GetKey(Base.Keys.KeyLSHIFT) Or Base.GetKey(Base.Keys.KeyRSHIFT) Then
  285.                         If Base.GetKey(Base.Keys.KeyUP) Then
  286.                             TmpPos.z = TmpPos.z - 3
  287.                         End If
  288.                         If Base.GetKey(Base.Keys.KeyDOWN) Then
  289.                             TmpPos.z = TmpPos.z + 3
  290.                         End If
  291.                         If Base.GetKey(Base.Keys.KeyLEFT) Then
  292.                             TmpPos.x = TmpPos.x - 3
  293.                         End If
  294.                         If Base.GetKey(Base.Keys.KeyRIGHT) Then
  295.                             TmpPos.x = TmpPos.x + 3
  296.                         End If
  297.                     Else
  298.                         If Base.GetKey(Base.Keys.KeyUP) Then
  299.                             TmpPos.z = TmpPos.z - 6
  300.                         End If
  301.                         If Base.GetKey(Base.Keys.KeyDOWN) Then
  302.                             TmpPos.z = TmpPos.z + 6
  303.                         End If
  304.                         If Base.GetKey(Base.Keys.KeyLEFT) Then
  305.                             TmpPos.x = TmpPos.x - 6
  306.                         End If
  307.                         If Base.GetKey(Base.Keys.KeyRIGHT) Then
  308.                             TmpPos.x = TmpPos.x + 6
  309.                         End If
  310.                     End If
  311.                 End If
  312.                 If GameCenter.PreJudge(TmpPos, 432, 1, 504) Then Player.SetPosition(TmpPos)
  313.             End Sub
  314.         End Class
复制代码
这是我用的STG类,应该能做下参考。
继承STGCore类,重写GenBullet,再创建对象,执行MainCircle。

对于帧率控制
  1. Public Class FPSCounter
  2.             ' 进行帧率计算和控制的类
  3.             ' 此类需要实例化
  4.             ' 精度为小数点后一位
  5.             ' 其中的Update要加入主游戏循环

  6.             Private StartTime As Integer
  7.             Private Count As Integer
  8.             Private FPSNum As Single
  9.             Private Const N As Integer = 60
  10.             Private Const FPS As Integer = 60

  11.             Public Sub New()
  12.                 StartTime = 0
  13.                 Count = 0
  14.                 FPSNum = 0
  15.             End Sub

  16.             Public Sub Update()
  17.                 If Count = 0 Then
  18.                     StartTime = System.Environment.TickCount
  19.                 End If
  20.                 If Count = N Then
  21.                     Dim TmpTime As Integer = System.Environment.TickCount
  22.                     FPSNum = 1000.0F / ((CType(TmpTime, Single) - CType(StartTime, Single)) / CType(N, Single))
  23.                     Count = 0
  24.                     StartTime = TmpTime
  25.                 End If
  26.                 Count = Count + 1
  27.             End Sub

  28.             Public Sub WaitTime()
  29.                 Dim TookTime As Integer = System.Environment.TickCount - StartTime
  30.                 Dim WaitTime As Integer = Count * 1000 / FPS - TookTime

  31.                 If WaitTime > 0 Then
  32.                     DX.WaitTimer(WaitTime)
  33.                 End If
  34.             End Sub

  35.             Public Function GetFPS(ByVal Digits As Integer) As Single
  36.                 Return Math.Round(FPSNum, Digits)
  37.             End Function

  38.             Public Function GetFPS() As Single
  39.                 Return FPSNum
  40.             End Function

  41.         End Class
复制代码
感觉还是垂直同步方便(((

点评

当初我也想用但是有点蛋疼。。。于是就用了 override  发表于 2015-6-9 11:42
虚函数也没问题么 对这个比较纠结  发表于 2015-6-9 10:59
效率没问题,我目前就是这样处理的。而且C++下的效率还要更高  发表于 2015-6-9 10:42
那个垂直同步是DX自己的一个函数。  发表于 2015-6-9 10:42
说起来 这样的方案是否可取:定义一个弹幕基类(普通直线弹幕) 然后弹幕的移动函数为虚函数 对于各种曲线弹幕加减速弹幕或者飞到一半改变弹种之类的 分别定义不同的派生类 采用不同的实际移动函数 这样效率如何  发表于 2015-6-9 10:36
垂直同步是DX或者vb.net提供的功能还是一个自己写的函数?  发表于 2015-6-9 10:34
后面那个类不是用的垂直同步  发表于 2015-6-9 10:23
唔 看了下后面这段 这个也不是用的垂直同步吧?  发表于 2015-6-9 10:22
赞 我去试试  发表于 2015-6-9 10:16
C++继承和派生开销基本为0  发表于 2015-6-9 10:14
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 少女注册中

本版积分规则

合作与事务联系|无图版|手机版|小黑屋|喵玉殿

GMT+8, 2025-10-31 06:39

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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