XT Knowledge Base
Hauptseite | Über | Hilfe | FAQ | Spezialseiten | Anmelden

Druckversion | Impressum | Datenschutz | Aktuelle Version

Spieleentwicklung mit JavaScript - PlayFieldControl-Klasse

(Unterschied zwischen Versionen)

(PlayFieldControl-Klasse)
(PlayFieldControl-Klasse)
Zeile 1: Zeile 1:
= PlayFieldControl-Klasse =
= PlayFieldControl-Klasse =
 +
Der nächste naheliegende Schritt besteht darin, das EventHandling in eine Klasse zu packen, die für die Steuerung des Spielfelds zuständig ist. Vorerst soll es genügen, die Karte mit der Maus verschieben zu können.
Der nächste naheliegende Schritt besteht darin, das EventHandling in eine Klasse zu packen, die für die Steuerung des Spielfelds zuständig ist. Vorerst soll es genügen, die Karte mit der Maus verschieben zu können.
Zeile 58: Zeile 59:
   //...
   //...
}
}
 +
</pre>
 +
Und siehe da:
 +
 +
[[Datei:Thatsitalert.png]]
 +
 +
Mit diesem hart erarbeiteten know how kann nun die PlayFieldControl-Klasse implementiert werden:
 +
<pre>
 +
  function PlayFieldControl( div_id, pf, button )
 +
  {
 +
    this.pf = pf;
 +
    this.dragx = -1;
 +
    this.dragy = -1;
 +
    this.button = button;
 +
    PlayFieldControl.instance = this;
 +
       
 +
    var div = document.getElementById( div_id );
 +
    div.addEventListener('mousedown', this.OnMouseDown, false);
 +
    div.addEventListener('mousemove', this.OnMouseMove, false);
 +
    div.addEventListener('mouseup', this.OnMouseUp, false);
 +
  }
 +
     
 +
  PlayFieldControl.prototype.OnMouseDown = function( e, fromMove )
 +
  {
 +
    var me = PlayFieldControl.instance;
 +
    if( (e.which == me.button || fromMove) )
 +
    {
 +
      me.dragx = e.pageX;
 +
      me.dragy = e.pageY;
 +
    }
 +
  }
 +
     
 +
  PlayFieldControl.prototype.OnMouseMove = function ( e )
 +
  {
 +
    var me = PlayFieldControl.instance;
 +
    if( me.dragx > 0 && me.dragy > 0 )
 +
    {
 +
      me.OnMouseUp( e, true );
 +
      me.OnMouseDown( e, true );
 +
    }
 +
  }
 +
     
 +
  PlayFieldControl.prototype.OnMouseUp = function( e, fromMove )
 +
  {
 +
    var me = PlayFieldControl.instance;
 +
    if( (e.which == me.button || fromMove) && me.dragx > 0 && me.dragy > 0 )
 +
    {
 +
      me.pf.move( me.dragx - e.pageX, me.dragy - e.pageY );
 +
      me.dragx = -1;
 +
      me.dragy = -1;
 +
    }
 +
  }       
</pre>
</pre>

Version vom 13:07, 3. Sep. 2010

PlayFieldControl-Klasse

Der nächste naheliegende Schritt besteht darin, das EventHandling in eine Klasse zu packen, die für die Steuerung des Spielfelds zuständig ist. Vorerst soll es genügen, die Karte mit der Maus verschieben zu können.

Hier ergibt sich allerdings ein Problem: Da die Methode addEventListener eine Funktion erwartet, geht der Context zum Objekt, dessen Methoden aufgerufen werden sollen verloren. Die Handlerfunktionen werden zwar aufgerufen, aber über this wird nicht auf den Inhalt des EventHandler-Objekts zugegriffen, sondern auf die Inhalte desjenigen DOM-Objekts, an die die EventHandler gebunden sind.

Beispiel:

function EventHandler( div_id )
{
  var div = document.getElementById( div_id );
  div.addEventListener( 'mousedown', this.OnMouseDown, false );
}

EventHandler.prototype.OnMouseDown = function( e )
{
  alert( this );
}

var eh;
function init()
{
  //...
  eh = new EventHandler( "board_div" );
  //...
}

Bei einem Klick erscheint diese Messagebox:

Datei:Eventalert.png

Das heißt, über this kann auf die Elemente des HTMLDivElements zugegriffen werden, für das der EventHandler installiert wurde, aber nicht auf das Objekt, dessen Methoden aufgerufen werden.

Wie erhält man in der Eventhandler-Methode nun Zugriff auf das Objekt?

Mit einem Trick! In einer statischen Variable kann man eine Referenz auf eine Instanz der Eventhandler-Klasse ableben und dann in der Eventhandler-Funktion darauf zugreifen. Der Haken dabei ist, dass es insgesamt nur eine Instanz gleichzeitig geben kann. Das sollte für unsere Zwecke aber ausreichend sein.

Der Eventhandler wird also wie folgt erweitert:

function EventHandler( div_id )
{
  EventHandler.instance = this;
  this.info = "That's it!";
  var div = document.getElementById( div_id );
  div.addEventListener( 'mousedown', this.OnMouseDown, false );
}

EventHandler.prototype.OnMouseDown = function( e )
{
  var me = EventHandler.instance;
  alert( me.info );
}

var eh;
function init()
{
  //...
  eh = new EventHandler( "board_div" );
  //...
}

Und siehe da:

Datei:Thatsitalert.png

Mit diesem hart erarbeiteten know how kann nun die PlayFieldControl-Klasse implementiert werden:

  function PlayFieldControl( div_id, pf, button )
  {
    this.pf = pf;
    this.dragx = -1;
    this.dragy = -1;
    this.button = button;
    PlayFieldControl.instance = this;
        
    var div = document.getElementById( div_id );
    div.addEventListener('mousedown', this.OnMouseDown, false);
    div.addEventListener('mousemove', this.OnMouseMove, false);
    div.addEventListener('mouseup', this.OnMouseUp, false);
  }
      
  PlayFieldControl.prototype.OnMouseDown = function( e, fromMove )
  {
    var me = PlayFieldControl.instance;
    if( (e.which == me.button || fromMove) )
    {
      me.dragx = e.pageX;
      me.dragy = e.pageY;
    }
  }
      
  PlayFieldControl.prototype.OnMouseMove = function ( e )
  {
    var me = PlayFieldControl.instance;
    if( me.dragx > 0 && me.dragy > 0 )
    {
      me.OnMouseUp( e, true );
      me.OnMouseDown( e, true );
    }
  }
      
  PlayFieldControl.prototype.OnMouseUp = function( e, fromMove )
  {
    var me = PlayFieldControl.instance;
    if( (e.which == me.button || fromMove) && me.dragx > 0 && me.dragy > 0 )
    {
      me.pf.move( me.dragx - e.pageX, me.dragy - e.pageY );
      me.dragx = -1;
      me.dragy = -1;
    }
  }