Zurück   Flashforum > Flash > ActionScript > ActionScript 3

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 19-07-2010, 12:06   #1 (permalink)
Neuer User
 
Registriert seit: Aug 2009
Beiträge: 146
Snake-artiges Spiel - Wie Bewegung realisieren?

Heyho!

Ich stehe vor einem wahrscheinlich recht "simplen" Problem, sehe aber irgendwie die Lösung vor lauter Möglichkeiten nicht.
Ich versuche gerade ein Snake-artiges Spiel zu programmieren, in dem der Spieler mit einem Körperteil anfängt (=Kopf) und weitere Körperteile einsammeln kann, die sich dann an den Kopf heranhängen und sich mti dem Kopf mitbewegen.
Im Gegensatz zu dem originalen Snake kann man die Schlange in beliebige Richtungen bewegen (also auch Diagonal, etc.), die Bewegegungsgeschwindigkeit variiert, der Kopf kann seinen eigenen Körper berühren und wenn man den Levelrand übertritt kommt man auf der anderen Seite wieder hinaus.
Mein Problem ist, dass ich einfach keinen Weg finde die Körperteile schlangenartig zu bewegen, damit meine ich, dass die Körperteile vom Kopf "gezogen" werden und wenn der Kopf seine Bewegungsrichtung verändert, die Körperteile versetzt nacheinander das gleiche tun.
"Keinen Weg finde" ist dabei etwas falsch formuliert. Ich finde schon mehrere Wege, aber keiner funktioniert wie ich mir das Wünsche. So bald die Bewegungsgeschwindigkeit sehr hoch ist oder man schnelel Richtungsänderungen hat (wie wild auf den Pfeiltasten raufhämmern zum Beispiel), reißt die Schlange einfach in der Mitte auf, es entstehen Lücken, Körperteiel bewegen sich unkontrolliert weiter, etc.

Hier mal mein genereller Aufbau:
Der Kopf und die Körperteile sind jeweils zwei verschiedene Klassen. Ich bewege den Kopf mit den Pfeiltasten durch ein Level. In einer Kollisionsklasse überprüfe ich, ob der Kopf auf dem Level ein Körperteil berührt. Ist das der Fall, wird dieses Körperteil in einem Vector innerhalb der Kopfklasse gespeichert. Außerdem erhält das neue Körperteil die derzeitige Bewegungsrichtung seines Vorgängers. Der Kopf hat damit Zugriff auf all seine Körperteile und steuert damit die Bewegung der ganzen Schlange. So ruft der Kopf zu erst bei sich eine "move();"-Funktion auf, die ihn bewegt, udn anschließend in eienr Schleife für jedes Körperteil ebenfalls eine ähnliche Funktion (körperteil[i].move();"
Nun kommt die Bewegungsänderung hinzu. Pro "move();"-Funktionsaufruf überprüft der Kopf, ob der Spieler eine Pfeiltaste gedrückt hat und ob sich dadurch seine Bewegungsrichtung ändert. Ist dies der Fall, wird gespeichert an welchem Punkt diese Bewegungsrichtung stattfindet und wie die neue Bewegungsrichtung aussieht. Dieser Wegpunkt neue Wegpunkt wird an alle Körperteile übergeben und dort in einem Vector gespeichert. (Kleiner Nachsatz zum Einsammeln der Körperteile: Sammelt man ein neues Körperteil ein, übernimmt dieses zusätzlich auch alle noch bevorstehenden Wegpunkte des Vorgängers).
Ruft der Kopf nun "körperteil[i].move();" auf, überprüft der Körperteil, ob er Wegpunkte ablaufen muss. Wenn nicht, hängt es sich in einem konstanten Abstand an den Vorgänger. Wird der Kopf bewegt, bewegen sich so zwangsläufig alle Körperteile mit, da sich der Abstand zwischen Kopf und Körperteil bzw. Körperteil udn Körperteil nicht verringern kann. Muss der Köperteil aber einen Wegpunkt ablaufen, bewegt es sich in einer gegeben Geschwindigkeit mit der ursprünglichen Bewegungsrichtung weiter. Anschließend wird überprüft, ob der Wegpunkt erreicht wurde. Wenn ja, übernimtm das Körperteil die neue Bewegungsrichtugn und hängt sich wieder an den Vorgänger bzw. läuft die noch anstehenden Wegpuntke ab.
Kleiner Zusatz: Ein Wegpuntk wird auch erstellt, wenn man die Levelgrenze überschreitet udn auf der anderen seite wieder herauskommt.

Soweit so gut. In der Theorie hört sich das prima an, in der Praxis reißt die Schlange aber in gewissen Situationen auf.

Hier ein paar Quellcodeauszüge:

Kopfklasse - "move();"-Funktion:
Code:
		// move head
		private function move():void
		{
			// get new walk direction
			if (pressLeft || pressRight || pressDown || pressUp)
				movingDirection = getAngle();
			// new movingDirection
			if (oldMovingDirection !== movingDirection)
			{
				addWaypointToBodyChain(position, movingDirection);	// adds new waypoint to all body elements
			}
			// move
			x += Math.cos(movingDirection) * speed;
			y += -Math.sin(movingDirection) * speed;	
			oldMovingDirection = movingDirection;
		}
		
		// get angle for walking direction
		private function getAngle():Number
		{
			// rotate dependent on keyboard input
			var newAngle:int;
			// "left input" (with and without up/down-drift)
			if (pressLeft && !pressDown && !pressUp) 
				newAngle = 180;
			else if (pressLeft && pressDown)
				newAngle = 225;
			else if (pressLeft && pressUp)
				newAngle = 135;
			// "right input" (with and without up/down-drift)
			if (pressRight && !pressDown && !pressUp) 
				newAngle = 0;
			else if (pressRight && pressDown)
				newAngle = 315;
			else if (pressRight && pressUp)
				newAngle = 45;
			// (strict) "up/down input"
			if (pressUp && !pressLeft && !pressRight) 
				newAngle = 90;
			if (pressDown && !pressLeft && !pressRight) 
				newAngle = 270;
			// return angle in rad
			return MathHelper.degInRad(newAngle);
		}
Körperklasse - "move();"-Funktion:
Code:
		// move
		private function move(leader:GameObject):void
		{
			// path stores all waypoints
			if (path.length == 0)
				snapToChain(leader);
			else
			{
				var wayPoint:Point = path.getWaypoint().point;
				// get distance to wayPoint
				if (distanceToPoint <= 0)
					distanceToPoint = MathHelper.distance(position, wayPoint);
				// update distance to wayPoint
				distanceToPoint -= speed; 
				// snap to point
				snapToPoint(wayPoint);
				// at waypoint?
				if (distanceToPoint <= 0)
				{
					movingDirection = path.getWaypoint().movingDirection;
					path.removeWaypoint();
				}
			}
		}

		
		// snapToChain
		public function snapToChain(leader:GameObject):void
		{
			position = leader.position;
			x -= Math.cos(movingDirection) * DISTANCE;
			y -= -Math.sin(movingDirection) * DISTANCE;
		}
		
		// snap to point
		private function snapToPoint(wayPoint:Point):void
		{
			position = wayPoint;
			x -= Math.cos(movingDirection) * distanceToPoint;
			y -= -Math.sin(movingDirection) * distanceToPoint;
		}
Das ist die letzte Variante die ich ausprobiert habe. Hier setze ich das Körperteil auf den Wegpunkt und versetze es wieder um eine bestimmte Distanz, die sich bei ejdem Durchgang verringert. Dadurch sieht es so aus, als ob sich das Körperteil zu dem Punkt hinbewegt. Hört sich zunächst nciht ganz logisch an, aber passt vom Schema her schön an das Anhängen an der Vorgänger und erleichtert das Erkennen, ob das Körperteil einen Wegpunkt erreicht hat oder nicht (Distanz wird negativ). Davor habe ich auch noch eingie andere Varianten ausprobiert, in denen ich simpel das Körperteil in Bewegungsrichtung bewegt habe, dann msuste ich immer überprüfen, ob das Körperteil über die Koordinaten des Puntkes "hinaus" war (falls BEwegeunsgrichtung "positiv", sonst natürlich andersherum). Aber egal welche Varianten ich genommen habe. Keine lief zufrieden stellend.

Habt ihr einen anderen Ansatz?

MfG,
Pipo

Geändert von Don Pipo (19-07-2010 um 12:07 Uhr)
Don Pipo ist offline   Mit Zitat antworten
Alt 19-07-2010, 15:10   #2 (permalink)
ING
whatever
 
Registriert seit: May 2008
Beiträge: 419
ich geh mal davon aus das sich die schlange aus einzelnen segmenten zusammensetzt, dann ist es das einfachste das letzte schlangen segment an die neue position zu setzen.

hab vor ewigkeiten mal ein tutorial für ein simples snake spiel geschrieben, vllt. findest du da drin ja noch die ein oder andere idee, ist allerdings noch alles as1 und für swish ausgelegt..
.
Angehängte Dateien
Dateityp: zip snake_tutorial.zip (96,3 KB, 6x aufgerufen)
ING ist offline   Mit Zitat antworten
Alt 19-07-2010, 15:43   #3 (permalink)
Neuer User
 
Registriert seit: Aug 2009
Beiträge: 146
Danke für die Rückmeldung. Das würde aber leider nicht funktionieren, da die Geschwindigkeit der Schlange variieren kann. Angenommen die Schange bewegt sich mit einem Pixel vorwärts und schreitet x1=1, x2=2, x3=3 ab und erhält dann einen Geschwindigkeitszuwachs, so dass sich die Schlange mit zwei Pixeln vorwärts bewegt und dann x4=5, x5=7, x6=9 abschreitet, so können nachfolgende Segmente nicht einfach x1, x2 und x3 übernehmen.

Einfach die Geschwindigsdifferenz zu den Koordinaten hinzuaddieren würde glaueb ich auch nicht funktionieren, da man dabei nicht die Richtungsänderung ab einem gewissen Punkt berücksichtigt.
Don Pipo ist offline   Mit Zitat antworten
Alt 19-07-2010, 18:02   #4 (permalink)
Techniker
 
Benutzerbild von hgseib
 
Registriert seit: Sep 2003
Ort: 64807
Beiträge: 16.324
wackeln
H.G.Seib
-> Pendel
Pendel, ein Pendel und 9 Pendel-Kette
ok, kein skelett und kricht auch nicht davon. aber mit der selben technik würde ich das hinbekommen, was du machen willst.
so wie die drehimpule von sekment zu sekment weiter gegeben werden, so kann man auch das 'ziehen' und gummiartige 'nachrucken' von sekment zu sekment weiter geben.

zusammenbau
nach dem 'einsammeln' gehören die teile als unterobjekte an den rumpf. so wackeln sie mit dem körper davon und so kann man die auch langsam an ihren drehpunkt hinbewegen lassen
(ohne quellcode)
http://www.seibsprogrammladen.de/fra...mpelmann/flash
__________________
die ultimative antwort auf alle programmierfragen: der debugger
mfg h.g.seib www.SeibsProgrammLaden.de

Geändert von hgseib (19-07-2010 um 18:09 Uhr)
hgseib ist offline   Mit Zitat antworten
Alt 19-07-2010, 18:20   #5 (permalink)
Keine Panik
 
Registriert seit: Apr 2010
Ort: Düsseldorf (im ernst)
Beiträge: 1.868
mir fällt es schwer nachzuvollziehen, wie die Bewegung aussehen soll, die du im Sinn hast.

teile deiner Beschreibung klingen wie das klassische Snake (tile-Based), andere lassen vermuten, dass du eine pixel-genaue Bewegung und somit Positioniereung im Sinn hast.

und bei dem Ausdruck "die Körperteile schlangenartig zu bewegen" hab ich vermutlich was völlig anderes im Sinn, als du !?

wäre gut, wenn du die fla/swf anhängen oder verlinken könntest, so dass ich mir das ganze mal ansehen kann, wie die Schlange sich momentan verhält.

im Anhang hab ich mal ein Würmchen (is noch keine Schlange) angehangen.
vielleicht hilft der Code ja weiter.

Steuerung mit den Pfeiltasten,
+/- (Num-Block) um neue Elemente an den Wurm anzuhängen/zu entfernen.
Angehängte Dateien
Dateityp: fla Worm_CS3.fla (58,5 KB, 7x aufgerufen)
Dateityp: swf Worm_CS3.swf (2,2 KB, 21x aufgerufen)
__________________
greetz Thomas

plz RTFM & Coding Conventions
thomas_E ist gerade online   Mit Zitat antworten
Alt 19-07-2010, 19:20   #6 (permalink)
Neuer User
 
Registriert seit: Aug 2009
Beiträge: 146
@hgseib:
Danke für das Beispiel mit der 9er Kette. Weiß nicht, ob ich das ganze aufs Spiel übertragen könnte, aber da sind glaueb ich ein paar Dinge drin, die für mich bei anderen Sachen interessant sein könnten.

@thomas_E:
Mit "schlangenartig" habe ich mich etwas in der Formulierung vergriffen, weil ich das Spiel "Snake" als Beispiel genommen habe. Die meisten meinen mit schlangenartig die typische S-Bewegung einer Schlange und eigentlich würde ich das auch unter dem Begriff verstehen, aber das meinte ich hier nicht. Entschuldigung für die Verwirrung. Wahrscheinlich wäre "raupenartig" besser gewesen, da es sich bei mir auch um eine Raupe handelt und nicht um eine Schlange. Ich meine damit nur, dass die Richtungsänderung bei der Bewegung für die einzelnen Segmente erst nach und nach vom Kopf bis zum Schwanz durchgegeben werden. Auf jeden Fall meinte ich keine kachelbasierte Bewegung, sondern pixelbasierte (im besten Fall in alle Richtungen, also 360°).
Dein angehängtes Beispiel ist so ziemlich das was ich gesucht habe! Nicht nur zu 100%, sondern eher zu 130%, weil deine Bewegung noch viel weiter reicht als das, was ich mir vorgestellt habe - was aber auch sehr positiv ist. Vielen Dank dafür. Ich werde mir spätestens morgen, wenn ich mehr Zeit habe, den Quellcode näher anschauen.

Im Anhang eine der Varianten die ich hatte, welche von der Bewegung her exakt meinen Vorstellungen entspricht, die aber nur bei langsamen Bewegungsgeschwindigkeiten- und Richtungsänderungen funktioniert.
Angehängte Dateien
Dateityp: swf SoundCaterpillar.swf (55,0 KB, 17x aufgerufen)

Geändert von Don Pipo (19-07-2010 um 19:26 Uhr)
Don Pipo ist offline   Mit Zitat antworten
Alt 19-07-2010, 21:55   #7 (permalink)
Techniker
 
Benutzerbild von hgseib
 
Registriert seit: Sep 2003
Ort: 64807
Beiträge: 16.324
SoundCaterpillar.swf
hmmmm, ich sehe nur ein sattes schwarz!?
__________________
die ultimative antwort auf alle programmierfragen: der debugger
mfg h.g.seib www.SeibsProgrammLaden.de
hgseib ist offline   Mit Zitat antworten
Alt 20-07-2010, 08:33   #8 (permalink)
Neuer User
 
Registriert seit: Aug 2009
Beiträge: 146
Hmm... das ist ja komisch. Habe es mal aus dem Anhang geladen, aber bei mir funktioniert es. Man steuert einen roten Pixelhaufen, der grüne Pixelhaufen einsammeln kann.
Don Pipo ist offline   Mit Zitat antworten
Alt 20-07-2010, 12:19   #9 (permalink)
Techniker
 
Benutzerbild von hgseib
 
Registriert seit: Sep 2003
Ort: 64807
Beiträge: 16.324
das swf alleine ist schwarz. wenn man es auf ein browserfenster zieht, dann kommt etwas. und es ist arg, arg langsam :-(
__________________
die ultimative antwort auf alle programmierfragen: der debugger
mfg h.g.seib www.SeibsProgrammLaden.de
hgseib ist offline   Mit Zitat antworten
Alt 20-07-2010, 12:56   #10 (permalink)
Neuer User
 
Registriert seit: Aug 2009
Beiträge: 146
Wow, gut zu wissen. Ich öffne die .swf immer im stand-alone Player und dort läuft die Anwendung bei mir mit 30 fps. Hochskaliert im Browser läuft sie auch bei mir wesentlich langsamer. Wird aber in beiden Fällen korrekt angezeigt.
Don Pipo ist offline   Mit Zitat antworten
Alt 20-07-2010, 17:03   #11 (permalink)
Techniker
 
Benutzerbild von hgseib
 
Registriert seit: Sep 2003
Ort: 64807
Beiträge: 16.324
letzteres ist klar. ja nach browser sind bis zu 40% weniger rechenleistung drinn.

ersteres verstehe ich allerdings nicht. da musst du ordentlich nachbessern! rückst du im hindergrund jedes quadrat einzeln? hast du für den hindergrund bitmapCache angeschaltet?

und warum ich im swf nichts sehe verstehe ich auch nicht. dachte erst, du fragst etwas übers internet ab. ist aber offensichtlich nicht der fall. naja, hat halt alles nichts mit deiner bewegerei zu tun. da musst du dich jetzt selbst durchschlängeln ;-)
__________________
die ultimative antwort auf alle programmierfragen: der debugger
mfg h.g.seib www.SeibsProgrammLaden.de
hgseib ist offline   Mit Zitat antworten
Alt 20-07-2010, 18:35   #12 (permalink)
Neuer User
 
Registriert seit: Aug 2009
Beiträge: 146
Zitat:
Zitat von hgseib Beitrag anzeigen
rückst du im hindergrund jedes quadrat einzeln? hast du für den hindergrund bitmapCache angeschaltet?
Japp. das sind einzelne Kacheln, die ich zu Beginn anordne und danach wende ich bitmapCache an.
Werd ncoh eingie Sachen ändern müssen... und mich durchschlängeln
Don Pipo ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Bildvergleich Spiel in Flash - wie realisieren? DennisM Flash Einsteiger 6 24-09-2007 21:46
Explorer-artiges Script Argh Flash MX 2004 1 26-08-2004 21:14
Aktion bei gleichen Koordinanten => Snake Spiel Swatchmaster ActionScript 1 2 02-06-2004 00:12
Bewegung für Snake Aydan-Pryde Flash 4 und Flash 5 1 04-07-2002 17:10
Mastermind Spiel in Flash realisieren smiets Flash 4 und Flash 5 0 08-05-2002 15:21


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:41 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele