Tutorials

ActionScript / PHP

Hoe PHP samen met Flash te laten communiceren. LET OP: Ik merk nu dat er een aantal foutjes in de code zitten, ik ben bezig om dat te fixen!

Pagina 1

Inleiding

Deze tutorial gaat over hoe je ActionScript met PHP laat communiceren. Dit doen we met een tussen stap XML. Voor nu is dat een makkelijke maar zeer doeltreffende mogelijkheid!
We gaan een PhotoViewer maken.
Ik verwacht dat je al enige basiskennis van ActionScript hebt, zo niet geen probleem. Maar ga dan na deze tutorial na of je alles begrijpt! Verder probeer ik zoveel mogelijk object-oriented te scripten in ActionScript (uit 'voorzorg' voor de nieuwe AS --> AS3.0).

Nou ik denk dat we maar moeten beginnen.
Pagina 2

Voorbereiding

In Flash programmeren wordt een bepaalde mapstructuur aangehouden.
We maken 5 mappen aan om alles gestructureerd te houden:

        PhotoGallery
         /         \
     assets    deploy
       /     \
    PHP   images
     /
includes


Uitleg:
PhotoGallery is de 'root' -map. De absolute basis van onze PhotoGallery.
assets is de map met de elementen. Hier komt de .fla en de .as in en de .xml.
images, spreekt voor zich denk ik ;-)
PHP, hier komen de PHP bestandjes.
includes, hier komen de functies etc.
deploy hier komt de uiteindelijke uitvoer. De .swf en de .html/.php

Zo nu hebben we de map structuur, maar we zijn er nog niet.
Start Macromdia Flash op!
Maak een nieuwe file aan, stel de dimensie (grootte) in. Ik doe dit nu op 750px bij 750px.

Belangrijk!
Klik op [file]>>[Publish Settings] (Ctrl+Shift+F12)
Hier stel je in: De swf naar de de Deploy map evenals de .html met als naam PhotoGallery (.swf/.html)
Dit doen we zodat we straks op publish gaan klikken of op Ctrl+Enter we niet door de hele computer .swf.tmp bestanden hebben staan.

Onze PhotoGallery gaat verschillende dingen bevatten.
Titel
Foto
Beschrijving

We gaan er nu voor zorgen dat deze ook beschreven kunnen worden. Ik doe dit bewust in Flash zelf. (Niet in ActionScript) Omdat het gewoon een heleboel extra werk gaat kosten. Als ik mij niet vergis moet dit wel gaan gebeuren in AS3.0 (de tijdlijn gaat verwijnen namelijk...:-( )
Klik op de tekst tool.
Maak een bovenaan een single-line 'Dynamic Text'. Geef gelijk de eigenschap mee. (ik heb Arial, vet, gecentreerd, 37px, zwart)
Geef hem de instance name titel_txt.

Maak nu onderaan de pagina een multiline Dynamic Text. Geef ook deze keer de eigenschappen mee (ik heb Arial, gecentreerd, 37px, zwart)

Nu gaan we de zogenaamde image_holder maken.
Klik de tekentool (vierkantje) aan en maak een vierkant. (bij mij 450px bij 450px) Selecteer het en maak er een MovieClip van (F8) met als titel imgholder. Geef hem dan de instance name; imgholder_mc.

Als laatste gaan we twee buttons maken. Gelukkig heeft Flash zelf een leuke library met knoppen. Klik op [Window]>>[Common Librarys]>>[Buttons]
Selecteer een leuke button en sleep hem naar je 'stage'. Kopieer hem en draai hem zodat je een vooruit en achteruit button hebt. Noem de ene button next_btn en de ander prev_btn.

Voorlopig zijn we klaar met de 'layout', bij ziet het nu zo uit:
Pagina 3

De PHP

Maak een file aan (functions.inc.php) in de map includes van PHP van assets.
Hierin gaan we de functies definieeren.

<?php
/**
 * Deze functie zal een xmlfile creeën
 * 
 * @param  string $imgfolder [optional]
 * @return boolean
 */
function createXMLfile($imgfolder = '../images/') {
	// Eerst gaan we alle dingen uit de database halen die we nodig hebben
	$selectPhotos_sql = "SELECT * FROM photos ORDER BY id DESC";
	if(!$selectPhotos_query = mysql_query($selectPhotos_sql)) {
		return false;
	}
	// Nu hebben we alle images met een .jpg of .JPG extentie
	// we gaan nu de XML file schrijven
	$xml = '<?xml version="1.0"?>';
	$xml .= "\n".'<fotos>';
	while($selectPhotos_row = mysql_fetch_assoc($selectPhotos_query)) {
		$xml .= "\n\t".'<foto';
		$xml .= ' src="'.$selectPhotos_row['photogallery_src'].'"';
		$xml .= ' titel="'.$selectPhotos_row['photogallery_title'].'">';
		$xml .= "\n\t\t".'<![CDATA['.$selectPhotos_row['beschrijving'].']]>';
		// <![CDATA[$string]]> is de htmlentities($string, ENT_QUOTES) voor XML
		$xml .= "\n\t".'</foto>';
	}
	$xml .= "\n".'</fotos>';
	
	// ok de sting is er. Nu gaan we de xmlfile openen.
	// w+ opent het bestand set de pointer aan het begin van het bestand en maakt het 0 bytes lang.
	if(!$open = fopen('../../PhotoGallery.xml', 'w+')) {
		return  false;
	}
	if(!fwrite($open, $xml)) {
		return false;
	}
	if(!fclose($open)) {
		return false;
	}
	
	// ok alles is goed doorlopen:
	return true;
}

/**
 * Deze functie zal een connectie maken met de database en 
 * gegevens in database stoppen
 * 
 * @param  string  $host = 'localhost'
 * @param  string  $username
 * @param  string  $password
 * @param  string  $database
 * @param  string  $titel
 * @param  string  $imgsrc
 * @param  string  $beschrijving
 * @param  boolean $createxml [optional]
 * @return boolean
 */
function insertData($host = 'localhost', $username, $password, $database, $titel, $imgsrc, $beschrijving, $createxml = false) {
	if(!mysql_connect($host, $username, $password)) {
		return false;
	}
	if(!mysql_select_db($database)) {
		return false;
	}
	$insertData_sql = 	"INSERT INTO photos ("
					.							"photo_titel,"
					.							"photo_src,"
					.							"photo_bescrijving"
					.						")"
					.						"VALUES ("
					.							"'".$titel."',"
					.							"'".$imgsrc."',"
					.							"'".$bescrijving."'"
					.						")";
	if(!mysql_query($insertData_sql)) {
		return false;
	}
	if($createxml) {
		if(!createXMLfile()) {
			return false;
		}
	}
	
	// alles is verzonden en als $createxml true was is ook de XML file gemaakt.
	return true;
}
?>

Je kan hier als je wilt nog een formuliertje aan koppelen enzo.. Dat doe ik niet, want dat is niet relevant.

In het volgende hoofdstuk zullen we de XML gaan ophalen in ActionScript.
Pagina 4

XML ontleden in AS

Zo nu zijn we - voor de meesten - op het moeilijkste gedeelte aangekomen. ActionScripting.
Eerst een korte uitleg hoe AS in elkaar steekt.
ActionScript lijkt heel erg op JavaScript.
Je moet variabelen defineren (dus nummer = 13, is niet goed. Dit meot dan worden:
var nummer:Number; nummer = 13. Of korter: var nummer:Number = 13;)
Zo zijn er nog een aantal dingen die we opweg gaan tegenkomen.

Creeer een nieuwe ActionScript file. PhotoGallery.as
Ga naar je .fla en klik op het eerste frame in je tijdlijn en druk dan op F9. Type in het venster wat te voorschijn komt:

// Let op zet GEEN puntkomma (;) achter de include en er moeten dubbele aanhalingtekens omheen!!
#include "PhotoGallery.as"


Ga weer naar je PhotoGallery.as.
We gaan beginnen met de makkelijkere dingen, we gaan de knoppen een functie meegeven. Dat doen we als volgt:

// eerst spreken we de button aan. Na de punt geven we een event mee, namelijk onRelease.
// Als er op geklikt word creeër een functie.
// Die functie traced (we zien straks wat trace doet!) zichzelf. Dat is dus logischerwijs next_btn.
next_btn.onRelease = function() {
    trace(this);
}
// nu gaan we hetzelfde doen met prev_btn
prev_btn.onRelease = function() {
    trace(this);
}

Klik op Ctrl+S (save hem dus in de map assets)
Ga weer terug naar je .fla en klik op Ctrl+Enter. De Flash exporteert nu.
Als je nu op prev_btn of next_btn klikt verschijnt er een venset Output:
En de tekst
_level0.next_btn
of:
_level0.prev_btn

We weten nu dat deze functie werkt. We laten de knoppen nu even voor wat het is.
Tijd om de XML op te gaan halen. Hieronder post ik de code met commentaar, dat is even wat makkelijker voor mij.

// Eerst gaan we alle variabelen aanmaken die we op dit moment nodig hebben
var fotos:Array = new Array();
var beschrijvingen:Array = new Array();
var titels:Array = new Array();
var welkeisnu:Number = 0;

// nu gaan we een Object aanmaken, namelijk een XML object
var xml:XML = new XML();

// nu de proccesing van het xml bestand.
// zoals we het samengestelt hebben in de PHP bestaat het uit een Child <fotos>
// en een ChildNode namelijk: <foto></foto>
// in die ChildNode staan attributes namelijk: src & titel
// ook staat er in die ChildNode weer een Child namelijk: beschrijving
// nu we dat weten zal het iets beter te begrijpen zijn. :)
// Eerst gaan we alle ChildNodes in een Array stoppen:
var childnodes:Array = xml.firstChild.childNodes;

// je ziet dus we pakken de eerste Child (firsChild), dit is je oma, 
// en daar de 'kinderen' van (childNodes), zijn je moeder en je tantes.
// nu moeten we dat weer gaan onderverdelen. Aangezien we in ActionScript geen foreach() kennen doen we
// het met een gewone for-loop
for(var i:Number = 0; i < childnodes.length; i++) {
	// we tellen childnodes door childnodes.length te doen. (array_length($var)) in PHP
	fotos.push(childnodes[i].attributes.src);
	// wat we hier doen is array_push in PHP. Daar stoppen we in:
	// xml.firstChild.childNodes[variabel].attributes.src
	titels.push(childnodes[i].attributes.titel);
	// wat we hier doen is array_push in PHP. Daar stoppen we in:
	// xml.firstChild.childNodes[variabel].attributes.titel
	beschrijvingen.push(childnodes[i].firstChild);
	// nu halen we niet een attribute op maar een kind van je moeder of tantes. Jij of één van je nichtjes.
	// in theorie zou hier dan ook weer een kind in kunnen staan. Maar zo diep gaan we vandaag niet 8-|
}

// zo nu hebben we mooi de XML uitelkaar getrokken, denk nu niet gelijk hoe kan dat nou, we hebben helemaal
// geen XML path opgegeven. Nee idd, dat gaan we nu doen!
xml.load('PhotoGallery.xml');

// Nu hebben we alles netjes in Arrays!
Pagina 5

MovieClipLoader Class en het laden van de fotos

Mooi we hebben nu alles in arrays. Nu word het tijd om de plaatjes te gaan inladen. Dit gaan we doen met de MovieClipLoader Class. Als je AS een beetje door begint te krijgen is dit vrij makkelijk en ik vind het een hele leuke class.
Of nou ja de class zelf is niks aan, maar de listeners of events zijn leuk, vind ik zelf... :)
Ok hier komt de code weer!

// Eerst gaan we twee objecten aanmaken de MovieClipLoader class
// en een leeg Object, hier komen straks de leuke functies voor de MovieClipLoader Class in.
var mcloader:MovieClipLoader = new MovieClipLoader();
var eventobject:Object = new Object();

// ook maken we alvast een Number aan, deze gaan we straks gebruiken bij de functie setInterval
var intervalid:Number;

// We laten de MCL Class even links liggen en we beginnen met het lege object
// Als je nu op F1 drukt krijg je de Flash help, als je daar intype MovieClipLoader Class
// krijg je uitleg over de Class, daar kijken we ook even niet naar, maar er staat een tabel in
// met alle events die deze class ondersteunt, namelijk:
/* 
onLoadComplete = function([target_mc:MovieClip], [httpStatus:Number]) {}
 Deze functie/event wordt uitgevoerd als de gehele clip (in ons geval een plaatje van jpg formaat).
 Let op:
 De clip is geladen, maar nog niet uitgevoerd. (Er word dus nog niks getoont);
 
onLoadError = function(target_mc:MovieClip, errorCode:String, [httpStatus:Number]) {}
 Als er een probleem is met laden begint deze functie met ratelen
 
onLoadInit = function([target_mc:MovieClip]) {}
 Deze functie/event wordt uitgevoerd waarneer de clip is geladen en in het eerste frame van zichzelf staat.
 Hier laten we pas het plaatje zien
 
onLoadProgress = function([target_mc:MovieClip], loadedBytes:Number, totalBytes:Number) {}
 Deze wordt uitgevoerd tussen onLoadStart en onLoadComplete, tijdens het laden zelf dus.
 Een mooie plek om een preloader neer te gooien
 
onLoadStart = function([target_mc:MovieClip]) {}
 Zodra de aanroep mcloader.loadClip(variabel) is geschiedt.
*/
// We gaan beginnen met de belangrijkste onLoadInit
// om hem mooi in te laden laten we hem infaden. Hierover later meer
eventobject.onLoadInit = function() {
	// We zijn nu op het punt van uitvoeren.
	// eerst gaan we de titel en beschrijving neerzetten
	titel_txt.text = titels[welkeisnu];
	// herriner je de variabel welke is nu nog? Deze zorgt ervoor dat er 'dynamisch' 
	// nieuwe plaatjes worden aangeroepen. Zo hebben we de juiste titel en beschrijving
	// bij het juiste plaatje.
	beschrijving_txt.text = beschrijvingen[welkeisnu];
	
	// setInterval(functionname, interval, parameters).
	// Dit is een loop, eentje die door blijft gaan totdat je clearInterval(intervalid) aanroept.
	intervalid = setInterval(fadein, 120, "imgholder_mc");
	
	// zodra er een nieuwe file is ingeladen zijn alle eigenschappen van een MC weg. Die moeten we dus 
	// opnieuw instellen. (Alleen de width en height voor nu).
	imgholder_mc._width = 450;
	imgholder_mc._height = 450;
}
 
// we gaan hier de functie definieren voor de setInterval;
function fadein(target_mc) {
	// de functie eval maakt van een string een object
	target_mc = eval(target_mc);
	// we gaan de Alpha (doorzichtigheid) naar honderd procent brengen.
	// in stappen van 5
	target_mc._alpha += 5;
	if(target_mc._alpha > 95) {
		// de alpha is nu groter dan 95, ga nooit op exacte waarde zitten, dit kan verkeerd uitpakken!
		// maar we setten wel de alpha wel naar naar 100%!
		target_mc._alpha = 100;
		// Nu hoeven de interval niet meer uit te voeren dus roepen we clearInterval aan!
		clearInterval(intervalid);
	}
}

// we gaan ook maar gelijk de functie om uit te faden maken.
function fadeuit(target_mc) {
	// de functie eval maakt van een string een object
	target_mc = eval(target_mc);
	// we gaan de Alpha (doorzichtigheid) naar 0 procent brengen.
	// in stappen van 5
	target_mc._alpha -= 5;
	if(target_mc._alpha < 5) {
		// de alpha is nu kleiner dan 5, ga nooit op exacte waarde zitten, dit kan verkeerd uitpakken!
		// maar we setten wel de alpha wel naar naar 0%!
		target_mc._alpha = 0;
		// Nu hoeven de interval niet meer uit te voeren dus roepen we clearInterval aan!
		clearInterval(intervalid);
	}
}

// wanneer moeten we de fadeout aan roepen?
// precies! bij onLoadStart
eventobject.onLoadStart = function() {
	// eerst halen we de titel en beschrijving weg
	titel_txt.text = '';
	beschrijving_txt.text = '';
	// nu setten we de interval
	setInterval(fadeuit, 120, "imgholder_mc");
}

// we maken ook een kleine preloader:
eventobject.onLoadProgress = function() {
	titel_txt.text = 'De nieuwe foto word ingeladen...';
	// dit is nu wel ff genoeg voor nu.
}

// nu gaan we ook de buttons meelaten doen, dit zijn de buttons die we eerder hebben gedefinieerd.
next_btn.onRelease = function() {
	// dit is next, dus volgende. Dat betekent dat welkeisnu verhoogt moet worden met 1
	welkeisnu++;
	// om een loop te maken gaan we even kijken of welkeisnu niet groter is dan fotos.length-1
	if(welkeisnu > fotos.length-1) {
		welkeisnu = 0;
	}
	// nu gaan we de nieuwe foto inladen
	// loadClip(url, target);
	mcloader.loadClip('images/' + fotos[welkeisnu], 'imgholder_mc');
}
prev_btn.onRelease = function() {
	// dit is prev, dus vorige. Dat betekent dat welkeisnu verlaagd moet worden met 1
	welkeisnu--;
	// om een loop te maken gaan we even kijken of welkeisnu niet kleiner is dan 0
	if(welkeisnu < 0) {
		welkeisnu = fotos.length-1;
	}
	// nu gaan we de nieuwe foto inladen
	// loadClip(url, target);
	mcloader.loadClip('images/' + fotos[welkeisnu], 'imgholder_mc');
}


Als het goed is moet nu alles werken.
Zorg dat er wat foto's staan in de image map en een link in de database.
We hebben verder niet iets ingevoegd of de functies aangeroepen in PHP, ik ga ervan uit dat je dat al kan.

Dit was mijn tutorial, ik hoop dat jullie er wat aangehad hebben!

Reacties

0
Nog geen reacties.