Scrolling Game Development Kit Forum

SGDK Version 1 => Script => Topic started by: billybob884 on 2005-11-11, 03:15:44 PM

Title: multiple hits
Post by: billybob884 on 2005-11-11, 03:15:44 PM
is there a way (other than using an inventory for each sprite) to make an enemy that required multiple hits to kill? Maybe just like 2 or 3, and not so much for the bosses, more for the level enemies.

--edit--
also, does the 'follow floor and slopes' movement option mean flat floor, or does it mean any flat surface (walls/ceiling)?
Title: multiple hits
Post by: durnurd on 2005-11-11, 05:19:31 PM
Floors and slopes means only down (or up if gravity is up).  Follow Left wall follows all walls around.

There are three other ways that I can think of to have "hitpoints" for enemies.  One is through scripting, each sprite having its own value in there, which would be much easier than creating an inventory item for each.

Another is to have three seperate sprite definitions which react differently to collisions with bullets.  The sprite you add to the map would create a different sprite in the same place as the old one and delete the old one upon collision.  So would the second one.  The third one would "kill" the enemy upon collision with a bullet.

The third way is instead to have "replenishable" health.  Basically, you have a counter inventory that has a global function adding one every second.  Have a max of maybe (MAX_FRAME_RATE * 2 or 3) and when it hits the maximum, reset to opposite limit and add 1 to anb "HP" inventory (max 3, initial 3) whenever you hit a sprite and HP is at 0, destroy the sprite and reset to 3.  So basically, you have one Hitpoint counter for all enemies.  The only problem with this is that if you hit one enemy twice, then another once, it will kill the second one in only one hit but the other will still require three more shots.  Overall though, it adds up to six shots total.  The other thing is that their hitpoints are regenerative, so you have a certain amount of time to shoot them three times before they regain a hitpoint.
Title: multiple hits
Post by: billybob884 on 2005-11-13, 07:51:20 PM
...Ok, it sounds to me like scripting ( shivers ) is the easiest way to go about this. ok, there are 4 different enemies in my 5th level: 2 are going to be '1-hitters', the sprite names are SC1-4,6-15; and NB1-8,10-20; and their templates are just SC and NB respectively, (I
Title: multiple hits
Post by: durnurd on 2005-11-13, 10:42:27 PM
Well, I started the script.  See if you can finish it....okay, just kidding.  But I can't think right now, and I have to go to bed, so here's the beginning anyway, if somebody wants to pick up where I left off or completely scrap it and start over.  Anybody who takes a look will notice that I created a class defined for multi-hitpoint sprites, so that this could be expanded and easily used for anybody who wants to have multi-hitpoint sprites.

Code: [Select]

Option Explicit

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Default Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   public function getMap()
      getMap = hMap
   End Sub
   public function getSprite()
      getSprite = hSpriteName
   End Sub
   public function getHPs()
      getHPs = hHPs
   end Sub
End Class

Sub Player_OnSpritesCollide(Name, ClsASprIdx, ClsBSprIdx, CollDefIdx)
   '-----Insert Juicy Stuff Here(?)-----
End Sub

'-----Initialize Sprites-----

Dim Hits(1)
set Hits(0) = new Hit("5-0TheMoon","MJW1-4",2)
set Hits(1) = new Hit("5-0TheMoon","MS1-13",3)

'-----End initialization-----

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16
Title: multiple hits
Post by: billybob884 on 2005-11-14, 04:57:10 AM
set Hits(0) = new Hit("5-0TheMoon","MJW1-4",2)
i know this is just the beginning, and you probably just put this there to start it off, but jus so u know, i meant 'MJW1, MJW2, MJW3, MJW4' when i said 'MJW1-4', and the same respectively for the others
Title: multiple hits
Post by: bluemonkmn on 2005-11-14, 07:07:58 AM
I would pick it up from there, but I have to go to work.  One trick remaining that hasn't been addressed in that implementation is how to keep the Hit objects connected to the sprite objects.  Right now it looks like the Hit object just has a sprite definition name in it.  This might work if you only use the sprite definition to create one sprite instance, but it wouldn't work in a general case where you might have multiple sprite instances based on the same definition.

(That gives me an idea for 2.0 -- since sprite definitions rarely need multiple instances, maybe I'll make a kind of sprite definition that inherently supports only having 1 instance of the sprite, and then you don't have to go looking for it every time you want to access it -- just use the name of the sprite like a global variable.  Then you can deal with the confusion of multiple sprites per definition only when you really need it).
Title: multiple hits
Post by: billybob884-no-login on 2005-11-14, 09:17:32 AM
well, then couldn't i just adda aline for each sprite? like having maybe 30 lines like

set Hits(0) = new Hit("5-0TheMoon","MJW1-4",2)

with each one having a different name in it?
Title: multiple hits
Post by: durnurd on 2005-11-14, 12:43:18 PM
Unfortunately, the onSpritesCollide only give you the sprite class rather than the sprite definition or sprite template.  I don't know what the name is used for.  But the problem is how to figure out exactly which sprites collided so you can access those sprites' User Data (and change their current HP).
Title: multiple hits
Post by: billybob884 on 2005-11-14, 12:59:53 PM
is there a way to maybe make the game tell the script when a certain colision occurs? heh, i'm probably not helping, am i
Title: multiple hits
Post by: durnurd on 2005-11-14, 03:10:01 PM
If you created a Special Function for each sprite collision, then yes, it would be possible.  For example, COL_MJW1Bullet would activate, then run through a loop like

Code: [Select]

for i = 0 to UBound(Hits)
   spr = Hits(i).getSprite
   if left(Special.Name,4 + len(spr)) = "COL_" & spr then
      '---Subtract Hitpoints
   end if
next


But then the problem would be finding the sprite to subtract the hitpoints from and also you would have to create the special function for each sprite (which could be done in the script during runtime, I suppose).
Title: multiple hits
Post by: durnurd on 2005-11-14, 03:33:12 PM
Okay, so I came up with this.  Note that I haven't tested it so I don't know if it will work (due to minor bugs).  However, it should work, in theory, to actually keep track of how many hitpoints each sprite has, and remove the sprite when their hitpoints run out (no explosion or anything;  This could be done though).  All you need is one collision definition between an enemy class and, for lack of a better term, an "attacking" class (i.e. a bullet or sword) (doesn't matter what they're called) that upon collision activates the COL_<ADef>* function
Code: [Select]

Option Explicit

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Default Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   public function getMap()
      getMap = hMap
   End function
   public function getSprite()
      getSprite = hSpriteName
   End function
   public function getHPs()
      getHPs = hHPs
   end function
End Class

Sub Player_OnPlayInit()
   Dim i
   Dim oNewSpecial
   Set oNewSpecial = NewSpecialFunction
   for i = 0 to ubound(Hits)
      oMap = ProjectObj.Maps(Hits(i).getMap())
      oNewSpecial.FuncType = 7 ' SPECIAL_EVENT
      oNewSpecial.Name = "COL_" & Hits(i).getSprite()
      oMap.AddSpecial(hostObj.AsObject(oNewSpecial))
   Next
End Sub

Sub Player_OnSpecialFunction(SpecialObj)
   dim i, layer, idx
   for i = 0 to UBound(Hits)
   spr = Hits(i).getSprite()
   if left(Special.Name,4 + len(spr)) = "COL_" & spr then
      spr = FindSpriteByDef(spr,layer,idx)
      if spr.UserData > Hits(i).getHPs() or spr.UserData < 0 then spr.UserData = 0
      spr.UserData = spr.UserData + 1
      if spr.UserData = Hits(i).getHPs() then
         layer.RemoveSprite(idx)
      end if
   end if
next
End Sub

Function FindSpriteByDef(SpriteName, byref oLayer, byref oSprIndex)
   dim i, j
   oMap = ProjectObj.GamePlayer.rMap
   for i = 0 to rMap.LayerCount
      for j = 0 to rMap.MapLayer(i).SpriteCount()
         if rMap.MapLayer(i).Sprite(j).SpriteDef.Name = SpriteName then
            set oLayer = rMap.MapLayer(i)
            oSprIndex = j
            set FindSpriteByDef = oLayer.Sprite(j)
         end if
      next
   next
End Function

'-----Initialize Sprites-----

Dim Hits(16)
Dim i
for i = 0 to 3
   set Hits(i) = new Hit
   Hits(i) "5-0TheMoon","MJW" & i + 1,2
next
for i = 4 to 16
   set Hits(i) = new Hit
   Hits(i) "5-0TheMoon","MS" & i - 3,3
next

'-----End initialization-----

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16
Title: multiple hits
Post by: billybob884 on 2005-11-15, 05:01:30 AM
ok, ill give it a shot this afternoon. one question i have is this: right now i have the colision of 'Attack' (ADef) and 'Enemy' (BDef), it activates COL_<ADef><BTemplate>, i did this so i would only need 1 class for enemy, so do i need to give each enemy with multiple hit points a seperate class? and does the enemy need to be the ADef in the colision?
Title: multiple hits
Post by: bluemonkmn on 2005-11-15, 05:54:19 AM
Quote from: "durnurd"
Unfortunately, the onSpritesCollide only give you the sprite class rather than the sprite definition or sprite template.  I don't know what the name is used for.  But the problem is how to figure out exactly which sprites collided so you can access those sprites' User Data (and change their current HP).


Actually it doesn't just give you the class.  It gives you the index of the sprite associated with the "Class A" sprite and the index of the sprite associated with the "Class B" sprite.  From this you can get the sprite instance (using Layer.Sprite()) and from that you can get the sprite definition and the sprite template using Sprite.rDef and Sprite.rDef.Template.  The "Name" parameter is the name of the layer on which the collision occurred (so you know which layer's sprite array to reference with Layer.Sprite()).

So for example, to get the sprite definition name of the first sprite in the collision, you'd use:
Code: [Select]
ProjectObj.GamePlayer.rMap.MapLayer(Name).Sprite(ClsASprIdx).rDef.Name
Title: multiple hits
Post by: bluemonkmn on 2005-11-15, 06:10:48 AM
Quote from: "billybob884"
ok, ill give it a shot this afternoon. one question i have is this: right now i have the colision of 'Attack' (ADef) and 'Enemy' (BDef), it activates COL_<ADef><BTemplate>, i did this so i would only need 1 class for enemy, so do i need to give each enemy with multiple hit points a seperate class? and does the enemy need to be the ADef in the colision?


COL_<ADef><BTemplate> will activate the same function for all enemies that use the same enemy template and all attackers that use the same attacker sprite definition.  In other words, it activates a unique function for each attacker sprite and enemy template combination.  So take, for example, these three attacker sprites:
SpriteDef: Sword1 Template: Sword Class: Attacker
SpriteDef: Bullet Template: Projectile Class: Attacker
SpriteDef: Missile1 Template: Projectile Class: Attacker

And these three enemy sprites:
SpriteDef: Ghoul1 Template: Ghostie Class: Enemy
SpriteDef: Phantom1 Template: Ghostie Class: Enemy
SpriteDef: Wolf1 Template: Wolf Class: Enemy

Using this data and a single collision definition, you end up with a number of functions that can be activated:
Collision Definition: When Attacker hits Enemy, Activate COL_<ADef><BTemplate>
Can activate:
COL_Sword1Ghostie
COL_BulletGhostie
COL_Missile1Ghostie
COL_Sword1Wolf
COL_BulletWolf
COL_MissileWolf

If you define your collision definition slightly differently, you could end up with different results:
Collision Definition: When Attacker hits Enemy, Activate COL_<ATemplate><BDef>
Can activate:
COL_SwordGhoul1
COL_SwordPhantom1
COL_SwordWolf1
COL_ProjectileGhoul1
COL_ProjectilePhantom1
COL_ProjectileWolf1

If you don't care what kind of weapon you use, you might do something like this:
Collision Definition: When Attacker hits Enemy, Activate COL_<BTemplate>
Can activate:
COL_Ghostie
COL_Wolf

One thing to keep in mind is that I think you need to have functions by those names in order for anything to happen.  I don't think you can just have a script to handle the collision.  You'll have to actually create functions for the names that you care about, and set them to a type of "Raise an Event" (or whatever) and then if you want to script them you can add script like durnurd provided.
Title: multiple hits
Post by: billybob884-nologin on 2005-11-15, 06:50:38 AM
Quote from: "durnurd"
no explosion or anything;


The explosions aren't that bad, I can just set up a second colision definition to create the explosion
Title: multiple hits
Post by: billybob884-nologin on 2005-11-15, 06:54:00 AM
Quote from: "bluemonkmn"
If you don't care what kind of weapon you use, you might do something like this:


the only problem is that, my shoot left and shoot right have 2 seperate templates, because of hte way the attack spins in each direction...
Title: multiple hits
Post by: durnurd on 2005-11-15, 09:02:37 AM
The script I supplied uses special functions anyway, but they are automatically created upon Plyaer_OnPlayInit, so you don't have to worry about that.  If class A is the weapon and class B is the enemy, then have a collision between the two activate the COL_<BDef>* Special Function.  That's all you need to do for the script to (supposedly) work.  I suppose I could rework the code so it worked for OnSpritesCollide, but if this works, then there's no need.
Title: multiple hits
Post by: billybob884-no-login on 2005-11-15, 09:17:34 AM
ok, ill give the script u posted a shot once i get home today.
Title: multiple hits
Post by: billybob884 on 2005-11-15, 01:10:20 PM
ok, using durnurds script, it brings up the error:
Code: [Select]
Script stopped at line 15 on character 8:
Expected 'Function'


i believe line 15 is the End sub right before public function getSprite(), unless hte first line counts as 0, then its the forementioned public function... line.

on a wild guess, i tried changing the 3 'end sub' lines to 'end function' lines, and it went past that, giving me hte next error of

Code: [Select]
line 44 character 40: expected 'then'

except, there is already a then in that 'if then' line. maybe changing the end sub was a mistake..


also, small side note, i figured out how to do hte explosions with a second colision thing, but is there a way to make the script alter an inventory item when one is destroyed? i.e. in this case, 'Score'? just +30 for MS and... i guess +20 for MJW.
Title: multiple hits
Post by: durnurd on 2005-11-15, 02:02:18 PM
I've updated the script (http://gamedev.comdel.net/viewtopic.php?p=1740#1740) to fix the errors reported so far.  You could just create a collision that activates COL_<ATemplate><BTemplate>* and create special functions called COL_EnemyAttackInventory to add points to your score (you get the idea.  Not like this exactly, but something similar)

Or it could be done in script if you wanted to.

Also, I was thinking the explosion would occur only upon death of the enemy.
Title: multiple hits
Post by: billybob884 on 2005-11-15, 03:11:50 PM
nah, i wanted explosions to occur when the attack touches anything (excet solid tiles). i just got lucky that this didn't turn out to be a problem (its not a bug, its a feature! ;) )

ok, as for the script,
stopped @ line 71 char. 27: expected ')'

thats the line
Code: [Select]
  Hits(i) = ("5-0TheMoon","MJW" & i + 1,2)

i guess it wants a ) where the comma in the center is


also, if i did the colision for the score, wouldnt it really get added twice (3x for MS) since its adding to the score each time it gets hit? i could just devidethe score by 2 (three) then, yea, that'll work just fine
Title: multiple hits
Post by: durnurd on 2005-11-15, 04:04:26 PM
Okay, fixed it.  I'm learning how to do classes in VB and VBScript at the same time here, so there's bound to be a few bugs here and there (still).

Try again
Title: multiple hits
Post by: billybob884 on 2005-11-15, 04:08:10 PM
line 71 character 12: expected end of statement

i believe its the line
Code: [Select]
  Hits(i) "5-0TheMoon","MJW" & i + 1,2
Title: multiple hits
Post by: durnurd on 2005-11-15, 07:42:57 PM
Well, now I'm stumped.  BlueMonk, any ideas?  How do classes work in VBScript?  Any idea?
Title: multiple hits
Post by: billybob884 on 2005-11-15, 07:56:58 PM
eh, don't worry about it, ill just set up inventory for them. it's really not that big a deal, there's not that many of them. thanks for trying though, you got a heck of a lot further then i would have ;)
Title: multiple hits
Post by: bluemonkmn on 2005-11-16, 06:13:27 AM
Looks like you can't combine Default Sub and Arrays very well.  I didn't even know you could have a Default Sub (I thought that was only for properties).  Anyway, you have to do one of the following:
Code: [Select]
Dim NewHit, MyHit(1)
Set NewHit = New Hit
NewHit "5-0TheMoon","MJW1-4",2
Set MyHit(0) = NewHit
Set NewHit = New Hit
NewHit "5-0TheMoon","MS1-13",3
Set MyHit(1) = NewHit
Code: [Select]
Set MyHit(0) = New Hit
MyHit(0).Hit "5-0TheMoon","MJW1-4",2
Set MyHit(1) = New Hit
MyHit(1).Hit "5-0TheMoon","MS1-13",3
Title: multiple hits
Post by: billybob884-nologin on 2005-11-16, 09:50:14 AM
"MJW1-4" and "MS1-13", will the script realise thats a range of sprites, or will it count that as 2? i think this was a concern before.
Title: multiple hits
Post by: billybob884-no login- on 2005-11-16, 09:52:17 AM
also, i just put the first section in to replace
Code: [Select]
Dim Hits(16)
Dim i
for i = 0 to 3
   set Hits(i) = new Hit
   Hits(i) "5-0TheMoon","MJW" & i + 1,2
next
for i = 4 to 16
   set Hits(i) = new Hit
   Hits(i) "5-0TheMoon","MS" & i - 3,3
next


so now i have this

Code: [Select]
Option Explicit

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Default Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   public function getMap()
      getMap = hMap
   End function
   public function getSprite()
      getSprite = hSpriteName
   End function
   public function getHPs()
      getHPs = hHPs
   end function
End Class

Sub Player_OnPlayInit()
   Dim i
   Dim oNewSpecial
   Set oNewSpecial = NewSpecialFunction
   for i = 0 to ubound(Hits)
      oMap = ProjectObj.Maps(Hits(i).getMap())
      oNewSpecial.FuncType = 7 ' SPECIAL_EVENT
      oNewSpecial.Name = "COL_" & Hits(i).getSprite()
      oMap.AddSpecial(hostObj.AsObject(oNewSpecial))
   Next
End Sub

Sub Player_OnSpecialFunction(SpecialObj)
   dim i, layer, idx
   for i = 0 to UBound(Hits)
   spr = Hits(i).getSprite()
   if left(Special.Name,4 + len(spr)) = "COL_" & spr then
      spr = FindSpriteByDef(spr,layer,idx)
      if spr.UserData > Hits(i).getHPs() or spr.UserData < 0 then spr.UserData = 0
      spr.UserData = spr.UserData + 1
      if spr.UserData = Hits(i).getHPs() then
         layer.RemoveSprite(idx)
      end if
   end if
next
End Sub

Function FindSpriteByDef(SpriteName, byref oLayer, byref oSprIndex)
   dim i, j
   oMap = ProjectObj.GamePlayer.rMap
   for i = 0 to rMap.LayerCount
      for j = 0 to rMap.MapLayer(i).SpriteCount()
         if rMap.MapLayer(i).Sprite(j).SpriteDef.Name = SpriteName then
            set oLayer = rMap.MapLayer(i)
            oSprIndex = j
            set FindSpriteByDef = oLayer.Sprite(j)
         end if
      next
   next
End Function

'-----Initialize Sprites-----

Dim NewHit, MyHit(1)
Set NewHit = New Hit
NewHit "5-0TheMoon","MJW1-4",2
Set MyHit(0) = NewHit
Set NewHit = New Hit
NewHit "5-0TheMoon","MS1-13",3
Set MyHit(1) = NewHit

'-----End initialization-----

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16
Title: multiple hits
Post by: durnurd on 2005-11-16, 11:12:19 AM
Here's the correct thing to have

Code: [Select]

'-----Initialize Sprites-----
Dim Hits(16), newHit, i
for i = 0 to 3
   set newHit = new Hit "5-0TheMoon","MJW" & i + 1,2
   set Hits(i) = newHit
next
for i = 4 to 16
   set newHit = new Hit "5-0TheMoon","MS" & i - 3,3
   set Hits(i) = newHit
next
'-----End Initialization-----


Let me know if this works.  If it does, I may make a scripting wizard add-on for it, but then of course, BlueMonk would have to go about releasing it, which would take time away from working on SGDK 2.0...
Title: multiple hits
Post by: billybob884 on 2005-11-16, 01:02:32 PM
close, but no cigar. line 68, char 25: expected end of statement

i think its
Code: [Select]
  set newHit = new Hit "5-0TheMoon","MJW" & i + 1,2
Title: multiple hits
Post by: durnurd on 2005-11-16, 05:10:46 PM
Oops, I got that backwards.
Code: [Select]

'-----Initialize Sprites-----
Dim Hits(16), i
for i = 0 to 3
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MJW" & i + 1,2
next
for i = 4 to 16
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MS" & i - 3,3
next
'-----End Initialization-----
Title: multiple hits
Post by: billybob884 on 2005-11-16, 08:40:25 PM
hey, getting closer! this time it actually got past the splash screen and went to a full black screen. but yet again:
line 29 character 7: variable is undefined: 'oMap'

Code: [Select]
     oMap = ProjectObj.Maps(Hits(i).getMap())

i think
Title: multiple hits
Post by: durnurd on 2005-11-16, 10:38:44 PM
Code: [Select]

Sub Player_OnPlayInit()
   Dim i, oMap
   Dim oNewSpecial
   Set oNewSpecial = NewSpecialFunction
   for i = 0 to ubound(Hits)
      oMap = ProjectObj.Maps(Hits(i).getMap())
      oNewSpecial.FuncType = 7 ' SPECIAL_EVENT
      oNewSpecial.Name = "COL_" & Hits(i).getSprite()
      oMap.AddSpecial(hostObj.AsObject(oNewSpecial))
   Next
End Sub
Title: multiple hits
Post by: billybob884 on 2005-11-17, 04:57:00 AM
hmmm, thats weird, same line and character...

line 29 character 7: argument not optional.
Title: multiple hits
Post by: bluemonkmn on 2005-11-17, 07:01:10 AM
There needs to be a "Set" on the same line before the "oMap ="...
Set oMap = [...]
Title: multiple hits
Post by: billybob on 2005-11-17, 09:16:08 AM
like this?

Set oMap = ProjectObj.Maps(Hits(i).getMap())
Title: multiple hits
Post by: billybob884 on 2005-11-17, 12:56:50 PM
line 39 char 4: variable undefined: 'spr'

so i added it to the end of the line looking like this
   dim i, layer, idx,

(after Sub Player_OnSpecialFunction(SpecialObj) )

and it gave me this

line 40 char 4: variable undefined: 'special'

so i added special, then it gave me

line 40 char 4: object required: 'special'

and idk where to go from there. let me know if what i did so far was wrong
Title: multiple hits
Post by: bluemonkmn on 2005-11-17, 06:37:09 PM
Don't add a Dim for Special.  Change it to SpecialObj to match the parameter name of the function.
Title: multiple hits
Post by: billybob884 on 2005-11-17, 08:34:09 PM
line 37 char 28: name redefined

Code: [Select]
  dim i, layer, idx, spr, SpecialObj

char 28 is the S, so i guess SpecialObj is wrong..?
Title: multiple hits
Post by: durnurd on 2005-11-17, 09:04:17 PM
Get rid of the "SpecialObj" on the Dim line and change where it says "Special.Name" to "SpecialObj.Name"
Title: multiple hits
Post by: billybob884 on 2005-11-17, 10:00:58 PM
hey! allright! i got into the game and can play wihtout any errors! ok, now, i know i need ot have special functions set up a certain way, so how should they go?

i think it was a colision for attack and the enemy activates a function that 'raises an event' but i'm not sure what (if anything) else. i've got tomorrow off from work, so ill have a good bit of the day to mess around with this.
Title: multiple hits
Post by: durnurd on 2005-11-18, 08:04:38 AM
You don't need to set up any special functions.  The script creates them at runtime.  All you need is a collision between the enemy class and a weapon class that activates COL_<ADef>* (if A is the enemy) or COL_<BDef>* (if class B is the enemy)
Title: multiple hits
Post by: billybob884 on 2005-11-18, 09:50:29 AM
Nice. I'll give it a shot when I get home in a few hours. (hooray for 7th study hall!)
Title: multiple hits
Post by: billybob884 on 2005-11-18, 01:32:06 PM
hmmm, maybe im doing something wrong in the colision.. because its not removing either of the MJ's..
i've got this colision set up:
Code: [Select]
SpriteA: Attack
SpriteB: EnemyMJ   (EnemyOthr is the class for other enemies)
Terminate A
Activate: COL_<BDef>*


I tried unchecking the 'Terminate A', but that didn't change anything.

since hte script has been changed several dozen times, and I may have made a mistake along the way, here it is for reference:

Code: [Select]
Option Explicit

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Default Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   public function getMap()
      getMap = hMap
   End function
   public function getSprite()
      getSprite = hSpriteName
   End function
   public function getHPs()
      getHPs = hHPs
   end function
End Class

Sub Player_OnPlayInit()
   Dim i, oMap
   Dim oNewSpecial
   Set oNewSpecial = NewSpecialFunction
   for i = 0 to ubound(Hits)
      Set oMap = ProjectObj.Maps(Hits(i).getMap())
      oNewSpecial.FuncType = 7 ' SPECIAL_EVENT
      oNewSpecial.Name = "COL_" & Hits(i).getSprite()
      oMap.AddSpecial(hostObj.AsObject(oNewSpecial))
   Next
End Sub

Sub Player_OnSpecialFunction(SpecialObj)
   dim i, layer, idx, spr
   for i = 0 to UBound(Hits)
   spr = Hits(i).getSprite()
   if left(SpecialObj.Name,4 + len(spr)) = "COL_" & spr then
      spr = FindSpriteByDef(spr,layer,idx)
      if spr.UserData > Hits(i).getHPs() or spr.UserData < 0 then spr.UserData = 0
      spr.UserData = spr.UserData + 1
      if spr.UserData = Hits(i).getHPs() then
         layer.RemoveSprite(idx)
      end if
   end if
next
End Sub

Function FindSpriteByDef(SpriteName, byref oLayer, byref oSprIndex)
   dim i, j
   oMap = ProjectObj.GamePlayer.rMap
   for i = 0 to rMap.LayerCount
      for j = 0 to rMap.MapLayer(i).SpriteCount()
         if rMap.MapLayer(i).Sprite(j).SpriteDef.Name = SpriteName then
            set oLayer = rMap.MapLayer(i)
            oSprIndex = j
            set FindSpriteByDef = oLayer.Sprite(j)
         end if
      next
   next
End Function

'-----Initialize Sprites-----
Dim Hits(16), i
for i = 0 to 3
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MJW" & i + 1,2
next
for i = 4 to 16
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MS" & i - 3,3
next
'-----End Initialization-----

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16


Let me know if I should post the entire game.
Title: multiple hits
Post by: billybob884 on 2005-11-18, 02:03:57 PM
oh, i just thought of this, it doesnt look like i state the layer name anywhere, is that necessary, or am i just missing it?


---edit---
on a side note, remember how we did hte verticl scrolling level? and how we set the side margines to 0, like the player could go all hte way to the side without getting stopped, untill he hit the "edge" of hte screen? well, my sister was playing through hte game with that script (i have 2 seperate scripts, one wiht hte stuff were working on now, and one with the forced scrolling levels, jump button, ect. from before), and after she beat the vertical scrolling level, its supposed to set the margines back to what they are for a regular player, i dont remember offhand, but hte point is, that level 5-0Moon (the one that has the MJ sprites for the 'work-in-progress' script) is that it doesnt. so i need some little bit saying on map 5-0 moon change the margines back to x,y (whatever they were).
Title: multiple hits
Post by: durnurd on 2005-11-18, 02:55:20 PM
it doesn't matter if Terminate A is checked or not.  I tell you what I'll do though.  I'll whip up a quick project and see if I can debug this all in one go before sending the rest to you.
Title: multiple hits
Post by: durnurd on 2005-11-18, 03:34:56 PM
Okay, this works now on my test project (It gave me shivers when I saw it work :)).  Let me know how it works for you.  (If it works, it could easily be put into the scripting wizard)

Code: [Select]

Option Explicit

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   public function getMap()
      getMap = hMap
   End function

   public function getSprite()
      getSprite = hSpriteName
   End function

   public function getHPs()
      getHPs = hHPs
   end function

End Class

Sub Player_OnPlayInit()
   Dim i, oMap
   Dim oNewSpecial
   for i = 0 to ubound(Hits)
      Set oNewSpecial = NewSpecialFunction
      Set oMap = ProjectObj.Maps(Hits(i).getMap())
      oNewSpecial.FuncType = 7 ' SPECIAL_EVENT
      oNewSpecial.Flags = 8 ' INTFL_RAISEEVENT
      oNewSpecial.Name = "COL_" & Hits(i).getSprite()
      oMap.AddSpecial(hostObj.AsObject(oNewSpecial))
   Next
End Sub

Sub Player_OnSpecialFunction(SpecialObj)
   dim i, layer, idx, spr

   for i = 0 to UBound(Hits)
   spr = Hits(i).getSprite()
   if left(SpecialObj.Name,4 + len(spr)) = "COL_" & spr then
      set spr = FindSpriteByDef(spr,layer,idx)
      if spr.UserData > Hits(i).getHPs() or spr.UserData < 0 then spr.UserData = 0
      spr.UserData = spr.UserData + 1
      if spr.UserData = Hits(i).getHPs() then
         layer.RemoveSprite(idx)
      end if
   end if
next
End Sub

Function FindSpriteByDef(SpriteName, byref oLayer, byref oSprIndex)
   dim i, j, oMap
   With ProjectObj.GamePlayer.rMap
      for i = 0 to .LayerCount - 1
         for j = 0 to .MapLayer(i).SpriteCount() - 1
            if .MapLayer(i).Sprite(j).rDef.Name = SpriteName then
               set oLayer = .MapLayer(i)
               oSprIndex = j
               set FindSpriteByDef = oLayer.Sprite(j)
            end if
         next
      next
   End with
End Function

'-----Initialize Sprites-----
Dim Hits(16), i
for i = 0 to 3
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MJW" & i + 1,2
next
for i = 4 to 16
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MS" & i - 3,3
next
'-----End Initialization-----

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16
Title: multiple hits
Post by: durnurd on 2005-11-18, 04:05:18 PM
And here's another version that doesn't use special functions, but acts directly using onSpritesCollide however this doesn't work as well as it could.  Unfortunately, if "Terminate A" is selected (and class A is the "bullet") then the script can't access the sprite because it's terminated before the script is called.  So you can't check to see what sprite is colliding with the enemy.  So if you uncheck that, it works, but then you have to destroy the sprite in the script (which is unfortunate if you want some sprites to be destroyed but want some sprites to remain, in which case another script class, Weapon, would have to be created)

However, it works fine if you're just using bullets.  Define a collision between a weapon (bullet) class and an enemy class (a and b respectively) and that's all you need.  Don't terminate either sprite, and you don't need to activate any special functions.

Oh, the good thing about this one is that it works for multiple instances of one sprite definition. (You also have to define the name of the weapon sprite at the bottom)

(Oh, and one thing, BlueMonk;  If you ever release another version of SGDK 1.x, or the Scripting documentation, change the description of the MapLayer function of the Map class to reflect the fact that you can pass the name of the layer rather than just the index)

Code: [Select]

Option Explicit

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   public function getMap()
      getMap = hMap
   End function

   public function getSprite()
      getSprite = hSpriteName
   End function

   public function getHPs()
      getHPs = hHPs
   end function

End Class

Sub Player_OnSpritesCollide(Name, ClsASprIdx, ClsBSprIdx, CollDefIdx)
   dim i, spr, sprName, atk
   set spr = ProjectObj.GamePlayer.rMap.MapLayer(Name).Sprite(ClsBSprIdx)
   atk = ProjectObj.GamePlayer.rMap.MapLayer(Name).Sprite(ClsASprIdx).rDef.Name

   for i = 0 to UBound(Weapons)
      if Weapons(i) = atk then exit for
   next

   if i > UBound(Weapons) then exit sub

   for i = 0 to UBound(Hits)
      sprName = Hits(i).getSprite()
      if spr.rDef.Name = sprName then
         ProjectObj.GamePlayer.rMap.MapLayer(Name).RemoveSprite(ClsASprIdx)
         if spr.UserData > Hits(i).getHPs() or spr.UserData < 0 then spr.UserData = 0
         spr.UserData = spr.UserData + 1
         if spr.UserData >= Hits(i).getHPs() then
            ProjectObj.GamePlayer.rMap.MapLayer(Name).RemoveSprite(ClsBSprIdx)
         end if
         exit sub
      end if
   next

End Sub

'-----Initialize Sprites-----
Dim Hits(16), Weapons(1), i
for i = 0 to 3
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MJW" & i + 1,2
next
for i = 4 to 16
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MS" & i - 3,3
next

Weapons(0) = "AttackLeft"
Weapons(1) = "AttackRight"
'-----End Initialization-----

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16
Title: multiple hits
Post by: billybob884 on 2005-11-18, 05:41:28 PM
ok, i used hte first one, and it works great, for the MJW, but the MS is another story, 01-09 dont die when i shoot, nad when i shot 10, it crashed and gave me line 46 on char 7: object required: 'FindSpriteByDef(...)'

i'm thinking its because it's not MS1, but MS01. i would change the 01-09 to 1-9 but i'm not sure if that would create problems with the others, since hteyd both be starting the same, like MS10 would match MS1, you know?

line 46 is
Code: [Select]
     set spr = FindSpriteByDef(spr,layer,idx)


----edit----
ok, renamed the sprites 01-09 to 1-9, so now it gives error to all of them, so at least its checking hte script for them all now instead of just 10-13. i'll just hope there arent any problems between them :-[
Title: multiple hits
Post by: durnurd on 2005-11-18, 09:53:35 PM
Is there anything particularily strange about those sprites?  Like they're on a different layer, or they're scripted sprites, or are they possibly created after the start of the level (though that shouldn't make a difference)?

I don't know what to tell you.  I tried exactly the script I gave you with sprites MJW1, MJW2, MJW3, and MJW4 and MS1 through MS8 (because I didn't spend enough time to create all 13 sprites)

What it seems like is it's not finding the sprite.  Either the sprite is being destroyed somehow before it's supposed to be destroyed (like you told it to destroy in the Sprites collision dialog perhaps?) or it's not finding it for some other reason I can't think of.
Title: multiple hits
Post by: billybob884 on 2005-11-18, 11:25:05 PM
hmmm, its on the main layer.. (same as the MJW's), no colision classes are calling for termination, no special functions are being activated to delete them.., this is very strange. i guess i'll try deleting them and remaking them under a different name...
Title: multiple hits
Post by: billybob884 on 2005-11-18, 11:49:22 PM
Nice!!! It works! I remade all the sprites, new paths, new template name, new instance name, and it works! oh man that was nice to see! all thats left is merging this script with the script i had before (split screen, jump button, & forced scrolling for 2 levels).

Original Script
Code: [Select]
' ======== INITIAL STARTUP SCRIPT (Number 0) =========

Sub Player_OnPlayInit()
HostObj.StartScript=1
End Sub

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16

#Split == Runtime Script (Number 1)

Option Explicit

Dim XOff, YOff
Dim P2OffsetX, P2OffsetY
Dim P2Actions, intSprTwo
Dim ScrollerSprite
ScrollerSprite = -1

Const nSprWidth = 41
Const nSprHeight = 75

Sub Display_KeyDown(KeyCode, Shift)
' E=69, S=83, D=68, F=70
If KeyCode = 69 Then P2Actions = P2Actions Or ACTION_UP
If KeyCode = 83 Then P2Actions = P2Actions Or ACTION_LEFT
If KeyCode = 68 Then P2Actions = P2Actions Or ACTION_DOWN
If KeyCode = 70 Then P2Actions = P2Actions Or ACTION_RIGHT
End Sub

Sub Display_KeyUp(KeyCode, Shift)
If KeyCode = 69 Then P2Actions = P2Actions And Not ACTION_UP
If KeyCode = 83 Then P2Actions = P2Actions And Not ACTION_LEFT
If KeyCode = 68 Then P2Actions = P2Actions And Not ACTION_DOWN
If KeyCode = 70 Then P2Actions = P2Actions And Not ACTION_RIGHT
End Sub

Sub Player_OnAfterMoveSprites()

if ProjectObj.GamePlayer.rMap.Name = "4-2SpaceFlight" and YOff = 0 then YOff = 15003 - ProjectObj.GamePlayer.rMap.ViewHeight 'ProjectObj.GamePlayer.rMap.HeightHeight

  Dim oMap, oPlayer, oLayer, nLyrWid, nLyrHgt, i
  Set oPlayer = ProjectObj.GamePlayer
  Set oMap = oPlayer.rMap


'Two Player Stuff
'If ProjectObj.GamePlayer.rMap.name = "0-4LevelSelect" or ProjectObj.GamePlayer.rMap.name = "map2" or ProjectObj.GamePlayer.rMap.name = "map3" or ProjectObj.GamePlayer.rMap.name = "map4" then

  If ProjectObj.GamePlayer.rMap.name <> "0-4LevelSelect" then
      intSprTwo = -1
oPlayer.ScrollMarginY = 185
  else
Set oLayer = oMap.MapLayer(1)
      If intSprTwo < 0 then
          For i = 0 to oLayer.SpriteCount - 1
              If oLayer.Sprite(i).rDef.Name = "Player2" then intSprTwo = i
          next
      End If
      With oLayer.Sprite(intSprTwo)
oPlayer.ScrollMarginY = 62
           If .ProcessAction(P2Actions) Then
              .CurState = (.CurState Mod (.rDef.Template.StateCount \ 2)) _
                        + .rDef.Template.StateCount \ 2
              .CurFrame = .CurFrame Mod .rDef.StateFrameCount(.CurState)
           Else
              .CurState = (.CurState Mod (.rDef.Template.StateCount \ 2))
           End If

          oMap.ViewTop = 240
          If P2OffsetX + oPlayer.ScrollMarginX > .X Then
              P2OffsetX = .X - oPlayer.ScrollMarginX
          End If
          If P2OffsetX + oMap.ViewWidth - oPlayer.ScrollMarginX < .X + nSprWidth Then
              P2OffsetX = .X - oMap.ViewWidth + oPlayer.ScrollMarginX + nSprWidth
          End If
          If P2OffsetY + oPlayer.ScrollMarginY > .Y Then
              P2OffsetY = .Y - oPlayer.ScrollMarginY
          End If
          If P2OffsetY + oMap.ViewHeight - oPlayer.ScrollMarginY < .Y + nSprHeight Then
              P2OffsetY = .Y - oMap.ViewHeight + oPlayer.ScrollMarginY + nSprHeight
          End If

          If P2OffsetX < 0 Then P2OffsetX = 0
          If P2OffsetY < 0 Then P2OffsetY = 0
           nLyrWid = oLayer.Columns * 32
           nLyrHgt = oLayer.Rows * 32
          If P2OffsetX > nLyrWid - oMap.ViewWidth Then P2OffsetX = nLyrWid - oMap.ViewWidth
          If P2OffsetY > nLyrHgt - oMap.ViewHeight Then P2OffsetY = nLyrHgt - oMap.ViewHeight
          oMap.Draw P2OffsetX, P2OffsetY, False
          oMap.ViewTop = 0
      End With
  End If

'Automatic Scrolling Stuff
  If ProjectObj.GamePlayer.rMap.name = "2-4BonusLevel" then
      XOff = XOff + 1
      With ProjectObj.GamePlayer
          if .PlayerSprite.X <= XOff then
              if .PlayerSprite.DX < 0 then .PlayerSprite.DX = 1
              .PlayerSprite.DX = .PlayerSprite.rDef.Template.MoveSpeed
              if .PlayerSprite.X < XOff - .PlayerSprite.Width / 2 then
                  XOff = 1
              End if
          end if
          .rMap.Draw XOff, YOff
      End With
  End If


If ProjectObj.GamePlayer.rMap.name = "4-2SpaceFlight" then
oPlayer.ScrollMarginX = 5
oPlayer.ScrollMarginY = 5

   If ScrollerSprite < 0 Then
      ScrollerSprite = FindScrollerSprite
   End If

   If ProjectObj.GamePlayer.PlayerSprite.rDef.rLayer.SpriteCount <= ScrollerSprite Then
      ScrollerSprite = FindScrollerSprite
   End If

   If ScrollerSprite >= 0 Then
      If Left(ProjectObj.GamePlayer.PlayerSprite.rDef.rLayer.Sprite(ScrollerSprite).rDef.Name, 8) <> "Scroller" Then
         ScrollerSprite = FindScrollerSprite
      End If
   End If

   With ProjectObj.GamePlayer
      .MapScrollX = .PlayerSprite.rDef.rLayer.Sprite(ScrollerSprite).X
      .MapScrollY = .PlayerSprite.rDef.rLayer.Sprite(ScrollerSprite).Y
      If .PlayerSprite.Y > .MapScrollY + .rMap.ViewHeight - .ScrollMarginY - .PlayerSprite.Height Then
         .PlayerSprite.DY = -.PlayerSprite.rDef.Template.MoveSpeed
      ElseIf .PlayerSprite.Y < .MapScrollY + .ScrollMarginY Then
         .PlayerSprite.DY = .PlayerSprite.rDef.Template.MoveSpeed
      End If

      If .PlayerSprite.X > .MapScrollX + .rMap.ViewWidth - .ScrollMarginX - .PlayerSprite.Width Then
         .PlayerSprite.DX = -.PlayerSprite.rDef.Template.MoveSpeed
      ElseIf .PlayerSprite.X < .MapScrollX + .ScrollMarginX Then
         .PlayerSprite.DX = .PlayerSprite.rDef.Template.MoveSpeed
      End If
   End With

end if

End Sub

Function FindScrollerSprite()
   Dim I
   With ProjectObj.GamePlayer.PlayerSprite.rDef.rLayer
      For I = 0 To .SpriteCount - 1
         If Left(.Sprite(I).rDef.Name, 8) = "Scroller" Then
            FindScrollerSprite = I
            Exit Function
         End If
      Next
   End With
   FindScrollerSprite = -1
End Function

Sub Player_OnControllerMove(OldActions, NewActions)

'Jumping Player
  With ProjectObj.GamePlayer.PlayerSprite
      If (Not OldActions) And NewActions And ACTION_BUTTON2 Then
          If (.rDef.SolidTest(.X, .Y + .Height) Or .rDef.SolidTest(.X + .Width - 1, .Y + .Height)) Or (Not .pRideOnRef Is Nothing) Then
              .DY = - .rDef.Template.JumpHeight
          End If
      End If
  End With

End Sub

intSprTwo = -1
HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.SinkObjectEvents CurrentDisplay, "Display"
HostObj.ConnectEventsNow()


with this

New Script
Code: [Select]
Option Explicit

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   public function getMap()
      getMap = hMap
   End function

   public function getSprite()
      getSprite = hSpriteName
   End function

   public function getHPs()
      getHPs = hHPs
   end function

End Class

Sub Player_OnPlayInit()
   Dim i, oMap
   Dim oNewSpecial
   for i = 0 to ubound(Hits)
      Set oNewSpecial = NewSpecialFunction
      Set oMap = ProjectObj.Maps(Hits(i).getMap())
      oNewSpecial.FuncType = 7 ' SPECIAL_EVENT
      oNewSpecial.Flags = 8 ' INTFL_RAISEEVENT
      oNewSpecial.Name = "COL_" & Hits(i).getSprite()
      oMap.AddSpecial(hostObj.AsObject(oNewSpecial))
   Next
End Sub

Sub Player_OnSpecialFunction(SpecialObj)
   dim i, layer, idx, spr

   for i = 0 to UBound(Hits)
   spr = Hits(i).getSprite()
   if left(SpecialObj.Name,4 + len(spr)) = "COL_" & spr then
      set spr = FindSpriteByDef(spr,layer,idx)
      if spr.UserData > Hits(i).getHPs() or spr.UserData < 0 then spr.UserData = 0
      spr.UserData = spr.UserData + 1
      if spr.UserData = Hits(i).getHPs() then
         layer.RemoveSprite(idx)
      end if
   end if
next
End Sub

Function FindSpriteByDef(SpriteName, byref oLayer, byref oSprIndex)
   dim i, j, oMap
   With ProjectObj.GamePlayer.rMap
      for i = 0 to .LayerCount - 1
         for j = 0 to .MapLayer(i).SpriteCount() - 1
            if .MapLayer(i).Sprite(j).rDef.Name = SpriteName then
               set oLayer = .MapLayer(i)
               oSprIndex = j
               set FindSpriteByDef = oLayer.Sprite(j)
            end if
         next
      next
   End with
End Function

'-----Initialize Sprites-----
Dim Hits(16), i
for i = 0 to 3
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MJW" & i + 1,2
next
for i = 4 to 16
   set Hits(i) = new Hit
   Hits(i).Hit "5-0TheMoon","MJS" & i - 3,3
next
'-----End Initialization-----

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16
Title: multiple hits
Post by: durnurd on 2005-11-19, 10:32:23 AM
I don't know why the code is split into two parts where the first part does nothing, but this may or may not work (depending on if Player_OnPlayInit() is called in the second script or only the first one.

Code: [Select]
' ======== INITIAL STARTUP SCRIPT (Number 0) =========

Sub Player_OnPlayInit()
   HostObj.StartScript = 1
End Sub

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16

#Split == Runtime Script (Number 1)

Option Explicit

Dim XOff, YOff
Dim P2OffsetX, P2OffsetY
Dim P2Actions, intSprTwo
Dim ScrollerSprite
Dim Hits(16), i
ScrollerSprite = -1
intSprTwo = -1

For i = 0 To 3
   Set Hits(i) = New Hit
   Hits(i).Hit "5-0TheMoon", "MJW" & i + 1, 2
Next
For i = 4 To 16
   Set Hits(i) = New Hit
   Hits(i).Hit "5-0TheMoon", "MJS" & i - 3, 3
Next

Const nSprWidth = 41
Const nSprHeight = 75

Sub Player_OnPlayInit()
   Dim i, oMap
   Dim oNewSpecial
   For i = 0 To UBound(Hits)
      Set oNewSpecial = NewSpecialFunction
      Set oMap = ProjectObj.Maps(Hits(i).getMap())
      oNewSpecial.FuncType = 7 ' SPECIAL_EVENT
      oNewSpecial.Flags = 8 ' INTFL_RAISEEVENT
      oNewSpecial.Name = "COL_" & Hits(i).getSprite()
      oMap.AddSpecial (HostObj.AsObject(oNewSpecial))
   Next
End Sub

Sub Display_KeyDown(KeyCode, Shift)
' E=69, S=83, D=68, F=70
If KeyCode = 69 Then P2Actions = P2Actions Or ACTION_UP
If KeyCode = 83 Then P2Actions = P2Actions Or ACTION_LEFT
If KeyCode = 68 Then P2Actions = P2Actions Or ACTION_DOWN
If KeyCode = 70 Then P2Actions = P2Actions Or ACTION_RIGHT
End Sub

Sub Display_KeyUp(KeyCode, Shift)
If KeyCode = 69 Then P2Actions = P2Actions And Not ACTION_UP
If KeyCode = 83 Then P2Actions = P2Actions And Not ACTION_LEFT
If KeyCode = 68 Then P2Actions = P2Actions And Not ACTION_DOWN
If KeyCode = 70 Then P2Actions = P2Actions And Not ACTION_RIGHT
End Sub

Sub Player_OnAfterMoveSprites()

    If ProjectObj.GamePlayer.rMap.Name = "4-2SpaceFlight" And YOff = 0 Then
        YOff = 15003 - ProjectObj.GamePlayer.rMap.ViewHeight
    End If

    Dim oMap, oPlayer, oLayer, nLyrWid, nLyrHgt, i
    Set oPlayer = ProjectObj.GamePlayer
    Set oMap = oPlayer.rMap

'Two Player Stuff

    If ProjectObj.GamePlayer.rMap.Name <> "0-4LevelSelect" Then
        intSprTwo = -1
        oPlayer.ScrollMarginY = 185
    Else
        Set oLayer = oMap.MapLayer(1)
        If intSprTwo < 0 Then
            For i = 0 To oLayer.SpriteCount - 1
                If oLayer.Sprite(i).rDef.Name = "Player2" Then intSprTwo = i
            Next
        End If
        With oLayer.Sprite(intSprTwo)
            oPlayer.ScrollMarginY = 62
            If .ProcessAction(P2Actions) Then
                .CurState = (.CurState Mod (.rDef.Template.StateCount \ 2)) _
                            + .rDef.Template.StateCount \ 2
                .CurFrame = .CurFrame Mod .rDef.StateFrameCount(.CurState)
            Else
                .CurState = (.CurState Mod (.rDef.Template.StateCount \ 2))
            End If
            oMap.ViewTop = 240
            If P2OffsetX + oPlayer.ScrollMarginX > .X Then
                P2OffsetX = .X - oPlayer.ScrollMarginX
            End If
            If P2OffsetX + oMap.ViewWidth - oPlayer.ScrollMarginX < .X + nSprWidth Then
                P2OffsetX = .X - oMap.ViewWidth + oPlayer.ScrollMarginX + nSprWidth
            End If
            If P2OffsetY + oPlayer.ScrollMarginY > .Y Then
                P2OffsetY = .Y - oPlayer.ScrollMarginY
            End If
            If P2OffsetY + oMap.ViewHeight - oPlayer.ScrollMarginY < .Y + nSprHeight Then
                P2OffsetY = .Y - oMap.ViewHeight + oPlayer.ScrollMarginY + nSprHeight
            End If
            If P2OffsetX < 0 Then P2OffsetX = 0
            If P2OffsetY < 0 Then P2OffsetY = 0
            nLyrWid = oLayer.Columns * 32
            nLyrHgt = oLayer.Rows * 32
            If P2OffsetX > nLyrWid - oMap.ViewWidth Then P2OffsetX = nLyrWid - oMap.ViewWidth
            If P2OffsetY > nLyrHgt - oMap.ViewHeight Then P2OffsetY = nLyrHgt - oMap.ViewHeight
            oMap.Draw P2OffsetX, P2OffsetY, False
            oMap.ViewTop = 0
        End With
    End If

'Automatic Scrolling Stuff
    If ProjectObj.GamePlayer.rMap.Name = "2-4BonusLevel" Then
        XOff = XOff + 1
        With ProjectObj.GamePlayer
            If .PlayerSprite.X <= XOff Then
                If .PlayerSprite.DX < 0 Then .PlayerSprite.DX = 1
                .PlayerSprite.DX = .PlayerSprite.rDef.Template.MoveSpeed
                If .PlayerSprite.X < XOff - .PlayerSprite.Width / 2 Then
                    XOff = 1
                End If
            End If
            .rMap.Draw XOff, YOff
        End With
    End If

   
    If ProjectObj.GamePlayer.rMap.Name = "4-2SpaceFlight" Then
        oPlayer.ScrollMarginX = 5
        oPlayer.ScrollMarginY = 5
        If ScrollerSprite < 0 Then
            ScrollerSprite = FindScrollerSprite
        End If
       
        If ProjectObj.GamePlayer.PlayerSprite.rDef.rLayer.SpriteCount <= ScrollerSprite Then
            ScrollerSprite = FindScrollerSprite
        End If
   
        If ScrollerSprite >= 0 Then
            If Left(ProjectObj.GamePlayer.PlayerSprite.rDef.rLayer.Sprite(ScrollerSprite).rDef.Name, 8) <> "Scroller" Then
                ScrollerSprite = FindScrollerSprite
            End If
        End If
   
        With ProjectObj.GamePlayer
            .MapScrollX = .PlayerSprite.rDef.rLayer.Sprite(ScrollerSprite).X
            .MapScrollY = .PlayerSprite.rDef.rLayer.Sprite(ScrollerSprite).Y
            If .PlayerSprite.Y > .MapScrollY + .rMap.ViewHeight - .ScrollMarginY - .PlayerSprite.Height Then
                .PlayerSprite.DY = -.PlayerSprite.rDef.Template.MoveSpeed
            ElseIf .PlayerSprite.Y < .MapScrollY + .ScrollMarginY Then
                .PlayerSprite.DY = .PlayerSprite.rDef.Template.MoveSpeed
            End If
            If .PlayerSprite.X > .MapScrollX + .rMap.ViewWidth - .ScrollMarginX - .PlayerSprite.Width Then
                .PlayerSprite.DX = -.PlayerSprite.rDef.Template.MoveSpeed
            ElseIf .PlayerSprite.X < .MapScrollX + .ScrollMarginX Then
                .PlayerSprite.DX = .PlayerSprite.rDef.Template.MoveSpeed
            End If
        End With
    End If
End Sub

Function FindScrollerSprite()
   Dim i
   With ProjectObj.GamePlayer.PlayerSprite.rDef.rLayer
      For i = 0 To .SpriteCount - 1
         If Left(.Sprite(i).rDef.Name, 8) = "Scroller" Then
            FindScrollerSprite = i
            Exit Function
         End If
      Next
   End With
   FindScrollerSprite = -1
End Function

Sub Player_OnControllerMove(OldActions, NewActions)

'Jumping Player
  With ProjectObj.GamePlayer.PlayerSprite
      If (Not OldActions) And NewActions And ACTION_BUTTON2 Then
          If (.rDef.SolidTest(.X, .Y + .Height) Or .rDef.SolidTest(.X + .Width - 1, .Y + .Height)) Or (Not .pRideOnRef Is Nothing) Then
              .DY = -.rDef.Template.JumpHeight
          End If
      End If
  End With
End Sub

Class Hit
   Private hMap
   Private hSpriteName
   Private hHPs
   Public Sub Hit(Map, SpriteName, HPs)
      hMap = Map
      hSpriteName = SpriteName
      hHPs = HPs
   End Sub

   Public Function getMap()
      getMap = hMap
   End Function

   Public Function getSprite()
      getSprite = hSpriteName
   End Function

   Public Function getHPs()
      getHPs = hHPs
   End Function

End Class

Sub Player_OnSpecialFunction(SpecialObj)
   Dim i, layer, idx, spr

   For i = 0 To UBound(Hits)
   spr = Hits(i).getSprite()
   If Left(SpecialObj.Name, 4 + Len(spr)) = "COL_" & spr Then
      Set spr = FindSpriteByDef(spr, layer, idx)
      If spr.UserData > Hits(i).getHPs() Or spr.UserData < 0 Then spr.UserData = 0
      spr.UserData = spr.UserData + 1
      If spr.UserData = Hits(i).getHPs() Then
         layer.RemoveSprite (idx)
      End If
   End If
Next
End Sub

Function FindSpriteByDef(SpriteName, ByRef oLayer, ByRef oSprIndex)
   Dim i, j, oMap
   With ProjectObj.GamePlayer.rMap
      For i = 0 To .LayerCount - 1
         For j = 0 To .MapLayer(i).SpriteCount() - 1
            If .MapLayer(i).Sprite(j).rDef.Name = SpriteName Then
               Set oLayer = .MapLayer(i)
               oSprIndex = j
               Set FindSpriteByDef = oLayer.Sprite(j)
            End If
         Next
      Next
   End With
End Function

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16

Title: multiple hits
Post by: bluemonkmn on 2005-11-19, 10:46:08 AM
The script is split into 2 parts because the Display events cannot be connected until after OnPlayInit has been called.
Title: multiple hits
Post by: billybob884 on 2005-11-19, 10:25:15 PM
mmm, it goes to the splash screen,. then goes to a full black screen, then doesnt do anything, so i tried alt+tab'ing it and it gave me the "method ~ of object ~ failed" message, and then: "error playing map: object variable or with blick variable not set" continuously untill i ctrl alt delete it
Title: multiple hits
Post by: billybob884 on 2005-11-20, 12:24:37 AM
..., wasn't this in teh general discusion? or am i just going crazy again...? (which is very likely ;) )
Title: multiple hits
Post by: bluemonkmn on 2005-11-20, 08:13:44 AM
Yes.  I moved it for obvious reasons :).  You can still see the original topic marked as "Moved" in General Discussion.
Title: multiple hits
Post by: billybob884 on 2005-11-20, 09:25:08 AM
I got it to work, but it
Title: multiple hits
Post by: billybob884 on 2005-11-21, 05:43:13 PM
I'll post 2 rar'ed versions later tonight, one wiht all files (approx 26mb compressed) and one with all but large sounds/videos (approx 8mb compressed)
Title: multiple hits
Post by: billybob884 on 2005-11-21, 07:34:43 PM
http://www.angelfire.com/ct3/billybob884/ChameleonMan_TRIMMED.rar

Open part 01 with winrar and itll put all three parts together (you probably already know all this)
http://h1.ripway.com/billybob884/ChameleonMan_FULL.part01.rar
http://h1.ripway.com/billybob884/ChameleonMan_FULL.part02.rar
http://h1.ripway.com/billybob884/ChameleonMan_FULL.part03.rar

[LINKS UNTESTED], also, give hte full one another hour to finish uploading, part 1 is done, and part 2 is like 1/2 way.

I think you can guess which is which (;))

-------------------

ok, all of them are uploaded, and they all work
Title: multiple hits
Post by: bluemonkmn on 2005-11-22, 07:13:10 AM
I spent most of my time this morning just modifying the project yet again to not depend on the missing media clips so I could try to run it.  Finally I got as far as realizing that commenting out the OnPlayerInit handler in the second block of code makes the project start up at least.  I guess something that it is doing is interfering with the normal operation of the game?  Maybe I'll have more time to look into it later.
Title: multiple hits
Post by: billybob884 on 2005-11-22, 01:46:26 PM
heh yea, im sorry about that, i cut out hte files but it completely slipped my mind to put in small "blank" ones. i had to cut out like 20 or so files b/c a lot of them were really big, and for whatever reason, audio and video don't compress well in a zip/rar file. yea, i tried commenting out that little section, and it runs at normal speed, but the nothing scripted owrks (either forced scrolling, hit points, i didn't try the jump button, but prob doesn't..). if you noticed, there are 3 "script" files in there, the new 1 that has the attempt at both merged together, and both the other 2 split (old = forced scroll, jump, 2 player; new = hit points)
Title: multiple hits
Post by: bluemonkmn on 2005-11-23, 06:16:02 AM
OK, simple problem (or at least simple to fix, not sure how simple the explanation is).  The block at the end of the script is incorrect.  It needs the line to connect the display events and it shouldn't have the "Play" line.  The end of the script should look like this:
Code: [Select]
HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.SinkObjectEvents CurrentDisplay, "Display"
HostObj.ConnectEventsNow()
Title: multiple hits
Post by: billybob884 on 2005-11-23, 07:57:56 AM
hmmm.. ok, thios fixes the slowness, and everything works except the multiple hit enemies, it doesnt crash when you hit them, but it doesn't kill them either
Title: multiple hits
Post by: bluemonkmn on 2005-11-23, 11:05:08 PM
There's a couple things you need to fix.  Mainly you need to remove the "Sub Player_OnPlayInit()" and "End Sub" lines from the second block of code because the code inside it will never execute since gameplay has already initiated (leave it there in the first block though).  Taking the code out of the sub will force it to execute when the second script starts, which is good enough.  You will also need to remove "i" from the Dim list of that code because i is already declared as a global variable in the second script block.

This will allow the collision code to start checking things, but now you will get errors because you have multiple sprites that begin with MJS1 (you have MJS1, MJS10, MJS11, MJS12 etc).  Is there any way you could rename your sprites to names like MJS01, MJS02 ... MJS10 MJS11 etc?  Then I think we could make this whle thing work better.
Title: multiple hits
Post by: billybob884 on 2005-11-24, 12:18:18 AM
All right!!! Everything works! ...except for killing MJS01-09, 10 and later work fine though. I tried doing just 1-9, and it didn
Title: multiple hits
Post by: durnurd on 2005-11-24, 12:32:47 AM
It would be easy to change, though I'm curious as to what's happening with that.  The names of the sprites should certainly be MSJ1 and not MSJ01 for the single-digit sprites....
Title: multiple hits
Post by: bluemonkmn on 2005-11-24, 08:20:00 AM
Oh, I forgot, when you change the sprite names to MJS01 - MJS09, you will also have to change the script that defines their hit points because it is still expecting them to be names MJS1 - MJS9.  I got it to work by changing the block of code that sets up their hit points to this:
Code: [Select]
For i = 0 To 3
   Set Hits(i) = New Hit
   Hits(i).Hit "5-0TheMoon", "MJW" & mid(cstr(i + 101), 2), 2
Next
For i = 4 To 16
   Set Hits(i) = New Hit
   Hits(i).Hit "5-0TheMoon", "MJS" & mid(cstr(i + 97), 2), 3
Next
Title: multiple hits
Post by: billybob884 on 2005-11-24, 09:49:14 AM
I only took the new Hits(i)... line for MJS because the other one stopped the MJW from working (maybe because i didn
Title: multiple hits
Post by: bluemonkmn on 2005-11-24, 10:47:28 AM
I think you just need to add a block like this to the end of you OnAfterMoveSprites sub to reset the scrolling margins for the moon:
Code: [Select]
   If ProjectObj.GamePlayer.rMap.Name = "5-0TheMoon" Then
        oPlayer.ScrollMarginX = 292
        oPlayer.ScrollMarginY = 196
    End If

I haven't noticed any slowdown in areas like you describe.  But I can imagine why it might be happening.  When you are on an area of the map like that, you have the screen full of tiles and at some point GameDev might be drawing so many tiles that it can't finish within a single frame on slower computers.  Here are some things to try:
1. Try eliminating unnecessary tiles in background layers behind those areas (tiles covered up by foreground layers)
2. Make sure you have the latest drivers for your video card, and the latest version of DirectX.
3. Try running on a faster computer, just to get an idea of what kind of computer increases the performance to the level you want/need.
4. Try running without script.  If the game runs faster in these areas when the script is not connected we could try optimizing the script to improve performance.
Title: multiple hits
Post by: billybob884 on 2005-11-25, 10:14:53 AM
Yea, I took the "mid-background" tiles off of that layer and merged then with the main layer, so I could delete that layer. It helped a little, but it