2D-Gelände, das "einstürzen" kann?

Übersicht BlitzBasic Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

FireballFlame

Betreff: 2D-Gelände, das "einstürzen" kann?

BeitragMo, Apr 17, 2006 13:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Es gibt doch bestimmt einige im Forum, die dieses alte Spielprinzip kennen:
- eine 2D-Landschaft, "von der Seite" betrachtet
- mehrere Panzer/Bunker
- die Spieler schießen nacheinander (in manchen Remakes auch gleichzeitig, aber ic mag's lieber rundenbasiert Wink )
- durch richtiges Abschätzen von Abschusswinkel und -kraft muss man die Gegner treffen

Ich würde so ein Spiel auch gerne mal nachbauen, aber ich weiß nicht, wie ich die Landschaft umsetzen soll. Wenn es eine Explosion gibt, "löst" die ja den Boden in ihrem Explosionsradius auf und überstehender Boden fällt herunter. Zur Veranschaulichung hier ein paar selbstgemachte Screenshots aus meiner Vorlage (die fast genauso alt ist wie ich):

user posted image

Ich weiß aber nicht, wie man das machen kann. Ich werde in die Grafik, obwohl komplett 2D, auch Sprites (Blitz3D) einbauen, weil man die zur Laufzeit skalieren/drehen und halbtransparent machen kann (siehe https://www.blitzforum.de/foru...hp?t=17393).
Also bin ich auf die Idee gekommen, ganz viele kleine Sprites (als Sandkörner) zu machen, alle mit einem Kollisionsradius zu versehen und sie dann nach unten fallen zu lassen, bis eine Kollision festgestellt wird. Das hat sich aber als sehr leistungsfressend erwiesen.
Hat vielleicht jemand eine gute Idee, wie man das mit 2D- oder 3D-Methoden lösen kann?
  • Zuletzt bearbeitet von FireballFlame am Di, Apr 18, 2006 0:01, insgesamt einmal bearbeitet
 

HW

BeitragMo, Apr 17, 2006 13:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Du solltest wohl am besten für die gesamte Landschaft ein Sprite nehmen. Wenn eine Kugel trifft, machst du den Sprite um den Einschlagpunkt herum transparent. Transparenz wird soweit ich weiß nicht bei der Kollision mitberechnet.

Kryan

BeitragMo, Apr 17, 2006 14:30
Antworten mit Zitat
Benutzer-Profile anzeigen
also so wie du vorschlägst wird es sehr langsam. ich hab mich auch mal an einem clonk-klon gewagt und Bin genau bei diesem punkt gescheitert Crying or Very sad
ich würde dir folgende variante vorschlagen:
1. die ganze map ist ein bild und am besten, es gibt nur eine hintergrundfarbe (schönere hintergründe kannst du ja so noch zeichnen)
2. beim einschlag einer kanonenkugel zeichnest du einen schwarzen kreis
3. du zählst alle pixel über dem einschlagsloch
4. alle pixel über diesem einschlagsloch lässt du verschwinden (mit einem schwarzen Rechteck)
5. du fügst die gezählten pixel am boden wieder hinzu

2.-5. kannst du so machen: (nur die Funktion ist für dich interessant, der Rest ist Demonstration!)
Code: [AUSKLAPPEN]

Graphics 640,480,32
Global map=CreateImage(640,480)
SetBuffer ImageBuffer(map)
Color 0,128,0
Rect 0,200,640,280
SetBuffer BackBuffer()
Repeat
 Cls
 DrawImage map,0,0
 If MouseHit(1) Then
  mx=MouseX()
  my=MouseY()
  Einschlag mx,my,30
  Color 255,0,0
  Oval mx-5,my-5,10,10
  Oval mx-30,my-30,30*2,30*2,0 ; 2.
 End If
 Color 255,0,0
 Oval MouseX()-5,MouseY()-5,10,10
 Flip
Until KeyHit(1)
End

Function Einschlag(x,y,radius)
 gb=GraphicsBuffer()
 SetBuffer ImageBuffer(map)
 Color 0,0,0
 Oval x-radius,y-radius,radius*2,radius*2 ; 2.
 hintergrund=-16777216
 For x2=x-radius To x+radius
  cnt=0
  For y2=y To 0 Step -1
   cnt=cnt+(ReadPixel(x2,y2,ImageBuffer(map))<>hintergrund) ; 3.
  Next
  Color 0,0,0
  Rect x2,0,1,y ; 4.
  y_boden=y+Sqr((radius)^2-(x2-x)^2)+6
  Color 0,128,0 ; Bodenfarbe
  Rect x2,y_boden-cnt,1,cnt ; 5.
 Next
 SetBuffer gb
End Function

Die Zeit, die diese Funktion pro Aufruf benötigt liegt bei 130 Millisekunden bei mir und ist, denk ich, akzeptabel für ein rundenbasiertes Spiel Wink

Viel Spaß damit,
kryan

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Apr 17, 2006 14:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Für 'wie man sowas macht' schaut mal einfach in eurem BB-Ordner und sucht mal nach parallax2... Dieses Beispiel macht genau das! Mit der Maus kann man den Hintergrund malen und wieder löschen. Das einzige was da nicht gemacht wird, ist das fallen der Pixel... Sowas sollte in eine extra Funktion gepackt werden, welche die Pixel permanent überprüft und wenn notwendig nach unten verschiebt...

FireballFlame

BeitragMo, Apr 17, 2006 17:17
Antworten mit Zitat
Benutzer-Profile anzeigen
OK, danke. Smile Die Methode von Kryan klingt schonmal gut.

Aber da gibt es noch ein Problem Sad :
Der Boden soll animiert sein, d.h. die überstehende Erde fällt in realistischem Tempo herunter.
Da aber die Bildschirmauflösung 800x600 betragen und das Spiel flüssig laufen soll (mindestens 50-60 fps) müsste ich, um ein realistisches "Flugtempo" zu erzielen, die Erd-Pixel (zumindest zu Beginn des Fallens) weniger als 1 Pixel pro Rechenschritt nach unten bewegen.
Kurz gesagt: 1 Pixel nach unten pro Rechenschritt ist zu viel.
Somit müsste ich alle fallenden Pixel in einem Type- oder Dim-Feld speichern - und ihre y-Position als Float. Aber das frisst Leistung und Speicher; vor allem bei bestimmten Waffen, die Erde/Sand-Fontänen in die Luft sprühen; das wären sehr viele Pixel...

Oder kann ich das irgendwie vermeiden Question

Goodjee

BeitragMo, Apr 17, 2006 17:26
Antworten mit Zitat
Benutzer-Profile anzeigen
du könntest rects oder images benutzen.....
außerdem könntest du nur ein paar weniger nehmen, als du wegsprengst, die anderen wurden dann vom wind weggetragen^^

du könntest sie auch gar ncht speichern und im bereich der explosion immer mit readpixelfast von unten nach oben gucken, ob ein pixel da ist, wenn ja übermalen und einen weiter unten einen neuen malen....könnte aber auch viel speed zoggen...

oder du könntest auch ale mit einheitlichem speed und int position in dims speichern, also nur einmal speed und 150mal ints...i


edit: vllt sind types besser, wenn ein pixel 'liegt' kannst du ihn einfach mit delete entfernen....
 

Dreamora

BeitragMo, Apr 17, 2006 17:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Da auf jedem Pixel nur untergrund sein kann oder nicht, sollte es ausreichen, einfach ein Dim mit grösse der Welt zu machen, (height,width,2), in welchem der Speed des Pixels auf dem Feld gespeichert ist. Types braucht es dafür eigentlich nicht.

Alternativ kannste natürlich auch ein Partikelsystem nutzen, um die gerade beweglichen Erdteile zu bewegen (da der Rest statisch ist, braucht der nicht gehandhabt zu werden, denn er kann sich nicht verändern) und entsprechend fallen zu lassen.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Kryan

BeitragMo, Apr 17, 2006 18:04
Antworten mit Zitat
Benutzer-Profile anzeigen
wart, ich optimiere meinen code noch, dass er deinen wünschen entspricht...
edit:
ok, krieg ich nicht hin
vielleicht kannst du ja noch den code zurechtbiegen Very Happy
ansonsten würde ich aber auch dreamoras lösung nehmen!

mfg kryan

FireballFlame

BeitragMo, Apr 17, 2006 23:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmmm... Idea juhu - ich glaub, ich hab eine Idee! Idea Ich hab das alles noch nicht richtig testen können, in den Osterferien im Urlaub bin ... aber...ich stelle mir das jetzt so vor:





Ich mache ein dreidimensionales Feld: "Dim Landschaft(x, y, 1)".
-> x und y sind Breite und Höhe der Landschaft
-> die dritte "Koordinate" (3. Dimension) kann dann den Wert 0 oder 1 haben, und...
- - -> 0 steht für den "Inhalt" des Pixels: 0=Luft, 1=Erde, 2=von Explosion verbrannte Erde oder so... (d.h. "Landschaft(0,0,0)" enthält den "Inhaltswert" des Pixels ganz oben links)
- - -> 1 steht für das vertikale Tempo des Pixels als Float (ich könnt ja später auch noch ein horizontales einführen) [d.h. "Landschaft(0,0,1)" enthält das Tempo des Pixels ganz oben links]


Und dieses Datenfeld mache ich zweimal.
Das 1. Feld ist das "richtige" und das 2. ist das 1. aus dem vorherigen Hauptschleifendurchlauf (Frame).
Alle Aktionen werden mit dem 1. Feld durchgeführt.
Anschließend werden die Felder 1 und 2 verglichen und alle Unterschiede auf den Imagebuffer der Landschaft gezeichnet.
(Nun wird wieder das 1. Feld ins 2. übertragen und die Schleife beginnt neu...)




-------------------------------


€: Ich weiß, dass das jetzt schwer nachzuvollziehen war; so sieht das eben aus, wenn ich versuche meine Gedanken aufzuschreiben Rolling Eyes Wink
...aber wenn ihr versteht, was ich meine - so könnte es doch gehen, oder?

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDi, Apr 18, 2006 0:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hää? Hab ich das richtig verstanden? Du willst für jeden Pixel ein Dimfeld nutzen? Das ist aber ganz schön viel Speicher den du da pro Schleifenduchlauf verwalten willst. Folgender Code hat bei meinem P4 2.8GHz ganze 9 FPS...:

Code: [AUSKLAPPEN]
Graphics 800,600,0,1
SetBuffer BackBuffer()

Dim xyz(799,599,1)

While Not KeyHit(1)

 For z=0 To 1
  For y=0 To 599
   For x=0 To 799
    xyz(x,y,1)=1
   Next
  Next
 Next

 ms=MilliSecs()
 If ms>mt mt=ms+999:fps=frame:frame=0 Else frame=frame+1
 Text 0,0,fps

 Flip 0
 Cls
Wend
End

Ausserdem währe es ganz schön schwierig ein Programm zu schreiben welches aus einem Dimfeld, welches auf Landschaftsebene programmiert ist, es auf bewegende Pixelebene zu programmieren. Hmmm, schlecht erklärt. Da jedes Pixel dann das Dimfeld-Raster ja verlässt und in das andere übergeht...

Folgende Idee hätte ich dabei:

Du erstellt eine Landschaft wie es als Beispiel in parallax2 zu sehen gibt. Wenn ein Teilbereich weggesprengt wird, dann übergibtst du die Explosion einer Funktion die folgendes macht. Ermiteln der Explosionsbreite (zB: Explosionsort x=100, y=200, Explosionsradius 30 Pixel, ergibt: ExplosionsXWeite ~60 Pixel). Eine Schleife läuft dann von x=70 bis x=130 und animiert nur den Teilbereich so, dass dieser einstürzen kann. Dabei wird eine zweite Schleife eingebaut die für Y zuständig ist, mit den gleichen Explosionshöhenberechnung. Ein anderer Codeabschnitt animiert nur ein paar rumfliegende Partikel, die kein weiteren Einfluss auf die Umgebung haben.

FireballFlame

BeitragDi, Apr 18, 2006 21:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hatte mir ja schon gedacht, dass das ziemlich viel Speicher und Leistung frisst... (siehe 2 Beiträge von mir vorher)
Und ich weiß noch immer nicht, was parallax2 überhaupt macht. Ich komm ja zur Zeit nicht an meinen BlitzBasic-PC ran!


Aber ich dachte, das Dim-Feld lesen geht vielleicht schneller als das schreiben...
Zumindest kann ich ja den Bereich auch so eingrenzen.
Solange die Pixel nicht seitwärts fliegen, reicht es ja, das Rechteck zu kontrollieren, dessen oberer Rand der höchste Punkt des Geländestücks über der Explosion und dessen restliche Ränder die Ränder der Explosion sind.
Das ist ja im Grunde das, was du geschrieben hast, oder?

FireballFlame

BeitragMo, Apr 24, 2006 23:05
Antworten mit Zitat
Benutzer-Profile anzeigen
€ Sry, dieser Beitrag hier hat sich grad erledigt... kann man den nicht löschen?
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit
 

Dreamora

BeitragMo, Apr 24, 2006 23:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Empfehlung: Löcher NIE so zeichnen, wie du es da machst (mit winkel 0 - X und cos / sin). Damit zeichnest/überprüfst du den gleichen Pixel unzählige Male und wirst teilweise sogar pixel garnicht betrachten.

Geh einfach von X-Radius bis X+Radius und Y-Radius bis Y+Radius durch und schau ob die Distanz im Quadrat (also D^2 = UnterschiedX^2 + UnterschiedY^2) kleiner ist als der Radius^2. Dort wo es das ist, bist du im Kreis.
Das wird um ein vielfaches schneller.

warum er die löcher nicht zeichnet, kann ich dir allerdings so auf anhieb auch nicht sagen.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

FireballFlame

BeitragDi, Apr 25, 2006 19:28
Antworten mit Zitat
Benutzer-Profile anzeigen
@Dreamora: Ich hab einmal ne x- und ne y-Koordinate verwechselt...
Zu dem Kreise zeichnen: Mal sehen... Falls nicht alle Pixel beachtet werden sollten, könnte ich aber auch den "Winkelschritt" mit Step einfach NOCH kleiner machen. Da das Loch nur einmal gezeichnet wird (zum Zeitpunkt der Explosion) geht das mit der Leistung in Ordnung.



Aber ich hab nun doch noch ein Problem... vielleicht könnt ihr mir da nochmal helfen...das Gelände stürzt nicht richtig ein.
Die wichtige Funktion ist die letzte. Ich habe zwei Dinge darin kommentiert ("skip_" und "For plus1=0 To 1...Next"). Je nach dem, ob man sie wieder einbaut oder nicht, kommt man zu interessanten Ergebnissen...aber nicht zu dem gewünschten. Die Erde soll sichtbar von oben nach unten fallen.


Ich hoffe, ihr könnt mir helfen und ich kriege den Rest des Spiels alleine hin...



Code: [AUSKLAPPEN]
AppTitle "BlitzBomb"
Graphics3D 800,600,16,1
SetBuffer BackBuffer()
SetFont LoadFont("times new roman",30)
Text 400,300,"Lädt, bitte warten...",1,1
Flip



SeedRnd MilliSecs()













Dim Landschaft#(800,500,1)      ; 3. Dimension: 0 beinhaltet Typ (0=Luft, 1=Erde), 1 beinhaltet Tempo
Dim Landschaft_#(800,500,1)

Global check_x1=0, check_x2=800, check_y1=0, check_y2=500
















Global Landschaftsbild=CreateImage(800,500)           : MaskImage landschaftsbild,255,0,128










Global cam=CreateCamera()   : CameraRange cam,1,9999   : CameraClsMode cam,0,1
Global timer=CreateTimer(50)











createlandschaft





































check_x1=0:check_x2=1:check_y1=0:check_y2=1



While Not KeyHit(1)
   WaitTimer timer
   UpdateWorld()
   Cls









   RenderWorld()



   DrawImage landschaftsbild,0,100
   drawhud



   mx=MouseX()
   my=MouseY()
   Color 255,0,0
   Oval mx-10,my-10,20,20,1


   If MouseHit(1) And my>=100 deletedirt mx,my-100,10




   erde_faellt___dimbackup
   Flip
Wend
End






















































Function createLandschaft(l_rand_links=0,l_rand_rechts=800)
SetBuffer ImageBuffer(landschaftsbild)

hl=Rand(20,470)


Color 255,0,128
Rect l_rand_links,0,l_rand_rechts-l_rand_links,500
Color 0,128,0

l#=hl
f#=0
pm#=0
hoehe#=0
last_f#=0
For crlz=l_rand_links To l_rand_rechts
   
   f=f+Rnd(-.075,.075)+pm/1500
   If f>2 f=2
   If f<-2 f=-2
   If Abs(f-last_f)>.8 f=(f+last_f)/2
   
   hoehe=l+f
   If hoehe>470 hoehe=470
   If hoehe<20 hoehe=20
   
   Rect crlz,hoehe,1,500-Int(hoehe)
   If hoehe<l pm=pm+Rnd(.1,1.5)
   If hoehe>l pm=pm-Rnd(.1,1.5)
   If hoehe>=470 pm=pm-5
   If hoehe<=20 pm=pm+5
   l=hoehe
   last_f=f
Next









LockBuffer
For dx=0 To 800
   For dy=0 To 500
      rgb=ReadPixelFast(dx,dy)
      r=(rgb And $FF0000)/$10000
      g=(rgb And $FF00)/$100
      b=rgb And $FF
      If r=0 And g=128 And b=0 landschaft(dx,dy,0)=1 Else landschaft(dx,dy,0)=0
      landschaft(dx,dy,1)=0
   Next
Next
UnlockBuffer
check_x1=0:check_x2=799:check_y1=0:check_y2=499
erde_faellt___dimbackup
SetBuffer BackBuffer()
End Function




























Function deleteDirt(ddx,ddy,ddradius)
Color 255,0,128

check_x1=ddx-ddradius
check_x2=ddx+ddradius
check_y2=ddy+ddradius
check_y1=0


;SetBuffer ImageBuffer(landschaftsbild):Oval ddx-10,ddy-10,20,20,1:SetBuffer BackBuffer()
For kreiswinkel=0 To 360
   ax=Cos(kreiswinkel)*ddradius
   ay=Sin(kreiswinkel)*-ddradius
   bx=Cos(180-kreiswinkel)*ddradius

   If Sgn(bx-ax)=1 Then
      For lt=ax To bx
         landschaft(ddx+lt,ddy+ay,0)=0
      Next
   Else
      For lt=ax To bx Step -1
         landschaft(ddx+lt,ddy+ay,0)=0
      Next
   End If
Next

End Function



































Function drawHUD()
Color 128,0,128
Rect 0,100,800,500,0


End Function































Function Erde_faellt___DimBackup()
SetBuffer ImageBuffer(landschaftsbild)
LockBuffer
For sdb_y=check_y2 To check_y1 Step -1
   For sdb_x=check_x1 To check_x2
      ;skip_=False
      If landschaft(sdb_x,sdb_y,0)<>0
         If landschaft(sdb_x,sdb_y+1,0)=0
            landschaft(sdb_x,sdb_y,1)=landschaft(sdb_x,sdb_y,1)+.9
            If landschaft(sdb_x,sdb_y,1)>=1 Then
               landschaft(sdb_x,sdb_y+1,1)=landschaft(sdb_x,sdb_y,1)
               landschaft(sdb_x,sdb_y,1)=0
               landschaft(sdb_x,sdb_y+1,0)=landschaft(sdb_x,sdb_y,0)
               landschaft(sdb_x,sdb_y,0)=0
               ;skip_=True
            End If
         Else
            landschaft(sdb_x,sdb_y,1)=0
         End If
      End If
      
;   For plus1=0 To 1
      lsp=landschaft(sdb_x,sdb_y+plus1,0)      
      If lsp<>landschaft_(sdb_x,sdb_y+plus1,0)
         If lsp=0
            r=255
            g=0
            b=128
         End If
         If lsp=1
            r=0
            g=128
            b=0
         End If
         WritePixelFast sdb_x,sdb_y+plus1,255*$1000000 + r*$10000 + g*$100 + b
      End If
;   Next
      
      landschaft_(sdb_x,sdb_y,0)=landschaft(sdb_x,sdb_y,0)
      landschaft_(sdb_x,sdb_y,1)=landschaft(sdb_x,sdb_y,1)
      
      ;If skip_ Exit
   Next
Next
UnlockBuffer
SetBuffer BackBuffer()
End Function




PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDi, Apr 25, 2006 19:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmmm, das Ergebnis (wenn die Animation durchlaufen ist) ist ja in Ordnung, nur die Animation selbst nicht. Wie wär's mit folgendem Ansatz: Nach einer Explosion werden die Pixel einfach gelöscht (ist jetzt auch schon so). Aber dann werden drei Schleifen x/y und eine Animationschleife durchlaufen die folgendes machen. Vergleichen ob es ein Pixel gibt wo unter diesem keines ist, wenn ja dann wird dieser Pixel einen Pixel nach unten kopiert (das ist dann die Animation). Jetzt gibt es zwei Möglichkeiten wird die Y-Schleife von oben nach unten durchlaufen, wird die abfallende Erde im laufe der Animation gestreckt (es fällt allmählich zusammen). Wird die Y-Schleife von unten nach oben durchlaufen, wird die abfallende Erde so zusammenfallen das die Lücke sich langsam schließt und oben am Rand die Erde zusammenfällt. Je nachdem wie du es haben willst... Gibt es nichts mehr zu verschieben/kopieren ist Animationsende. Jetzt sieht es so aus, also ob die Pixel komplett nach unten fallen und somit keine Animation als abfallende Erde zu sehen ist. Es entsteht eine art Blubberblase die nach oben steigt.

Soll das Spiel später in 3D sein? Wenn nicht, kannst du die 3D-Befehle auch weg lassen...

Hummelpups

BeitragDi, Apr 25, 2006 20:10
Antworten mit Zitat
Benutzer-Profile anzeigen
klemmt deine return taste???
naja!

Inarie hat meines erachtens eine gute methode geschrieben. Einfach
aufn Imagebuffer zugreifen.
Weiß nicht ob das nun schon angesprichen wurde.

War mal so dreißt und habs hoch geladen...
http://www.blitzhelp.net/blitz...&id=98

IMurDOOM
blucode - webdesign - Ressource - NetzwerkSim
BlitzBasic 2D - BlitzMax - MaxGUI - Monkey - BlitzPlus

FireballFlame

BeitragDi, Apr 25, 2006 21:11
Antworten mit Zitat
Benutzer-Profile anzeigen
hectic hat Folgendes geschrieben:
Vergleichen ob es ein Pixel gibt wo unter diesem keines ist, wenn ja dann wird dieser Pixel einen Pixel nach unten kopiert (das ist dann die Animation).

Hab ich ja schon so...nur mit einem Unterschied: es wird nicht ein Pixel nach unten gesetzt sondern erstmal der Tempo-Float erhöht. Wenn der dann >=1 ist, wird das Pixel versetzt. Das ist, damit die Animation ganz langsam beginnen kann (<Pixel pro Rechenschritt).

Zitat:
Jetzt gibt es zwei Möglichkeiten wird die Y-Schleife von oben nach unten durchlaufen, wird die abfallende Erde im laufe der Animation gestreckt (es fällt allmählich zusammen). Wird die Y-Schleife von unten nach oben durchlaufen, wird die abfallende Erde so zusammenfallen das die Lücke sich langsam schließt und oben am Rand die Erde zusammenfällt. Je nachdem wie du es haben willst...

Ich wollte die zweite Variante...

Zitat:

Soll das Spiel später in 3D sein? Wenn nicht, kannst du die 3D-Befehle auch weg lassen...


Es soll NICHT direkt in 3D sein, aber ich brauche das trotzdem.
Ich will nämlich Sprites einbauen, die dann wie 2D aussehen, aber in Echtzeit skaliert und gedreht werden können - und halbtransparent gemacht.
siehe http://www.unrealsoftware.de/s..._bb_3dto2d



Und nein, meine Return-Taste klemmt nicht, aber ich lass immer mindestens nen halben Bildschirm Abstand zwischen den Funktionen. Dann seh ich besser, wo sie zu Ende sind Cool
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDi, Apr 25, 2006 23:09
Antworten mit Zitat
Benutzer-Profile anzeigen
So habs mal selbst ausprobiert. Hier kannst du mal testen ob es überhaupt von der Geschwindigkeit hin kommen kann. Mit dem Mausrad kann man die Explosionsgröße einstellen. Mit linker Maustaste kann man zeichnen. Mit der rechten Maustaste kann man eine Explosion erzeugen. Da jegliche Prüfungsroutinen fehlen, darf man keine Explosion ausserhalb des Bildschirmbereiches erzeugen. Code: [AUSKLAPPEN]
gfx%=640
gfy%=480
rd%=60
Graphics gfx,gfy,0,1
SetBuffer FrontBuffer()

Color 64,64,96
For x=0 To gfx
 Rect x,gfy/4+(Sin(x)+Cos(x*3))*20,1,gfy,1
Next




While Not KeyHit(1)
 mx=MouseX()
 my=MouseY()
 rd=rd-MouseZSpeed()*10
 If rd>200 rd=200
 If rd<10 rd=10

 If MouseDown(1)
  Color 64,64,96
  Oval mx-rd/2,my-rd/2,rd,rd,1
 End If

 If MouseHit(2)
  Color 0,0,0
  Oval mx-rd/2,my-rd/2,rd,rd,1
  x1=mx-1-rd/2
  x2=mx+1+rd/2
  yy=my+4+rd/2
  anim=rd
 End If

 Color 0,0,0
 Rect 0,0,gfx,gfy,0

 Color 255,255,255
 Line mx-rd/2,0,mx+rd/2,0
 Line 0,my-rd/2,0,my+rd/2
 Line mx-rd/2,gfy-1,mx+rd/2,gfy-1
 Line gfx-1,my-rd/2,gfx-1,my+rd/2

 If anim>0
  LockBuffer FrontBuffer()
   For x=x1 To x2 Step 1
    a=0
    For y=yy To 0 Step-1
     If a<>3
      If a=0 If ReadPixelFast(x,y)=$FF000000 a=1
      If a=1 If ReadPixelFast(x,y)=$FF404060 a=2:WritePixelFast x,y+1,$FF404060
      If a=2 If ReadPixelFast(x,y)=$FF000000 a=3:WritePixelFast x,y+1,$FF000000:Exit
     End If
    Next
   Next
   anim=anim-1
  UnlockBuffer FrontBuffer()
 End If

 Color 0,0,0:Rect 0,0,40,32,1:Color 255,255,255:ms=MilliSecs()
 If ms>mt mt=ms+498:fps=frame:frame=0 Else frame=frame+2
 Text 0,0,fps
 Text 0,16,anim

 ;VWait
Wend
End

FireballFlame

BeitragMi, Apr 26, 2006 19:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Joa..danke, das sieht erstmal so aus, wie ichs mir vergestellt hab...nur dass das Tempo sich noch erhöhen soll (wie in Wirklichkeit halt)
Das Tempo wär für normale Munition (relativ kleine Löcher) in Ordnung, für große nicht... aber dann lass ichs einfach schneller laufen, es ruckelt höchstens.

Hm...ich schau mir den Code mal an...
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit
 

BIG BUG

BeitragSa, Apr 29, 2006 11:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe hier auch mal eine Variante anzubieten. Ist bei wenigen zu bewegenden Pixeln zwar langsamer als Hectics Lösung, dafür bei größeren Mengen schneller.
Mit dem Parameter c_useimage kann man zwischen der Copyrect und Image-Methode umschalten. Geschwindigkeitsmäßig macht das aber keinen großen Unterschied.

Code: [AUSKLAPPEN]


Const gfx%         = 800
Const gfy%         = 600
Const window       = 1
Const c_useimage   = True
Const c_backcolor  = $FF000000
Const c_expldurchm = 61
Const c_pixelstep  = 3


Dim pix_x(c_expldurchm)
Dim pix_Y(c_expldurchm)

Global img_map


Type t_column

   Field xpos
   Field ypos
   Field height
   Field speed = 1
   Field image

End Type


;-------------------------
AppTitle "BlitzBomb"
Graphics3D gfx,gfy,16,window
SetBuffer BackBuffer()

SeedRnd MilliSecs()


img_map = CreateMap()


While Not KeyHit(1)


SetBuffer ImageBuffer(img_map)

upd_time = MilliSecs()
UpdateMap()
upd_time = MilliSecs()-upd_time


If MouseHit(1) Then BombMap(mx, my, c_expldurchm)



SetBuffer BackBuffer()

Cls
DrawImage img_map,0,0

mx=MouseX()
my=MouseY()
Color 255,0,0
Oval mx-10,my-10,20,20,1



For i = 0 To c_expldurchm-1

   WritePixel pix_x(i), pix_y(i), $FF0000

Next

Text 10, 10, upd_time


Flip
Wend
End

;--------------------------

Function CreateMap()

   Local x, img

   img = CreateImage(gfx, gfy)

   SetBuffer ImageBuffer(img)
   Color 15,152,0
   For x=0 To gfx
      Rect x,gfy/4+(Sin(x)+Cos(x*3))*20,1,gfy,1
   Next
   

   Return img

End Function




Function UpdateMap()

   Local col.t_column
   Local new_ypos


   For col = Each t_column
   
      new_ypos = col\ypos + col\speed
      If new_ypos < gfy And ReadPixel(col\xpos, new_ypos) = c_backcolor Then 

         ;Pixelreihe nach unten bewegen
         If c_useimage Then
            DrawBlock col\image, col\xpos, new_ypos-col\height
         Else
            CopyRect col\xpos, col\ypos-col\height, 1, col\height+1, col\xpos, new_ypos-col\height
         EndIf
         col\ypos = new_ypos

      Else
         If col\image Then FreeImage col\image
         Delete col
      EndIf

   Next


End Function


Function CreateMassMover(p_xpos, p_ypos, p_height)

   Local col.t_column

   Local pix0, pix1

   If p_xpos < 0 Or p_xpos >= gfx% Then Return 0

;  wegen kleinen Ungenauigkeiten bei der Positionsermittlung lieber 2 Pixel prüfen
   pix0 = ReadPixel(p_xpos, p_ypos)
   pix1 = ReadPixel(p_xpos, p_ypos-1)

   If pix0 = c_backcolor And pix1 = c_backcolor Return 0 ;Nichts zu bewegen
   If pix0 = c_backcolor Then p_ypos = p_ypos - 1 ;Reihe muss 1 weiter oben starten

   col = New t_column
   col\xpos   = p_xpos
   col\ypos   = p_ypos
   col\height = p_height
   col\speed  = 1
   col\image  = CreateImage(1, p_height+1)
   GrabImage col\image, p_xpos, p_ypos-p_height

End Function


Function BombMap(p_xpos, p_ypos, p_durchm)

   Local x#, y, height
   Local x_pos, y_pos
   Local x_multi# = 1.0 / (p_durchm-1)
   Local h_radi = p_durchm / 2
   Local h_radi_quad = (h_radi+0.5)^2
 
   If p_durchm = 0 Then Return 0   

   ;Loch erstellen
   Color 0,0,0 
   Oval p_xpos-h_radi,p_ypos-h_radi,p_durchm,p_durchm,1   

   ;MassMover-Reihen erstellen
   For x = -h_radi To h_radi
 
      ;am Explosionskreis positionieren
      y = Sqr(h_radi_quad - x*x)

      xpos = p_xpos + x
      ypos = p_ypos - y

      ;Position der Startpixel anzeigen
      pix_x(x+h_radi) = xpos
      pix_y(x+h_radi) = ypos

      CreateMassMover(xpos, ypos, gfy%-100 )

   Next

End Function
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group