Zurück   Flashforum > Flash > ActionScript > Spielkonzepte und Spieleprogrammierung

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 21-04-2007, 15:42   #1 (permalink)
x39
 
Benutzerbild von georgem
 
Registriert seit: Oct 2004
Ort: St.Gallen, Schweiz
Beiträge: 1.261
Kraftfeld programmieren?

Hallo,

wie programmiert man eigentlich ein Kraftfeld?

Ich hab hier mal etwas probiert, aber ich denke das ist vielleicht ein ganz falscher angang...

Ansehen: http://www.margaris.de/?p=1026

Fla: ist unten angehängt.

Code:

PHP-Code:
import flash.filters.DropShadowFilter;
//
MovieClip.prototype.startFill = function(color1alpha1linesizecolor2alpha2) {
    
with (this) {
        
beginFill(color1alpha1);
        
lineStyle(linesizecolor2alpha2);
    }
};
MovieClip.prototype.box = function(x1y1x2y2) {
    
with (this) {
        
polygon4(x1y1x2y1x2y2x1y2);
    }
};
MovieClip.prototype.polygon4 = function(x1y1x2y2x3y3x4y4) {
    
with (this) {
        
moveTo(x1y1);
        
lineTo(x2y2);
        
lineTo(x3y3);
        
lineTo(x4y4);
    }
};
/////////////////
cc 1;
for (
yi=0yi<=9yi++) {
    
cc *= -1;
    for (
xi=0xi<=9xi++) {
        
_root.createEmptyMovieClip("atom"+xi+"o"+yixi+10*yi);
        
_root["atom"+xi+"o"+yi].createEmptyMovieClip("quant"1);
        
cc *= -1;
        if (
cc eq 1) {
            
_root["atom"+xi+"o"+yi].quant.startFill(0xFF7F0010010100);
        }
        if (
cc eq -1) {
            
_root["atom"+xi+"o"+yi].quant.startFill(0x007FFF10010100);
        }
        
_root["atom"+xi+"o"+yi].quant.box(-3, -333);
        
_root["atom"+xi+"o"+yi].quant.endFill();
        
_root["atom"+xi+"o"+yi]._x xi*30;
        
_root["atom"+xi+"o"+yi]._y yi*30;
    }
}
_root._x 100;
_root._y 100;
//
function dist(x1y1x2y2) {
    var 
dx x1-x2;
    var 
dy y1-y2;
    return (
dx*dx+dy*dy);
}
_root.onEnterFrame = function() {
    
_mx _root._xmouse;
    
_my _root._ymouse;
    for (
yi=0yi<=9yi++) {
        for (
xi=0xi<=9xi++) {
            
dist(_mx_my_root["atom"+xi+"o"+yi]._x_root["atom"+xi+"o"+yi]._y);
            
//trace(d)
            
if (d<5000) {
                
darta = (Math.atan2(_root._ymouse-_root["atom"+xi+"o"+yi]._y_root._xmouse-_root["atom"+xi+"o"+yi]._x));
                
_root["atom"+xi+"o"+yi].quant._x = -(5000-d)/100*Math.cos(darta);
                
_root["atom"+xi+"o"+yi].quant._y = -(5000-d)/100*Math.sin(darta);
                
//
                
_root["atom"+xi+"o"+yi]._xscale _root["atom"+xi+"o"+yi]._yscale=100+(5000-d)/100;
                var 
filter:DropShadowFilter = new DropShadowFilter(3+(5000-d)/2504500.5, (5000-d)/1000, (5000-d)/1000);
                
_root["atom"+xi+"o"+yi].filters = [filter];
            }
            if (
d>=5000) {
                
_root["atom"+xi+"o"+yi].quant._x 0;
                
_root["atom"+xi+"o"+yi].quant._y 0;
                
_root["atom"+xi+"o"+yi]._xscale _root["atom"+xi+"o"+yi]._yscale=100;
                var 
filter:DropShadowFilter = new DropShadowFilter(34500.511);
                
_root["atom"+xi+"o"+yi].filters = [filter];
            }
        }
    }
};
stop(); 
Es geht weniger darum ob das Kraftfeld auf die Maus reagiert , oder einfach verschiedene Objekte interagieren.
Ich glaube in der Mathematik wären die richtigen Stichworte Gradientenfeld oder Strömungsfeld. Hat aber nichts mit dem oberen Beispiel zu tun, wäre aber sicherlich der professionele Ansatz...

Habt ihr Ideen, Erfahrungen, Links?



Danke im voraus.
Angehängte Dateien
Dateityp: rar kraftfeld.rar (5,4 KB, 5x aufgerufen)
__________________
The Sleeper Must Awaken

www.margaris.de | www.exosolar.net

Geändert von georgem (21-04-2007 um 15:45 Uhr)
georgem ist offline   Mit Zitat antworten
Alt 21-04-2007, 16:07   #2 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
Ich würde dein Beispiel folgendermaßen umsetzen:
Jeder Punkt ist eine eigenständige Masse mit einem Ursprungsort, zu dem sie eine anziehende Kraft (wächst mit r oder mit r^2) verspürt. Die Maus übt auf die Massen eine abstoßende Kraft aus (wächst mit 1 / r oder 1 / r^2).
Aus der resultierenden Kraft kannst du dann mit a = f / m die Beschleunigung dieser Masse ausrechnen, und damit wiederum ihre Geschwindigkeit anpassen.
__________________
»Carpe diem«, sagte der Graf. (Terry Pratchett: Ruhig Blut!)
Janoscharlipp ist offline   Mit Zitat antworten
Alt 21-04-2007, 18:06   #3 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
hier mal wie ich mir das vorgestellt habe:
(Klasse importieren, und dann ForceField.main(_root); aufrufen)
PHP-Code:

class ForceField extends MovieClip
{
    public static var 
symbolName String "__Packages.ForceField";
    private static var 
symbolLinked Boolean Object.registerClass(symbolNameForceField);
    
    public static function 
main(timeline:MovieClip) : Void
    
{
        var 
rows Number 10;
        var 
columns Number 10;
        
        var 
spaceX Number 15;
        var 
spaceY Number 15;
        
        var 
offsetX Number 100;
        var 
offsetY Number 100;
        
        var 
row Number;
        var 
column Number;
        
        var 
point ForceField;
        
        for (
row 0row rowsrow++) {
            for (
column 0column columnscolumn++) {
                
point ForceField(timeline.attachMovie(symbolName"point" + (row columns column), row columns column));
                
                
point.setOrigin(column spaceX offsetXrow spaceY offsetY);
            }
        }
    }
    
    private var 
originX Number;
    private var 
originY Number;
    
    private var 
speedX Number;
    private var 
speedY Number;
    
    public function 
ForceField(Void)
    {
        
speedX 0;
        
speedY 0;
        
        
draw();
    }
    
    public function 
draw(Void) : Void
    
{
        var 
Number 5;
        
        
beginFill(0x000000100);
        
        
moveTo(-r, -r);
        
lineTo(r, -r);
        
lineTo(rr);
        
lineTo(-rr);
        
lineTo(-r, -r);
        
        
endFill();
    }
    
    public function 
setOrigin(x:Numbery:Number) : Void
    
{
        
_x originX x;
        
_y originY y;
    }
    
    public function 
onEnterFrame(Void) : Void
    
{
        
// Kraft durch die Maus
        
var mouseDistance Number Math.sqrt(_xmouse _xmouse _ymouse _ymouse);
        
        var 
mouseForceX Number = -_xmouse mouseDistance mouseDistance 100;
        var 
mouseForceY Number = -_ymouse mouseDistance mouseDistance 100;
        
        
// Kraft zurück zum Startpunkt
        
var dx Number originX _x;
        var 
dy Number originY _y;
        var 
originDistance Number Math.sqrt(dx dx dy dy);
        
        var 
originForceX Number dx originDistance;
        var 
originForceY Number dy originDistance;
        
        
// Gesamtkraft
        
var resultingForceX Number mouseForceX originForceX;
        var 
resultingForceY Number mouseForceY originForceY;
        
        
// Beschleunigung
        
var mass Number 10;
        
        var 
accelerationX Number resultingForceX mass;
        var 
accelerationY Number resultingForceY mass;
        
        
// Anpassung der Geschwindigkeit
        
speedX += accelerationX;
        
speedY += accelerationY;
        
        
// Bewegung
        
_x += speedX;
        
_y += speedY;
        
        
// Dämpfung der Geschwindigkeit
        
speedX *= 0.9;
        
speedY *= 0.9;
    }

__________________
»Carpe diem«, sagte der Graf. (Terry Pratchett: Ruhig Blut!)
Janoscharlipp ist offline   Mit Zitat antworten
Alt 22-04-2007, 21:48   #4 (permalink)
x39
 
Benutzerbild von georgem
 
Registriert seit: Oct 2004
Ort: St.Gallen, Schweiz
Beiträge: 1.261
danke vielmals für das Beispiel.

Ich konnte es da ich nicht so ganz mit Klassen auskomme nicht kompilieren *scham*

Wie auch immer, hab es auf normal-sprache übersetzt (oder baby-sprache je nachdem). Und anstatt quadrate kleine randomzahlen eingebaut. Hab ich was falsch übersetzt?

So siehts aus: http://www.margaris.de/flashforum/forcefield.html

Hier der Code (unten das fla):

PHP-Code:
var rows:Number 10;
var 
columns:Number 10;
var 
spaceX:Number 30;
var 
spaceY:Number 30;
var 
offsetX:Number 20;
var 
offsetY:Number 20;
var 
row:Number;
var 
column:Number;
for (
row=0row<rowsrow++) {
    for (
column=0column<columnscolumn++) {
        
_root.createEmptyMovieClip("point"+(row*columns+column), row*columns+column);
        
with (_root["point"+(row*columns+column)]) {
            var 
r:Number 5;
            
createTextField("txt",0,0,0,30,20)
            
txt.text random(10)
            
txt.selectable false
            txt
.embedFonts true
            txt
.setTextFormat(_root.my_arial)
        }
        
_root["point"+(row*columns+column)].speedX 0;
        
_root["point"+(row*columns+column)].speedY 0;
        
_root["point"+(row*columns+column)]._x _root["point"+(row*columns+column)].originX=column*spaceX+offsetX;
        
_root["point"+(row*columns+column)]._y _root["point"+(row*columns+column)].originY=row*spaceY+offsetY;
        
_root["point"+(row*columns+column)].onEnterFrame = function() {
            
// Kraft durch die Maus 
            
var mouseDistance:Number Math.sqrt(this._xmouse*this._xmouse+this._ymouse*this._ymouse);
            var 
mouseForceX:Number = -this._xmouse/mouseDistance/mouseDistance*100;
            var 
mouseForceY:Number = -this._ymouse/mouseDistance/mouseDistance*100;
            
// Kraft zurück zum Startpunkt 
            
var dx:Number this.originX-this._x;
            var 
dy:Number this.originY-this._y;
            var 
originDistance:Number Math.sqrt(dx*dx+dy*dy);
            var 
originForceX:Number dx*originDistance;
            var 
originForceY:Number dy*originDistance;
            
// Gesamtkraft 
            
var resultingForceX:Number mouseForceX+originForceX;
            var 
resultingForceY:Number mouseForceY+originForceY;
            
// Beschleunigung 
            
var mass:Number 10;
            var 
accelerationX:Number resultingForceX/mass;
            var 
accelerationY:Number resultingForceY/mass;
            
// Anpassung der Geschwindigkeit 
            
this.speedX += accelerationX;
            
this.speedY += accelerationY;
            
// Bewegung 
            
this._x += this.speedX;
            
this._y += this.speedY;
            
// Dämpfung der Geschwindigkeit 
            
this.speedX *= 0.9;
            
this.speedY *= 0.9;
        };
    }

Es sieht gut aus, etwas ähnliches hatte ich auch einmal entwickelt, ist aber nicht was ich mir eigentlich vorstelle.
Es sollte so sein, dass ich einer Zahl sage: "Du stosst jetzt alle anderen ab, mit Kraft X." Jetzt sollten die nächsten Nachbarn auch am weitesten abgestossen werden , soweit eigentlich logisch. Was noch dazukommt: Die 1.nachbarn dürfen die zweiten nicht überlagern, sondern müssten an der nächsten Reihe Nachbarn anstossen, und diese nicht weiter wegstossen. Hätte also auch etwas mit Kollisionsabfrage zu tun, und würde schnell unperformant werden, deshalb wäre das ganz auch nicht für 100 Partikel gedacht, sondern vielleicht 20.
Ich plane ein Menu zu bauen, wo wen man auf einen Punkt rollovert, diese etwas hervorgehoben wird, und eben die unmittelbaren Nachbarn (und auch die Nachbarsnachbarn) etwas abgestossen werden - ohne allerdings die Nachbarsnachbarn zu überlagern ( da diese ja weniger bis gar nicht abgestossen werden, könnte das passieren), sondern an ihnen abgeblockt zu werden .... müsste damit es richtig gut aussieht, ziemlich physikalisch gelöst werden, also mit Kraft UND Gegenkraft.
Die Atome des Menus sollen schlussendlich kurze Texte/Wörter darstellen, und in einer x,y Matrix nicht unähnlich oben angeordnet sein.

Also danke soweit, weil jetzt konnte ich erstmals richtig darüber nachdenken und weiss jetzt was ich überhaupt will.
Angehängte Dateien
Dateityp: rar forcefield.rar (23,7 KB, 5x aufgerufen)
__________________
The Sleeper Must Awaken

www.margaris.de | www.exosolar.net
georgem ist offline   Mit Zitat antworten
Alt 23-04-2007, 08:17   #5 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
Also das was du da gebastelt hast, verhält sich anders, als mein Beispiel.

Wenn sich jedes Objekt auf jedes andere auswirkt, wirst du in der Tat bissel Probleme mit der Performance bekommen, aber bei 20 Objekten sollte es noch gehen.

Das die Objekte sich nicht überlagern kannst du am einfachsten verhindern, indem du einfach die Abstände groß genug, und die Kraft klein genug machst.

Aber vielleicht solltest du dich erstmal kurz mit AS2 auseinander setzen.
__________________
»Carpe diem«, sagte der Graf. (Terry Pratchett: Ruhig Blut!)
Janoscharlipp ist offline   Mit Zitat antworten
Alt 23-04-2007, 09:27   #6 (permalink)
x39
 
Benutzerbild von georgem
 
Registriert seit: Oct 2004
Ort: St.Gallen, Schweiz
Beiträge: 1.261
ja genau, dürfte das klügste sein, erstmal Klassen-manierismen zu verstehen.
__________________
The Sleeper Must Awaken

www.margaris.de | www.exosolar.net
georgem 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



Alle Zeitangaben in WEZ +1. Es ist jetzt 18:20 Uhr.

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


Copyright ©1999 – 2012 Marc Thiele