Ball Fragen

  • Ball Fragen

    Ich hatte gerade eine Idee für ein kleines Spiel, leider weiß ich mit meinen bisherigen Kenntnissen nicht, wie ich es umsetzen soll, daher 2 Fragen zu einem runden Objekt (bspw. einen Ball).

    1. Ich möchte beeinflussen können in welche Richtung er fliegt bspw. ich berühre Ihn unten links, er soll nach rechts oben fliegen, ich berühre Ihn mittig oben, er fliegt mittig nach unten usw.

    2. Er soll von Wänden abprallen, bspw. er kommt schräg von unten, also soll er schräg nach oben fliegen

    Ich hoffe das Prinzip ist verständlich erklärt.
  • Jedes GameMaker Object hat die eingebauten Variablen hspeed und vspeed. Beide zusammen kannst du benutzen um deinen Ball in jede beliebige Richtung zu lenken.

    hspeed = 1 - Ball fliegt nach rechts
    vspeed = 1 - Ball fliegt nach unten
    Beides zusammen - Ball fliegt nach rechts unten.

    Dabei gibts ein kleines Problem, aber dazu dann später.

    Wenn du den Ball jetzt von unten nach oben schicken willst, zB bei jedem Mausklick und die Geschwindigkeit von der Distanz zur Mausposition abhängig sein soll, dann geht das so:

    GML-Quellcode

    1. if mouse_check_pressed(mb_left){hspeed = x - mouse_x;vspeed = y - mouse_y;}


    x - mouse_x ist distanz zwischen x vom Ball und der Maus ( bei ball.x = 32 und mouse_x = 24 => 32-24 = 8 => hspeed = 8 )


    Das vorher schon erwähnte Problem kennt man von alten Computerspielen, wo man oft schneller läuft wenn man nach Vorne und nach Rechts gleichzeitig läuft anstatt nur nach Vorne oder Rechts. Wenn der Ball hspeed und vspeed auf Eins hat, dann wandert er auch schneller diagonal durch den Raum, als wenn er nur entlang der x oder y achse wandert.
    Um das zu verhindern, muss man sich einen Kreis um den Ball vorstellen, der einen Radius der Geschwindigkeit hat. Egal wo man jetzt den Ball hinbewegt auf diesem Kreis, hat er die selbe Geschwindigkeit. Mit hspeed und vspeed hat man eher ein Quadrat um den Ball das die Geschwindigkeit anzeigt.

    GML-Quellcode

    1. if mouse_check_button_pressed(mb_left){//winkel zwischen ball und mousevar dir = point_direction(x, y, mouse_x, mouse_y);//distanz zwischen ball und mouse, was dann als speed gehandelt wirdvar spd = point_distance(x, y, mouse_x, mouse_y);//lengthdir_x und _y sind wie cos und sin und bezeichnen einfach eine länge in Richtung eines winkels einmal für die x und einmal für die y achsehspeed = lengthdir_x(spd, dir - 180);vspeed = lengthdir_y(spd, dir - 180);//lengthdir_x(32, 0 bis 360) und lengthdir_y(16, 0 bis 360) beschreibt zB eine Ellipse mit einer Breite von 32 und Höhe von 16 pixel}



    So, das war jetzt ein bisschen viel, aber ich hoffe es war verständlich :)

    EDIT:
    Die Kollisionen hab ich vergessen - da musst du bloß hspeed oder vspeed umdrehen also mal -1 rechnen. zB

    GML-Quellcode

    1. if(collision_line(x, y, x, y+vspeed, obj_wand, false, true){
    2. //wenn oben oder unten am ball (je nach vspeed) eine kollision mit obj_wand stattfindet, dann dreh den vspeed um
    3. vspeed *= -1;
    4. }

    ancient-pixel.com
    youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Aku_Ryou ()

  • Neu

    Ja klar :)

    das kannst du auch mit den lengthdir funktionen machen:
    Du holst dir mit point_direction() die Richtung in die es gehen soll und die Länge sind dien 50 Pixel.

    GML-Quellcode

    1. lengthdir_x(50, dir);
    2. lengthdir_y(50, dir);

    ancient-pixel.com
    youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)
  • Neu

    ahja, dass hätte ich beinahe vergessen, wenn du direction direkt einstellst, dann brauchst du nur die speed variable auf 50 stellen.

    GML-Quellcode

    1. direction = point_direction(x, y, 63, 110);
    2. speed = 50;

    das wars mehr brauchst du dann nicht.

    btw: die lengthdir funktionen geben dir eine Zahl zurück, also musst du wenn dann x += lengthdir_x(len, dir) und y += lengthdir_y() benutzen.
    Wie kommst du auf die fixen Zahlen bei point_direction?

    webwhiteboard.com/board/wqjrgeet

    ich hab unter dem Link ein Whiteboard erstellt wo du siehst was ich meine, in blau ist die direction eingezeichnet die dein code machen würde und in grün, dass was du eigtl machen willst :) ich hoffe, dass macht das verständlicher

    ancient-pixel.com
    youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)
  • Neu

    Gut danke, es funktioniert halbwegs ..., aber nur wenn ich einen niedrigen speed einstelle, benutze ich bspw. 50, dann fliegt das Objekt aus dem Bildschirm und man hat es nie wieder gesehen ...,

    Was mir aber immer noch nicht gefällt ist, ich benutze unterschiedliche Sprites für jede Richtung,

    Also ungefähr so:

    if direction = 180
    {
    sprite_index = spr_left;
    }
    if direction = 90
    {
    sprite_index = spr_up;
    }
    if direction = 0
    {
    sprite_index = spr_right;
    }
    if direction = 270
    {
    sprite_index = spr_down;
    }

    Wenn bspw. das Objekt gerade nach links läuft und spr_left angezeigt wird, bleibt dieses spr_left immer noch, obwohl das Objekt sich nach dem antippen zur Mitte zu bewegt und eigentlich spr_right angezeigt werden müsste ...,

    Hinzu kommt auch noch das sie das Objekt meist auf direktem Weg zur Mitte zu bewegt, also meistens schräg ...,
    Am Besten wäre es aber wenn es sich nur in die 4 Hauptrichtungen (90,180,270,360) bewegen würde und so sein Ziel erreicht, da das einfach authentischer ausschaut ...,

    Das ist aber glaube ich sehr komplex ...
  • Neu

    Ohja ^^ da wirds ein bissl komplexer.

    Das einfachste ist da noch, zuerst vertikal und dann horizontal zu gehen. Dann gehst du immer in einem Haken zum Ziel.

    Oder alle 32px in Treppchen zum Ziel.
    Dazu kannst du schaun, ob entlang der x oder entlang der y achse, die distanz zum ziel länger ist, und dann in diese Richtung gehen.

    GML-Quellcode

    1. distX = point_distance(x, y, room_height*0.5, y);
    2. //checkt die distanz nur entlang der x achse
    3. distY = point_distance(x, y, x, room_height * 0.5);
    4. //checkt die distanz nur entlang der y achse


    wenn distX länger ist als distY, dann ist die direction 90 oder 270 je nachdem ob y größer oder kleiner als room_height * 0.5 ist

    ancient-pixel.com
    youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)
  • Neu

    Also im Step Event hatte ich nur diesen:

    if direction = 180
    {
    sprite_index = spr_left;
    }
    if direction = 90
    {
    sprite_index = spr_up;
    }
    if direction = 0
    {
    sprite_index = spr_right;
    }
    if direction = 270
    {
    sprite_index = spr_down;
    }

    Und im Maus Links gedrückt diesen:

    distX = point_distance(x, y, room_height*0.5, y);
    distY = point_distance(x, y, x, room_height*0.5);

    speed = 0.4;

    Ich möchte nämlich das der 2 Code nur ausgeführt wird wenn ich auf das Objekt drauf klicke, wenn ich aber im Step Event mit if mouse_check_button_pressed arbeite, dann wird der Code auch ausgeführt sobald ich irgentwo in den Raum klicke ...
  • Neu

    Mein letzter Code sollte dir ja nur eine Idee geben, was du machen kannst in Verbindung mit den anderen Code Stückerl die ich hier gepostet habe.

    In deinem jetzigen Code benutzt du ja zB gar keine direction um anzugeben wohin es gehen soll, wenn du speed = 0.4; angibst. Standardmäßig ist direction 0, also rechts.

    ancient-pixel.com
    youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)