Author Topic: Mouse Aiming/sthooting  (Read 17203 times)

ragingmime

  • Visitor
  • *
  • Posts: 11
    • View Profile
Mouse Aiming/sthooting
« on: 2006-02-05, 03:48:40 PM »
I've set up the wizard-based shooting script in my game, and I'm trying to find a way to use it to let the player aim and shoot with the mouse, a la Abuse.

I've been trying to use the mouse input sample script to make crosshairs that the player can move with the mouse, but the script doesn't work. I get the error "Object Variable or With Block variable not set" when I include this line:
HostObj.SinkObjectEvents CurrentDisplay, "Display"
What's going on? Here's the rest of the script:

Sub CurrentDisplay_MouseMove(Button, Shift, X, Y)
With ProjectObj.GamePlayer
ProjectObj.GamePlayer.rMap.SpriteDefs("aim").X = X + .MapScrollX - .rMap.ViewLeft
ProjectObj.GamePlayer.rMap.SpriteDefs("aim").Y = Y + .MapScrollY - .rMap.ViewTop
End With
End Sub


Also, I don't understand the point of the initialization script area of this sample. It has a connecteventsnow line when there's already a connecteventsnow line in the runtime script. Is this sample from an older version of the game maker? Am I missing something there?

Thanks in advance.

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Mouse Aiming/sthooting
« Reply #1 on: 2006-02-06, 06:57:53 AM »
Yes, the key point you are missing is that the display object does not exist until the Player_OnPlayInit event occurs.  But ConnectEventsNow cannot execute inside an event because no events can be triggered until ConnectEventsNow has executed.  So to get around this catch-22 I implemented a solution which allows you to put multiple scripts within a single file (you all knew there had to be some reason behind this right?  Here it is!)  Multiple scripts are separated by a line that starts with "#Split" and you can transfer control from one script to another using the HostObj.StartScript property.  When StartScript is set, GameDev will transfer contron to another script at its next opportunity, clearing out everything it knows about the old script and transferring only the data that you store into the HostObj.TempStorage property (and other GameDev object properties -- but no variables, functions or events are retained).

So this is how you can connect different event handlers at different times.  The first script's main purpose is to wait until the OnPlayInit event occurs before attempting to attach to the display's events.  When OnPlayInit occurs, it transfers control to the other (main) script which hooks up event handlers to the Display object.

Is that enough to help you figure out the problem you are having?

ragingmime

  • Visitor
  • *
  • Posts: 11
    • View Profile
Re: Mouse Aiming/sthooting
« Reply #2 on: 2006-02-06, 03:50:06 PM »
Thanks! Yep, that does help: now I'm not getting any error messages when I start the game.

The crosshairs sprite (called "aim," using the template "aimtemp" and on the path "aimpath") still isn't moving, though. I've made sure that it's set as an initial instance, that the control is set to "simple (scripted)", that its movement speed is at the maximum (although I'm not sure that matters), etc. The crosshairs sprite appears when the script isn't running, but it of course doesnt' move. When the game is run with the script, the crosshairs sprite still appears but it also doesn't move when I move the mouse. The code right now is:


#Split == Runtime script (Number 1) ============
'Modified by ragingmime

Sub CurrentDisplay_MouseMove(Button, Shift, X, Y)
With ProjectObj.GamePlayer.rMap
.Sprite("aim").X = X + .MapScrollX - .rMap.ViewLeft
.Sprite("aim").Y = Y + .MapScrollY - .rMap.ViewTop
End With
End Sub
                   
HostObj.SinkObjectEvents CurrentDisplay, "Display"
HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()


Can you see anything else that I'm doing wrong?

Thanks a lot!
« Last Edit: 2006-02-06, 03:58:23 PM by ragingmime »

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Mouse Aiming/sthooting
« Reply #3 on: 2006-02-06, 04:20:27 PM »
I think that sub called "CurrentDisplay_MouseMove" should be "Display_MouseMove" though I'm not entirely sure.  If that doesn't work, try putting in a line that you know will have an effect (like "x = x / 0") inside that event.  If it crashes, you know the problem is that the sprite is not displaying after it's moved.  Otherwise, if it doesn't crash, then you know that the problem is that the event is never being called (because of the name of the sub)
Edward Dassmesser

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Mouse Aiming/sthooting
« Reply #4 on: 2006-02-07, 07:10:24 AM »
Yes, durnurd has it right.  Let me briefly explain the parameters of "SinkObjectEvents".  The first parameter is an object that will raise events.  The second parameter determines by what name the object's events will be handled.  So when you provide "Display" as the second parameter, that means that every event handler that handles an event coming from CurrentDisplay should start with "Display_".

ragingmime

  • Visitor
  • *
  • Posts: 11
    • View Profile
Re: Mouse Aiming/sthooting
« Reply #5 on: 2006-02-07, 01:52:21 PM »
Thanks; that was probably part of the problem. It seems like the event still isn't being triggered, though, because I can put all kinds of garbage in Display_MouseMove and never get an error:
Code: [Select]

' ===== Initialization Script (Number 0) =======
Sub Player_OnPlayInit()
HostObj.StartScript=1
HostObj.StartScript=2
End Sub

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

#Split == Runtime script (Number 1) ============
'Modified by ragingmime

Sub Display_MouseMove(Button, Shift, X, Y)
With ProjectObj.GamePlayer.rMap
sdfsddsfsa
.Sprite("aim").X = X + .MapScrollX - .rMap.ViewLeft
.Sprite("aim").X = X /0
.Sprite("aim").Y = Y + .MapScrollY - .rMap.ViewTop
End With
End Sub
                   
HostObj.SinkObjectEvents CurrentDisplay, "Display"
HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()

Script number 2 is a shooting script, which runs fine.

Do you see anything else I might be doing wrong? Thanks for all your great help.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Mouse Aiming/sthooting
« Reply #6 on: 2006-02-07, 03:36:42 PM »
As far as I'm aware, only one script can be active at a time.  You need to put them together in one script.  Just copy

Code: [Select]
Sub Display_MouseMove(Button, Shift, X, Y)
With ProjectObj.GamePlayer.rMap
sdfsddsfsa
.Sprite("aim").X = X + .MapScrollX - .rMap.ViewLeft
.Sprite("aim").X = X /0
.Sprite("aim").Y = Y + .MapScrollY - .rMap.ViewTop
End With
End Sub
                   
HostObj.SinkObjectEvents CurrentDisplay, "Display"

into the other script and get rid of the one you copied it from.
Edward Dassmesser

ragingmime

  • Visitor
  • *
  • Posts: 11
    • View Profile
Re: Mouse Aiming/sthooting
« Reply #7 on: 2006-02-07, 06:36:31 PM »
Okay, I did that and I got the proper error messages. Now, I'm getting another error message and I think the problem is in how I'm referring to the sprites. I guess the sprite is owned by the layer within the map, not by the map as I have it.

The code right now is:

Code: [Select]
#Split == Runtime script (Number 1) ============

Sub Display_MouseMove(Button, Shift, X, Y)
With ProjectObj.GamePlayer
.rMap.Sprite("aim").X = X + .MapScrollX - .rMap.ViewLeft
.rMap.Sprite("aim").Y = Y + .MapScrollY - .rMap.ViewTop
End With
End Sub

But apparently Sprite is owned by Layer. Layer isn't owned by rMap, becuase using .rMap.rLayer.Sprite gives me an error, as does PlayerSprite.rDef.rLayer.Sprite. I've read the reference, but apparently I'm just not understanding something.

Thanks for all your help; I really appreciate it.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Mouse Aiming/sthooting
« Reply #8 on: 2006-02-07, 10:23:49 PM »
First of all, there is no rLayer attribute of the Map object.  You need to find the layer by giving its index.  Second of all, there is no Sprite property of a map (only of a layer) and if you're going to use it, you have to use the index.

Code: [Select]
With ProjectObj.GamePlayer.rMap.MapLayer(0).SpriteDefs(1)
   .X = X + .MapScrollX - .rMap.ViewLeft
   .Y = Y + .MapScrollY - .rMap.ViewTop
End With

where 0 is the map layer counting from the top down in the list where the sprite is, starting at 0.  and 1 is the index of the Sprite you are using.
« Last Edit: 2006-02-07, 10:27:02 PM by durnurd »
Edward Dassmesser

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Mouse Aiming/sthooting
« Reply #9 on: 2006-02-07, 10:28:19 PM »
And I may actually be wrong about requiring the index instead of the name for either the layer or the sprite or both (I seem to remember something about that maybe) but that's the way it is in the refference, which is by no means perfect.
Edward Dassmesser

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Mouse Aiming/sthooting
« Reply #10 on: 2006-02-07, 10:55:33 PM »
Well, the scripting reference should be correct at least as far as data types go since it is generated from the source code.  It is correct at least with respect to this.  When you refer to a layer using Map.MapLayer you can pass a name or a number, as indicated by the "Variant" parameter type (even though the parameter's name is "Index" -- I would describe it as having "named indexes").  And when you refer to a sprite on a layer, you will see that that can only take an integer, which means you can't refer to sprites by name.  The reason is sprites don't have names.  Sprite Definitions have names, but you can have multiple sprite instances based on the same definition, so all sprite instances are just referred to by index.  Generally you will only have one instance per definition, so often times it works to loop through the collection of sprites and search for a sprite index whose definition name matches a particular value.  But when you refer to the Sprites property on a layer, you will have to use numeric indexes.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Mouse Aiming/sthooting
« Reply #11 on: 2006-02-08, 08:36:51 AM »
Ah yes.  The refference says that MapLayer gets the map by its ordinal index, but says nothing about its name (but then the example had variant as data type, so there you go)
Edward Dassmesser

ragingmime

  • Visitor
  • *
  • Posts: 11
    • View Profile
Re: Mouse Aiming/sthooting
« Reply #12 on: 2006-02-08, 12:49:28 PM »
Are sprite definitions the same thing as templates? I thought that, at least within the GameDev editor, both sprite templates and specific sprites are named. Are sprites within the editor technically sprite definitions (because you could create multiple sprites with script?) If that's the case, could I refer to the sprite definition by name and then refer to index 0 of that sprite defintion to get the sprite that I see in the editor? How would I do that?

If I'm controlling a sprite with script, do I have to make an instance of the sprite within the script? If I want to get at a sprite that's already there (i.e. initial instance is checked and it exists in the game even without the script running), how do I reference it/figure out its index? (I only see a field for the name in the GameDev editor). Would it be considered a sprite definition, a sprite, or something else?

Sorry to be a pain about this, it's just that this object hierarchy is a little confusing. You guys have been really helpful - thanks again!

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Mouse Aiming/sthooting
« Reply #13 on: 2006-02-08, 12:59:50 PM »
Sprite templates define how a sprite works.  Sprite definitions define the specific location and existance of a sprite, and then you can use special functions to instantiate those sprite definitions as sprites.  The index of a given sprite is equal to number of sprites created before it during the course of playing a level.  This includes those created by checking the "initial instance" flag of a definition, or through special functions or script (or any way possible to create sprites).

You can't access an index of a specific sprite definition.  So if you create five "enemy" sprites, you can't say SpriteDefs("enemy").sprite(0) to access the first "enemy" sprite created.  You have to count how many sprites were created before it, and add that to the index you want.
Edward Dassmesser

ragingmime

  • Visitor
  • *
  • Posts: 11
    • View Profile
Re: Mouse Aiming/sthooting
« Reply #14 on: 2006-02-08, 04:00:16 PM »
Okay, I get it. Thanks!

The crosshairs now move with the mouse with this code:
Code: [Select]
Sub Display_MouseMove(Button, Shift, X, Y)
With ProjectObj.GamePlayer
.rMap.MapLayer(0).Sprite(14).X = X + .MapScrollX - .rMap.ViewLeft
.rMap.MapLayer(0).Sprite(14).Y = Y + .MapScrollY - .rMap.ViewTop
End With
End Sub
                   
HostObj.SinkObjectEvents CurrentDisplay, "Display"
HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()

The problem I'm running into now is that when I kill an enemy, the index of my crosshairs sprite changes (there's one less sprite, so it becomes #13 instead of #14) and "I get a subscript out of range." Is there any way to find the index of a given sprite and plug that in instead of hard-coding the number? I poked around in the documentation and found a way of doing the reverse - i.e. getting the sprite definition's name if you have the index - but that doesn't help me, becasue the index is variable while the name is (I assume) static.

Any suggestions? Thanks a lot... you guys are amazingly helpful!