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 ()

  • Ja danke, werde ich alles mal ausprobieren ...,

    Aber ist es denn auch möglich, im Raum einen Punkt auszuwählen (bspw. genau die Mitte des Raumes),

    Und jedesmal wenn ich auf ein Objekt (welches sich selbständig im Raum bewegt) klicke, soll sich dieses bspw. 50 Pixel in Richtung dieses Punktes bewegen, (muss nicht unbedingt ein Ball sein) ...
  • 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 ;)
  • 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 ;)
  • 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 ...
  • 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 ;)
  • 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 ...
  • 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 ;)
  • Ich würde gern noch mal auf den Ball zurück kommen,

    habe einige Tipps von hier ausprobiert, folgendes läuft aber noch nicht so ganz richtig:

    1. Wenn ich die "mouse_check_button Funktion nehme, dann reagiert der Ball immer auch wenn ich Ihn gar nicht anklicke, daher habe ich das mit

    hspeed = x - mouse_x;
    vspeed = y - mouse_y;

    in den Maus Klick Event verschoben, da ich nur wenn der Ball angeklickt wird, möchte das er sich bewegt

    2. Er fliegt immer extrem schnell, kann man das nicht ändern, dass er bspw. nur mit einer Geschwindikeit von 1 fliegt?
  • Um zu überprüfen ob du den ball angeklickt hast musst du prüfen ob die mausposition mit dem ball sprite überlappt. mouse_check_button, checkt ja nur ob du generell irgendwo die maustaste drückst - so wie wenn du eine keyboardtaste abfragen würdest.

    GML-Quellcode

    1. if(mouse_check_button_pressed(mb_left){
    2. if(collision_point(mouse_x, mouse_y, obj_ball, true, false){
    3. // das wird nur ausgeführt wenn du auf das ball sprite geklickt hast
    4. }
    5. }


    diese art der abfrage schaut zuerst ob die maus generell gedrückt wurde und dann ob die maus über dem sprite ist. Die beiden letzten argumente 'true, false' geben an ob die abfrage precise ist (kommt auf deine sprite mask an) und ob es auch das obj_ball betreffen kann, der den code ausführt (self).

    ancient-pixel.com
    youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)
  • Gut also der Code im Step Event ist jetzt dieser:

    if (mouse_check_button_pressed(mb_left))
    {
    if (collision_point(mouse_x, mouse_y, object1, true, false))
    {
    hspeed = x - mouse_x
    vspeed = y - mouse_y
    alarm[0] = room_speed*1
    }
    }

    move_bounce_all(true)

    Der Ball bewegt sich leider noch extremst schnell, da kommt man mit dem Auge fast gar nicht hinterher (hat bestimmt ein Speed von 10 oder ähnlichem), manchmal knallt er auch durch die Wand, selbst wen ich move_boune_solid verwende und die Wand auf solide stell.