Hallo Community!
Ich bin im Moment dabei, einen kleinen, billigen Klon des VZ-Spiels "IcyTower" zu erstellen. Sprich: Eine Figur, die von unten nach oben hüpft, von Plattform zu Plattform, und versucht, so hoch wie möglich zu kommen, ohne abzustürzen.
Bin mittlerweile soweit:
- Spielfigur
- Beweglich (links/rechts)
- "animiert"
- durch quadratische Funktion (Parabel) ermitteltes Sprungverhalten (realistischer Sprung durch verschiedene Pixel-Schritte)
- Plattformen
- als Klasse "Block" erstellt (Eigenschaften der Größe, Position und des Verhaltens einzelner Plattformen)
- da dynamisches Erstellen der Blöcke eine List Of (Block) zum verwalten der Blöcke
-> Dynamisches, von ein paar Variablen beeinflusstes Berechnen der Figur und der Blöcke per GDI.
Problem:
- Ich muss zwangsläufig eine Kollision erkennen lassen, wann meine Figur in/auf einer Plattform ist, um von dieser erneut einen Sprung nach oben auszuführen, unabhängig davon, ob sich die Figur noch im Sprung nach oben oder im Fall nach unten oder noch ganz in der Sprung-Sequenz befindet
- Gleichzeitig muss ich die Blöcke einen Pixel weiter wandern lassen und sie ggf. löschen, wenn sie außer Sicht sind.
- Ich habe beides im OnPaint-Event und habe nur noch ein riesiges Gemetzel an Code auf dem Bildschirm :(.
- Ein provisorischer SB (Sicherheitsbalken) soll mit der Figur kollidieren und ihn am Fallen hindern, solange sie noch keine normale Plattform mindestens einmal berührt hat.
Ich habe schon versucht, verschiedene Subs zu erstellen, um mir A) den Code übersichtlicher zu gestalten und B) mit Parametern leichter und schneller arbeiten zu können, aber richtig hingehauen hats net.
Frage:
A) Da ich die zu fallenden/springenden Pixel erst darauf prüfen muss, ob sie eine Kollision ergeben, bewegt sich meine Figur gar nicht mehr und eine For-Schleife wird nicht einmal mehr angesprochen...
B) Meine Berechnung, um die Figur im Spielfeld zu halten scheint trotz eiskalter Logik für die Katz zu sein
Quellcode:
(komischerweise tendiert Chrome dazu, dass mein VB-Code nie richtig angezeigt wird, deswegen hab ich den Quellcode auch noch mal in dem Dateianhang)
Hoffe, dass ihr mir weiterhelfen könnt
Fragen wie "Warum bist Du denn auf diesen Schwachsinn gekommen?!" kann ich getrost mit "Wahnsinn durch Schlafmangel und Verzweiflung" im Voraus beantworten
MfG,
X-Zat / Moritz
Ich bin im Moment dabei, einen kleinen, billigen Klon des VZ-Spiels "IcyTower" zu erstellen. Sprich: Eine Figur, die von unten nach oben hüpft, von Plattform zu Plattform, und versucht, so hoch wie möglich zu kommen, ohne abzustürzen.
Bin mittlerweile soweit:
- Spielfigur
- Beweglich (links/rechts)
- "animiert"
- durch quadratische Funktion (Parabel) ermitteltes Sprungverhalten (realistischer Sprung durch verschiedene Pixel-Schritte)
- Plattformen
- als Klasse "Block" erstellt (Eigenschaften der Größe, Position und des Verhaltens einzelner Plattformen)
- da dynamisches Erstellen der Blöcke eine List Of (Block) zum verwalten der Blöcke
-> Dynamisches, von ein paar Variablen beeinflusstes Berechnen der Figur und der Blöcke per GDI.
Problem:
- Ich muss zwangsläufig eine Kollision erkennen lassen, wann meine Figur in/auf einer Plattform ist, um von dieser erneut einen Sprung nach oben auszuführen, unabhängig davon, ob sich die Figur noch im Sprung nach oben oder im Fall nach unten oder noch ganz in der Sprung-Sequenz befindet
- Gleichzeitig muss ich die Blöcke einen Pixel weiter wandern lassen und sie ggf. löschen, wenn sie außer Sicht sind.
- Ich habe beides im OnPaint-Event und habe nur noch ein riesiges Gemetzel an Code auf dem Bildschirm :(.
- Ein provisorischer SB (Sicherheitsbalken) soll mit der Figur kollidieren und ihn am Fallen hindern, solange sie noch keine normale Plattform mindestens einmal berührt hat.
Ich habe schon versucht, verschiedene Subs zu erstellen, um mir A) den Code übersichtlicher zu gestalten und B) mit Parametern leichter und schneller arbeiten zu können, aber richtig hingehauen hats net.
Frage:
A) Da ich die zu fallenden/springenden Pixel erst darauf prüfen muss, ob sie eine Kollision ergeben, bewegt sich meine Figur gar nicht mehr und eine For-Schleife wird nicht einmal mehr angesprochen...
B) Meine Berechnung, um die Figur im Spielfeld zu halten scheint trotz eiskalter Logik für die Katz zu sein
Quellcode:
(komischerweise tendiert Chrome dazu, dass mein VB-Code nie richtig angezeigt wird, deswegen hab ich den Quellcode auch noch mal in dem Dateianhang)
VB.NET-Quellcode
- Imports System.DrawingImports System.Drawing.Drawing2D
- Public Class Form1
- #Region "Benjii" 'Eigenschaften Benji's Dim B_X As Integer = 200 Dim B_Y As Integer = 200 Dim B_W As Integer = My.Resources.Benji_Normal.Size.Width Dim B_H As Integer = My.Resources.Benji_Normal.Size.Height 'Bewegung Benji's Public Enum BenjisDirection normal = 1 up = 2 down = 3 left = 4 right = 5 End Enum Dim BenjisFace As String = BenjisDirection.normal 'Normale Steigung Benji's Dim BenjiJump As String() = {16, 8, 11, 7, 6, 6, 4, 5, 3, 4, 3, 2, 3, 2, 2, 1, 2, 1, 1, 1, 0, 1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -2, -1, -2, -2, -3, -2, -3, -4, -3, -5, -4, -6, -6, -7, -11, -8, -16} Dim BenjiJumpC As Integer = 0 Dim BenjiJumpMulti As Double = 1 'Fällt? Dim BenjiFallin As Boolean = False#End Region#Region "Blöcke" 'Block-Liste Dim BlockList As List(Of Block) = New List(Of Block) Dim BlockSpeed As Double = 1#End Region#Region "SicherheitsBalken" Dim SB_Exists As Boolean = True Dim SB_PX As Integer = 0 Dim SB_PY As Integer = 400 Dim SB_SX As Integer = Me.Width Dim SB_SY As Integer = 10
- #End Region
- Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs) Dim bg As Graphics = e.Graphics 'Berechne und verwalte Benji's Verhalten If Not BenjiFallin = True Then If Not BenjiJumpC > 46 Then BenjiJumpC += 1 Else BenjiFallin = True End If End If CalculateCollusion(BenjiJump(BenjiJumpC)) Select Case BenjisFace Case BenjisDirection.normal bg.DrawImage(My.Resources.Benji_Normal, New Point(B_X, B_Y)) Case BenjisDirection.up bg.DrawImage(My.Resources.Benji_Up, New Point(B_X, B_Y)) Case BenjisDirection.down bg.DrawImage(My.Resources.Benji_Down, New Point(B_X, B_Y)) Case BenjisDirection.right bg.DrawImage(My.Resources.Benji_Right, New Point(B_X, B_Y)) Case BenjisDirection.left bg.DrawImage(My.Resources.Benji_Left, New Point(B_X, B_Y)) End Select If SB_Exists = True Then bg.DrawRectangle(Pens.Black, New Rectangle(New Point(SB_PX, SB_PY), New Size(SB_SX, SB_SY))) 'Kontrolliere Verhalten der Blöcke If Not BlockList.Count < 1 Then For Each Block As Block In BlockList With Block If Not .PosY + .SizeX > Me.Height Then .PosY += BlockSpeed Dim BlockRect As New Rectangle(New Point(.PosX, .PosY), New Size(.SizeX, .SizeY)) If .Typ = Little_Benji.Block.BTyp.normal Then bg.DrawRectangle(Pens.Black, BlockRect) Else bg.DrawRectangle(Pens.Gray, BlockRect) End If Else BlockList.RemoveAt(BlockList.IndexOf(Block)) Exit For End If End With Next End If End Sub 'OnPaint
- Private Sub CalculateCollusion(ByVal Distance As Double) For i = 0 To Distance * BenjiJumpMulti If Not Distance < 0 Then B_Y += -(Distance) Else B_Y += Distance End If If SB_Exists = True Then If B_Y + B_H >= SB_PY Then BenjiJumpC = 0 BenjiFallin = False Exit Sub End If End If Label1.Text = B_X & "|" & B_Y If Not BlockList.Count < 1 Then For Each Block As Block In BlockList With Block If B_Y + B_H >= .PosY And B_Y <= .SizeY + .PosY Then If B_X + B_W >= .PosX And B_X <= .SizeX + .PosX Then BenjiJumpC = 0 BenjiFallin = False SB_Exists = False Exit Sub End If End If End With Next End If Next End Sub
- Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick Me.Invalidate() End Sub
- Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown Select Case e.KeyCode Case Keys.Right For i = 0 To 10 If Not B_X + B_W + 1 > Me.Width Then B_X += 1 Else Exit For End If Next BenjisFace = BenjisDirection.right Case Keys.Left For i = 0 To 10 If B_X - i > 0 Then B_X -= 1 Else Exit For End If Next BenjisFace = BenjisDirection.left
- 'Nun kommen die Hoch- und die Runtertasten, um den Multiplikator zu testen... Case Keys.Up BenjiJumpMulti += 0.1 Case Keys.Down If Not BenjiJumpMulti - 0.1 < 1 Then BenjiJumpMulti -= 0.1 End If End Select End Sub
- Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick Dim R As New System.Random Dim NewBlock As New Block(50, 10, R.Next(0, 600), 0, 1) BlockList.Add(NewBlock) End Sub
- Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click B_X = Me.Width / 2 B_Y = Me.Height / 2 End Sub
- Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click CalculateCollusion(BenjiJump(BenjiJumpC)) End SubEnd Class
Hoffe, dass ihr mir weiterhelfen könnt
Fragen wie "Warum bist Du denn auf diesen Schwachsinn gekommen?!" kann ich getrost mit "Wahnsinn durch Schlafmangel und Verzweiflung" im Voraus beantworten
MfG,
X-Zat / Moritz