Strange error. Doesn't appear in release mode...
BlitzMax Forums/BlitzMax Beginners Area/Strange error. Doesn't appear in release mode...
| ||
Hello, When I am compiling my game in release mode the game runs very well. But when I try to compile it in debug mode I have a strange error with description: Unhandled Exception:Assert failed. Then when I go to the debug line it goes to the cue sound code (from the audio library of blitzmax) Method Cue:TDirectSoundChannel( alloced_channel:TChannel=Null ) Local t:TDirectSoundChannel=TDirectSoundChannel( alloced_channel ) If t Assert t._static <============= THE ERROR GOES HERE Else t=TDirectSoundChannel.Create( False ) EndIf t.Cue Self Return t End Method The bug is produced when I try to play a sound with channel. For example I have one code bellow to describe what I do and produce this error. Produce the error in debug mode PlaySound(Door_Opening1, Ch_Door_Opening1) It doesn't produce any error in debug mode but you don't have 3D sounds and other channel playing. PlaySound(Door_Opening1) The wav files loaded and get assigned to a channel. Door_Opening1 = LoadSound("zip::Sounds.zip//Doormech1.wav") Ch_Door_Opening1 = CueSound(Door_Opening1) I load my wav and assign it to the channel. with CueSound command. If I will play the sound without CueSound the error is not appearing. I tried to allocate the channel to but I have the same error. Door_Opening1 = LoadSound("zip::Sounds.zip//Doormech1.wav") Ch_Door_Opening1 = AllocChannel() Ch_Door_Opening1 = CueSound(Door_Opening1) Do you know why this error is appearing in debug mode and not in release and how to fix it? Thank you very much... |
| ||
I tried to allocate the channel to but I have the same error. Door_Opening1 = LoadSound("zip::Sounds.zip//Doormech1.wav") Ch_Door_Opening1 = AllocChannel() Ch_Door_Opening1 = CueSound(Door_Opening1) Pretty sure this code isn't doing what you think it's doing. If you pre-allocate the channel then you pass that channel to CueSound, thus: Ch_Door_Opening1 = AllocChannel() CueSound(DoorOpening1, Ch_Door_Opening1) The way you've done it, is to create a channel then immediately overwrite it with another that's returned from CueSound(). Hit a similar error myself a long time ago and found pre-allocation of the channel to be the work-around. |
| ||
I tried your way and a new error was appeared: Unhandled Exception:Attempt to access field or method of Null object It goes to audio.bmx at the code: Function CueSound:TChannel( sound:TSound,channel:TChannel=Null ) Return sound.Cue( channel ) <=== THE ERROR IS HERE End Function I tried to just rem the Assert t._static line in the post above and the game worked in debug mode. |
| ||
Ch_Door_Opening1 is defined as a TChannel, right? |
| ||
Yes And is a global variable. Global Door_Opening1:TSound Global Ch_Door_Opening1:TChannel |
| ||
Hm... actually, which variable is showing Null in the debugger? The sound, or the channel? (or both?) |
| ||
It hits the error in debugger to the channelFunction CueSound:TChannel( sound:TSound,channel:TChannel=Null ) Return sound.Cue( channel ) End Function Unhandled Exception:Attempt to access field or method of Null object at the channel. Is it a bug of the language? |
| ||
I doubt it - I've never hit this problem in all my years of Blitzmax. Are you using Linux, by any chance? |
| ||
Windows 7 |
| ||
"Assert" is ignored in "Release mode", so that is why you only see it in Debug. The "problem" is the same in both cases. Replace "assert" with a throw-variant and it will raise the exception in both cases. Unhandled Exception:Attempt to access field or method of Null object at the channel. Seems not "channel" is null, but "sound", because above clearly states, that something wants to access a METHOD or FIELD of something which is null. I assume that it failed to load the sound somehow. Before you do the "CueSound" - could you do a If not DoorOpening1 then print "DoorOpening1 is null" and check if that gets print before crashing? bye Ron |
| ||
I put the code you said and I added an end command to make the program ends.Global Door_Opening1:TSound Global Ch_Door_Opening1:TChannel Door_Opening1 = LoadSound("zip::Sounds.zip//Doormech1.wav") If Not Door_Opening1 Then Print "DoorOpening1 is null" End CueSound(Door_Opening1, Ch_Door_Opening1) And the error continued and the program hit in other file and other line. So I discovered the problem is with the channel. So I added another one line. If Not Ch_Door_Opening1 Then Print "Ch_Door_Opening1 is null" End And then the program ended with message "Ch_Door_Opening1 is null" So the channel is Null not the sound. Door_Opening1 = LoadSound("zip::Sounds.zip//Doormech1.wav") CueSound(Door_Opening1, Ch_Door_Opening1) If Not Door_Opening1 Then Print "Door_Opening1 is null" End If Not Ch_Door_Opening1 Then Print "Ch_Door_Opening1 is null" End Only changing with Ch_Door_Opening1 = CueSound(Door_Opening1) Instead of CueSound(Door_Opening1, Ch_Door_Opening1) The first cuesound return the channel to Ch_Door_Opening1 And the second one pass the channel Ch_Door_Opening1 as argument. What is the difference between? It Doesn't produce the "Unhandled Exception:Attempt to access field or method of Null object at the channel. " But produce the other with the assert as before. And when I remove the "Assert t._static" line. The program works. I think I will remove this "Assert t._static" thing and I will continue my game :) |
| ||
A bit random, but you do have speakers/headphones plugged in? I vaguely recall a problem with DirectSound from years back where Blitzmax would crap out if there wasn't - as if there was no soundcard present at all. |
| ||
I have headphones to test the volume and pan. And speakers to test the sounds in generic. I discovered yet another bug in my door sounds and 3d effects. I will post some demo when I will fix my sound errors. |
| ||
I have another problem about when I try to play 2 same sounds simultaneously I hear the sound distorted. I will send you a demo. I try to play the same sound for my doors near and far , but when I am playing the same sound during other sound is playing I hear the sound distorted. |
| ||
You need to allocate individual channels for them. I was wondered about your "if bla = null then print X end"... I thought it needs to get chained using ";" ("if bla = null then print X;end") but somehow this isnt true... @your error. You posted this previously: It hits the error in debugger to the channel Function CueSound:TChannel( sound:TSound,channel:TChannel=Null ) Return sound.Cue( channel ) End Function Which is saying: "sound.cue(channel)" is raising the error about access to null-ed child elements. This would mean, that "sound" does not contain "cue()". In all other cases, the debugger would jump to the error within the "Cue" method. In all cases your debugging pane on the right side will show variable names + content (or memory address) - if something is null, this is printed too. Ok back to the problem ... FreeAudio does not have this assert in "cue" - it just creates the channel if you did not provide a valid/existing one. Your DX-one instead checks if the existing TChannel is in reality a "TDirectSoundChannel" one ... and then it checks if it got created with a static-flag. Ok ... so guess what? that "_static" isnt used anywhere - it is used in the "openalaudio"-version to check for a leak, but within Blitzmax the DirectSoundAudio-version isnt using "_static" for anything useful. If you want to get rid of the assert you might create your channel correspondingly: local myChannelOne:TChannel ?Win32 myChannelOne = TDirectSoundChannel(true) ?not Win32 myChannelOne = AllocChannel() ? But ... I just checked "AllocChannel()" and it runs the "AllocChannel"-Method of the individual Audiodriver ... ... did you set the AudioDriver at all? And if YES... do you create all these channels AFTER the audio driver was set? The channel you are using and which is "not null" but of the type "TDirectSoundChannel" should have a "_static" value of "true" to not alert the "assert". Short: you could remove that _static portion without problems. A real "debugging"-pane-analysis by you might help which portion of a object was null. bye Ron |
| ||
Hello again, I have to say I haven't set any audio driver and I thought this happens automatically or choose the windows drivers. How to set audiodrivers? I have one little demo about what I have created so far with your very precious help. :) Download a demo , and see how my sounds hear The code of the doors in my game: For All_Doors = 1 To max_doors 'If Party.direction = 1 Or Party.direction = 2 Then If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 And Doors[Party.Level, All_Doors].Orientation = 1 Then Doors[Party.Level, All_Doors].dist_x1 = Doors[Party.Level, All_Doors].x - Party.x Doors[Party.Level, All_Doors].dist_y1 = Doors[Party.Level, All_Doors].y - Party.y Doors[Party.Level, All_Doors].distance = Sqr((Doors[Party.Level, All_Doors].dist_x1 * Doors[Party.Level, All_Doors].dist_x1) + (Doors[Party.Level, All_Doors].dist_y1 * Doors[Party.Level, All_Doors].dist_y1)) Doors[Party.Level, All_Doors].direction1 = ATan2(Doors[Party.Level, All_Doors].y - Party.y, Doors[Party.Level, All_Doors].x - Party.x) EndIf 'EndIf 'If Party.direction = 3 Or Party.direction = 4 Then If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 And Doors[Party.Level, All_Doors].Orientation = 2 Then Doors[Party.Level, All_Doors].dist_x2 = Doors[Party.Level, All_Doors].x - Party.x Doors[Party.Level, All_Doors].dist_y2 = Doors[Party.Level, All_Doors].y - Party.y Doors[Party.Level, All_Doors].distance = Sqr((Doors[Party.Level, All_Doors].dist_x2 * Doors[Party.Level, All_Doors].dist_x2) + (Doors[Party.Level, All_Doors].dist_y2 * Doors[Party.Level, All_Doors].dist_y2)) Doors[Party.Level, All_Doors].direction2 = ATan2(Doors[Party.Level, All_Doors].y - Party.y, Doors[Party.Level, All_Doors].x - Party.x) EndIf 'EndIf 'if the distance is from 0 - 5 then hear far and near If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 And Doors[Party.Level, All_Doors].Orientation = 1 Then If Doors[Party.Level, All_Doors].distance >= 0 And Doors[Party.Level, All_Doors].distance <= 1.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) End If If Doors[Party.Level, All_Doors].distance >= 2 And Doors[Party.Level, All_Doors].distance <= 2.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) End If If Doors[Party.Level, All_Doors].distance >= 3 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) End If If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) End If If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 4.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) End If If Doors[Party.Level, All_Doors].distance >= 5 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) End If EndIf 'if the distance is from 0 - 5 then hear far and near 'rem If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 And Doors[Party.Level, All_Doors].Orientation = 2 Then If Doors[Party.Level, All_Doors].distance >= 0 And Doors[Party.Level, All_Doors].distance <= 1.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) Ch_Door_Closing2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) Ch_Door_Closed2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) End If If Doors[Party.Level, All_Doors].distance >= 2 And Doors[Party.Level, All_Doors].distance <= 2.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) Ch_Door_Closing2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) Ch_Door_Closed2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) End If If Doors[Party.Level, All_Doors].distance >= 3 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) Ch_Door_Closing2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) Ch_Door_Closed2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) End If If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) Ch_Door_Closing2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) Ch_Door_Closed2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) End If If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 4.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) Ch_Door_Closing2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) Ch_Door_Closed2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) End If If Doors[Party.Level, All_Doors].distance >= 5 Then Ch_Door_Opening2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) Ch_Door_Closing2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) Ch_Door_Closed2.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) End If EndIf 'endrem 'Door animation mechanism , delay the animation a little If (Current_time >= Doors[Party.Level, All_Doors].Door_Deadline_time) Then Current_time = MilliSecs() Doors[Party.Level, All_Doors].Door_Deadline_time = Current_time + 1 Doors[Party.Level, All_Doors].Time_Delay = Doors[Party.Level, All_Doors].Time_Delay + 1 'Synchronize the door animation speed according to the FPS If fps <= 29 Then door_speed = 10 If fps >= 30 And fps <= 39 Then door_speed = 15 If fps >= 40 And fps <= 49 Then door_speed = 20 If fps >= 50 And fps <= 59 Then door_speed = 25 If fps >= 60 And fps <= 79 Then door_speed = 30 If fps >= 80 And fps <= 99 Then door_speed = 35 If fps >= 100 And fps <= 119 Then door_speed = 40 If fps >= 120 And fps <= 139 Then door_speed = 45 If fps >= 140 Then door_speed = 50 'Delay 65 millisecs If Doors[Party.Level, All_Doors].Time_Delay >= door_speed Then Doors[Party.Level, All_Doors].Time_Delay = 0 'Reset the delay timer If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 And Doors[Party.Level, All_Doors].Orientation = 1 Then 'If the door is in opening state If Doors[Party.Level, All_Doors].State = 1 Then 'Increase the animation frame If Doors[Party.Level, All_Doors].Frame = 1 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 2 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 3 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 4 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 5 Then Doors[Party.Level, All_Doors].State = 3 Return EndIf EndIf 'If the door is in closing state If Doors[Party.Level, All_Doors].State = 2 Then 'Decrease the animition frame If Doors[Party.Level, All_Doors].Frame = 1 Then Doors[Party.Level, All_Doors].State = 4 'PlaySound(Door_Closed1, Ch_Door_Closed1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 2 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closed1, Ch_Door_Closed1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 3 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing1, Ch_Door_Closing1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 4 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing1, Ch_Door_Closing1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 5 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing1, Ch_Door_Closing1) Return EndIf EndIf EndIf If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 And Doors[Party.Level, All_Doors].Orientation = 2 Then 'If the door is in opening state If Doors[Party.Level, All_Doors].State = 1 Then 'Increase the animation frame If Doors[Party.Level, All_Doors].Frame = 1 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening2, Ch_Door_Opening2) Return EndIf If Doors[Party.Level, All_Doors].Frame = 2 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening2, Ch_Door_Opening2) Return EndIf If Doors[Party.Level, All_Doors].Frame = 3 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening2, Ch_Door_Opening2) Return EndIf If Doors[Party.Level, All_Doors].Frame = 4 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening2, Ch_Door_Opening2) Return EndIf If Doors[Party.Level, All_Doors].Frame = 5 Then Doors[Party.Level, All_Doors].State = 3 Return EndIf EndIf 'If the door is in closing state If Doors[Party.Level, All_Doors].State = 2 Then 'Decrease the animition frame If Doors[Party.Level, All_Doors].Frame = 1 Then Doors[Party.Level, All_Doors].State = 4 'PlaySound(Door_Closed1, Ch_Door_Closed1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 2 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closed2, Ch_Door_Closed2) Return EndIf If Doors[Party.Level, All_Doors].Frame = 3 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing2, Ch_Door_Closing2) Return EndIf If Doors[Party.Level, All_Doors].Frame = 4 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing2, Ch_Door_Closing2) Return EndIf If Doors[Party.Level, All_Doors].Frame = 5 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing2, Ch_Door_Closing2) Return EndIf EndIf EndIf EndIf EndIf Next EndFunction |
| ||
I do not understand how the "demo code" will help to narrow down the bug. In all cases: I think there is some code which could get shortened a bit. You do things for all cases, so there is no need to have it written each time. Also pay attention to your "ifs" regarding the state: if state = 1 then doSomething if state = 2 then doSomethingElse if you change "state" within "doSomething" you might trigger that "if state = 2" in the same cycle, so better if ... elseif ... in such cases. @FPS doorspeed adjustment ??? why don't you "delta" this thing? Just define eg. "0.5seconds for whole animation" and then subtract the delta from a "timer value" which got set to 0.5 on start. It reaches 0 and 0.5seconds there gone. The relative progress is then (1.0 - timeLeft/0.5) I do not want to teach you how to write code, but just a suggestion to make things more pregnant (you could even shorten that whole "doors" thing by looping through them using If Doors[Party.Level, All_Doors].distance >= 0 And Doors[Party.Level, All_Doors].distance <= 1.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 1) End If If Doors[Party.Level, All_Doors].distance >= 2 And Doors[Party.Level, All_Doors].distance <= 2.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.7) End If If Doors[Party.Level, All_Doors].distance >= 3 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.4) End If If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.2) End If If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 4.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.09) End If If Doors[Party.Level, All_Doors].distance >= 5 Then Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * 0.0) End If local volumeMod:float = 1.0 If Doors[Party.Level, All_Doors].distance >= 0 And Doors[Party.Level, All_Doors].distance <= 1.99 Then volumeMod = 1 Else If Doors[Party.Level, All_Doors].distance >= 2 And Doors[Party.Level, All_Doors].distance <= 2.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then volumeMod = 0.7 Else If Doors[Party.Level, All_Doors].distance >= 3 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then volumeMod = 0.4 Else If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then volumeMod = 0.2 Else If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 4.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then volumeMod = 0.09 'I would prefer an "else" -> in all other cases do a volume=0 'Else Else If Doors[Party.Level, All_Doors].distance >= 5 Then volumeMod = 0 End If Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * volumeMod) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * volumeMod) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * volumeMod) Please show the code creating/allocating the channels. @Setaudiodriver No you should not be needed to do so ... but I was not aware that you do not do that, so I assumed a potential flaw in your code (channel allocation before the audio driver is inited -> another audio driver would create a channel then). bye Ron |
| ||
This delta timer I have have relation about frames per second. If for some reason your computer lags in frames per second the I calibrate the timers so animation speed will be the same if the frames per second drop or increase. About the creating and allocating channels I don't do anything complex I just use Global variables for the channel and the sounds Global Door_Opening1:TSound Global Ch_Door_Opening1:TChannel Global Door_Opening2:TSound Global Ch_Door_Opening2:TChannel And then I load my sound from .wav file Door_Opening1 = LoadSound("zip::Sounds.eob//Doormech1.wav") Ch_Door_Opening1 = CueSound(Door_Opening1) Door_Opening2 = LoadSound("zip::Sounds.eob//Doormech1.wav") Ch_Door_Opening2 = CueSound(Door_Opening1) I made a little change in the code and I create to separated sounds for horizontal and vertical doors. In fact the sound is the same but this avoids to play the same channel when you will open 2 doors which are horizontal. Did you saw the demo? Then the I am checking if the player is far or near to the door to hear the sound launder or quiet by increasing or decreasing the sound volume. OK the volumeMod was nice it shortened my code a lot. About the state of the door is my complex mechanism to tell to engine that my door is opening or closing or closed or opened to reverse the animation or start animation or stop. |
| ||
I am on Linux, not on Windows so I wont run your app except in a VM (which I use for building .exe files). @Globals I just wanted to know... because you might do some untold things there. There is nothing wrong with using the "convencience accessors" (cuesound, loadsound) instead of their "oop" ones (Ch_Door_Opening2 = Door_Opening1.cue()). The whole audio-cueing-thing leaves me puzzled everytime so you are not alone. @State Yepp, I use states for my "elevator" too. Just make sure you do not forget "cases" and create dead loops or situations the door hangs inbetween states. @Sound Maybe Skidracer is able to explain for what the assert is used in the sound core. Think he is more firm regarding this mod. bye Ron |
| ||
I made a lots of changes and I improved the code a little. Now the problem is , when you open the door1 you hear the sound. When you are opening the door2 and if there is a door1 near you hear the sound. Of the door1 But if you open the door4 which is far from door1 or other doors the code calculates the distance more than 5 because door4 if far from the door1 or 2 and you don't hear nothing. But the for next loop scans all doors and I should hear the sounds of the doors which are in distance <=5 individually. If I will not use soundvolume or volumeMod I can hear all the door sound equally but I will not have this near and far sound effect. The new code is shorter than previously: The sound distortions wasn't about channel allocations. Also I still work with the assert code removed. Function Door_Mechanics() For All_Doors = 1 To max_doors 'Door animation mechanism , delay the animation a little If (Current_time >= Doors[Party.Level, All_Doors].Door_Deadline_time) Then Doors[Party.Level, All_Doors].Door_Deadline_time = Current_time + Doors[Party.Level, All_Doors].Time_Delay 'If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 And Doors[Party.Level, All_Doors].Orientation = 1 Then 'If the door is in opening state If Doors[Party.Level, All_Doors].State = 1 Then 'Increase the animation frame If Doors[Party.Level, All_Doors].Frame = 1 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 2 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 3 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 4 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame + 1 PlaySound(Door_Opening1, Ch_Door_Opening1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 5 Then Doors[Party.Level, All_Doors].State = 3 Return EndIf EndIf 'If the door is in closing state If Doors[Party.Level, All_Doors].State = 2 Then 'Decrease the animition frame If Doors[Party.Level, All_Doors].Frame = 1 Then Doors[Party.Level, All_Doors].State = 4 'PlaySound(Door_Closed1, Ch_Door_Closed1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 2 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closed1, Ch_Door_Closed1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 3 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing1, Ch_Door_Closing1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 4 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing1, Ch_Door_Closing1) Return EndIf If Doors[Party.Level, All_Doors].Frame = 5 Then Doors[Party.Level, All_Doors].Frame = Doors[Party.Level, All_Doors].Frame - 1 PlaySound(Door_Closing1, Ch_Door_Closing1) Return EndIf EndIf EndIf 'Synchronize the door animation speed according to the FPS If fps <= 29 Then Doors[Party.Level, All_Doors].Time_Delay = 100 If fps >= 30 And fps <= 39 Then Doors[Party.Level, All_Doors].Time_Delay = 150 If fps >= 40 And fps <= 49 Then Doors[Party.Level, All_Doors].Time_Delay = 200 If fps >= 50 And fps <= 59 Then Doors[Party.Level, All_Doors].Time_Delay = 250 If fps >= 60 And fps <= 79 Then Doors[Party.Level, All_Doors].Time_Delay = 300 If fps >= 80 And fps <= 99 Then Doors[Party.Level, All_Doors].Time_Delay = 350 If fps >= 100 And fps <= 119 Then Doors[Party.Level, All_Doors].Time_Delay = 400 If fps >= 120 And fps <= 139 Then Doors[Party.Level, All_Doors].Time_Delay = 450 If fps >= 140 Then Doors[Party.Level, All_Doors].Time_Delay = 500 If Doors[Party.Level, All_Doors].x > 0 And Doors[Party.Level, All_Doors].y > 0 Then Doors[Party.Level, All_Doors].dist_x1 = Doors[Party.Level, All_Doors].x - Party.x Doors[Party.Level, All_Doors].dist_y1 = Doors[Party.Level, All_Doors].y - Party.y Doors[Party.Level, All_Doors].distance = Sqr((Doors[Party.Level, All_Doors].dist_x1 * Doors[Party.Level, All_Doors].dist_x1) + (Doors[Party.Level, All_Doors].dist_y1 * Doors[Party.Level, All_Doors].dist_y1)) Doors[Party.Level, All_Doors].direction1 = ATan2(Doors[Party.Level, All_Doors].y - Party.y, Doors[Party.Level, All_Doors].x - Party.x) Ch_Door_Opening1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * Doors[Party.Level, All_Doors].volumeMod) Ch_Door_Closing1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * Doors[Party.Level, All_Doors].volumeMod) Ch_Door_Closed1.SetVolume(Doors[Party.Level, All_Doors].Sound_Volume * Doors[Party.Level, All_Doors].volumeMod) If Doors[Party.Level, All_Doors].distance >= 0 And Doors[Party.Level, All_Doors].distance <= 1.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Doors[Party.Level, All_Doors].volumeMod = 1 Continue If Doors[Party.Level, All_Doors].distance >= 2 And Doors[Party.Level, All_Doors].distance <= 2.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Doors[Party.Level, All_Doors].volumeMod = 0.7 Continue If Doors[Party.Level, All_Doors].distance >= 3 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Doors[Party.Level, All_Doors].volumeMod = 0.4 Continue If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 3.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Doors[Party.Level, All_Doors].volumeMod = 0.2 Continue If Doors[Party.Level, All_Doors].distance >= 4 And Doors[Party.Level, All_Doors].distance <= 4.99 And Stairs[Party.Level, All_Doors].transfering = 0 Then Doors[Party.Level, All_Doors].volumeMod = 0.09 Continue If Doors[Party.Level, All_Doors].distance >= 5 Then Doors[Party.Level, All_Doors].volumeMod = 0 Continue EndIf Next EndFunction Walk around and open some doors. Click here for next update |
| ||
Ok, I adjusted your code - and more important, placed some comments in it. What I have done is: redone some of the logic to catch previously ignored pitfalls (values differing to your expectations). Often used "array accesses" were shortened using a local variable - exception is if they are used in an "if...elseif...elseif"-part because they then are only used once at the end (for the if-condition which fit). I also stopped PlaySound to get called in all cases - because this leads to this effect: - door 1 opens and plays a sound - door 3 opens and starts a sound too - so the sound of door1 is stopped inbetween The "new" approach just plays a sound if no other open sound (vice versa for close) is playing. I will post some kind of "ChannelPool" within the next minutes, so you should be able to play multiple sounds simultaneously. Just have to write one (so it will be a bit of untested and raw). The pool shouldn't be needed at all, as it is some kind of "software mixing" and no hardware mixer (which then has a limit of eg. 16 channels). So in theory EACH of your doors could have its own channel ... and because this doors cannot be in open,close,closed-state at the same time, you wont need to play 3 sound files at once (for each door). In my game each of the room-doors in the building has its own channel to play sounds. bye Ron |
| ||
Ok, here is a simple channel pool including an example. if you prefer colored code visit my frameworks page: tchannelpool: https://github.com/GWRon/Dig/blob/master/base.sfx.channelpool.bmx sample: https://github.com/GWRon/Dig/blob/master/samples/channelpool/channelpool.bmx for your code this means, that you need some slight modifications (no check for already playing etc.). I will post a modified version of the code soon. EDIT: here we go, your code incorporating the channel pool and another adjustment (reordered volumeMod-calculation and volume-adjustment) EDIT2: I extended my TChannelPool to enable "protection" of certain channels (so the "random overwrite of existing channels with channelLimit enabled" wont return these channels -> like "backgroundMusic"-channels). I also created some more convenience-accessors, although I do not like them for this short type names (they are useful to shorten code for the purpose of reclaiming a bit of overview in your code). Also try to NOT create too long lines of code - most editors present you a vertical line (80 chars) which is a good length of a code line. This is more important if you share your code with others (smaller screens) or want compare DIFF-files (left and right side showing differences between files). I know this is hard some times but maybe worth to give a try. It eases the path to detect mistakes because it allowes your eyes to focus on a smaller area of the screen (or allows for bigger font sizes :p). bye Ron |
| ||
Your code looks nice , is little complex and I forgot to send you the type of those doors.Type My_doors Field x:Byte 'position X on the map Field y:Byte 'position Y on the map Field dist_x1:Int 'Distance calculation for horizontal doors Field dist_y1:Int Field dist_x2:Int 'Distance calculation for vertical doors Field dist_y2:Int Field distance:Int Field direction1:Int 'sound direction pan for each horizontal door Field direction2:Int 'sound direction pan for each vertical door Field Level:Byte 'Which level is the door on Field State:Byte '1 opening 2 closing 3 opened 4 closed Field Have_button:Byte 'have a button to open or close it Field Time_delay:Int 'animation speed Field Locked:String 'L= locked U= unlocked Field Frame:Byte 'sprite animation frame Field Locked_with_item:String 'the item or key to unlock the door Field Orientation:Byte '1= horizontal or 2= vertical Field Graphic:String 'the graphic of the door "01"=Door graphic1 "02"=Door graphic2 etc.. Field Button_pressed:Byte 'The button was pressed then start the door mechanics Field Door_Deadline_time:Int Field Sound_Pan:Float Field Sound_Volume:Float Field volumeMod:Float Field volumeMod1:Float Field volumeMod2:Float EndType Global Doors:My_Doors[max_levels + 1, max_doors + 1] For lvl = 1 To max_levels For All_Doors = 1 To max_doors Doors[lvl, All_Doors] = New My_doors Next Next Also I replaced all doors. with Doors[Party.Level, All_Doors]. Because I have my own ready made type. I removed the 'local door:TDoorObject = Doors[Party.Level, All_Doors] Because I am already have my types. I have to change my code again. I created a new file in my project and I copied the code above. I remove some multiple Local k:String because the compiler have error with duplicate identifier and I put only once in the Function GetRandomChannelKey:String(). Also I removed some Local channel:TChannel and I put on top of the function GetRandomChannelKey:String() too , because the compiler complained about duplicate identifiers. I need to change the code about the door states because you have changed a little. The state=1 means the door is opening and plays the opening sound. The state=2 means the door is closing and plays the closing sound another sound. The state=3 means the door is opened and stops the animation The state=4 means the door is closed and plays the shut door sound another one and stops the animation. It seems the Channel Pool code did very nice work for a draft changing of my code , I will fix few error in states and some duplicated identifiers. I hear the sound well now without distortions near and far to all doors. Now I have and the soundpan commands to make the sound hear from the left or right speaker or both speakers if you are in front of the door or back. I added and another one line GetPooledChannel(channelKey).SetPan(Doors[Party.Level, All_Doors].Sound_Pan) The GetPooledChannel command is very nice. The code below is for sound pan. 'skip doors with negative and 0 coordinates and continue to next door If Doors[Party.Level, All_Doors].x <= 0 Or Doors[Party.Level, All_Doors].y <= 0 Then Continue Doors[Party.Level, All_Doors].dist_x1 = Doors[Party.Level, All_Doors].x - Party.x Doors[Party.Level, All_Doors].dist_y1 = Doors[Party.Level, All_Doors].y - Party.y Doors[Party.Level, All_Doors].distance = Sqr((Doors[Party.Level, All_Doors].dist_x1 * Doors[Party.Level, All_Doors].dist_x1) + (Doors[Party.Level, All_Doors].dist_y1 * Doors[Party.Level, All_Doors].dist_y1)) Doors[Party.Level, All_Doors].direction = ATan2(Doors[Party.Level, All_Doors].y - Party.y, Doors[Party.Level, All_Doors].x - Party.x) 'Pan the sound if the party is on specific direction If Doors[Party.Level, All_Doors].Orientation = 1 'The party faces to the North If Party.direction = 1 Then 'The door direction is in front or in back If Doors[Party.Level, All_Doors].direction = -90 Or Doors[Party.Level, All_Doors].direction = 90 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = 0 sound_panned = 1 'The door direction is to the left or the right If Doors[Party.Level, All_Doors].direction < - 90 Or Doors[Party.Level, All_Doors].direction > 90 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = -1 sound_panned = 1 'The door direction is to the right or the the left If Doors[Party.Level, All_Doors].direction > - 90 Or Doors[Party.Level, All_Doors].direction < 90 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = + 1 sound_panned = 1 'The party faces to the South ElseIf Party.direction = 2 Then If Doors[Party.Level, All_Doors].direction = 90 Or Doors[Party.Level, All_Doors].direction = -90 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = 0 sound_panned = 1 ElseIf Doors[Party.Level, All_Doors].direction < 90 Or Doors[Party.Level, All_Doors].direction < - 45 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = -1 sound_panned = 1 ElseIf Doors[Party.Level, All_Doors].direction > 90 Or Doors[Party.Level, All_Doors].direction > - 45 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = + 1 sound_panned = 1 'The party faces to the West ElseIf Party.direction = 3 Then If Doors[Party.Level, All_Doors].direction = 180 Or Doors[Party.Level, All_Doors].direction = 0 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = 0 sound_panned = 1 ElseIf Doors[Party.Level, All_Doors].direction > 0 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = -1 sound_panned = 1 ElseIf Doors[Party.Level, All_Doors].direction < 0 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = + 1 sound_panned = 1 'The party faces to the East ElseIf Party.direction = 4 Then If Doors[Party.Level, All_Doors].direction = 180 Or Doors[Party.Level, All_Doors].direction = 0 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = 0 sound_panned = 1 ElseIf Doors[Party.Level, All_Doors].direction < 0 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = -1 sound_panned = 1 ElseIf Doors[Party.Level, All_Doors].direction > 0 And sound_panned = 0 Then Doors[Party.Level, All_Doors].Sound_Pan = + 1 sound_panned = 1 EndIf End If But this works for only for the first door. What do I am making wrong? You need to wear headsets to see the difference from the left and right speaker. The updated demo is here. I have disabled the party collision to travel though walls and step left , right and in front of each door to hear the effect (Only in door1). Click here for updated demo I still don't understand when I put elseif. Suppose if there is not any if means else. Supplementary: You will open only the horizontal doors (North and South doors) not the vertical one , I haven't done it yet. .orientation is the 1=horizontal or 2=vertical doors :) |
| ||
First of all: there is NO need to remove the whole "door = Doors[...]" part just because I wrote a different type name behind "door:". Just use local door:My_doors = Doors[Party.Level, All_Doors] and there you go... @else If 10 < 5 then print "this if is skipped !" ElseIf 10 < 8 print "this elseIf is skipped !" ElseIf 10 < 11 print "this elseif is finally run" Else print "in all other situations not catched by aboves if/elseif this is run" EndIf Your chain of "ifs" might ignore the "in all other cases" portion. You tend to use "return" to skip further processing of follow up "ifs". The "else if" makes such things needless. @locals / double definitions Yeah, I use "SuperStrict" as much as I can, which does not blame such things. Also my code wasnt test compiled (as I miss much your code to do this)... So ... I modified your code -- and I am pretty sure that your "sound_panned = 0" is the source of your problem with only the first door getting a panning. Once the first door gets a panning, your "sound_panning" is set to "1". The next door then starts with "sound_panning=1" already and therefor would never pass the conditions in the if-clauses. If you really need such a sound_panned (eg. to check afterwards if a panning took place) make sure, you reset that variable in the head of the for-loop. 'RON: replace "My_Doors" with whatever is the name of the door ' type local door:My_Doors = Doors[Party.Level, All_Doors] 'skip doors with negative and 0 coordinates and continue to next door If door.x <= 0 Or door.y <= 0 Then Continue door.dist_x1 = Doors[Party.Level, All_Doors].x - Party.x door.dist_y1 = Doors[Party.Level, All_Doors].y - Party.y door.distance = Sqr((door.dist_x1 * door.dist_x1) + (door.dist_y1 * door.dist_y1)) door.direction = ATan2(door.y - Party.y, door.x - Party.x) 'RON: you checked for "sound_panned = 0" in ALL your following ' ifs ... so you can do that ONCE for all ' -> just add it to the enclosing "if" ... but I do not know ' what is the source of "sound_panned" ? if you do not ' reset that for EACH door in the loop, only your first ' door will get a pan ' I assume you included that because your "ifs" are not ' catching all situations and therefore multiple adjustments ' are run for a single door. 'If door.Orientation = 1 And sound_panned = 0 'Pan the sound if the party is on specific direction 'If door.Orientation = 1 'The party faces to the North If Party.direction = 1 Then 'The door direction is in front or in back If door.direction = -90 Or door.direction = 90 door.Sound_Pan = 0 'The door direction is to the left or the right ElseIf door.direction < - 90 Or door.direction > 90 door.Sound_Pan = -1 'The door direction is to the right or the the left 'RON: there is no need to check for directions: you only ' have front, back, left and right as options, and ' you already checked for "front/back/left" Else Then door.Sound_Pan = + 1 EndIf 'The party faces to the South ElseIf Party.direction = 2 Then 'RON: Are you sure about that "-45" ? compared to ' "faces to the north" this should be similar, with ' left and right switched ? If door.direction = 90 Or door.direction = -90 door.Sound_Pan = 0 ElseIf door.direction < 90 Or door.direction < - 45 door.Sound_Pan = -1 ElseIf door.direction > 90 Or door.direction > - 45 door.Sound_Pan = + 1 EndIf 'The party faces to the West ElseIf Party.direction = 3 Then If door.direction = 180 Or door.direction = 0 door.Sound_Pan = 0 ElseIf door.direction > 0 door.Sound_Pan = -1 Else door.Sound_Pan = + 1 EndIf 'The party faces to the East ElseIf Party.direction = 4 Then If door.direction = 180 Or door.direction = 0 door.Sound_Pan = 0 ElseIf door.direction < 0 door.Sound_Pan = -1 Else door.Sound_Pan = + 1 EndIf EndIf End If Also pay attention to the "south"-part, as it seems to contain a mistake (-45, 45 compared to "north" with -90, 90). @ChannelPool Glad it is of help ... but that also proofs that your code contained some flaws regarding the channels (and not the blitz-modules). PS: I wondered a bit about your code format: My Blitzcompiler blames the first "elseif" there. I used this test: If 1 < 10 Then Print "Ok" ElseIf 2 < 10 Then Print "ok2" Else Then Print "ok3" I know you are able to use a single-line if "if x then do" but you cannot concatenate with "elseif" on a new line. For this you need to separate "condition" and action like I did in the code above and below. If 1 < 10 Print "Ok" ElseIf 2 < 10 Print "ok2" Else Print "ok3" EndIf PPS: If you post such "wide" code portions, use the {codebox} forumcode instead of the {code} variant - this enables scrollbars on both axis. This is nicer for people without fullhd-resolution. bye Ron |
| ||
You are right , with the south direction code , if the door direction if less than minus 45 means it will be less than 90 too and when the door direction if greater than 90 it will be also greater then minus 45 so i removed the less than minus 45 and greater than -45 code :P I will not used a single door object because I would like to see each time my whole array of my door type. Also you use local door:TDoorObject = Doors[Party.Level, All_Doors] But my doors needs to be global and I am already have initialized my doors on my types in other source file. Your code worked perfectly and now all of my doors have 3D sound and I can hear them near and far and in my left and right speakers. You deserve a copy of my game when it finishes and your name in my credits. :) I will try to use the same sound code for my monsters and other sound source for my game. About the SuperStrict , I will not use it because it drops errors to other codes which I don't see any error. Also SuperStrict not allows you the goto command. |
| ||
Goto ... there is no need to use it ... in no way. SuperStrict errors: post the portion it errors out and I will try to solve it. @single door objects I do not create a "new" door or so ... I just create another reference to the object in the array. So the only moment you need to access "Doors[level, all_doors]" is if you want to remove a door from the array (or "null" it there). I assume you have a misconception about globals and local variables referencing them. Such references allow to save processing time. Eg. you could do a "GetPooledChannel(name)" each time - or just store the channel in a local variable for the time of the "loop". Imagine "GetComplexCalculationResult()" needs 20 ms each time it is called. Now in your code you use that call instead of using a cached result. 20 times used sums up to 400ms, but with the cache you stay at 20ms for the one time calculation. In this case the performance isn't the reason of my change, it is the shortening of code. Why? You are at a coder level in BlitzMax which still fights with some errors here and there. And a shorter line of code surely eases the process of detecting errors just by viewing it. Another hint: your door-type could store some helping functions - eg. to return the distance to a given coordinate. Or to return the direction to another object by a given coordinate + viewing direction. Why? This shortens the code of the function maintaining sounds, animation etc. . It separates functionality and makes it easier to reuse code for other things instead of copying code to here. Also it eases again the readability in more complex portions of your source code. The earlier you begin teaching yourself the oop-way and benefits of BlitzMax (methods etc.) the more you will improve dev-speed-wise and maybe even enjoy the language a bit more. Ok, enough "teaching lesson" for now ... post your SuperStrict-errors and we will see if I can be of help. bye Ron |
| ||
This superstrict generated errors in places there were no errors. For example: Compile Error: Expression of type 'String Array' cannot be invoked At code: I don't see any error there. The array variable was: This is one example of lots of errors appeared from nowhere. |
| ||
Because you try to run "levels" as a function/method ... just look a bit more closer and you see: you mixed "( )" and "[ ]". If levels(....) is like calling "my array definition"(). Replace If levels(Party.level, Party.x, Party.y - 1, 1) <> "00" with If levels[Party.level, Party.x, Party.y - 1, 1] <> "00" and the error will be gone. - I am really sure that the content of this "if ...endif" causes some bugs in the way you use it now - it is either NEVER run or EVERYTIME ... depending on how bcc compiles this ahem.. "stuff". Up to the next error... PS: for these short codes, {code} is still the better solution (as it does not have this min-height definition when displayed in the browser). {codebox} is good for "long lines" to not break out of the posting "default width" (100%) and for codes with many lines. bye Ron |
| ||
Ooop it seems I had a type with those brackets. Also I used {codebox} to post my question. I will fix these brackets and I will tell you if there is any other error. Why the compiler didn't warn me? I fixed a lots of typo error with ( instead of [ I fixed a lots of missing or misspelling variables. And it compiled with superstrict :P |
| ||
I have to do one small fix in sound when I am entering in stairs and changing level with the new code , the sound is not fading out. If I will fix and this one , this version is free of bugs until the next one :P |
| ||
I fixed a lots of typo error with ( instead of [ I fixed a lots of missing or misspelling variables. that is why I prefer (Super)Strict ... misspelled variables can lead to really unsuspected behaviour. Glad it works better and better. bye Ron |