Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

27.08.2014, 21:36

Blasteteroids mit Allegro

Hallo erstmal,
bin gérade das Buch C-Programmierung von Kopf bis Fuss am durchackern. Unter anderem ist dort die Aufgabe gestellt das Spiel Blasteroids (Asteroids in Original) mit Allgro zu programmieren.
Das Raumschiff in dem Spiel dreht sich beim Ändern der Position ( Pfeiltasten oben, unten, rechts, links ) gleichzeitig immer um die eigene Achse. Es rotiert also bzw. dessen Koordinatensystem. Diese Steuerung funktioniert auch bei mir. Durch Nutzung der Allegro_Transform Funktion klappt das ganz gut, wenn ich sie richtig verstanden habe 8ich denke nicht). Auch Asteroiden schweben schon zum Abschiessen über den Bildschirm.Und da hakt es.Jetzt will ich aber das das Raumschiff einen "Strich abschiesst " (Ist in der Aufgabe gefordert).
So nach meinen Verstandniss muss ich die x,y Position und die aktuelle Rotation des Raumschiffes (enterprise) auf ein Koordinatensystem für den "Blaster" übertragen.

else if (al_key_down(&keystate,ALLEGRO_KEY_SPACE))
{

blaster->sx = enterprise.sx;
blaster->sy = enterprise.sy;
blaster->heading = enterprise.richtung;
degree = (((enterprise.richtung)*180)/3.14159);
draw_blast(test);

}
Bis hierhin zeichnet er auch den Blaster in die Richtige Richtung und am Abschusspunkt. Mit der M Taste (erstmal nur zum Testen) möchte ich den Blaster in genau diese Schussrichtung fortbewegen 8währned ich natürlich das Raumschiff weiterbewege.
Meiner Meinung nach müsste es so funktionieren.

else if(al_key_down(&keystate,ALLEGRO_KEY_M)){

blaster->sx = blaster->sx + cos(degree);
blaster->sy = blaster->sy + (sin(degree)*-1.0);
draw_blast(test);

}
Nun Klappt aber nicht ganz . Shee ich das falsch ? oder habe ich da ein Denkfehler? Ich muss doch nur den Koordinatenursprung des Blasters bewegen.? Der Bewegt sich überall hin nur nicht in Schussrichtung. Hab ich da was nicht ganz verstanden? Etwas übersehen?Falschen Ansatz Oder muss ich tatsächlich noch eine Fallunterscheidung mit berücksichtigen was die Winkel über 90° , 180, 260, 360.° und ist noch komplizierter.?Ich probiere hier wie doof rum. Inzwischen ist mein Code so chaotisch das ich auch nicht en gesamten Code reinstellen mag Hier zumindes die Struct und die Funktionen zum zeichnen des Schiffes und des Blasters

typedef struct Blast {

float sx;
float sy;
float heading;
float speed;
int gone;
ALLEGRO_COLOR color;
ALLEGRO_TRANSFORM transblast;
struct Blast *ende;
} Blast;

void draw_blast(Blast* neu)
{

ALLEGRO_TRANSFORM (neu->transblast);
al_identity_transform(&neu->transblast);
al_rotate_transform(&neu->transblast,(neu->heading));
al_translate_transform(&neu->transblast,neu->sx,neu->sy);
al_use_transform(&neu->transblast);
al_draw_line(0,0,-16,-20,neu->color,3.0);
}


typedef struct {
float sx;
float sy;
float richtung;
float speed;
int leben;
ALLEGRO_TRANSFORM transformship;
}Spaceship;


void draw_ship(Spaceship* s)
{
ALLEGRO_TRANSFORM (s->transformship);
al_identity_transform(&s->transformship);
al_rotate_transform(&s->transformship,s->richtung);
al_translate_transform(&s->transformship,s->sx,s->sy);
al_use_transform(&s->transformship);

al_draw_line(-8,9,0,-11,al_map_rgb(44, 117, 255), 3.0f);
al_draw_line(0,-11,8,9,al_map_rgb(44, 117, 255), 3.0f);
al_draw_line(-6,4,-1,4,al_map_rgb(44, 117, 255), 3.0f);
al_draw_line(6,4,1,4,al_map_rgb(44, 117, 255), 3.0f);
}
Vielen dank :( :( :( :(

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

28.08.2014, 07:02

Willkommen im Forum!
sin und cos arbeiten nicht mit Grad, sondern mit Radiant.
Der Umrechnungsfaktor von Grad nach Radiant ist §\frac{\pi}{180}§.

RmbRT

Treue Seele

Beiträge: 169

Wohnort: Darmstadt

Beruf: Student

  • Private Nachricht senden

3

28.08.2014, 12:02

Zitat

C-/C++-Quelltext

1
blaster->sy = blaster->sy + (sin(degree)*-1.0);

Ich weis nicht, ob das *-1.0 wegoptimiert wird, aber es ist schneller, eine zahl zu negieren, als zu multiplizieren.
Schneller müsste sein:

C-/C++-Quelltext

1
blaster->sy = blaster->sy + (-sin(degree));
bzw.

C-/C++-Quelltext

1
blaster->sy = blaster->sy - sin(degree);


Sorry fürs pingelig sein, aber es soll nur helfen.

MfG,
RmbRT
"Dumm ist, wer dummes tut."

4

28.08.2014, 20:31

Erstmal danke für die Antworten.
Das hat nix mit pingelig zu tun und ist vollkommen ok :). Ich lerne das ja noch daher sehe jegliche Kritik als vollkommen.
Ok ich hab das mit der Umrechnung in Rad probiert, das Ergebnis ist dasselbe .... ich bin allerdings zugegebenermaßen nicht mehr ganz so fit mit den ganzen Winkelfunktionen. Habe das Gefühl das ich aber genau da was falsch mache. .....Hab noch mal folgendes versucht und mit der M Taste das Raumschiff in Flugrichtung zu bewegen was aber auch nicht hinhaut Zweitens hab ich ein wenig mit der al_rotate_transform(ALLEGRO_TRANSFORM *trans, float theta) Funktion rumprobiert ..... und das Raumschiff nur mit der rechten Pfeiltaste rotieren lassen. Allerdings wird immer um einen bestimmten Wert erhöht (als letztes um 0.1). Ich verstehe dabei nicht so ganz die Rotate Funktion . Das Argument theta deutet darauf hin das es sich Polarkoordinaten handelt oder nicht? Ich verstehe auch nicht so ganz den Bezug zu 360° wieso bei einer Umdrehung des Raumschiffes der Wert 6.0 gestiegen ist. Werd noch irre. Aber für heute ist erstmal Schluss. Irgendwie fehlt der aha Effekt. :)



if(al_key_down(&keystate,ALLEGRO_KEY_DOWN))
{ enterprise.sy += 2;}
else if(al_key_down(&keystate,ALLEGRO_KEY_UP))
{ enterprise.sy -= 2;}

else if(al_key_down(&keystate,ALLEGRO_KEY_RIGHT))
{ enterprise.sx += 2;
enterprise.richtung+= 0.01;

}

else if(al_key_down(&keystate,ALLEGRO_KEY_LEFT))
{ enterprise.sx -= 2}

Werbeanzeige