Käytän tässä LINSSI-koodivinkissä pohjalla jo aiemmin julkaistua "Monta-spriteä"-koodivinkkiä. Muutosten takia laitan koko koodin.
Muutokset tehty 05.01.2006
Tekniikka:
Pyöreän linssin toteutuksessa käytetään "StretchBlt", API-funktiota.
Vaiheet linssin tekemiseksi:
1) Kopioidaan ja suurennetaan sprite()-kuvakontrolliin alue 48*48, kokoon 60*60
2) Maskataan kuvalla, jossa valkoinen pallo ja mustat reunat vbSrcAnd-toiminnolla, jolloin kuvasta korvataan reunalla olevat osat valkoisella.
3) Kopioidaan alkuperäisestä neliö normaali 60*60
Maskataan kuvalla, jossa valkoiset reunat ja musta pallo keskellä vbSrcAnd-toiminnolla, jolloin kuvasta saadaan musta ympyrä, jossa kuvan reuna.
4) Yhdistetään kaksi Spriteä vbSrcPaint-toiminnolla.
5) Siirretään kuva näytölle vbSrcCopy-toiminnolla, jolloin linssi on valmis.
Huomaa, että sprite()-muuttujassa olevat koordinaatit ovat suurentamattoman linssin koordinaatteja (48*48). Suurennoksen jälkeen linssi sijoitetaan suuremman kokonsa takia hieman ylä-vasemmalle, jolloin keskipiste pysyy samana.
Välkkymisen estämiseksi käytetään kaksoispuskurointia.
Kontrollit Form PL:ssä
Maski(0) on 60*60 pistettä. Valkoinen ympyrä ja mustat reunat.
Maski(1) on 60*60 pistettä. Musta ympyrä ja valkoiset reunat.
pSprite() 0-5 (60*60) pistettä.
pSprite() 6-11 (60*60) pistettä. (Tarvitaan muokkauksessa apuna)
pKuva, Tulostettava kuva
Timer1, ajastin interval = 20
Formi F2!Buffer Samankokoinen kuva kuin pKuva, Alkuperäisen kuvan talletuspaikka.
Formi F3!Buffer Samankokoinen kuva kuin pKuva, Tähän kuvaan piirretään piilossa.
Koska maskeja on vaikea kuvailla tämän tarkemmin hae koko koodin ZIP-versio kotisivuiltani.
http://koti.mbnet.fi/joresoft/Download/Esim/Linssi esim.zip
Form PL
Option Explicit Private Sub Form_Load() Dim I%, J%, Lupa As Boolean For I = 0 To 5 Do Sprite(I).X = Rand(pKuva.Width) Sprite(I).Y = Rand(pKuva.Height) Do Sprite(I).SX = (Rand(2) - 1) * Rand(3) Sprite(I).SY = (Rand(2) - 1) * Rand(3) Loop Until Sprite(I).SX <> 0 And Sprite(I).SY <> 0 Sprite(I).Z = 1 Sprite(I).On = True Sprite(I).Value = I Sprite(I).Mask = 0 Sprite(I).Old = I Sprite(I).ScaleX = pSprite(I).ScaleWidth Sprite(I).ScaleY = pSprite(I).ScaleHeight Lupa = True 'Asetetaan spritet kuvaan If I > 0 Then For J = 0 To 5 If I <> J Then If OnkoTörmäys(Sprite(J).X, Sprite(J).Y, Sprite(I).X, Sprite(I).Y, Sprite(J).ScaleX, Sprite(J).ScaleY) Then Lupa = False End If End If Next J End If Loop Until Lupa Next I Timer1.Enabled = True End Sub Private Sub Form_Unload(Cancel As Integer) End End Sub Private Sub Timer1_Timer() Dim I%, J% Timer1.Enabled = False ' Sammutetaan tämä ajastin For I = 0 To 5 ' käydään läpi Spritet 0 - 5 Sprite(I).X = Sprite(I).X + Sprite(I).SX ' Yksi askel X-suuntaan 'Onko törmännyt toisiin? For J = 0 To 5 If I <> J Then If OnkoTörmäys(Sprite(J).X, Sprite(J).Y, Sprite(I).X, Sprite(I).Y, Sprite(J).ScaleX, Sprite(J).ScaleY) Then 'on törmäys, käännetään suunta Sprite(I).SX = -Sprite(I).SX Sprite(J).SX = -Sprite(J).SX Sprite(I).X = Sprite(I).X + Sprite(I).SX End If End If Next J 'Onko mennyt ylos kuvan raunan? käännetään jos näin on If Sprite(I).X + Sprite(I).ScaleX > pKuva.Width + 12 Then Sprite(I).SX = -1: Sprite(I).X = Sprite(I).X - 1 If Sprite(I).X - 16 < 0 Then Sprite(I).SX = 1: Sprite(I).X = Sprite(I).X + 1 Sprite(I).Y = Sprite(I).Y + Sprite(I).SY 'Onko spritet tärmänneet toisiinsa? For J = 0 To 5 If J <> I Then If OnkoTörmäys(Sprite(J).X, Sprite(J).Y, Sprite(I).X, Sprite(I).Y, Sprite(J).ScaleX, Sprite(J).ScaleY) Then 'on, käännetään suunta Sprite(I).SY = -Sprite(I).SY Sprite(J).SY = -Sprite(J).SY Sprite(I).Y = Sprite(I).Y + Sprite(I).SY End If End If Next J 'Onko mennyt ylos kuvan raunan? käännetään jos näin on If Sprite(I).Y + Sprite(I).ScaleY > pKuva.Height + 12 Then Sprite(I).SY = -1: Sprite(I).Y = Sprite(I).Y - 1 If Sprite(I).Y - 16 < 0 Then Sprite(I).SY = 1: Sprite(I).Y = Sprite(I).Y + 1 'Piirretään kuvat PiirräLinssi Sprite(I) Next I 'Kopioidaan valmis kuva zz = BitBlt(PL!pKuva.hdc, 0, 0, PL!pKuva.ScaleWidth, PL!pKuva.ScaleHeight, F3!Buffer.hdc, 0, 0, vbSrcCopy) 'Asetetaan Puskuriin alkuperäinen kuva reuraavaa piirtoa varten. zz = BitBlt(F3!Buffer.hdc, 0, 0, PL!pKuva.ScaleWidth, PL!pKuva.ScaleHeight, F2!Buffer.hdc, 0, 0, vbSrcCopy) Timer1.Enabled = True End Sub
Moduuliin
Option Explicit 'Muuttujat Public Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'näiden avulla sitten saadaankin jo parempi kuvanlaatu. Private Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long, ByVal hStretchMode As Long) As Long Const STRETCHMODE = vbPaletteModeNone Type SpriteType 'Pelinapin yms. Muuttuja määrittely Value As Integer ' Arvo On As Boolean ' On/Off X As Integer ' X-paikka ruudulla Y As Integer ' Y-paikka Z As Integer ' Z-paikka SX As Integer ' Lisäyslaskuri SY As Integer Temp As Integer ' Väliaikainen tieto 'Kuvankäsittelyyn liittyvät muuttujat Old As Integer ' Mikä spitren vanha kuva käytössä Mask As Integer ' Mikä Spriten Maski käytössä ScaleX As Integer ' Spriten X-koko ScaleY As Integer ' Spriten Y-koko End Type Global Sprite(0 To 5) As SpriteType Global zz& Function Rand(R As Integer) Randomize Timer Rand = Int(Rnd(1) * R) DoEvents End Function Sub PiirräLinssi(I As SpriteType) Dim J% J = I.Value zz = SetStretchBltMode(F2!Buffer.hdc, STRETCHMODE) ' Asetetaan venytys tilaan. 'Otetaan suurennettava kohta zz = StretchBlt(PL!pSprite(J).hdc, 0, 0, 60, 60, F3!Buffer.hdc, I.X, I.Y, 48, 48, vbSrcCopy) 'Pyöreä maski mustat reunat zz = BitBlt(PL!pSprite(J).hdc, 0, 0, 60, 60, PL!pMask(0).hdc, 0, 0, vbSrcAnd) 'Kopioidaan alkuperäisestä neliö normaali koossa zz = BitBlt(PL!pSprite(J + 6).hdc, 0, 0, 60, 60, F2!Buffer.hdc, I.X - 12, I.Y - 12, vbSrcCopy) 'Maskataan se :Pyöreä maski valkoiset reunat zz = BitBlt(PL!pSprite(J + 6).hdc, 0, 0, 60, 60, PL!pMask(1).hdc, 0, 0, vbSrcAnd) 'Yhdistetään linssit, joka maskataan taustan kanssa. zz = BitBlt(PL!pSprite(J + 6).hdc, 0, 0, 60, 60, PL!pSprite(J).hdc, 0, 0, vbSrcPaint) 'sijoitetaan se hieman ylä-vasemmalle zz = BitBlt(F3!Buffer.hdc, I.X - 12, I.Y - 12, 60, 60, PL!pSprite(J + 6).hdc, 0, 0, vbSrcCopy) PL!pSprite(J).Refresh PL!pSprite(J + 6).Refresh End Sub Function OnkoTörmäys(X1%, Y1%, X2%, Y2%, SX%, SY%) As Boolean If X1 + SX > X2 Then If X1 < X2 + SX Then If Y1 + SY > Y2 Then If Y1 < Y2 + SY Then OnkoTörmäys = True End If End If End If End If End Function
Upea! Hienoa työtä.
Aikamoisen hieno!
löytyykö net:tille
theman.. StretchBlt-function korvaava komento VB.NET kielessä.
System.Drawing.Graphics.DrawImage
Katso VB.NET esimerkki "StretchBlt"-API:sta.
http://www.mentalis.org/apilist/StretchBlt.shtml
Varmaan osaat jo BitBlt-funktion?
Lisäys "PiirräLinssi"-aliohjelmaan.
laita viimeiseksi riviksi:
PL!pSprite(J).Refresh 'Näytetään spriten grafiikka.
Vähänkö hieno! *taputuksia*
EIpäs toimi linkki koodiin...
Nyt toimii, korjasin sen klo 0:22...
Oli jäänyt pois, kun jouduin asentaan kaikki uudestaan.. ;)
nothing works... (siis linkeistä)
Aihe on jo aika vanha, joten et voi enää vastata siihen.