游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5156|回复: 16

【急】如何在DD中将一个图片旋转一定的角度?

[复制链接]

5

主题

27

帖子

27

积分

注册会员

Rank: 2

积分
27
发表于 2005-10-23 21:48:00 | 显示全部楼层 |阅读模式
如题!望各位大侠赐教!!!

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-24 16:32:00 | 显示全部楼层

Re:【急】如何在DD中将一个图片旋转一定的角度?

'//*  ================== ddraw.bas ===========

'*****************************************************************
'
'IMPORTANT TO NOTE:
'
'When using resource files and the CreateSurfaceFromResource
'command in DirectX 7.0, you will not be able to run your program
'by simply pressing F5 or selecting the run menu item, you will
'get an error. dX7 will only recognize your resource file if you
'compile your program and RUN THE COMPILED VERSION.
'
' - Lucky
'
'*****************************************************************

'Major DX Objects
Dim dx As New DirectX7
Dim dd As DirectDraw7

Dim Primary As DirectDrawSurface7       'Primary surface
Dim BackBuffer As DirectDrawSurface7    'Backbuffer surface
Dim ddsdPrimary As DDSURFACEDESC2       'Primary surface description
Dim ddsdBackBuffer As DDSURFACEDESC2    'Backbuffer surface description

Dim Ship(39) As DirectDrawSurface7      'Array of surfaces that will contain our ship
Global Running As Boolean               'Determines if the program should still be running
Global Facing As Integer                'Determines the direction the ship is currently facing
Global Zoom As Single                   'How far are we zoomed?
Global ColourFill As Integer            'Variable that determines the colour of the background

Const SpriteWidth = 60                  'Width of the sprite we're displaying
Const SpriteHeight = 60                 'Height of the sprite we're displaying
   
Public Sub Initialize()

    'This routine initializes the display mode, and the primary/backbuffer complex
   
    'Handles errors
    On Local Error GoTo ErrOut
   
    'Creates the directdraw object
    Set dd = dx.DirectDrawCreate("")
      
    'Set the cooperative level and displaymode...
    Call dd.SetCooperativeLevel(FrmDirectX.hWnd, DDSCL_FULLSCREEN Or DDSCL_EXCLUSIVE Or DDSCL_ALLOWREBOOT)
    Call dd.SetDisplayMode(640, 480, 16, 0, DDSDM_DEFAULT)
   
    'Create the primary complex surface with one backbuffer
    ddsdPrimary.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
    ddsdPrimary.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX
    ddsdPrimary.lBackBufferCount = 1
    Set Primary = dd.CreateSurface(ddsdPrimary)
   
    'Get the backbuffer from the primary surface
    Dim caps As DDSCAPS2
    caps.lCaps = DDSCAPS_BACKBUFFER
    Set BackBuffer = Primary.GetAttachedSurface(caps)
   
    'Set the colour (for text output) of the backbuffer
    BackBuffer.SetForeColor vbWhite
   
    'Initialize the global variables
    Facing = 0
    Zoom = 1
    ColourFill = 0
    Running = True
   
    'Load the sprites
    LoadSurfaces
         
    'Clears the buffer
    ClearBuffer
   
    Exit Sub
   
ErrOut:
    Running = False             'If there's an error, exit the program
   
End Sub

Private Sub LoadSurfaces()

Dim i As Integer

    'This routine loads all of the surfaces we're going to be using
    For i = 0 To UBound(Ship)
        LoadSprite Ship(i), "vegan" & i, SpriteWidth, SpriteHeight, vbBlack
    Next

End Sub

Public Sub ClearBuffer()

Dim DestRect As RECT

    'This routine clears the backbuffer and displays the text
    With DestRect           'This rectangle must be defined the same as the screen (which we set as 640x480)
        .Bottom = 480
        .Left = 0
        .Right = 640
        .Top = 0
    End With
   
    'Fill the entire backbuffer with the colour dictated by "ColourFill"
    BackBuffer.BltColorFill DestRect, ColourFill
   
    'Draw the text on the backbuffer the describe the keys
    BackBuffer.DrawText 100, 100, &quotress ESC to exit", False
    BackBuffer.DrawText 100, 120, "Left or Right arrows to animate", False
    BackBuffer.DrawText 100, 140, "'O' button zooms out, 'I' zooms back in", False
    BackBuffer.DrawText 100, 160, "and Up or Down arrows to change backdrop.", False

End Sub

Public Sub LoadSprite(ByRef Sprite As DirectDrawSurface7, File As String, bWidth As Integer, bHeight As Integer, ColourKey As Integer)

Dim CKey As DDCOLORKEY
Dim ddsdNewSprite As DDSURFACEDESC2
   
    'This routine loads sprites in the FObject file and sets their colour keys
    ddsdNewSprite.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT           'Set the surface description to include the Capabilities, Width and Height
    ddsdNewSprite.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN                    'Set the surface's capabilities to be an offscreen surface
    ddsdNewSprite.lWidth = bWidth                                           'Set the width of the surface
    ddsdNewSprite.lHeight = bHeight                                         'Set the height of the surface
    Set Sprite = dd.CreateSurfaceFromResource("", File, ddsdNewSprite)      'Load the bitmap from the resource file into the surface using the surface description
    CKey.low = ColourKey                                                    'Set the low value of the colour key
    CKey.high = ColourKey                                                   'and the high value (in this case they're the same because we're not using a range)
    Sprite.SetColorKey DDCKEY_SRCBLT, CKey                                  'Set the sprites colourkey using the key just created

End Sub

Public Sub DisplaySprite()

Dim SrcRect As RECT
Dim DestRect As RECT

    'Set up the source rectangle
    With SrcRect
        .Bottom = SpriteHeight
        .Left = 0
        .Right = SpriteWidth
        .Top = 0
    End With
   
    'Set up the destination rectangle (taking zoom into account)
    With DestRect
        .Bottom = SpriteHeight * Zoom
        .Left = 0
        .Right = SpriteWidth * Zoom
        .Top = 0
    End With
   
    'Blit the surface on to the backbuffer at the specified location, using the colour key of the source
    BackBuffer.Blt DestRect, Ship(Facing), SrcRect, DDBLT_KEYSRC Or DDBLT_WAIT

End Sub

Public Sub Flip()

    'Flip the attached surface (the backbuffer) to the screen
    Primary.Flip Nothing, DDFLIP_WAIT
   
End Sub

Public Sub Terminate()

Dim i As Integer

    'This routine must destroy all surfaces and restore display mode
    Set Primary = Nothing
    Set BackBuffer = Nothing
    For i = 0 To UBound(Ship)
        Set Ship(i) = Nothing
    Next
    Call dd.RestoreDisplayMode
    Call dd.SetCooperativeLevel(FrmDirectX.hWnd, DDSCL_NORMAL)

End Sub

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-24 16:32:00 | 显示全部楼层

Re:【急】如何在DD中将一个图片旋转一定的角度?

'//* ============DInput.bas===================

'*****************************************************************
'
'IMPORTANT TO NOTE:
'
'When using resource files and the CreateSurfaceFromResource
'command in DirectX 7.0, you will not be able to run your program
'by simply pressing F5 or selecting the run menu item, you will
'get an error. dX7 will only recognize your resource file if you
'compile your program and RUN THE COMPILED VERSION.
'
' - Lucky
'
'*****************************************************************

'dX Variables
Dim dx As New DirectX7
Dim di As DirectInput
Dim diDEV As DirectInputDevice
Dim diState As DIKEYBOARDSTATE

'Loop counter
Dim i As Integer

'Public array showing which keys are active
Public aKeys(211) As Boolean

'Keycode constants
Global Const DIK_ESCAPE = 1
Global Const DIK_1 = 2
Global Const DIK_2 = 3
Global Const DIK_3 = 4
Global Const DIK_4 = 5
Global Const DIK_5 = 6
Global Const DIK_6 = 7
Global Const DIK_7 = 8
Global Const DIK_8 = 9
Global Const DIK_9 = 10
Global Const DIK_0 = 11
Global Const DIK_MINUS = 12
Global Const DIK_EQUALS = 13
Global Const DIK_BACKSPACE = 14
Global Const DIK_TAB = 15
Global Const DIK_Q = 16
Global Const DIK_W = 17
Global Const DIK_E = 18
Global Const DIK_R = 19
Global Const DIK_T = 20
Global Const DIK_Y = 21
Global Const DIK_U = 22
Global Const DIK_I = 23
Global Const DIK_O = 24
Global Const DIK_P = 25
Global Const DIK_LBRACKET = 26
Global Const DIK_RBRACKET = 27
Global Const DIK_RETURN = 28
Global Const DIK_LCONTROL = 29
Global Const DIK_A = 30
Global Const DIK_S = 31
Global Const DIK_D = 32
Global Const DIK_F = 33
Global Const DIK_G = 34
Global Const DIK_H = 35
Global Const DIK_J = 36
Global Const DIK_K = 37
Global Const DIK_L = 38
Global Const DIK_SEMICOLON = 39
Global Const DIK_APOSTROPHE = 40
Global Const DIK_GRAVE = 41
Global Const DIK_LSHIFT = 42
Global Const DIK_BACKSLASH = 43
Global Const DIK_Z = 44
Global Const DIK_X = 45
Global Const DIK_C = 46
Global Const DIK_V = 47
Global Const DIK_B = 48
Global Const DIK_N = 49
Global Const DIK_M = 50
Global Const DIK_COMMA = 51
Global Const DIK_PERIOD = 52
Global Const DIK_SLASH = 53
Global Const DIK_RSHIFT = 54
Global Const DIK_MULTIPLY = 55
Global Const DIK_LALT = 56
Global Const DIK_SPACE = 57
Global Const DIK_CAPSLOCK = 58
Global Const DIK_F1 = 59
Global Const DIK_F2 = 60
Global Const DIK_F3 = 61
Global Const DIK_F4 = 62
Global Const DIK_F5 = 63
Global Const DIK_F6 = 64
Global Const DIK_F7 = 65
Global Const DIK_F8 = 66
Global Const DIK_F9 = 67
Global Const DIK_F10 = 68
Global Const DIK_NUMLOCK = 69
Global Const DIK_SCROLL = 70
Global Const DIK_NUMPAD7 = 71
Global Const DIK_NUMPAD8 = 72
Global Const DIK_NUMPAD9 = 73
Global Const DIK_SUBTRACT = 74
Global Const DIK_NUMPAD4 = 75
Global Const DIK_NUMPAD5 = 76
Global Const DIK_NUMPAD6 = 77
Global Const DIK_ADD = 78
Global Const DIK_NUMPAD1 = 79
Global Const DIK_NUMPAD2 = 80
Global Const DIK_NUMPAD3 = 81
Global Const DIK_NUMPAD0 = 82
Global Const DIK_DECIMAL = 83
Global Const DIK_F11 = 87
Global Const DIK_F12 = 88
Global Const DIK_NUMPADENTER = 156
Global Const DIK_RCONTROL = 157
Global Const DIK_DIVIDE = 181
Global Const DIK_RALT = 184
Global Const DIK_HOME = 199
Global Const DIK_UP = 200
Global Const DIK_PAGEUP = 201
Global Const DIK_LEFT = 203
Global Const DIK_RIGHT = 205
Global Const DIK_END = 207
Global Const DIK_DOWN = 208
Global Const DIK_PAGEDOWN = 209
Global Const DIK_INSERT = 210
Global Const DIK_DELETE = 211

Public Sub Initialize()

    'Create the direct input object
    Set di = dx.DirectInputCreate()
        
    'Aquire the keyboard as the device
    Set diDEV = di.CreateDevice("GUID_SysKeyboard")
   
    'Get input nonexclusively, only when in foreground mode
    diDEV.SetCommonDataFormat DIFORMAT_KEYBOARD
    diDEV.SetCooperativeLevel FrmDirectX.hWnd, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE
    diDEV.Acquire
   
End Sub

Public Sub CheckKeys()
   
    'Get the current state of the keyboard
    diDEV.GetDeviceStateKeyboard diState
   
    'Scan through all the keys to check which are depressed
    For i = 1 To 211
        If diState.Key(i) <> 0 Then
            aKeys(i) = True             'If the key is pressed, set the appropriate array index to true
        Else
            aKeys(i) = False            'If the key is not pressed, set the appropriate array index to false
        End If
    Next
   
End Sub

Public Sub Terminate()
   
    'Unaquire the keyboard when we quit
    diDEV.Unacquire
   
End Sub

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-24 16:33:00 | 显示全部楼层

Re:【急】如何在DD中将一个图片旋转一定的角度?

'//*  ===========FrmDirectX.frm==============

'*****************************************************************
'
'IMPORTANT TO NOTE:
'
'When using resource files and the CreateSurfaceFromResource
'command in DirectX 7.0, you will not be able to run your program
'by simply pressing F5 or selecting the run menu item, you will
'get an error. dX7 will only recognize your resource file if you
'compile your program and RUN THE COMPILED VERSION.
'
' - Lucky
'
'*****************************************************************

Private Sub Form_Load()
   
    DDraw.Initialize            'Initialize DirectDraw
    DInput.Initialize           'Initialize DirectInput
    Me.Show                     'Show the form
    MainLoop                    'Run the main loop

End Sub

Private Sub MainLoop()

    On Error GoTo ErrOut
   
    Do While Running
        HandleKeys              'Check the DirectInput data for significant keypresses
        DDraw.DisplaySprite     'Display the appropriate frame of the sprite
        DDraw.Flip              'Flip the backbuffer to the screen
        DDraw.ClearBuffer       'Erase the backbuffer so that it can be drawn on again
        DoEvents                'Give windows its chance to do things
    Loop
   
ErrOut:

    ExitProgram                 'If an error occurs, leave the program
   
End Sub

Public Sub ExitProgram()

    DDraw.Terminate             'Unload the DirectDraw variables
    DInput.Terminate            'Unload the DirectInput variables
    End                         'End the program
   
End Sub

Private Sub HandleKeys()

    DInput.CheckKeys                                            'Get the current state of the keyboard
    If DInput.aKeys(DIK_ESCAPE) Then Running = False            'Has the escape key been pressed?
    If DInput.aKeys(DIK_UP) Then ColourFill = ColourFill + 1    'Increase the background colour if the up arrow is pressed
    If DInput.aKeys(DIK_DOWN) Then ColourFill = ColourFill - 1  'Decrease the background colour if the down arrow is pressed
    If DInput.aKeys(DIK_I) Then                                 'If the "I" key is pressed, zoom in
        If Zoom > 1 Then Zoom = 1                               'Limit zoom in to 1x
        If Zoom < 1 Then Zoom = Zoom + 0.01
    End If
    If DInput.aKeys(DIK_O) Then                                 'If the "O" key is pressed, zoom out
        If Zoom < 0.1 Then Zoom = 0.1                           'Limit zoom out to 10x
        If Zoom > 0.1 Then Zoom = Zoom - 0.01
    End If
    If DInput.aKeys(DIK_LEFT) Then                              'If the left arrow is pressed, rotate the ship left
        If Facing > 0 Then Facing = Facing - 1                  'If we're above zero, decrease the facing variable
        If Facing = 0 Then Facing = 39                          'If we're at zero, set the facing variable to 39 (the max)
    End If
    If DInput.aKeys(DIK_RIGHT) Then                             'If the right arrow is pressed, rotate the ship right
        If Facing < 39 Then Facing = Facing + 1                 'If we're below 39 then increase the facing variable
        If Facing = 39 Then Facing = 0                          'If we're at 39, set the facing variable to 0 (the min)
    End If

End Sub

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-24 16:35:00 | 显示全部楼层

Re: 【急】如何在DD中将一个图片旋转一定的角度?

例子
[em3] [em16] [em17] [em20] [em13]

sf_20051024163430.zip

78.69 KB, 下载次数:

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-26 18:40:00 | 显示全部楼层

Re: 【急】如何在DD中将一个图片旋转一定的角度?

'//* ***********************************************************************
'//* *  这一个替代人员组在顶点上面为一个子画面,考虑
'//* *  宽度,画面高度,顶涂颜色, 和转动角度
'//* *  注意: 半径, G 和 B 听写 [颜]色子画面将会是 -
'//* *  1,1,1 是正常,较低的数值将会使顶点变成彩色
'//* *  v1      * v3
'//* *  |\        |
'//* *  |  \      |
'//* *  |    \    |
'//* *  |      \  |
'//* *  |        \|
'//* *  * v0      * v2
'//* ***********************************************************************
Sub SetUpGeom(Verts() As D3DTLVERTEX, DDSurface As My_Surface, Src As RECT, Dest As RECT, ByVal R As Single, ByVal G As Single, ByVal B As Single, ByVal A As Single, ByVal Angle As Single)

    Dim SurfW As Single
    Dim SurfH As Single
    Dim XCenter As Single
    Dim YCenter As Single
    Dim Radius As Single
    Dim XCor As Single
    Dim YCor As Single
   'Call Err_Msg_Log.AppendToLog("SetUpGeom 参数设定 ...", True, True)
'//* Width of the surface
    SurfW = DDSurface.iWidth
    '//* Height of the surface
    SurfH = DDSurface.iHeight
    '//* Center coordinates on screen of the sprite
    '//*  置中在子画面的荧屏上的坐标
    XCenter = Dest.Left + (Dest.Right - Dest.Left - 1) / 2
    YCenter = Dest.Top + (Dest.Bottom - Dest.Top - 1) / 2
   
    '//* Calculate screen coordinates of sprite, and only rotate if necessary
    '//*  计算子画面的荧屏坐标, 和如果有需要的话只使旋转
    If Angle = 0 Then
        XCor = Dest.Left
        YCor = Dest.Bottom
    Else
        XCor = XCenter + (Dest.Left - XCenter) * Sin(Angle) + (Dest.Bottom - YCenter) * Cos(Angle)
        YCor = YCenter + (Dest.Bottom - YCenter) * Sin(Angle) - (Dest.Left - XCenter) * Cos(Angle)
    End If
   
    '//* 0 - Bottom left vertex
    dx.CreateD3DTLVertex XCor, YCor, 0, 1, dx.CreateColorRGBA(R, G, B, A), _
    0, Src.Left / SurfW, (Src.Bottom + 0.1) / SurfH, Verts(0)
    '//* Calculate screen coordinates of sprite, and only rotate if necessary
    If Angle = 0 Then
        XCor = Dest.Left
        YCor = Dest.Top
    Else
        XCor = XCenter + (Dest.Left - XCenter) * Sin(Angle) + (Dest.Top - YCenter) * Cos(Angle)
        YCor = YCenter + (Dest.Top - YCenter) * Sin(Angle) - (Dest.Left - XCenter) * Cos(Angle)
    End If
   
    '//*  高耸左边的顶 (1-Top left vertex)
    dx.CreateD3DTLVertex _
    XCor, YCor, 0, 1, _
    dx.CreateColorRGBA(R, G, B, A), 0, _
    Src.Left / SurfW, Src.Top / SurfH, Verts(1)
    '//* Calculate screen coordinates of sprite, and only rotate if necessary
    '//*  计算子画面的荧屏坐标, 和如果有需要的话只使旋转
    If Angle = 0 Then
        XCor = Dest.Right
        YCor = Dest.Bottom
    Else
        XCor = XCenter + (Dest.Right - XCenter) * Sin(Angle) + (Dest.Bottom - YCenter) * Cos(Angle)
        YCor = YCenter + (Dest.Bottom - YCenter) * Sin(Angle) - (Dest.Right - XCenter) * Cos(Angle)
    End If
   
    '//* 2 - Bottom right vertex
    dx.CreateD3DTLVertex XCor, YCor, 0, 1, _
    dx.CreateColorRGBA(R, G, B, A), 0, _
    (Src.Right + 0.1) / SurfW, (Src.Bottom + 0.1) / SurfH, Verts(2)
    '//* Calculate screen coordinates of sprite, and only rotate if necessary
    '//*  计算子画面的荧屏坐标, 和如果有需要的话只使旋转
    If Angle = 0 Then
        XCor = Dest.Right
        YCor = Dest.Top
    Else
        XCor = XCenter + (Dest.Right - XCenter) * Sin(Angle) + (Dest.Top - YCenter) * Cos(Angle)
        YCor = YCenter + (Dest.Top - YCenter) * Sin(Angle) - (Dest.Right - XCenter) * Cos(Angle)
    End If
    '//* 3 - Top right vertex
    dx.CreateD3DTLVertex XCor, YCor, 0, 1, _
    dx.CreateColorRGBA(R, G, B, A), 0, _
    (Src.Right + 0.1) / SurfW, Src.Top / SurfH, Verts(3)
End Sub


这个是主要的思路,图片任意角度,,

sf_20051026183938.rar

458.63 KB, 下载次数:

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-26 18:50:00 | 显示全部楼层

Re: 【急】如何在DD中将一个图片旋转一定的角度?

这个例子有你要的所有

R ,, F ,, + / - 等按键,屏幕上有说明,。。 [em5] [em4]
[em20] [em14] [em1] [em13] [em3] [em5]

sf_20051026184940.zip

69.91 KB, 下载次数:

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-26 19:04:00 | 显示全部楼层

Re:【急】如何在DD中将一个图片旋转一定的角度?

不是我写的例子:特此声明
不是我写的例子:特此声明
不是我写的例子:特此声明
不是我写的例子:特此声明
他人版权,出事不管
关税==灌水=落石出

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-10-26 19:04:00 | 显示全部楼层

Re:【急】如何在DD中将一个图片旋转一定的角度?

不是我写的例子:特此声明
不是我写的例子:特此声明
不是我写的例子:特此声明
不是我写的例子:特此声明
他人版权,出事不管
关税==灌水=落石出

5

主题

27

帖子

27

积分

注册会员

Rank: 2

积分
27
 楼主| 发表于 2005-11-8 13:41:00 | 显示全部楼层

Re:【急】如何在DD中将一个图片旋转一定的角度?

关键是...我需要的是图片旋转,不是将不同的图片显示啊...

这个例子实现的是按照用户的按键来装载不同的图片,出现动画的效果...
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 15:10

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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