Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Not too advanced, code provided, help wanted!

So I've been working on a new ABS for the community, and hit a little bump in the road, so was wondering if someone could help.  Basically, the below code will check to see if any events projectile hit-box is overlapping the enemy.  If so, it will return true and change the projectiles self switch D on if it's not passable.  Here's my code thus far:

Code:
def projectile_overlaps_event(event)
  for i in 1..$game_map.events.keys.size
    if ($game_map.events[event].x + ($game_map.events[event].width / 2)) > $game_map.events[i].projectile_left_edge
      if ($game_map.events[event].x - ($game_map.events[event].width / 2)) < $game_map.events[i].projectile_right_edge
         if ($game_map.events[event].y - $game_map.events[event].height) < $game_map.events[i].projectile_lower_edge
            if ($game_map.events[event].y - $game_map.events[event].legs) > $game_map.events[i].projectile_upper_edge
                if $game_map.events[i].projectile_passable == false
                  $game_self_switches[[$game_map.map_id, i, 'D']] = true
                  $game_map.need_refresh = true
                end
                return true
            end 
         end
      end    
    end
  end
end

Sorry if it's messy, I'm not much of a scripter and I'm still learning.  =)  Anyways, because I'm calling this definition from the enemy events themselves, is there anyway I can tell the event what i equals?  I mean, right now it returns true that it was hit by a projectile.  My problem is that I don't know how to define which projectile has hit it, because obviously a arrow will do different damage and effects than a rocket.  Can anyone with a better understanding of scripts help me?  Thanks in advance.

Edit:  I was also wondering if there's a better method than $game_map.events.keys.size to check how many events are on the map.  As of now, it keeps adding one, so every time a projectile is fired, it checks another keeps adding one more event to check, even after the projectile is erased.  Better yet, would there be a way to check just the projectiles instead of every event?
 
Thanks for the help, I actually figured that part out before you posted.  Stupid mistake on my part.  :blush:  But I edited the main post so as not to waste this thread.  Could you possibly help me out with that?  Thanks.  :thumb:
 

Zeriab

Sponsor

Why are you using events for projectiles?
Why are they added to the normal game_map events?
Why can't you delete them afterwards?
What happens if a projectile hits another projectile?
How can you separate the projectiles from the normal map events? Is it worth separating the projectiles from the normal map events?
My antilag script provides the mean of a general faster events on specific tile lookup. Can you benefit from this? What is the cost?
Could you make a more lightweight class for controlling the projectiles?

These are some questions you could ask yourself to help you reflect upon what you have.

*hugs*
- Zeriab
 
Thanks for getting me started Zeriab.  I'm still new to this scripting business, your questions do help me think outside the box a bit.

Zeriab":23vutvmy said:
Why are you using events for projectiles?
I want this system to be easy to alter and edit for the average user.  Events are the most friendly way to do this, as opposed to creating scripts for the projectiles which could intimidate novice RMXP users.  Events in general are easier to edit and see what the hell they're doing.   :smile:

Zeriab":23vutvmy said:
Why are they added to the normal game_map events?
I'm using a script which will spawn an event from one map to another.  So essentially, there is a map set aside as a projectile database that users will be able to edit that one event (flight pattern, damage, speed, etc.) without the hassle of editing different events on different maps.

Zeriab":23vutvmy said:
Why can't you delete them afterwards?
I believe they're deleting just fine, it's the function $game_map.events.keys.size that's giving me a problem.  Every time a new projectile is fired, the $game_map.events.keys.size increases one in value, even if a fired projectiles has been erased.  So if I fire 3 arrows, all of which have been erased, $game_map.events.keys.size will still read 3.  I believe this is the function I need to change to decrease the work the script is doing.

Zeriab":23vutvmy said:
How can you separate the projectiles from the normal map events? Is it worth separating the projectiles from the normal map events?
I'm not sure how I'd seperate them from the normal map events, as I'm still a scripting novice.  I'm also not sure if it'd be worth it, besides the fact that my function for checking projectile collisions would have to check a lot less variables, as opposed to every event on the map.

Zeriab":23vutvmy said:
My antilag script provides the mean of a general faster events on specific tile lookup. Can you benefit from this? What is the cost?
I haven't looked into any anti-lag scripts just yet, but it is something I intend on doing.  I want to fix my basic problem first, before just throwing an anti-lag script at it and hoping it goes away.  I will definitely keep yours in mind, though I should mention that these projectiles aren't tile-based, the collision is actually going to be pixel-based.

Zeriab":23vutvmy said:
Could you make a more lightweight class for controlling the projectiles?
Again, that's what I'm attempting to do.  The class itself isn't large, this one definition is the only thing that's bogging it down, and I even pinpointed the reason why.  I'm just not sure how I can go about making it check only the number of events on the map, as opposed to an increasing number every time a projectile is fired.

You definitely helped me pinpoint my problem though, thank you for your help.  I hope answering these questions will help me.  Cheers mate, and thanks for the hugs.  :wink:

Edit:  After some more pondering, I think a good solution would be to add every projectile event_id into an array, then check the values of the array.  After the event was erased, the value would need to be taken out of the array (which could always be done from the event itself).  Could you possibly help me with that, or show me the right direction?
 
perhaps to remove all the entries of the array you could use clear, then compact to delete all the nil values? I am not a tutorial person, but reading the help files helps me kinda with arrays.
 

Zeriab

Sponsor

I'm glad you are putting some effort into this and took the time to answer all questions.
If you keep it up I am sure you will become a good scripter in no time at all ^_^

Ace of Spades":3gvhhihk said:
Zeriab":3gvhhihk said:
Why are you using events for projectiles?
I want this system to be easy to alter and edit for the average user.  Events are the most friendly way to do this, as opposed to creating scripts for the projectiles which could intimidate novice RMXP users.  Events in general are easier to edit and see what the hell they're doing.   :smile:
Events are typically easy to edit for the average user. Using events as input is not a bad idea.
Why must you retain the input as events? What about converting it to another format? Think about conversion. How would it work out? What benefits can you achieve from it? What are the costs or compromises you must make? (The complexity of the code increases for one)

Ace of Spades":3gvhhihk said:
Zeriab":3gvhhihk said:
Why are they added to the normal game_map events?
I'm using a script which will spawn an event from one map to another.  So essentially, there is a map set aside as a projectile database that users will be able to edit that one event (flight pattern, damage, speed, etc.) without the hassle of editing different events on different maps.
I meant why are they added to $game_map.events?
Is it a requirement of the script?
Couldn't they be added to $game_map.projectiles? (Or something similar)

Ace of Spades":3gvhhihk said:
Zeriab":3gvhhihk said:
Why can't you delete them afterwards?
I believe they're deleting just fine, it's the function $game_map.events.keys.size that's giving me a problem.  Every time a new projectile is fired, the $game_map.events.keys.size increases one in value, even if a fired projectiles has been erased.  So if I fire 3 arrows, all of which have been erased, $game_map.events.keys.size will still read 3.  I believe this is the function I need to change to decrease the work the script is doing.
Erasing is not deleting. What I mean is why you are not deleting the erased events from the $game_map.events. (Hash deletion: http://www.ruby-doc.org/docs/Programmin ... ash.delete)

Ace of Spades":3gvhhihk said:
Zeriab":3gvhhihk said:
How can you separate the projectiles from the normal map events? Is it worth separating the projectiles from the normal map events?
I'm not sure how I'd seperate them from the normal map events, as I'm still a scripting novice.  I'm also not sure if it'd be worth it, besides the fact that my function for checking projectile collisions would have to check a lot less variables, as opposed to every event on the map.
This is very much related to the question of why they are added to $game_map.events.
You could perhaps consider this again after some time if you feel it is too difficult for you at the moment.

Ace of Spades":3gvhhihk said:
Zeriab":3gvhhihk said:
My antilag script provides the mean of a general faster events on specific tile lookup. Can you benefit from this? What is the cost?
I haven't looked into any anti-lag scripts just yet, but it is something I intend on doing.  I want to fix my basic problem first, before just throwing an anti-lag script at it and hoping it goes away.  I will definitely keep yours in mind, though I should mention that these projectiles aren't tile-based, the collision is actually going to be pixel-based.
It's not so much that you should use an anti-lag. The interesting point is that I have altered the collision system in my antilag to a generally more efficient structure. You can find it here in full version and here in the no spriteset version. Both contain the collision detection where I use a hash to look up events on specific tiles.
You could still use a grid-based approach even if you are going pixel-based. The problem does become more complex because objects can exists in several grids at the same time.
This might be too difficult for you to deal with at the moment. The naive solution is much easier.

Ace of Spades":3gvhhihk said:
Zeriab":3gvhhihk said:
Could you make a more lightweight class for controlling the projectiles?
Again, that's what I'm attempting to do.  The class itself isn't large, this one definition is the only thing that's bogging it down, and I even pinpointed the reason why.  I'm just not sure how I can go about making it check only the number of events on the map, as opposed to an increasing number every time a projectile is fired.
Didn't you say that you are using events?
Or are you just using events as input and then convert them? (As I talked about earlier ^^)

@Dariencove: $game_map.events is a hash, not an array ;)

Good luck with you project ^^
*hugs*
- Zeriab
 
Erasing is not deleting. What I mean is why you are not deleting the erased events from the $game_map.events. (Hash deletion: http://www.ruby-doc.org/docs/Programmin ... ash.delete)

Hmm, interesting.  So if there's 20 events on the map, and all 20 of them were erased, the map would still process as if there are 20 events on the map?  Hm, I imagine that'd make things quite laggy.  Can you give me anymore information on deleting events?  I followed your link, but it's not very descriptive, so I'm still a bit lost.  I think I'm just one of those people who needs someone to explain stuff to me.  :down:    But, good news is I did a lot of fixing up on the code I posted.  Now the collisions are only checked for the events in the projectile array, and it won't check any if the array is empty.  The projectiles themselves are set to automatically add and delete themselves from the array as needed.  However, I'm still getting the lag because of the map still processing the erased events.
 

Zeriab

Sponsor

It's great to hear it's going the right way.
Use this to delete the events:
Code:
$game_map.events.delete(event_id)
You might have to erase the event and update it again before deleting it. Just do some experiments.

I just noticed you used this:
Code:
for i in 1..$game_map.events.keys.size
It's dangerous since you are perfectly able to delete an event in the editor and thus have 'gaps' where there are no event present.
Use this instead:
Code:
for i in $game_map.events.keys

*hugs*
- Zeriab
 
Little progress update... A lot of the problems I had are going away.  I've been working very hard at this, and I managed to rework a lot of what I had.

Code:
def projectile_overlaps_event(event)
  if $projectiles_array.empty? != true
    $projectiles_array.each do |i|
      if ($game_map.events[event].x + ($game_map.events[event].width / 2)) > $game_map.events[i].attack_left_edge
        if ($game_map.events[event].x - ($game_map.events[event].width / 2)) < $game_map.events[i].attack_right_edge
           if ($game_map.events[event].y - $game_map.events[event].height) < $game_map.events[i].attack_lower_edge
              if ($game_map.events[event].y - $game_map.events[event].legs) > $game_map.events[i].attack_upper_edge
                  $game_map.events[event].hit_by_projectile_id = i
                  if $game_map.events[i].projectile_passable == false
                    $game_self_switches[[$game_map.map_id, i, 'D']] = true
                    $game_map.need_refresh = true
                  end
                  return true
              end 
           end
        end    
      end
    end
  end
end

It will now only check events in the projectiles array now.  Projectiles are automatically added to the array when they are created, and they take themselves out of the array when they're destroyed.  The array clears whenever a new map is loaded, and when you revisit an old map, if a projectile is still active on that map, it will re-add itself into the array.  :thumb:  I'm still having some trouble with the whole deleting events thing.  Whenever I delete an event, the graphic still remains and it will actually screw up the script which creates the new events.  Here is the script that copies events over from other maps.  Is there anyway you could perhaps help me edit this, so as to avoid all the lag from processing expended events?

Code:
#==============================================================================
# ** Service_Event
#------------------------------------------------------------------------------
#  24/03/08 - MGCaladtogel
#==============================================================================
class Service_Event
  #--------------------------------------------------------------------------
  # * copy_event : copies a Game_Event from one map to the current map
  #     map_id    : source map's id
  #     event_id  : source event's id
  #     x         : new event's x-coordinate (facultative)
  #     y         : new event's y-coordinate (facultative)
  #--------------------------------------------------------------------------
  def self.copy_event(map_id, event_id, x=nil, y=nil)
    # loads the source map and the event
    map = load_data(sprintf("Data/Map%03d.rxdata", map_id))
    event = map.events[event_id]
    # alters default coordinates
    if x != nil
      event.x = x
      event.y = y
    end
    # finds a unused id
    new_event_id =  $game_map.events.keys.sort[$game_map.events.keys.size - 1] + 1
    event.id = new_event_id
    # instanciates a new Game_Event from the loaded event
    new_event = Game_Event.new($game_map.map_id, event)
    # adds the event to the current map
    $game_map.events[new_event_id] = new_event
    # clears and re-creates the spriteset's character_sprites to obtain a correct display
    character_sprites = $scene.spriteset.character_sprites
    for sprite in character_sprites
      sprite.dispose
    end
    character_sprites.clear
    for i in $game_map.events.keys.sort
      sprite = Sprite_Character.new(@viewport1, $game_map.events[i])
      character_sprites.push(sprite)
    end
    character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
  end
end

#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
class Scene_Map
    attr_accessor :spriteset
end

#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
class Spriteset_Map
  attr_accessor :character_sprites
  attr_accessor :viewport1
end
 

Zeriab

Sponsor

I would suggest that you change this part:
Code:
if $projectiles_array.empty? != true
To this:
Code:
unless $projectiles_array.empty?

It if faster although insignificantly in this case and more pretty.

As for deletion. Erase the event before deleting it:
Code:
event = $game_map.events[1]
event.erase
#event.update
#event.refresh
$game_map.events.delete(1)
You might have to use the .update or .refresh methods to make the graphic disappear. Refresh is slower than update.

If you get this to work properly I doubt you will have any problems with script that copies events over from other maps ^^

*hugs*
- Zeriab
 
Well, I must admit the deleting of events game me a bit of trouble to being with, but I think I worked out all the bugs.  The problem was, I'm erasing the projectiles from the projectile events themselves, so I couldn't erase the event then delete it.  I fixed this by simply changing the graphic event graphic to none, and then deleting it.  I still had problems with the event creator, but I realized it's because all the self switches of the deleted events still stayed on.  I just tweaked it a bit so all the self switches turn off when creating a new event, and now it works like a charm!  All the unnecessary events are deleted off the map, and the frame rate is much better now.  I want to thank you for all your help Zeriab, for being patient and for taking the time to help me.  You didn't plop an answer right in front of me, you just gave me all the tools I needed to find a solution, which is much more helpful.  You'll definitely be getting a spot in my credits.   :thumb:

*Hugs*
 

Zeriab

Sponsor

I am glad you solved the problem
You did post this in RGSS support so I guess you wanted to learn how to do it rather than get the solution. Seems like I guessed right ^_^

Take care and good luck with your project
*hugs*
- Zeriab
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top