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

![]() |
FireballFlameBetreff: 2D-Gelände, das "einstürzen" kann? |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() - 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): ![]() 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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() 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 ![]() Viel Spaß damit, kryan |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
OK, danke. ![]() Aber da gibt es noch ein Problem ![]() 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 ![]() |
||
![]() |
Goodjee |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() ansonsten würde ich aber auch dreamoras lösung nehmen! mfg kryan |
||
![]() |
FireballFlame |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmmm... ![]() ![]() 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 ![]() ![]() ...aber wenn ihr versteht, was ich meine - so könnte es doch gehen, oder? |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
€ 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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
@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 |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() |
||
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 |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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) |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group