Scrolling Game Development Kit Forum
SGDK Version 1 => Script => Topic started 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)?
-
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.
-
...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
-
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.
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
-
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
-
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).
-
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?
-
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).
-
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
-
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
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).
-
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
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
-
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?
-
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:
ProjectObj.GamePlayer.rMap.MapLayer(Name).Sprite(ClsASprIdx).rDef.Name
-
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.
-
no explosion or anything;
The explosions aren't that bad, I can just set up a second colision definition to create the explosion
-
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...
-
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.
-
ok, ill give the script u posted a shot once i get home today.
-
ok, using durnurds script, it brings up the error:
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
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.
-
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.
-
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
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
-
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
-
line 71 character 12: expected end of statement
i believe its the line
Hits(i) "5-0TheMoon","MJW" & i + 1,2
-
Well, now I'm stumped. BlueMonk, any ideas? How do classes work in VBScript? Any idea?
-
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 ;)
-
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:
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
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
-
"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.
-
also, i just put the first section in to replace
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
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
-
Here's the correct thing to have
'-----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...
-
close, but no cigar. line 68, char 25: expected end of statement
i think its
set newHit = new Hit "5-0TheMoon","MJW" & i + 1,2
-
Oops, I got that backwards.
'-----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-----
-
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'
oMap = ProjectObj.Maps(Hits(i).getMap())
i think
-
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
-
hmmm, thats weird, same line and character...
line 29 character 7: argument not optional.
-
There needs to be a "Set" on the same line before the "oMap ="...
Set oMap = [...]
-
like this?
Set oMap = ProjectObj.Maps(Hits(i).getMap())
-
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
-
Don't add a Dim for Special. Change it to SpecialObj to match the parameter name of the function.
-
line 37 char 28: name redefined
dim i, layer, idx, spr, SpecialObj
char 28 is the S, so i guess SpecialObj is wrong..?
-
Get rid of the "SpecialObj" on the Dim line and change where it says "Special.Name" to "SpecialObj.Name"
-
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.
-
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)
-
Nice. I'll give it a shot when I get home in a few hours. (hooray for 7th study hall!)
-
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:
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:
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.
-
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).
-
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.
-
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)
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
-
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)
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
-
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
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 :-[
-
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.
-
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...
-
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
' ======== 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
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
-
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.
' ======== 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
-
The script is split into 2 parts because the Display events cannot be connected until after OnPlayInit has been called.
-
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
-
..., wasn't this in teh general discusion? or am i just going crazy again...? (which is very likely ;) )
-
Yes. I moved it for obvious reasons :). You can still see the original topic marked as "Moved" in General Discussion.
-
I got it to work, but it
-
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)
-
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
-
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.
-
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)
-
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:
HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.SinkObjectEvents CurrentDisplay, "Display"
HostObj.ConnectEventsNow()
-
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
-
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.
-
All right!!! Everything works! ...except for killing MJS01-09, 10 and later work fine though. I tried doing just 1-9, and it didn
-
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....
-
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:
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
-
I only took the new Hits(i)... line for MJS because the other one stopped the MJW from working (maybe because i didn
-
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:
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.
-
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