Rollem

In diesem Monat habe ich mich entschlossen, ein kleines Spiel-Beispiel für die Nutzer der Commercial Version von A6, die auf ein Physikobjekt beschränkt sind, zu schreiben. Es ist ein Klon von “Marbles”, ohne optischen Zucker, aber mit den meisten Leveldesign-Elementen; der Code für den Ball ist fertig und kann in jedem Spiel benutzt werden.

Das Spielziel ist simpel: Sie müssen soviele Juwelen wie möglich einsammeln, indem Sie diese berühren. Der Punktestand wird mit Hilfe eines einfachen Panels in der oberen linken Ecke des Bildschirms angezeigt.

panel score_pan
{
    pos_x = 5;
    pos_y = 5;
    layer = 10;
    digits = 10, 10, 5, _a4font, 1, total_score;
    flags = overlay, refresh, visible;
}

Sehen wir uns die Main Funktion an:

function main()
{
    time_smooth = 0;
    fps_max = 140;
    fps_lock = on;
    level_load (rollem_wmb);
    wait (3);
    ph_setgravity (vector(0, 0, -386));
    while (1)
    {
       camera.x = ball.x;
       camera.y = ball.y;
       camera.z = 1500;
       camera.tilt = -90;
       wait (1);
    }
}

Die Funktion sorgt dafür, dass die “time”-Variable nicht interpoliert wird (time_smooth = 0), um heftige Sprünge zu vermeiden. Die Framerate wird auf 140 begrenzt (die Physikengine läuft mit 70 fps) und “time” wird auf den durch fps_max festgelegten Wert gesetzt. Das Level wird geladen und anschließend wird eine Gravitation eingestellt, die erdähnlichen Verhältnissen entspricht. Die “while”-Schleife stellt sicher, dass die Kamera dem Ball folgt, 1500 Quants über ihm und nach unten weisend.

var mouse_sensitivity = 400; // experimental value
var key_sensitivity = 250; // experimental value

action physics_ball
{
    ball = my;
    my.scale_x = 1.5;
    my.scale_y = my.scale_x;
    my.scale_z = my.scale_x;
    phent_settype (my, ph_rigid, ph_sphere);
    phent_setmass (my, 5, ph_sphere);
    phent_setfriction (my, 40);
    phent_setdamping (my, 20, 20);
    phent_setelasticity (my, 80, 5);
    while(1)
    {
       vec_set (temp, nullvector);
       temp.x = (key_cur - key_cul) * key_sensitivity + mouse_force.x * mouse_sensitivity;
       temp.y = (key_cuu - key_cud) * key_sensitivity + mouse_force.y * mouse_sensitivity;
       temp.z = 0;
       vec_rotate (temp, vector(camera.pan, 0, 0));
       vec_normalize (temp, 200 * time);
       phent_addtorqueglobal (my, temp);
       wait (1);
    }
}

Wie Sie sehen ist die Action für den Ball recht simpel: der “ball” Zeiger wird gesetzt, das Model wird skaliert und dann sorgt sie dafür, dass sich der Ball wie eine Kugel verhält, die 5 Kilogramm wiegt. Der Reibungskoeffizient wird auf 40 gesetzt und es werden geeignete Werte für Dämpfung und Elastizität gesetzt; Sie können diese nach Herzenslust abändern.

Die “while”-Schleife bewegt den Ball, wenn der Spieler die Pfeiltasten drückt und / oder die Maus bewegt. Vergessen Sie nicht, auch die Werte “mouse_sensitivity” und “key_sensitivity” anzupassen. Mit vec_rotate wird die Bewegungskraft in Richtung der Kamera gedreht und dann begrenzen wir die Kraft, die auf den Ball wirkt durch 200 * time. Die folgende Codezeile gibt dem Ball noch eine Rotationskraft.

Was fehlt noch? Ach ja, die Juwelen!

action gem_bonus
{
    my.scale_x = 1;
    my.scale_y = my.scale_x;
    my.scale_z = my.scale_x;
    my.passable = on;
    while (ball == null) {wait (1);}
    while (vec_dist(ball.x, my.x) > 70)
    {
       my.pan += 3 * time;
       wait (1);
    }
    snd_play (gem_wav, 100, 0);
    total_score += 10;
    my.invisible = on;
}

Als erstes werden sie skaliert; ich habe ihre Größe auf 1 gesetzt, aber vielleicht möchten Sie einen anderen Wert. Die Juwelen sind passierbar und warten bis die “ball” Entity existiert. Jedes Juwel wartet, bis der Ball näher als 70 Quants gekommen ist und dreht sich bis dahin. Kommt der Ball näher, erklingt ein Geräusch, es gibt 10 Punkte und das Juwel wird unsichtbar. Das war es schon!

 

Handles

Was ist zu tun, wenn man 20 verschiedene Entities ansprechen möchte? Natürlich können Sie 20 verschiedene Zeiger definieren, die z.B. tree1 bis tree20 heißen und sagen wir mal ihre Höhen durch Anweisungen wie tree4.z = 200; oder tree15.z = 150; ändern. Aber was machen Sie bei 100 oder 1000 Entities? Wer möchte schon 1000 Zeiger definieren?

Dieser kleine Artikel demonstriert die Handhabung von sogenannten Handles – das sind eindeutige Zahlen, die einer Entity, einer Action, einem String, einem Bitmap, einem Panel zugeordnet werden können... (beinahe) alles, was Sie je brauchen.

var index = 0;
var my_entities[100]; // control up to 100 different entities

entity* temp_ptr; // temporary pointer to the entity

Ich habe eine Variable namens index definiert und ein Array erstellt, der bis zu 100 Handles aufnehmen kann. Die Zahl 100 ist natürlich nur ein Beispiel, Sie können auf diese Weise problemlos über 10.000 Entities kontrollieren. Außerdem habe ich einen temporären Zeiger namens temp_ptr definiert.

action control_entities
{
    my_entities[index] = handle (my);
    index += 1;
    // put the rest of your entity code here
}

Die obige Action wird unseren Entities zugewiesen; sie speichert den Handle (eine Zahl) im Array und zwar an der Position, die durch die index Variable gegeben ist und erhöht den Index dann um 1, damit die folgenden Entities diesen Eintrag nicht überschreiben.

function move_entity(number, height)
{
    temp_ptr = ptr_for_handle(my_entities[number]);
    temp_ptr.z += height; // increase the z of the entity by "height" quants
}

Dies ist ein simples Beispiel einer Funktion, die eien Entity in z-Richtung bewegt; Sie könnten sie z.B. für Publikumssprites in Ihrem Sportspiel benutzen. Rufen Sie die Funktion so auf:

move_entity(5, 40);

und sie wird die 5. Entity um 40 Quants nach oben bewegen; oder auf diese Weise

move_entity(23, -30);

und die 23. Entity wird um 30 Quants nach unten bewegt. Wenn Sie in einer Schleife zufällige Zahlen und Höhen generieren und die Entities sich nach diesen Werten bewegen, erhalten Sie im Handumdrehen eine realistisch aussehende Menschenmenge!