Joe's mini Game. Die erste

Nabend,
ich habe mit ein Shape auf ein Image gelegt.
nun bewege ich mit den Cursortasten das Image.
Mit etwas Fantasie denkt man ein Auto fährt über eine Stadt.
es ruckelt noch etwas aber damit kann ich leben.
Nun überlege ich wie ich es verhinder das mein Shape über ein Haus auf meinem Image fährt. kann ich bereiche angeben ? oder soll ich dort ein Frame einbauen ? kann ich feststellen wenn mein „Auto“ einen Frame trifft. oder sagen das image.top 100 bis 200 & image.left 200 bis 300 ein „haus“ ist und wenn shape1 = image.top … msgbox „Auto Kaputt“

Argh was schreibe ich um Code zu posten … hmpf >
Option Explicit
Private Declare Function GetAsyncKeyState Lib „user32“ _
(ByVal vKey As Long) As Integer

Private Sub Timer1_Timer()
Dim i As Integer
For i = 0 To 255
'If GetAsyncKeyState(i) Then
’ List1.AddItem i
'End If

If GetAsyncKeyState(37) Then 'Bild nach rechts
Image1.Left = Image1.Left + 1
End If
If GetAsyncKeyState(38) Then 'Bild nach unten
Image1.Top = Image1.Top + 1
End If
If GetAsyncKeyState(39) Then 'Bild nach links
Image1.Left = Image1.Left - 1
End If
If GetAsyncKeyState(40) Then 'Bild nach Oben
Image1.Top = Image1.Top - 1
End If

Next

End Sub

N’abend Joe! :smile:

ich habe mit ein Shape auf ein Image gelegt.

Image … :frowning:

nun bewege ich mit den Cursortasten das Image.
Mit etwas Fantasie denkt man ein Auto fährt über eine Stadt.
es ruckelt noch etwas aber damit kann ich leben.

??? Das ruckelt und flimmert … brrrr. Nimm das OCX ‚TransParPic‘. Das ist dafür gebaut. Das habe ich Dir doch schon mal gemailt?

Nun überlege ich wie ich es verhinder das mein Shape über ein
Haus auf meinem Image fährt.

Ich male dann immer eine Straße auf das Bild, der Rest ist mit dem Lesen von Farben kein Problem mehr. Entweder direkt mit Farbe = Point(x,y), das ist aber langsam, oder das Bild in ein Array laden, rechnen … das geht schnell.

Gruß, Rainer

Och … und wieder bei 0 anfangen :stuck_out_tongue:P

wenn du die Mail heute geschickt hast kann es gut sein … Wenn nicht, hast du mir das noch nicht gemailt :stuck_out_tongue:

TransParPic ? Werde ich mal raussuchen.

mfg jonny

TransParPic ? wo bekomme ich die OCX ?

mfg jonny

Mail ist unterwegs (o.w.T.)

Nabend Joe :smile:

Mache es dir mal nicht so schwer. Auch denke mal nicht so kompliziert.
Aus deinem Ansatz könnte man etwas machen :wink: Aber das waere sehr rechenaufwaendig.
Es geht Viel einfacher :smile:

Nutze einfach die API IntersectRect! Sie gibt dir zurueck ob sich 2 Objecte ueberlappen!

Die Declaration und defintionschaut wiefolgt aus

Type RECT
 Left As Long
 Top As Long
 Right As Long
 Bottom As Long
End Type

Declare Function IntersectRect Lib "user32" Alias "IntersectRect" (lpDestRect As RECT, lpSrc1Rect As RECT, lpSrc2Rect As RECT) As Long

Sodele nun einmal zu den Parametern!
Der zweite und dritte Parameter, sind deine 2 Objecte, die auf Kollision überwacht werden sollen!
Im ersten Parameter bekommst du die Überlappung wieder!
Wenn du eine Variable als Boolean declarierst und dann die API Aufrufst bekommst du ein true zurueck wenn eine Kollision stattgefunden hat, ansonsten False :smile:

Bsp.:

dim Col as Boolean
Col = IntersectRect(udtTempRect, mudtRect1, mudtRect2)

Soll aber eine Kresiförmige Kollisionsabfrage stattfinden, so musst du nen bissl tricksen :smile: Verwende dazu folgende Function

Private Function GetDist(intX1 As Single, intY1 As Single, intX2 As Single, intY2 As Single) As Single
GetDist = Sqr((intX1 - intX2) ^ 2 + (intY1 - intY2) ^ 2)
End Function

Aber nun mal schnell nen kleines Demo, ist ungetestet sollte aber laufen :smile:

Option Explicit

Private Type RECT
 Left As Long
 Top As Long
 Right As Long
 Bottom As Long
End Type

Private Declare Function IntersectRect Lib "user32" (lpDestRect \_
 As RECT, lpSrc1Rect As RECT, lpSrc2Rect As RECT) As Long

Dim mudtRect1 As RECT
Dim mudtRect2 As RECT
'Kreis Koordinaten
Dim msngCircle1X As Single
Dim msngCircle1Y As Single
Dim msngCircle2X As Single
Dim msngCircle2Y As Single
'Flags
Dim mblnCircles As Boolean 'Es handelt sich um Kreise
Dim mblnRects As Boolean ' Es handelt sich um Rechtecke
Dim mblnCollision As Boolean 'Kollision
Dim mblnRunning As Boolean 'Ist gestartet
Dim mblnLeftKey As Boolean 'links bewegen
Dim mblnRightKey As Boolean 'Rechts bewegen
Dim mblnDownKey As Boolean 'Nach Unten bewegen
Dim mblnUpKey As Boolean 'Nach oben bewegen

Private Sub Form\_Load()
'Bei Verwendung von Kreisen, dann die kresikoordinaten festlegen!
'bsp
'Randomize
'msngCircle1X = Rnd() \* me.ScaleWidth
'msngCircle1Y = Rnd() \* me.ScaleHeight
'msngCircle2X = Rnd() \* me.ScaleWidth
'msngCircle2Y = Rnd() \* me.ScaleHeight
With mudtRect1
.Top = Daten Top von deinen Object
.Left = Daten Left von deinen Object
.Bottom = 'Unter Kante deines Objectes (Top + HEIGHT)
.Right = 'Rechte Kante deines Objectes (Left + WIDTH)
End With
With mudtRect2
.Top = Selbe wir mudtRect1 nur von dem anderen Object
.Left =Selbe wir mudtRect1 nur von dem anderen Object 
.Bottom = Selbe wir mudtRect1 nur von dem anderen Object
.Right = Selbe wir mudtRect1 nur von dem anderen Object
End With
mblnRects = True
mblnRunning = True
Do While mblnRunning
If mblnCircles Then
CircleCollision
MoveCircle
DrawCircle msngCircle1X, msngCircle1Y, 30, vbWhite
If mblnCollision Then
DrawCircle msngCircle2X, msngCircle2Y, 20, vbRed
Else
DrawCircle msngCircle2X, msngCircle2Y, 20, vbWhite
End If
ElseIf mblnRects Then
RectCollision
MoveRect
DrawRect mudtRect1, vbWhite
If mblnCollision Then
DrawRect mudtRect2, vbRed
Else
DrawRect mudtRect2, vbWhite
End If
End If
End If
DoEvents
Loop
End Sub

Private Sub MoveCircle()
If mblnDownKey = True Then msngCircle1Y = msngCircle1Y + 1
If mblnUpKey = True Then msngCircle1Y = msngCircle1Y - 1
If mblnLeftKey = True Then msngCircle1X = msngCircle1X - 1
If mblnRightKey = True Then msngCircle1X = msngCircle1X + 1
End Sub

Private Sub MoveRect()
With mudtRect1
If mblnDownKey = True Then
.Top = .Top + 1
.Bottom = .Bottom + 1
End If
If mblnUpKey = True Then
.Top = .Top - 1
.Bottom = .Bottom - 1
End If
If mblnLeftKey = True Then
.Left = .Left - 1
.Right = .Right - 1
End If
If mblnRightKey = True Then
.Left = .Left + 1
.Right = .Right + 1
End If
End With
End Sub

Private Sub CircleCollision()
mblnCollision = GetDist(msngCircle1X, msngCircle1Y, \_
msngCircle2X, msngCircle2Y) 

Sodele das muesste alles gewesen sein und wie du siehst eigentlich ganz simple. Die Eigentliche Abfrage bedarf nur 1 Zeile! :wink:

MfG Alex

Ich soll aber nur die OCX nutzen ?
bin mit dem ding gerade etwas überfordert.
Ich werde kurz nochmal den Tip von Anno in mein Ruckel Projekt einfügen.

Ist das mit dem Timer für bewegung ok ? oder wie würde man das machen ?

mfg jonny

Hi Joe,

Ich soll aber nur die OCX nutzen ?

Ja, klar. Ich habe nur den Quellcode gemailt, damit Du auch was lernst dabei. :smile: … (Der ist natürlich nicht von mir!)

bin mit dem ding gerade etwas überfordert.

Du mußt das entsprechende Projekt aufrufen. An der stelle, wo Du sonst die .exe erstellst, kannst Du hier das OCX erstellen. Schreib’s nach .\System32

Ich werde kurz nochmal den Tip von Anno in mein Ruckel Projekt
einfügen.

Ja, Kollisionsabfrage mit Regions ist natürlich Klasse, das hätte mir auch einfallen sollen. :frowning:

Ist das mit dem Timer für bewegung ok ? oder wie würde man das
machen ?

Jo, ist OK. Würde ich auch so machen.

Gruß, Rainer

Nabend Alex,
erstma danke,
kurze frage: habe mir eben mal deine Demo angepasst. sieht ganz net aus :stuck_out_tongue: und funktioniert. Nur ist das so zuviel Code bzw ich würde nur kopieren ohne zu verstehen …

frage:

Wenn ich nun 2 Shapes habe und diese aus Kollision prüfen möchte reicht dieser Code ? wohl nicht wenn ich mir deine Demo anschaue. oder?

Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Declare Function IntersectRect Lib „user32“ Alias „IntersectRect“ (lpDestRect As RECT, lpSrc1Rect As RECT, lpSrc2Rect As RECT) As Long

dim Col as BooleanCol = IntersectRect(udtTempRect, mudtRect1, mudtRect2)

Ich habe nun viele methoden gefunde.
Die eine Funktioniert mit GetPixel mit einem Farbcode ? ist das richtig ? DIe Kolisionsprüfung schein auf den ersten blick etwas komplex, und mit Koordinaten bin ich morgen noch am koords festlegen.

kurz noch eine andere frage:
Wenn ich mit Tabstrips arbeite. WO genau werden die namen der einzelnen Tabs festgelegt ?

danke .

GETPixel !!
soo. mit GetPixel scheint es am „leichtesten“ machbar. habe nur ein problem. Ich bewege mit dem Pfeiltasten das Image unter meinem SHape.
Wenn ich aber zum ermitteln des Pixels Shape1.Top & Shape1.left verwende. geht das nur so lange bis ich das Fenster verschiebe :confused:

oder habe ich gerade einen Denk fehler ? werde mal ne runde pennen bis später

mfg joe

Nabend Alex,

Guten Mprgen Joe,

erstma danke,

Nichts zu danken :smile:

kurze frage: habe mir eben mal deine Demo angepasst. sieht
ganz net aus :stuck_out_tongue: und funktioniert. Nur ist das so zuviel Code
bzw ich würde nur kopieren ohne zu verstehen …

Naja die eigentliche Prüfung bedarf nur 1 Zeile!
Es war wie gesagt ein Demo und dort ist die Bewegung etc. mit drinnen, deswegen ein wenig mehr Code. Auch ist da eine Prüfung drinnen wenn es sich um 2 Kreise handelt!

Was hast du denn daran nicht verstanden?

frage:

Wenn ich nun 2 Shapes habe und diese aus Kollision prüfen
möchte reicht dieser Code ? wohl nicht wenn ich mir deine Demo
anschaue. oder?

Klar, die API IntersectRect überprüft ob sie das Object deren Masse in Dem Typ RECT liegen überschneiden. Wenn ja dann bekommst du den Überlappungsbreich im 1 Parameter wieder :smile:
Bisp. du hast ein Auto das faehrt auf einer Strasse. Nun prüfst du ob das Auto die strasse verlaest.
bei geringfuegiger Abweichung, welche du mit der API aus dem ersten Parameter bekommst, sind nur 2 Raender ( Im rennen, zum Bsp.) über den Rand gefahren -> Auto faehrt weiter, aber Reifen sind dreckig und Auto schliert. Ist es zuviel so dreht sich dann das auto. Bei totaler Überlappung faehrt es vor einer Mauer etc.

Wie du siehst brauch man manchmal den ersten Parameter :s

Du hast geschrieben das du das mit GetPixel lösen willst. Hmm Naja das wäre eine Variante. Ist aber nen bissl aufwändig :s
Bendenke da aber bitte das wenn du systemfarben verwendest, du sie nicht einfach mit If Getpixel(x,y,deinFarbCode) abfragen kannst.
Da musst du den Farbcode des Hintergrundes glaube erst mit OLESysColor oder wie die API Heisst (Muesst ich nachschauen) prüfen.

Aber was ist wenn dein Object über die Hintergrundfarbe rutscht?

Bsp. Du hast eine Linie die schwarz ist und 3 Pixel breit … Du bewegst dein Object nun auf die Linie… Ok es erkennt das schwarz und löst die Kollision aus. Aber das macht er genau 3 mal! Was ist danach?

Anders Formuliert koennte man auch sagen

Du hast 2 Shapes.
Schape 1 = Dein bewegtes Object
Shape 2 = Dein Object (Haus)
Shape 1 ist grösser Shape 2

Was ist dann wenn shape1 genau ueber shape 2 liegt? Und somit Shape2, shape 1 komplett überdeckt? Somit wird eine Kollision nicht ausgelöst :s

MfG Alex

Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Declare Function IntersectRect Lib „user32“ Alias
„IntersectRect“ (lpDestRect As RECT, lpSrc1Rect As RECT,
lpSrc2Rect As RECT) As Long

dim Col as BooleanCol = IntersectRect(udtTempRect, mudtRect1,
mudtRect2)

Hi Joe,

Die eine Funktioniert mit GetPixel mit einem Farbcode ? ist
das richtig ?

die Funktion heißt in VB Point(). Hatte ich doch geschrieben.

kurz noch eine andere frage:
Wenn ich mit Tabstrips arbeite. WO genau werden die namen der
einzelnen Tabs festgelegt ?

k.A.

Gruß, Rainer

Nabend,
Wie bekomme ich meine Form auf dem Monitor genau in der Mitte angezeigt ? und wie ermittel ich genau die Mitte eines Monitors ?
habe das problem das Getpixel nicht mehr Funktioniert sobald ich meine Form verschiebe.

mfg jonny

Hallo
Erst einmal, ich hab nichts auf diesem Rechner, und ich weiß nicht alles aus dem Kopf.
Getpixel ist etwa2 mal schneller als das VB-Pendant Point.
Solltest du Methoden verwenden, die tatsächlich irgendwelche Probleme mit dem Koordinatensystem verursachen, weil sie z.B. verschiedene Bezugspunkte haben, dann gibt es Funktionen zum Umrechnen. GetClientRect usw… Man manchmal auch die Koordinaten selber umrechnen.
Sollte es daran liegen, das die Api-Funktionen etwas zu kompliziert für Dich sind, empfehle ich, sich auf das reine VB zu beschränken.
Vielleicht liegt ein Fehler darin, die Pixel in Twips umzurechnen.
Da gibts auch eine Funktion für. Ich meinte TwipsPerPixelxundy oder so.
Für Deine Kollisionskontrolle würde ich ein Datenfeld mit Koordinaten der Umrisse der nichtrunden oder nichtquadratischen Objekte vorziehen.
Aber das wird doch ganz schön kompliziert, oder?
Für den Bildschirm gibts das Screen Objekt. Screen.Width oder Screen.Height liefert was du wissen möchtest.
Manche Arten von Windows lassen sich per Eigenschaft auch auf den Bildschirm zentrieren, das ist aber eher nicht notwendig.
Wenn du wirklich Wert auf ein ruckelfreies Game legst, dann hast Du eine Ablaufsteuerung mit Timer, beschränkst Dich mit dem Basic auf Positionen und Datenfelder, letzteres in Verbindung mit GetDIBits und SetDIBits usw…
Da braucht man dann noch kein direkt-x.
Aber ich habe lange dafür gebraucht, um rauszufinden wie das geht und es ist sehr schwierig, wenn man keine Beispielprogramme verwendet.
Frag mal den Anno1974, der kennt sich da aus.
MfG
Matthias

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Joe,

wenn Du Getpixel verwendest mußt Du erstens das Handle des Steuerelements übergeben. Übergibst Du nichts, steht da Null und das ist der Desktop. Übergibst Du das Handle von Picture1 als Long und der Scalemode von Picture1 steht auf 3 = Pixel, funktioniert das, wenn Du den zweiten Punkt auch beachtest.

Die Ereignisse von Picture1 wie z.B.: Picture1_MouseMove() geben Dir X und Y als single zurück. Getpixel erwartet die Koordinaten aber als Long!

Du brauchst also zusätzliche Variablen und mußt die Koordinaten erst in das richtige Format wandeln, bevor Du Ergebnisse bekommst.

So gehts:

Option Explicit

Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long

Private Sub Form\_Load()
 Picture1.Line (0, 0)-(200, 200)
End Sub

Private Sub Picture1\_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
 Dim cx As Long
 Dim cy As Long
 cx = X
 cy = Y
 If Button = 1 Then
 Me.Caption = GetPixel(Picture1.hdc, cx, cy)
 End If
End Sub

Gruß, Rainer

Nun wird mir einiges klar :stuck_out_tongue: habe aber noch das problem das wenn ich deinen Code verwende
Me.Caption = GetPixel(Picture1.hdc, cx, cy)
nur ein -1 in die Caption schreibt.

mfg joe

Hi Joe,

Nun wird mir einiges klar :stuck_out_tongue: habe aber noch das problem das
wenn ich deinen Code verwende
Me.Caption = GetPixel(Picture1.hdc, cx, cy)
nur ein -1 in die Caption schreibt.

??? Scale Mode steht auf Pixel? Autoredraw auf ‚true‘? Das Steuerelement heißt aich ‚Picture1‘?

Bei mir läuft es, ist getestet, das kann nur eine Kleinigkeit sein.

Setze mal einen Stoppunkt und sieh Dir das Handle, den Inhalt von cx und yc an.

Gruß, Rainer

Bei mir läuft es, ist getestet, das kann nur eine Kleinigkeit
sein.

Setze mal einen Stoppunkt und sieh Dir das Handle, den Inhalt
von cx und yc an.

Hallo Joe, Rainer,
und auch den Inhalt von cy *find* :smile:)
Im Ernst, sowas kann die Kleinigkeit sein, also, ist Option Explicit gesetzt!?
Und in Excel-Vba gibts oft Probleme durch „Picture 1“ und „Picture1“.
Nur mal so von Vba zu VB gesagt.
Vielleicht wäre es auch chic einen Code zu haben der alle Eigenschaften/parameter eines Objekts auflistet, damit man die vergleichen kann und dann gleich Fehlerquellen erkennen oder ausschließen kann.
Gruß
Reinhard

Hi Joe,

und auch den Inhalt von cy *find* :smile:)

*gg* immer meine ‚Backsubenvervuchsler‘ :smile:

Im Ernst, sowas kann die Kleinigkeit sein, also, ist Option
Explicit gesetzt!?

Hab’ ich das vergessen? Sorry. :frowning:

Und in Excel-Vba gibts oft Probleme durch „Picture 1“ und
„Picture1“.
Nur mal so von Vba zu VB gesagt.

Ja, klar. Die Namen setzt VB doch aber selbst, da kann man kaum etwas falsch machen.

Vielleicht wäre es auch chic einen Code zu haben der alle
Eigenschaften/parameter eines Objekts auflistet, damit man die
vergleichen kann und dann gleich Fehlerquellen erkennen oder
ausschließen kann.

Ja, ich könnte das auch alles im Code unterbringen, dann sieht das aber komplizierter aus, als es ist.

Joe hat aber auch noch nicht wieder geantwortet, das bedeutet bei Joe: ‚hat funktioniert‘.

Gruß, Rainer