|
|
发表于 2015-6-9 09:29:48
|
显示全部楼层
- Public Class STG3D
- ' STG相关的数据结构和函数
- ' 此类不可实例化
- Public Const DivideNum As Integer = 12
- Public Const JUDGE_GRAZE As Integer = 1
- Public Const JUDGE_MISS As Integer = 2
- Public Const JUDGE_AWAY As Integer = 3
- Public Const TEX_SPHERE As Integer = -2
- Public Const TEX_CIRCLE As Integer = -1
- Public Class Bullet
- ' 抽象的弹幕类
- ' 也可作为物体的基类
- Private Position As Base.Point3D
- Private Speed As Base.Point3D
- Private Rotate As Base.Point3D
- Private Scale As Base.Point3D
- Private TexPtr As Integer
- Private Texture As DxVB.DxImage
- Public IsEnabled As Boolean
- Public IsGrazed As Boolean
- Public Sub New()
- Position.x = 0 : Position.y = 0 : Position.z = 0
- Speed.x = 0 : Speed.y = 0 : Speed.z = 0
- Rotate.x = 0 : Rotate.y = 0 : Rotate.z = 0
- Scale.x = 0 : Scale.y = 0 : Scale.z = 0
- TexPtr = 0 : IsEnabled = False : IsGrazed = True
- Texture = New DxVB.DxImage
- End Sub
- Public Sub New(ByVal Texture As DxVB.DxImage)
- Position.x = 0 : Position.y = 0 : Position.z = 0
- Speed.x = 0 : Speed.y = 0 : Speed.z = 0
- Rotate.x = 0 : Rotate.y = 0 : Rotate.z = 0
- Scale.x = 0 : Scale.y = 0 : Scale.z = 0
- TexPtr = Texture.Handle : IsEnabled = False : IsGrazed = True
- Me.Texture = Texture
- End Sub
- Public Sub SetTexture(ByVal Texture As DxVB.DxImage)
- TexPtr = Texture.Handle
- Me.Texture = Texture
- End Sub
- Public Function GetPosition() As Base.Point3D
- Return Position
- End Function
- Public Sub SetPosition(ByVal x As Double, ByVal y As Double, ByVal z As Double)
- Position.x = x : Position.y = y : Position.z = z
- End Sub
- Public Sub SetPosition(ByRef Point As Base.Point3D)
- Position = Point
- End Sub
- Public Function GetSpeed() As Base.Point3D
- Return Speed
- End Function
- Public Sub SetSpeed(ByVal x As Double, ByVal y As Double, ByVal z As Double)
- Speed.x = x : Speed.y = y : Speed.z = z
- End Sub
- Public Sub SetSpeed(ByRef Point As Base.Point3D)
- Speed = Point
- End Sub
- Public Sub SetRotate(ByVal x As Double, ByVal y As Double, ByVal z As Double)
- Rotate.x = x : Rotate.y = y : Rotate.z = z
- End Sub
- Public Sub SetScale(ByVal x As Double, ByVal y As Double, ByVal z As Double)
- Scale.x = x : Scale.y = y : Scale.z = z
- End Sub
- Public Function PreJudge(ByRef Point As Base.Point3D, ByVal Range As Double) As Boolean
- Return Math.Abs(Point.x - Position.x) < Range And Math.Abs(Point.y - Position.y) < Range And Math.Abs(Point.z - Position.z) < Range
- End Function
- Public Function PreJudge(ByRef Point As Base.Point3D, ByVal RangeX As Double, ByVal RangeY As Double, ByVal RangeZ As Double) As Boolean
- Return Math.Abs(Point.x - Position.x) < RangeX And Math.Abs(Point.y - Position.y) < RangeY And Math.Abs(Point.z - Position.z) < RangeZ
- End Function
- Public Function Judge(ByRef Point As Base.Point3D) As Integer
- If (Base.Distance3D(Point, Position) > Base.Average3D(Scale) * 1.5D) Then
- Return JUDGE_AWAY
- ElseIf (Base.Distance3D(Point, Position) > Base.Average3D(Scale)) Then
- Return JUDGE_GRAZE
- Else
- Return JUDGE_MISS
- End If
- End Function
- Public Function Distance(ByRef Bullet As Bullet) As Single
- Return Base.Distance3D(Position, Bullet.GetPosition())
- End Function
- Public Sub Draw()
- 'If TexPtr = -2 Then DxVB.DrawSphere(Position.x, Position.y, Position.z, Base.Average3D(Scale), DivideNum, 255, 255, 255, 0, 0, 0, True)
- 'If TexPtr = -1 Then DxVBDLL.DX.DrawCircle(Position.x, Position.z, Base.Average3D(Scale), DX.GetColor(255, 255, 255))
- 'If TexPtr > 0 Then DxVB.DrawPic(Texture, Position.x, Position.z)
- If TexPtr = 0 Then DX.DrawPixel(Position.x, Position.z, &HFFFFFF)
- DxVB.DrawPic(Texture, Position.x, Position.z, Base.Average3D(Rotate))
- End Sub
- End Class
- Public Class STGCore
- ' STG的核心函数在这里
- ' 包括绘制,判定和控制
- ' 弹幕生成需要继承这个类
- ' 此类需要实例化
- Protected ArrayNumA As Integer
- Protected ArrayNumB As Integer
- Protected Bullets As Bullet(,)
- Public Shared Player As Bullet
- Protected Shared OriPlayer As Base.Point3D
- Protected Shared GameCenter As Bullet
- Protected CorePosition As Bullet
- Protected Shared GameRange As Double
- Protected Shared DefaultTex As Integer
- Protected Shared Graze, Miss, Num As Integer
- 'Protected STGThread As Thread
- Public Shared Sub InitShared(ByVal CenterX As Double, ByVal CenterY As Double, ByVal CenterZ As Double, ByVal Range As Double, _
- ByVal PlayerX As Double, ByVal PlayerY As Double, ByVal PlayerZ As Double, ByVal PlayerSize As Double, ByVal DefaultTexture As Integer)
- Player = New Bullet(New DxVB.DxImage)
- Player.SetPosition(PlayerX, PlayerY, PlayerZ)
- Player.SetScale(PlayerSize, PlayerSize, PlayerSize)
- Player.IsEnabled = True
- OriPlayer = Player.GetPosition()
- GameCenter = New Bullet()
- GameCenter.SetPosition(CenterX, CenterY, CenterZ)
- GameRange = Range : DefaultTex = DefaultTexture
- Graze = 0 : Miss = 0 : Num = 0
- End Sub
- 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, _
- ByVal PlayerX As Double, ByVal PlayerY As Double, ByVal PlayerZ As Double, ByVal PlayerSize As Double, ByVal DefaultTexture As Integer)
- ArrayNumA = ArrayNum1
- ArrayNumB = ArrayNum2
- ReDim Bullets(ArrayNumA, ArrayNumB)
- InitBullet()
- Player = New Bullet(New DxVB.DxImage)
- Player.SetPosition(PlayerX, PlayerY, PlayerZ)
- Player.SetScale(PlayerSize, PlayerSize, PlayerSize)
- Player.IsEnabled = True
- OriPlayer = Player.GetPosition()
- GameCenter = New Bullet()
- GameCenter.SetPosition(CenterX, CenterY, CenterZ)
- CorePosition = New Bullet()
- CorePosition.SetPosition(CenterX, CenterY, CenterZ)
- GameRange = Range : DefaultTex = DefaultTexture
- 'STGThread = New Thread(JudgeACtrl)
- End Sub
- Public Sub New(ByVal ArrayNum1 As Integer, ByVal ArrayNum2 As Integer, ByVal CenterX As Double, ByVal CenterY As Double, ByVal CenterZ As Double)
- ArrayNumA = ArrayNum1
- ArrayNumB = ArrayNum2
- ReDim Bullets(ArrayNumA, ArrayNumB)
- InitBullet()
- CorePosition = New Bullet()
- CorePosition.SetPosition(CenterX, CenterY, CenterZ)
- 'STGThread = New Thread(JudgeACtrl)
- End Sub
- Public Sub Run()
- 'STGThread.Start();
- End Sub
- Public Sub Close()
- 'STGThread.Abort();
- End Sub
- Public Sub GetInfo(ByVal x As Single, ByVal y As Single)
- DxVB.DrawString("Graze: " + Graze.ToString(), x, y, 20)
- DxVB.DrawString("Miss: " + Miss.ToString(), x, y + 25, 20)
- DxVB.DrawString("Num: " + Num.ToString(), x, y + 50, 20)
- End Sub
- Public Shared Sub GetInfo(ByRef Miss As Integer, ByRef Graze As Integer, ByRef Num As Integer)
- Miss = STGCore.Miss : Graze = STGCore.Graze : Num = STGCore.Num
- End Sub
- Public Function GetCenter() As Base.Point3D
- Return CorePosition.GetPosition()
- End Function
- Public Sub SetCenter(ByVal Point As Base.Point3D)
- CorePosition.SetPosition(Point)
- End Sub
- Private Sub InitBullet()
- For i = 0 To Bullets.GetUpperBound(0) Step 1
- For j = 0 To Bullets.GetUpperBound(1) Step 1
- Bullets(i, j) = New Bullet()
- Next j
- Next i
- End Sub
- Public Sub MainCircle()
- GenBullet()
- JudgeBullet()
- DrawBullet()
- End Sub
- Public Sub MainCircle(ByVal Time As Long, ByVal JmpRate As Integer)
- GenBullet()
- JudgeBullet()
- If Time Mod JmpRate = 0 Then DrawBullet()
- End Sub
- Protected Overridable Sub GenBullet()
- Dim TmpPoint As Base.Point3D
- For i = 0 To ArrayNumA - 1
- For j = 0 To ArrayNumB - 1
- If Not Bullets(i, j).IsEnabled Then
- TmpPoint.x = CorePosition.GetPosition().x
- TmpPoint.y = CorePosition.GetPosition().y
- TmpPoint.z = CorePosition.GetPosition().z
- Bullets(i, j).SetPosition(TmpPoint)
- Bullets(i, j).SetScale(20, 20, 20)
- Bullets(i, j).IsEnabled = True
- End If
- TmpPoint.x = 0
- TmpPoint.y = 0
- TmpPoint.z = 0
- TmpPoint.x = Bullets(i, j).GetPosition().x + TmpPoint.x
- TmpPoint.y = Bullets(i, j).GetPosition().y + TmpPoint.y
- TmpPoint.z = Bullets(i, j).GetPosition().z + TmpPoint.z
- If Base.Distance3D(Bullets(i, j).GetPosition(), GameCenter.GetPosition()) > GameRange Then
- Bullets(i, j) = New EngineCore.STG3D.Bullet()
- End If
- Next j
- Next i
- End Sub
- Protected Overridable Sub DrawBullet()
- For i = 0 To Bullets.GetUpperBound(0) Step 1
- For j = 0 To Bullets.GetUpperBound(1) Step 1
- If Bullets(i, j).IsEnabled Then Bullets(i, j).Draw()
- Next j
- Next i
- DrawPlayer()
- End Sub
- Protected Shared Sub DrawPlayer()
- Player.Draw()
- End Sub
- Protected Overridable Sub JudgeBullet()
- Num = 0
- For i = 0 To Bullets.GetUpperBound(0) Step 1
- For j = 0 To Bullets.GetUpperBound(1) Step 1
- If Bullets(i, j).IsEnabled Then
- If GameCenter.PreJudge(Bullets(i, j).GetPosition(), GameRange) Then
- Num = Num + 1
- Else
- Bullets(i, j) = New Bullet()
- End If
- End If
- Next j
- Next i
- For i = 0 To Bullets.GetUpperBound(0) Step 1
- For j = 0 To Bullets.GetUpperBound(1) Step 1
- If Bullets(i, j).IsEnabled Then
- If Bullets(i, j).IsEnabled And Player.PreJudge(Bullets(i, j).GetPosition(), GameRange) Then
- If Player.Judge(Bullets(i, j).GetPosition()) = JUDGE_AWAY And Not Bullets(i, j).IsGrazed Then
- Bullets(i, j).IsGrazed = True
- End If
- If Player.Judge(Bullets(i, j).GetPosition()) = JUDGE_GRAZE And Bullets(i, j).IsGrazed Then
- Bullets(i, j).IsGrazed = False
- Graze = Graze + 1
- End If
- If Player.Judge(Bullets(i, j).GetPosition()) = JUDGE_MISS Then
- Bullets(i, j) = New Bullet()
- Miss = Miss + 1
- Player.SetPosition(OriPlayer)
- End If
- End If
- End If
- Next j
- Next i
- End Sub
- Public Shared Sub Control()
- Dim TmpPos As Base.Point3D
- TmpPos = Player.GetPosition()
- If DefaultTex = TEX_SPHERE Then
- If Base.GetKey(Base.Keys.KeyLSHIFT) Or Base.GetKey(Base.Keys.KeyRSHIFT) Then
- If Base.GetKey(Base.Keys.KeyUP) Then
- TmpPos.z = TmpPos.z + 3
- End If
- If Base.GetKey(Base.Keys.KeyDOWN) Then
- TmpPos.z = TmpPos.z - 3
- End If
- If Base.GetKey(Base.Keys.KeyLEFT) Then
- TmpPos.x = TmpPos.x - 3
- End If
- If Base.GetKey(Base.Keys.KeyRIGHT) Then
- TmpPos.x = TmpPos.x + 3
- End If
- Else
- If Base.GetKey(Base.Keys.KeyUP) Then
- TmpPos.z = TmpPos.z + 5
- End If
- If Base.GetKey(Base.Keys.KeyDOWN) Then
- TmpPos.z = TmpPos.z - 5
- End If
- If Base.GetKey(Base.Keys.KeyLEFT) Then
- TmpPos.x = TmpPos.x - 5
- End If
- If Base.GetKey(Base.Keys.KeyRIGHT) Then
- TmpPos.x = TmpPos.x + 5
- End If
- End If
- Else
- If Base.GetKey(Base.Keys.KeyLSHIFT) Or Base.GetKey(Base.Keys.KeyRSHIFT) Then
- If Base.GetKey(Base.Keys.KeyUP) Then
- TmpPos.z = TmpPos.z - 3
- End If
- If Base.GetKey(Base.Keys.KeyDOWN) Then
- TmpPos.z = TmpPos.z + 3
- End If
- If Base.GetKey(Base.Keys.KeyLEFT) Then
- TmpPos.x = TmpPos.x - 3
- End If
- If Base.GetKey(Base.Keys.KeyRIGHT) Then
- TmpPos.x = TmpPos.x + 3
- End If
- Else
- If Base.GetKey(Base.Keys.KeyUP) Then
- TmpPos.z = TmpPos.z - 6
- End If
- If Base.GetKey(Base.Keys.KeyDOWN) Then
- TmpPos.z = TmpPos.z + 6
- End If
- If Base.GetKey(Base.Keys.KeyLEFT) Then
- TmpPos.x = TmpPos.x - 6
- End If
- If Base.GetKey(Base.Keys.KeyRIGHT) Then
- TmpPos.x = TmpPos.x + 6
- End If
- End If
- End If
- If GameCenter.PreJudge(TmpPos, 432, 1, 504) Then Player.SetPosition(TmpPos)
- End Sub
- End Class
复制代码 这是我用的STG类,应该能做下参考。
继承STGCore类,重写GenBullet,再创建对象,执行MainCircle。
对于帧率控制
- Public Class FPSCounter
- ' 进行帧率计算和控制的类
- ' 此类需要实例化
- ' 精度为小数点后一位
- ' 其中的Update要加入主游戏循环
- Private StartTime As Integer
- Private Count As Integer
- Private FPSNum As Single
- Private Const N As Integer = 60
- Private Const FPS As Integer = 60
- Public Sub New()
- StartTime = 0
- Count = 0
- FPSNum = 0
- End Sub
- Public Sub Update()
- If Count = 0 Then
- StartTime = System.Environment.TickCount
- End If
- If Count = N Then
- Dim TmpTime As Integer = System.Environment.TickCount
- FPSNum = 1000.0F / ((CType(TmpTime, Single) - CType(StartTime, Single)) / CType(N, Single))
- Count = 0
- StartTime = TmpTime
- End If
- Count = Count + 1
- End Sub
- Public Sub WaitTime()
- Dim TookTime As Integer = System.Environment.TickCount - StartTime
- Dim WaitTime As Integer = Count * 1000 / FPS - TookTime
- If WaitTime > 0 Then
- DX.WaitTimer(WaitTime)
- End If
- End Sub
- Public Function GetFPS(ByVal Digits As Integer) As Single
- Return Math.Round(FPSNum, Digits)
- End Function
- Public Function GetFPS() As Single
- Return FPSNum
- End Function
- End Class
复制代码 感觉还是垂直同步方便(((
|
|