logic for a bombblast to throw player in "right" direction

Discussion in 'RPG Maker MV' started by Martin, Jul 11, 2019.

  1. Martin

    Martin Veteran Veteran

    Messages:
    82
    Likes Received:
    15
    First Language:
    Norwegian
    Hello, I have been trying to figure this out, but I'm stumbling a bit when I constantly feel there must be a better way to check for this and do action based on what tile around the blast hero is standing on.

    We have this bomb that the hero has placed randomly on a map.
    the x of this is 279 and y 280.

    When it explodes I dont want it to always throw the hero x-1 y-1 and random did not work either. It is just not natural to jump into a blast.

    So I wanted to know what tile the hero is actually standing on and push him/her in the natural direction of the blast.

    I have drawn out this attachment while trying to find the best way to do this in eventing.
    positionofblast.jpg

    And after a while I started making this
    Screenshot 2019-07-10 at 18.53.42.png

    But I needed to stop there, because I have to know if there is a better way to do this?
    Have you done this before with results? Can a plugin do this? maybe I have missed a setting in conditionals but I have to know if i'm on the wrong track here :o thanks
     
    #1
  2. Restart

    Restart Veteran Veteran

    Messages:
    63
    Likes Received:
    36
    First Language:
    English
    Primarily Uses:
    RMMV
    Set a movement route (for 'this event'), and add in this script line

    Code:
    $gamePlayer._directionFix = true;newX=2*$gamePlayer.x-this.x;newY=2*$gamePlayer.y-this.y;if($gameMap.isValid(newX,newY)){$gamePlayer.jump(newX-$gamePlayer.x, newY-$gamePlayer.y);}else{$gamePlayer.jump(0,0);}$gamePlayer._directionFix = false;
    
    It has to be in a move route, because that makes the game know what 'this' is referring to (just putting in a script block doesn't include that info).


    Here's the unwrapped version which is easier to follow
    Code:
    $gamePlayer._directionFix = true; //directionfix so character doesn't turn to move
    newX=2*$gamePlayer.x-this.x;
    newY=2*$gamePlayer.y-this.y;
    if($gameMap.isValid(newX,newY)){
    $gamePlayer.jump(newX-$gamePlayer.x, newY-$gamePlayer.y); //jump to the new location
    }else{
    //jump in place so we look like we're being flung by the blast, but don't actually move
    $gamePlayer.jump(0,0);
    }
    $gamePlayer._directionFix = false;//remove directionfix now that forced movement is over 
    That's a basic example (just doubling the distance from the bomb), but from that it should be pretty straightforward to figure out how to fine-tune it to fit what you want exactly (set newX and newY however you want).

    The '.jump' command is a relative position rather than absolute, so it's pretty easy to work with. The one thing I should warn you about it is that it doesn't safety-check where the player lands, (which is why my example tests that).
     
    Last edited: Jul 11, 2019
    #2
    Martin likes this.
  3. Martin

    Martin Veteran Veteran

    Messages:
    82
    Likes Received:
    15
    First Language:
    Norwegian
    Wow, yeah thank you this seems like a really good solution, I will try next time I rpgmake. Looking forward to it!
    Thank you so much!
     
    #3
  4. Martin

    Martin Veteran Veteran

    Messages:
    82
    Likes Received:
    15
    First Language:
    Norwegian
    Thank you @Restart ! It made it so much better. :ywink:Could I please ask for your solution for when a object is checking to see if
    variable 279:X dropBomb and 280:Y dropBomb is in a neighbouring tile. I have it working with eventing now but it sucks such fps.
    This is for the chests and other scenery to know when to blow up. I would really appreciate, im starting to learn code, but im more of a graphics dude. Im guessing the script logic you wrote earlier is quite the same? just the opposite? Like instead of player checking if close to the bomb, we must have object checking if close to the bomb
     
    Last edited: Jul 15, 2019
    #4
  5. Restart

    Restart Veteran Veteran

    Messages:
    63
    Likes Received:
    36
    First Language:
    English
    Primarily Uses:
    RMMV
    Sure, how does this look?

    Code:
    //range for our bomb, going with a square area (you can obviously fancy this up later if you like)
    var blastZone=3;
    // check every event on the map.  Unless something is crazy, checking them all shouldn't produce too much lag.
    // if you have a TON of events you might want to check which events are on nearby tiles using $gameMap.eventIdXy(x,y) instead,
    // but that only grabs the first event on each tile which is a little unreliable.
    for (var myCounter = 1; myCounter <= $gameMap.events().length; myCounter++) {
       //if we are in range
       if (  ( Math.abs($gameMap.event(myCounter).x-this.x)<blastZone) && ( Math.abs($gameMap.event(myCounter).y-this.y)<blastZone))
       {
           //check to see if the image it uses has a filename with the word breakable in it somewhere
           if($gameMap.event(myCounter).characterName().contains("breakable"))
           {
               //if so, play an animation,
               $gameMap.event(myCounter).requestAnimation(1);
               //and erase the event
               $gameMap.event(myCounter).erase();
           }
       }
    }
    compressed for a single line
    Code:
    var blastZone=3;for (var myCounter = 1; myCounter <= $gameMap.events().length; myCounter++) {   if (  ( Math.abs($gameMap.event(myCounter).x-this.x)<blastZone) && ( Math.abs($gameMap.event(myCounter).y-this.y)<blastZone))   {       if($gameMap.event(myCounter).characterName().contains("breakable"))       {           $gameMap.event(myCounter).requestAnimation(1);            $gameMap.event(myCounter).erase();        }   }}
    Generally if something happens once and causes a change on the map (like a bomb exploding), it's most efficient to put all the logic into the bomb, instead of the map.
     
    #5
    Martin likes this.
  6. Martin

    Martin Veteran Veteran

    Messages:
    82
    Likes Received:
    15
    First Language:
    Norwegian
    Wow, just wow! Superthankyou! I will play with this today, and I really liked the logic of "breakable" in filename!

    And just to be curious, would it be possible to use a events note "breakable" instead of a filename?

    I cant thank you enough! You have been of much needed help here <3
     
    Last edited: Jul 16, 2019 at 12:51 AM
    #6
  7. Martin

    Martin Veteran Veteran

    Messages:
    82
    Likes Received:
    15
    First Language:
    Norwegian
    I have played around with it for a while and the results are fantastic! :) :smile:
    I dont know if you have time for more of my nonsense :kaoluv:
    But I have given it a try to activate the conflicted event C selfswitch. I have tried some variations and will continue to try. I looked up the RMMV Script calls list but there is no definition on how to do just that.

    Code:
    var blastZone=3;for (var myCounter = 1; myCounter <= $gameMap.events().length; myCounter++) {   if (  ( Math.abs($gameMap.event(myCounter).x-this.x)<blastZone) && ( Math.abs($gameMap.event(myCounter).y-this.y)<blastZone))   {       if($gameMap.event(myCounter).characterName().contains("breakable"))       {           $gameMap.event(myCounter).requestAnimation(25);          $gameSelfSwitches.setValue([this._mapId, ? ,’C’]);      }   }}
    
    edit: .. hmm.. I think its not possible for events to interact with eachother like that when the event ID is not defined?.. So if im not wrong, (trying to understand this) We can find out where the object is on map and play animation there and delete it, and move it. But we can not "get" which object it is exactly so therefore we are not able to manipulate its selfswitch? This is at least what I came to understand when reading around
     
    Last edited: Jul 16, 2019 at 2:50 AM
    #7
  8. Restart

    Restart Veteran Veteran

    Messages:
    63
    Likes Received:
    36
    First Language:
    English
    Primarily Uses:
    RMMV
    to base off of notes, you'd have to do

    $gameMap.event(myCounter).event().note.contains("breakable")


    Basically 'myCounter' contains the current event's id, and referencing $gameMap.event(myCounter) references whatever the event is. That said, controlling self-switches through script calls is a little tricky - every time I do that I have to look the syntax up in the script call list

    [​IMG]

    So instead of the
    $gameMap.event(myCounter).requestAnimation(1);
    $gameMap.event(myCounter).erase();
    instead we'd do something like
    Code:
    var key = [$gameMap._mapId;,myCounter, 'A'];
    $gameSelfSwitches.setValue(key, true);
    haven't tested but should work.
     
    Last edited: Jul 16, 2019 at 10:08 AM
    #8
    Martin likes this.
  9. Martin

    Martin Veteran Veteran

    Messages:
    82
    Likes Received:
    15
    First Language:
    Norwegian
    Thanks again for this! I tried, but with no luck. I will update if I find out what I did wrong here. :)


    edit:

    I now tried to set SelfSwitch C if it had breakable in its name just to check what was the problem. But did not turn any results.


    edit:
    Then I tried with .note.contains and .erase and that worked.

    - So then it must be with the selfswitch comand.

    Code:
    var blastZone=3;for (var myCounter = 1; myCounter <= $gameMap.events().length; myCounter++) {   if (  ( Math.abs($gameMap.event(myCounter).x-this.x)<blastZone) && ( Math.abs($gameMap.event(myCounter).y-this.y)<blastZone))   {       if($gameMap.event(myCounter).event().note.contains("breakable"))        {     var key = [$gameMap._mapId;, myCounter, ‘C’];         $gameSelfSwitches.setValue(key, true);     }   }}
    { var key = [$gameMap._mapId;, myCounter, ‘C’]; $gameSelfSwitches.setValue(key, true); }
    { var key = [$gameMap._mapId, myCounter, ‘C’]; $gameSelfSwitches.setValue(key, true); }
    ( I also tried without the ; after mapId just to be sure)
     
    Last edited: Jul 17, 2019 at 1:44 AM
    #9
  10. Restart

    Restart Veteran Veteran

    Messages:
    63
    Likes Received:
    36
    First Language:
    English
    Primarily Uses:
    RMMV
    the semicolon is a typo, but

    Code:
    var blastZone=3;for (var myCounter = 1; myCounter <= $gameMap.events().length; myCounter++) {   if (  ( Math.abs($gameMap.event(myCounter).x-this.x)<blastZone) && ( Math.abs($gameMap.event(myCounter).y-this.y)<blastZone))   {       if($gameMap.event(myCounter).characterName().contains("Damage"))       {           $gameMap.event(myCounter).requestAnimation(1);            var key = [$gameMap._mapId,myCounter, 'A'];$gameSelfSwitches.setValue(key, true);        }   }}
    seems to work for me in my test case
     
    #10
    Martin likes this.
  11. Martin

    Martin Veteran Veteran

    Messages:
    82
    Likes Received:
    15
    First Language:
    Norwegian
    It works like a charm! Thank you! Im so happy with it! This did really change the way events can interact for me and it will make a huge difference in the gamedemo im building

    You have been of much help mr.!
     
    #11

Share This Page