VisualBasic Button mit Tasten bewegen

FeelsGoodManJPG

Lt. Commander
Registriert
Juni 2008
Beiträge
1.218
Hi,
ich will mir n kleines Game machen, indem man mit nem Auto (Button) Hindernissen (Buttons), die von oben runterfallen, ausweichen muss. Jetzt hab ich nur 2 Probleme.

1. Wie bekomm ich den Button zum Bewegen? bzw welchen Befehl muss ich benutzen um die Position von ihm zu ändern? bei button1.position.x = ... kommt immer n fehler beim kompilieren und bei button1.left = ... kommt ein runtime fehler :(

2. ist eig das gleiche problem... xD nur mit der Position der Hindernisse

Hab nach 2 Std googlen nichts gefunden das funktioniert.

Hoffe ihr habt ne Lösung.
lg
 
Wäre schön wenn man gleich mal die verwendete Umgebung und die genauen Fehlermeldungen/Exceptions schreiben würde. Es gibt so viele Visual Basics, das man nicht allgemein von VB sprechen kann. Also was nun VB (1,2,3,4,5,6 ?), VBA (?), VBS (?), VB.Net (1,2,3,4). Welche Programmierumgebung nimmt derjenige der ein Problem hat?

Mensch, Hellsehen kann keiner... Aber stattdessen weiß ich jetzt das du einen E6400 mit 3.2 GHz, Asus HD5850 und 4 GB Ram am Start hast. Denke mal darüber nach...
 
probier mal die Property Location komplett zu überschreiben:

Code:
button1.location = new Point(button1.location.x+1, button1.location.y)

sollte den button um 1 nach rechts berwegen.
 
Also doch nur wieder heiteres Rätselraten...

Control.SetBounds() könnte auch helfen
 
sry hab noch nie was im forum gefragt was sich ums programmieren dreht..
ich verwende visual studio 2008 express

danke!

Hindernis.Location = New Point(position1, position2) klappt perfekt.
und danke für die onlinehilfe, hab selbst nix gefunden... hab aber auch nach dem falschen gesucht =/

@rossibaer:
ist doch schön wenn du weißt welche hardware ich benutz ;)


Naja, neues Problem :D

Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
If sender = 97 Then
car.Location = New Point(carmove + 40, 482)

End If
End Sub

Hier will ich dass sich der button "car" bewegt wenn ich die taste "a" drücke. KeyPreview is auf true.
Bei der Bedingung der If kommt immer der Fehler "Der Operator = ist für Typ Form 1 und Typ Integer nicht definiert." wenn ich dann a drücke. Habs auchschon mit <> anstatt von = probiert (hab ich oinline schon öfter gesehen) aber da kommt genau das gleiche.
 
Erst mal ganz wichtig: Schalte Option Strict ein! Gerade, wenn man erst damit anfängt, sollte man ganz bewusst mit Datentypen umgehen. (Und später genauso...) Alles andere wäre nur Faulheit und eine weitere Fehlerquelle. Mit Option Strict Off schaltest du Prüfungen durch den Compiler einfach aus. Dadurch wird zusätzlicher Code generiert, und es ist nicht offensichtlich, wo das passiert und ob du diese implizite Typkonvertierungen überhaupt haben willst.

Zum Problem: Weißt du, was "Sender" ist? Auch das steht in der Hilfe. :) Du musst nur auf das Wort "Keypress" (nach dem Handles) gehen und F1 drücken. Dann bekommst du die kontextsensitive Hilfe.

"Sender" ist immer das Objekt, das das Ereignis ausgelöst hat, also in diesem Fall die Form. Du willst aber wissen, welches Zeichen eingegeben wurde. Das steht in e.KeyChar. Also

if e.keychar = "a"c then

Das Suffix 'c' nach dem "a" bedeutet, dass es sich um ein Char-Literal (also keinen String mit Länge 1) handelt. Das entspricht dem Datentyp der Eigenschaft KeyChar.
(s. auch http://msdn.microsoft.com/en-us/library/s9cz43ek(VS.80).aspx )


EDIT: Option Strict kannst du pro Datei ("Option Strict On" am Dateianfang), pro Projekt (Projekteigenschaften -> Kompilieren) und als Vorgabe für neue Projekte (Optionen -> Projekte und Projektmappen -> VB-Standard) festlegen. Also letzteres am besten gleich nach der VB-installation auf On stellen. Wie gesagt, bei bereits vorhandenen Projekten musst du das noch nachträglich ändern.
 
Zuletzt bearbeitet: (ergänzt)
WLibero schrieb:
if e.keychar = "a"c then

Alternative:
Code:
If e.KeyCode = Keys.A Then

find' ich persönlich eleganter, da über diese Enumeration der Zugriff auf die Funktionstasten einheitlich funktioniert.
 
danke euch beiden. das strict, bedeutet das, dass der compiler nmichtmehr slebst variablen deklariert die ich ncht selbst deklariert hab?

hab vorhin nochn howto auf youtube gefunden, da wird das so gemacht:


Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

If e.KeyCode = Windows.Forms.Keys.A Then

carmove -= 10
car.Location = New Point(carmove, Me.Height - 170)


End If

so funtkionierts auch wunderbar in meinem programm. mit keypress gings nicht, da hat er das e.KeyCode nicht angenommen.
 
S!x w3g dr3i schrieb:
danke euch beiden. das strict, bedeutet das, dass der compiler nmichtmehr slebst variablen deklariert die ich ncht selbst deklariert hab?
Natürlich musst du Variablen deklarieren. Du meinst aber wahrscheinlich Option Explicit, aber es ist schon so lange her, dass ich Variable nicht selbst deklariert habe. Siehe Hilfe unter Option Strict bzw Option Explicit. Immerhin letzteres ist per Default auf 'On'.

Du musst dir doch bewusst sein, womit du arbeitest!? Als Programmierer arbeitest du ständig mit irgendwelchen Daten. Du hast 0,0 Chancen wenn du dir nicht überlegst, mit welcher Art von Daten, d.h. mit welchem Datentyp du arbeitest.
... mit keypress gings nicht, da hat er das e.KeyCode nicht angenommen.

Du würfelst alles wild durcheinander. Hast du meinen Vorschlag überhaupt versucht? Hätte funktoniert. Ich habe e.KeyChar und nicht e.Keycode geschrieben. Ich habe dir dabei geholfen, das KeyPress-Ereignis zu behandeln. Jetzt auf einmal willst du KeyDown verwenden. Ist dir der Unterschied überhaupt klar? Oder kopierst du einfach nur etwas was du nicht verstehst?
Ergänzung ()

Kagee schrieb:
Alternative:
Code:
If e.KeyCode = Keys.A Then

find' ich persönlich eleganter, da über diese Enumeration der Zugriff auf die Funktionstasten einheitlich funktioniert.
Im KeyPress-Ereignis, das er behandelt, gibt es kein e.KeyCode weil KeyPress im Gegensatz zu KeyDown/Up keinen Tastendruck sondern die Zeicheneingabe behandelt. Im KeyDown/Up hätte ich auch e.keycode genommen. Ich wollte ihm nur da nicht reinreden weil er soll erst mal selbst damit warm werden und dann kann man immer noch maulen. ;)
 
Zuletzt bearbeitet: (überfl. Zitat entfernt)
Natürlich setz ich mich damit außeinander, welchen Datentyp ich benutz, deklarier natürlich auch alles selbst :D
Bei KeyPress hab ich e.keychar schon versucht, da is dann aber nie was passiert. Aber leigt daran, dass ich das "a"c nicht ausprobiert habe so wie du es mir gesagt hast!

Habs eben mal mit KeyPress getestet, funtkioniert, aber macht keinen Unterschied o.O

Was ist denn der unterschied zwischen KeyPress und KeyDown?

P.S: Ich beschäftige mich normal mit C++ , VB hab ich nur alle 2 Wochen in der Schule, und da machen wir fast nix, hauptsächlich VBA und seit letzter Woche VB... bin daher blutiger Anfänger ;)


EDIT:
Bei beiden Events passiert kurz nix wenn man auf der Taste bleibt, also nur bei der Position von dem Button mein ich. Weißt du wie man das ändern kann, dass er gleich reagiert? Sonst muss man immer drauf rumhämmern um schnell genug Ausweichen zu können.

EDIT2:
Wie ist denn der Code für die linke und rechte Pfeiltaste? Find dazu nix..

gruß und danke
 
Zuletzt bearbeitet:
Hab keine Benachrichtigung erhalten, deshalb erst jetzt:
Was ist denn der unterschied zwischen KeyPress und KeyDown?
Zuerst kommt das KeyDown-Ereignis. Darin ist e.keycode abhängig von der gedrückten Taste. Es ist ein "virtual-key code" bzw in VB eine Konstante (ein Enum), die die Taste identifiziert.

Anschließend setzt Windows die Taste bzw Tastenkombination (z.B. mit Shift oder Strg) in ein Zeichen um. Ausnahmen sind z.B. die Funktionstasten (wie Kagee auch schon schrieb) oder auch Shift oder Strg. Bei denen bleibt es bei KeyDown. Sie alleine gedrückt erzeugen kein Zeichen, also kommt auch kein KeyPress-Ereignis.

Beispiel:
Drückst du Return, wird zuerst KeyDown ausgelöst mit e.Keycode=Keys.Return. Zusätzlich wird die Return-Taste umgesetzt in das Zeichen CR (Code 13) das im Keypress-Ereignis ankommt.

Du kannst aber auch Strg+M drücken. Dadurch kommt zuerst Keydown mit e.keycode=keys.ControlKey (also Strg) und danach nochmal Keydown mit e.keycode=keys.M. Die Tastenkombination Strg+M wird zusätzlich in das Steuerzeichen CR umgesetzt, das im anschließenden Keypress-Ereignis ankommt.

Ergo: Du kannst CR entweder durch Enter oder durch Strg+M eingeben.

(Hintergrund (falls irgendwann von Interesse) ;) )

hauptsächlich VBA und seit letzter Woche VB
hmmmm:rolleyes: Aber da misch ich mich jetzt nicht ein. ;)

Wie ist denn der Code für die linke und rechte Pfeiltaste? Find dazu nix..
Per Intellisense bekommst du alle Möglihckeiten angezeigt, also wenn du "if e.keycode=" eintippst, poppt eine Liste auf. Fallst du in der Liste nur nicht das passende gefunden hast, dann schreibe ins Keydown-Ereignis:
Code:
debug.print (e.keycode.tostring)
Dann Programm starten und Pfeiltasten drücken. Dann bekommst du "Left" oder "Right" angezeigt. Das kannst du im Programm dann verwenden, also "if e.keycode=Keys.Left" etc.
Bei beiden Events passiert kurz nix wenn man auf der Taste bleibt, also nur bei der Position von dem Button mein ich. Weißt du wie man das ändern kann, dass er gleich reagiert? Sonst muss man immer drauf rumhämmern um schnell genug Ausweichen zu können.
Das ist die normale Tastenwiederholung wie du sie bei jeder Texteingabe hast. Das zu ändern ist jetzt nicht so ganz trivial für den Anfang - es sei denn du änderst die Einstellung in der Systemsteuerung, aber das wäre natürlich systemweit. Spontan sehe ich 2 mgl. Lösungen, ich führe jetzt aber nur mal eine aus. Melde mich nochmal damit....
Ergänzung ()

Nur mal so als grobes Grundgerüst:
Code:
Public Class Form1

   Private LeftKeyDown As Boolean
   Private WithEvents Timer As New Timer With {.Interval = 100}

   Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) _
      Handles Me.KeyDown

      If e.KeyCode = Keys.Left Then
         If Not LeftKeyDown Then
            LeftKeyDown = True
            MoveLeft()
            Timer.Start()
         End If
      End If

   End Sub
   Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) _
      Handles Me.KeyUp

      If e.KeyCode = Keys.Left Then
         If LeftKeyDown Then
            LeftKeyDown = False
            Timer.Stop()
         End If
      End If

   End Sub
   Private Sub Timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer.Tick

      MoveLeft()

   End Sub
   Private Sub MoveLeft()
      'hier Objekt nach links bewegen
   End Sub
End Class
Beim Drücken der Taste wird ein Timer gestartet, der alle 100ms sein Tick-Ereignis auslöst. In dem wird das Objekt bewegt. Alle weiteren KeyDown-Ereignisse für die Taste werden ignoriert. Sobald die Taste losgelassen wird, wird der Timer wieder ausgeschaltet und die Bewegung stoppt somit.
 
WLibero schrieb:
Im KeyPress-Ereignis, das er behandelt, gibt es kein e.KeyCode weil KeyPress im Gegensatz zu KeyDown/Up keinen Tastendruck sondern die Zeicheneingabe behandelt.

oh das kann sein. ich habe den code nicht ins VS übertragen :D.Aber wie du schon richtig anmerkst, bei einem Spiel im weiteren Sinne würde auch ich eher das Key-Down-Ereignis abfangen....

@ Topic

Erste anlaufstelle sollte immer die MSDN Library sein. Dort findet man zu vielen (nicht allen) Themen Beispielscode in mehreren Sprachen, die alles abdecken sollten, was man für den Einsteig braucht. Wenn man sich wie du im moment Frage, wie man eine solche Tastenabfrage realisiert, suchst du am besten nach dem Ding, welches du benutzen willst. In deinem Fall ist das die KeyChar-Eigenschaft der Klasse KeyPressEventArgs. Daher suchst du in der MSDN Lib nach "KeyPressEventArgs.KeyChar" und der wird dir folgendes ausspucken:
http://msdn.microsoft.com/de-de/library/system.windows.forms.keypresseventargs.keychar.aspx

und im VB-Beispielcode steht dann eine Zeile wie:
Code:
If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
 
EDIT: Oh man, wie peinlich für mich. :rolleyes: Du hast ja geschrieben dass das aus der Hilfe kommt. Insofern beziehe das Folgende bitte nicht auf dich sondern auf die Beispiel-Macher bei MSFT. :freak:

Kagee schrieb:
Code:
If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
Ich will dir nicht wirklich widersprechen. :) Das funktioniert auch. Ich persönlich, wenn ich das sagen darf, würde das aber nicht so machen. Die Keys-Enumeration sind keine Zeichencodes sondern Tastencodes, wenngleich Keys.Return "zufällig" das Steuerzeichen CR erzeugt. Zwischen Tastencodes und erzeugtem Zeichen besteht jedoch kein prinzipieller Zusammenhang. Deutlicher wird das, wenn man z.B. Keys.Subtract (Minus auf Ziffernblock) drückt. Der Tastencode ist 109 aber das erzeugte Minuszeichen hat Code 45.

Deswegen für CR besser ControlChars.Cr verwenden, also
Code:
If e.KeyChar = ControlChars.Cr
Oder allgemeiner (außerhalb MSVB namespace):
Code:
Convert.ToChar(13)
 
Zuletzt bearbeitet:
@WLibero:
Wow Danke :)
Es funktioniert perfekt! Und verstanden was es macht hab ich auch ^.^
Den Tipp mit dem
Code:
debug.print (e.keycode.tostring)
kann ich gut gebrauchen! Hab das Left und Right davor auchschon gefunden und gestestet, aber da hab ich immer nur zwischen den Buttons hin und her geswitcht. Hab das problem so gelöst, dass ich sie einfach auf Disable gemacht hab. Jetzt Kommt halt immer beim Punktezähler der Strich, obwohl der auf ReadOnly ist.

@ Kagee:
In der Hilfe hab ich schon oft geschaut, aber leider nie richtig verstanden was die mir damit sagen wollten^^ Oft sind auch keine beispiele dabei.

Edit:

Hier mal das fast fertige Spiel zum Download.
 
Zuletzt bearbeitet:
@ WLibero
ah. ich verstehen was du meinst. Ich habs lediglich aus der MDSN kopiert :D.

Bedenklich, wenn dort solche Zeilen stehen und man sich wundert, warum die Belegte Taste "Ziffernblock Minus" auch ausgelöst wird, wenn man "Minus" drückt.

Was ich eigentlich zeigen wollte war aber eine grundsätzliche Vorgehensweise zur Selbsthilfe mit der MSDN ;)

edit:
@ S!x w3g dr3i:
Lustige Sache :) Auf die Idee sowas mit Buttons zu machen wäre ich gar nicht gekommen :D
 
Zuletzt bearbeitet:
aber da hab ich immer nur zwischen den Buttons hin und her geswitcht.
Hast' Recht. Liegt daran, dass die Pfeiltasten "dialog keys" sind, also zur Navigation benutzt werden, wie du ja gemerkt hast. Liesse sich hiermit ändern:
Code:
   Protected Overrides Function ProcessDialogKey _
      (ByVal keyData As System.Windows.Forms.Keys) As Boolean

      If keyData = Keys.Left OrElse keyData = Keys.Right Then
         Return False
      Else
         Return MyBase.ProcessDialogKey(keyData)
      End If

   End Function
 
Will grade nen 2 Spielermodus machen und bin auf folgendes Problem gestoßen.
Code:
 If e.KeyCode = Keys.A Then
            If Not LeftKeyDown Then
                LeftKeyDown = True
                MoveLeft2()
                BewegungLeft2.Start()
            End If
        End If

Was muss ich da bei If Not LeftKeyDown Then reinschreiben für LeftKeyDown?
AKeyDown gibts nicht und mit . oder sowas hats mir auch nix angezegt was gehen könnte.
 
Schau mal am Anfang im Code. Da hatte ich LeftKeyDown deklariert. Die Variable ist nur dazu da, die weiteren KeyDown-Events, die beim Festhalten der Taste auftreten, zu ignorieren. Genauso kannst du es mit anderen Tasten machen.
 
Zuletzt bearbeitet:
Zurück
Oben