So funktioniert es: sie drücken R (record) und bewegen die camera um den Spieler (oder woimmer sie hin möchten), die ganze Zeit werden die Koordinaten der Camera (x,y,z,pan,tilt und roll) in einem riesigen Array gespeichert. Drücken sie nochmal R und die Aufzeichnung wird beendet - eine kleine Datei (cutdata.txt) wird auf ihre Festplatte gespeichert. Jetzt können sie diese laden und abspielen wann immer sie wollen. Lassen sie uns einen Block auf den Code werfen:
view
cutscene_camera{}
var
start_pos[6];
action
cutscene_on
{
start_pos[0] = my.x;
start_pos[1] = my.y;
start_pos[2] = my.z;
start_pos[3] = my.pan;
start_pos[4] = my.tilt;
start_pos[5] = my.roll;
waitt (64);
camera.visible = off;
cutscene_camera.size_x = screen_size.x;
cutscene_camera.size_y = screen_size.y;
cutscene_camera.pos_x = 0;
cutscene_camera.pos_y = 0;
cutscene_camera.x = my.x;
cutscene_camera.y = my.y;
cutscene_camera.z = my.z;
cutscene_camera.visible = on;
on_mouse_right = null;
while (1)
{
cutscene_camera.x += 30 * cos(cutscene_camera.pan) * (mouse_right - mouse_left)
* time;
cutscene_camera.y += 30 * sin(cutscene_camera.pan) * (mouse_right - mouse_left)
* time;
cutscene_camera.z += 100 * sin(cutscene_camera.tilt) * (mouse_right - mouse_left)
* time;
cutscene_camera.pan -= 20 * (mouse_force.x) * time;
cutscene_camera.tilt += 25 * (mouse_force.y) * time;
if (key_r == 1 && index == 0) // if we press r and we aren't recording
already
{
record_data();
}
if (key_p == 1) // if we press p
{
play_data();
}
wait (1);
}
}
Als erstes müssen sie eine Entity im Level platzieren und ihr die Aktion cutscene_on zuweisen; ihre Position sollte nahe an der letztendlichen Cutscene Position liegen. Wir speichern die anfängliche Position (x,y,z,pan,tilt und roll) in start_pos[6] und dann warten wir 4 Sekunden um sicher zu gehen das der Splashscreen verschwunden ist. Ich habe einen neuen View mit dem Namen cutscene_camera hinzugefügt der den alten view (camera) ersetzen soll. Der neue cutscene_camer View wird mit Hilfe der Maus und ihrer Tasten bewegt (inklusive der rechten Maustaste) also musste ich alle Rechtsklickaktionen entfernen. Der Code der die cutscene_camera bewegt ist Simpel (werfen sie einen Blick auf die Kameras im AUM 4 - ich habe dort einen ähnlichen Code). Sie wundern sich vielleicht was es mit dem (mouse_right - mouse_left) auf sich hat. Wenn wir die rechte Maustaste drücken, mouse_right = 1 wird sich die Kamera nach hinten bewegen und wenn wir die linke Maustaste drücken, mouse_left = 1 wird sich die Kamera nach vorne bewegen. Wenn beide Tasten gedrückt werden wird sich die Kamera nicht bewegen da mouse_right - mouse_left = 0 (das passiert auch wenn keine Taste gedrückt ist).
if
(key_r == 1 && index == 0)
{
record_data();
}
if
(key_p == 1)
{
play_data();
}
Wenn wir R drücken und nicht schon aufgenommen wird, wird die Aktion record_data aufgerufen. Wir müssen P drücken um die zuletzt gespeicherten Daten zu laden und abzuspielen.
Die Funktion record_data speichert die Koordinaten der Kamera in ein Array und speichert diese in die Datei welche dieses beinhaltet auf der Festplatte.
var cutscene_position[60000];
function
record_data()
{
index = 0;
while (index < 60000)
{
cutscene_position[index] = 0;
index += 1;
}
index = 0;
while (key_r == 0 && index < 59994)
{
cutscene_position[index+0] = cutscene_camera.x;
cutscene_position[index+1] = cutscene_camera.y;
cutscene_position[index+2] = cutscene_camera.z;
cutscene_position[index+3] = cutscene_camera.pan;
cutscene_position[index+4] = cutscene_camera.tilt;
cutscene_position[index+5] = cutscene_camera.roll;
index += 6;
wait (1);
}
filehandle = file_open_write("cutdata.txt");
temp = 0;
while (temp <= index)
{
file_var_write(filehandle, cutscene_position[temp]);
temp += 1;
}
file_close(filehandle);
beep;
}
Als erstes löschen wir den Inhalt des Arrays um sicher zu gehen das es keine Daten der letzten Aufnahme mehr beinhaltet. Ich habe ein Array mit 60.000 Elementen benutzt, wir nehmen 6 davon in jedem Frame (x,y,z,pan,tilt und roll) das reicht also für 10.000 Frames, sogar wenn das Spiel mit 100 FPS läuft reicht dies für 100 Sekunden (erhöhen sie die Anzahl der Elemente nach ihren Bedürfnissen).
Die Aufnahme wird gestoppt indem sie wieder R drücken oder wenn das Array voll ist. Der erste Befehl nachdem die While-Schleife gestartet wurde ist die Datei cutdata.txt zu öffnen (oder sie zu erstellen und zu öffnen falls diese noch nicht existierte). Die Daten der cutscene_camera Aktion sind hier gespeichert. Am Ende verdeutlicht uns ein Beep das die Aufnahme fertig ist.
Die letzte Funktion öffnet die Datei cutdata.txt, liest seinen Inhalt und stellt die Position der cutscene_camera jedes Frame wieder her:
function
play_data()
{
filehandle = file_open_read("cutdata.txt");
index = 0;
temp = 0;
while (key_l == 0 || temp < 59994)
{
cutscene_camera.x = file_var_read(filehandle);
cutscene_camera.y = file_var_read(filehandle);
cutscene_camera.z = file_var_read(filehandle);
cutscene_camera.pan = file_var_read(filehandle);
cutscene_camera.tilt = file_var_read(filehandle);
cutscene_camera.roll = file_var_read(filehandle);
if (cutscene_camera.x + cutscene_camera.y + cutscene_camera.z + cutscene_camera.pan
+ cutscene_camera.tilt + cutscene_camera.roll == 0)
{
index = 0;
cutscene_camera.x = start_pos[0];
cutscene_camera.y = start_pos[1];
cutscene_camera.z = start_pos[2];
cutscene_camera.pan = start_pos[3];
cutscene_camera.tilt = start_pos[4];
cutscene_camera.roll = start_pos[5];
return;
}
temp += 1;
wait (1);
}
}
Die Kamera stoppt wenn wir das Ende der Datei erreicht haben (temp > 59994) oder wenn wir die ersten Null-Elemente im Array gefunden werden (werfen sie einen Blick auf die If-Verzweigungen), nun wird die Kamera in ihre ursprüngliche Position zurückversetzt. Es gibt zwei kleine Panels für das Aufnehmen (rot) und für das Abspielen (grün).
Tasten neu belegen
Die
Möglichkeit Tasten neu zu belegen kann sowohl in A4 als auch in A5
implentiert werden, aber mit A5 ist dies viel einfacher. Ich habe ein kleines
Stand-Alone Beispiel erstellt welches eine wmb Box durch ein kleines Level
bewegt, sie können die Bewegungstasten durch ein klick auf ein Panel
jederzeit ändern.
Als erstes werden wir einige Strings, Variablen, ein Panel und einen Text definieren:
string
empty_str, " ";
string
up_str, "Move up";
string
down_str, "Move down";
string
left_str, "Move left";
string
right_str, "Move right";
var
left_key;
var
right_key;
var
up_key;
var
down_key;
entity*
player;
panel
redefine_pan
{
bmap redefine_map;
pos_x = 510;
pos_y = 10;
flags = refresh, overlay, visible;
on_click = change_keys();
}
text
redefine_txt
{
pos_x = 10;
pos_y = 10;
font = comic_font;
string = empty_str;
}
Die main Funktion ist ziemlich simpel:
function
main()
{
fps_max = 50;
d3d_panels = on;
load_level (<redeftst.wmb>);
wait (2);
camera.x = 0;
camera.y = 0;
camera.z = 490;
camera.tilt = -90;
mouse_map = pointer_map;
mouse_mode = 2;
while(1)
{
mouse_pos.x = pointer.x;
mouse_pos.y = pointer.y;
wait(1);
}
}
Wir setzen die Kameraposition und -winkel, danach setzen wir den Mauscursor und machen in sichtbar (mouse_mode = 2) die Funktion main endet mit einem Code der die Maus bewegt. Die Aktion welche zu dem Spieler referiert ist eine einzige Zeile:
action
set_player
{
player
= me;
}
Jedes
Mal wenn wir auf den redefine_pan Panel klicken wird die Funktion change_keys
aufgerufen:
function
change_keys()
{
redefine_txt.visible = on;
redefine_txt.string = up_str;
while (key_any == 0) {wait(1);}
while (key_any == 1) {wait(1);}
up_key = key_lastpressed;
key_set(up_key, move_up);
redefine_txt.string = down_str;
while (key_any == 0) {wait(1);}
while (key_any == 1) {wait(1);}
down_key = key_lastpressed;
key_set(down_key, move_down);
redefine_txt.string = left_str;
while (key_any == 0) {wait(1);}
while (key_any == 1) {wait(1);}
left_key = key_lastpressed;
key_set(left_key, move_left);
redefine_txt.string = right_str;
while (key_any == 0) {wait(1);}
while (key_any == 1) {wait(1);}
right_key = key_lastpressed;
key_set(right_key, move_right);
redefine_txt.visible = off;
}
Lassen
sie uns einen Blick auf den Code für "Nach oben bewegen" werfen -
die anderen Codes sind alle ziemlich ähnlich:
redefine_txt.visible
= on;
sie
machen den Text sichtbar
redefine_txt.string
= up_str;
zeigen
den "Nach oben bewegen" String
while
(key_any == 0) {wait(1);}
warten
bis eine Taste gedrückt wird
while
(key_any == 1) {wait(1);}
warten
bis sie losgelassen wird
up_key
= key_lastpressed;
speichern
die zuletzt gedrückte Taste in der up_key Variable
key_set(up_key,
move_up);
und
teilt die Funktion move_up der Taste zu
Ich habe eine simple move_up Funktion benutzt, ohne Kollisionserkennung. Sie wollen so eine Funktion sicherlich nicht in ihrem Spiel verwenden.
function
move_up()
{
while (key_pressed(up_key) == 1)
{
player.x += 10 * time;
wait (1);
}
}
Solange die Taste die in up_key gespeichert wurde gedrückt wird, bewegt sich der Spieler (die Box) nach oben. Die Funktionen welche die Box nach unten, nach links und nach rechts sind ähnlich.