ID:2152886
 
I'm trying to add some background music to my game, using areas to do so. I use areas and use Entered() to produce the music. It works well, but I'm experiencing some issues.

1. When a player logs in, it isn't detecting the area and is not playing the music because of that. They have to walk off of the /area and back on to it to make the music play. I've tried some stuff like so to get it to work, but to limited success.
var/area/Music = locate(/area/Music) in loc
if(Music)
src<<"good"
Music.Entered(src)
else
src<<"not good"


2. The first time a player enters an area and music begins to play, it freezes their screen for like 0.4-0.8 seconds. It only occurs on the first time that music file is played. After that, you can walk on and off of the area to create the music with no freezes.

One more question, is using sounds in a game something that should generally be avoided? And does the format of a sound file have any effect on performance? Thank you!
#1 You may need to set a location variable and have the variable check the location first.

#2 is causing lag because the player has to download the music resources, that's unavoidable. Once it's downloaded, it wont happen again. (Unless they clear their cache)

#3 I personally use ogg formats, but that's just my preference. 90% of byond users keep their sounds disabled anyways, so it's really up to you.
I see. I'm not sure I entirely understand what you mean with #1, set a location how and where?
Well, it really depends on your game. Side scrollers for example would have a completely different setup than top down view games.

Just a general way to do it would be to save a location variable like "Town 1" for example to the player and upon login, check their location, then call the background music so it verifies where the player is and which music to play. The location itself would be a mob/var just to clarify.
Alright, I'll try to figure it out. Thank you for the help!
Not a problem. If you need more help, either reply here or page me. I'll do what I can. Music based on locations can be a pain in the ass sometimes.
Yeah. It was either use /area and Entered(), or make a long if-else nest using x,y,z and returning the music file that way. The /area way seemed easier. Just got to figure out how to get music to play when they login correctly, only problem I have with it now
mob/var/Location //Town 1 for example

mob
Login()
src.Set_Music()//You could also place this in your player load proc
..()

mob
proc
Set_Music()
if(src.Location=="Town 1")//If the player is in Town 1
src<<sound('AudioFile1.ogg')//Play this file
if(src.Location=="Town 2")//If the player is in Town 2
src<<sound('AudioFile2.ogg')//Play this file


Just an example to point you in the right direction.
Do you suppose there's any way to reference an /area you're standing on? That's what I'm trying to do with code like this:
var/area/Music = locate(/area/Music) in loc 
if(Music)
src<<"area detected"
Music.Entered(src)
else
src<<"area not detected"
I personally have never tried using an area to play music before so I can't say a way to successfully pull it off.

You say that function already works, except for people who are just logging in so, you can leave your current feature in place for the players who are already logged in, but use the snippet I provided for people who are logging in to force the correct music to play.

Or you could wait for someone else to help you with that one. Sorry I can't be more help, but as I said, I've never tried applying music to an area.
You've been a great help, thank you! I'll try to figure out a way to do this that will produce the best results while waiting for a programmer who is much more experienced than I with this kind of stuff
Very well. Sorry I couldn't do more.
Movement events don't fire when you set loc directly, which I'm guessing is what you're doing when the player is placed on the map for the first time.

You're on the right track. If you can't call Move() to place the player on the map (you'd have to figure out what to do if the destination is obstructed), then you have to make sure that movement events (Exited(), Uncrossed(), Entered(), and Crossed()) are fired correctly after you force the movement.

The area at a particular turf is turf.loc. For example, if your loc is a turf, then the area you're in can be referenced with loc.loc.
This is the code I'm using. For whatever reason, it isn't finding the area I'm in when I login, even if I log in on top of /area/Music. I'm trying to make it call Entered() on the /area you login on top of, but I can't seem to reference it

mob/proc
login_procs()

var/area/Music = locate(/area/Music) in loc.loc
if(Music)
src<<"area detected"
Music.Entered(src)
else
src<<"area not detected"

area
Music

icon = 'music shade.dmi'
mouse_opacity = 0
layer = 74
invisibility = 10

var music

Entered(mob/O)
if(!istype(O) || !O.client)return

O << sound(music, repeat = 1, channel = 1)

Arena
icon_state = "arena"
music = 'Arena.ogg'

Hospital
icon_state = "hospital"
music = 'Hospital.ogg'
In response to SinfulPhoenix
var/area/Music = locate(/area/Music) in loc.loc

Let's break this down.
var/area/Music
// Create a new variable called "Music" of the type "/area" (not of type /area/Music)

locate(/area/Music) in loc.loc
// Get an instance of /area/Music inside the contents of loc.loc.
// loc.loc is the current area; the area containing src.

Do you see the problem?

What you really want is a reference to the area containing src, which you already know:
var area/Music = loc.loc
You'd just want to reference loc.loc and not use locate(), which won't find it.

if(istype(loc.loc,/area/Music))
var/area/Music/Music = loc.loc
Music.Entered(src)


But more ideally, you'd make the action of playing music a proc belonging to the area, then call that proc instead of calling Entered() which could cause all sorts of headaches.
loc.loc seems to reference "the area" instead of /area/Music. Which makes sense, because this is in the loc help topic: "For areas, this value is always null, since an area may not be contained by any other object." Which leaves me with the same problem, I can't seem to reference the /area/Music and then call Entered() to play the music. I made a proc belonging to /area/Music called play_music(), but as before, I can't reference the area to call that proc
In response to SinfulPhoenix
Obtain loc.loc, then see if it is or is a subtype of /area/Music, if it is, you can ask it to play_music()

Nadrew wrote the code for that above.
This is so frustrating. Lol. It's giving me "undefined proc for Music.play_music()". Ignore the indentation errors

mob/proc
login_proc()
if(istype(loc.loc,/area/Music))
src << "[loc.loc]"
var/area/Music = loc.loc
Music.play_music(src)

area
Music

icon = 'music shade.dmi'
mouse_opacity = 0
layer = 74
invisibility = 10

var music

proc
play_music(var/mob/O)
O << sound(music, repeat = 1, channel = 1)

Entered(mob/O)
if(!istype(O) || !O.client)return
play_music(O)

Arena
icon_state = "arena"
name = "Arena Music"
music = 'Arena.ogg'
In response to SinfulPhoenix
That's actually an issue with Nadrew's code.
He defined var/area/Music = loc.loc that is a /area *CALLED* "Music", not a /area/Music

a simple fix for that is to change it to var/area/Music/Music = loc.loc
(which is a /area/Music *CALLED* "Music", the reason I said to reuse "Music" as the name is it saves you updating the play_music() call)
Page: 1 2