-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Audio Manager #1
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
/client/wz_client/ | ||
/node_modules/ | ||
/client/bundle.js | ||
/.vscode/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"favorites.resources": [ | ||
"src\\server\\server.js" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,33 @@ | |
* `npm install` | ||
* `npm run local` to start the application with inspectable client code. | ||
* `npm run dev` to start the application with minified IIFE client code. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is my comment on the RZ thread. I don't think it should be part of the README. |
||
|
||
## Ragezone Post | ||
|
||
* Hi all, | ||
|
||
* After futzing around with the physics, I've come to realize that replicating the physics from the original client will be a much harder task than I anticipated. As such, I will have to slow down development and take time to do research and reverse engineer (as best as possible) the physics. You won't see many updates in the near future, but I assure you all that I am still actively working on this project. | ||
|
||
* Additionally, because I spent a lot of time working on the client, I acknowledge that some very important things are lacking: documentation and unit tests. These will be added soon. | ||
|
||
* In lieu of updates, I am opening up the project for anyone to clone and play around with. See it here: https://github.com/johncintron/nodin. | ||
|
||
* Edit: Answers to what I suspect will be FAQs: | ||
|
||
* How do I get past the login screen? | ||
* Go in the developer console and enter: LoginState.enterGame(); You can also move up the login map by mutating the Camera.y attribute. | ||
|
||
* How do I switch maps? | ||
* MapleMap.load(id); where id is the map id you want to load. | ||
|
||
* How do I attach equips to the character? | ||
* MyCharacter.attachEquip(slot, id); where slot is the equip slot and id is the equip id. | ||
|
||
* How do I spawn another player? | ||
* MapleCharacter.fromOpts(obj).then(m => MapleMap.characters.push(m)); | ||
|
||
* Why no WebGL? | ||
* I ditched Phaser because it was too heavy and some MapleStory-specific things were hard to implement using Phaser. Implementing the rendering engine in WebGL would have taken me forever and the game as it stands today runs at 60 FPS on Firefox and Chrome with an i7 processor. | ||
|
||
* If anyone wishes to contribute, feel free to PM me and I will add you as a collaborator. I welcome all pull requests! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
{ | ||
"PORT": 8000, | ||
"PORT": 8100, | ||
"SERVER_WZ_ROOT_DIR": "./wz_server/" | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,10 @@ import WZManager from './wzmanager'; | |
|
||
const AudioManager = {}; | ||
|
||
AudioManager.playBGM = async function(name) { | ||
var musicVolume = 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not recommended to use var. Try using const instead There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is correct. Take a look at this style guide: https://github.com/airbnb/javascript. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As an addendum, I don't recommend storing these variables at the module level. I prefer assigning these variables to the |
||
var SFXVolume = 1; | ||
|
||
AudioManager.playBGM = async function (name) { | ||
if (name !== this.bgmName) { | ||
if (!!this.bgm) { | ||
this.bgm.pause(); | ||
|
@@ -13,11 +16,29 @@ AudioManager.playBGM = async function(name) { | |
return; | ||
} | ||
const [filename, child] = name.split('/'); | ||
console.log(filename, child); | ||
const wzNode = await WZManager.get(`Sound.wz/${filename}.img/${child}`); | ||
this.bgm = wzNode.nGetAudio(); | ||
this.bgm.loop = true; | ||
this.bgm.play(); | ||
|
||
//Debug | ||
this.setMusicVolume(0.01); | ||
this.setSFXVolume(0.01); | ||
} | ||
}; | ||
|
||
AudioManager.setMusicVolume = async function (vol) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, I was trying to make some sort of validation |
||
if (typeof (vol) === 'number') { | ||
this.musicVolume = vol; | ||
this.bgm.volume = this.musicVolume; | ||
} | ||
} | ||
|
||
AudioManager.setSFXVolume = async function (vol) { | ||
if (typeof (vol) === 'number') { | ||
this.SFXVolume = vol; | ||
} | ||
} | ||
|
||
export default AudioManager; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import AudioManager from './audiomanager'; | ||
import WZManager from './wzmanager'; | ||
import DRAW_IMAGE from './drawimage'; | ||
import DRAW_TEXT from './drawtext'; | ||
|
@@ -80,21 +81,21 @@ class MapleCharacter { | |
await this.setHair(this.hair); | ||
this.setStance(this.stance); | ||
} | ||
async setSkinColor(sc=0) { | ||
async setSkinColor(sc = 0) { | ||
this.head = await WZManager.get(`Character.wz/0001200${sc}.img`); | ||
this.body = await WZManager.get(`Character.wz/0000200${sc}.img`); | ||
this.baseBody = await WZManager.get(`Character.wz/00002000.img`); | ||
this.skinColor = sc; | ||
} | ||
setStance(stance='stand1', frame=0) { | ||
setStance(stance = 'stand1', frame = 0) { | ||
if (!!this.baseBody[stance]) { | ||
this.stance = stance; | ||
this.setFrame(frame); | ||
this.oscillateFrames = stance.startsWith('stand'); | ||
this.oscillateFactor = 1; | ||
} | ||
} | ||
setFrame(frame=0, carryOverDelay=0) { | ||
setFrame(frame = 0, carryOverDelay = 0) { | ||
this.frame = !this.baseBody[this.stance][frame] ? 0 : frame; | ||
|
||
this.delay = carryOverDelay; | ||
|
@@ -107,31 +108,31 @@ class MapleCharacter { | |
if (!this.oscillateFrames) { | ||
this.setFrame(this.frame + 1, carryOverDelay); | ||
} else { | ||
const nextFrame = this.frame + 1*this.oscillateFactor; | ||
const nextFrame = this.frame + 1 * this.oscillateFactor; | ||
if (!this.baseBody[this.stance][nextFrame]) { | ||
this.oscillateFactor *= -1; | ||
} | ||
const nextOscillatedFrame = this.frame + 1*this.oscillateFactor; | ||
const nextOscillatedFrame = this.frame + 1 * this.oscillateFactor; | ||
this.setFrame(nextOscillatedFrame, carryOverDelay); | ||
} | ||
} | ||
async setFace(face=20000) { | ||
async setFace(face = 20000) { | ||
this.Face = await WZManager.get(`Character.wz/Face/000${face}.img`); | ||
this.face = face; | ||
} | ||
setFaceExpr(faceExpr='blink', faceFrame=0) { | ||
setFaceExpr(faceExpr = 'blink', faceFrame = 0) { | ||
if (!!this.Face[faceExpr]) { | ||
this.faceExpr = faceExpr; | ||
this.setFaceFrame(faceFrame); | ||
} | ||
} | ||
setFaceFrame(faceFrame=0) { | ||
setFaceFrame(faceFrame = 0) { | ||
this.faceFrame = !this.Face[this.faceExpr][faceFrame] ? 0 : faceFrame; | ||
} | ||
advanceFaceFrame() { | ||
this.setFaceFrame(this.faceFrame + 1); | ||
} | ||
async setHair(hair=30030) { | ||
async setHair(hair = 30030) { | ||
this.Hair = await WZManager.get(`Character.wz/Hair/000${hair}.img`); | ||
this.hair = hair; | ||
} | ||
|
@@ -214,7 +215,7 @@ class MapleCharacter { | |
const lu = await WZManager.get('Effect.wz/BasicEff.img/LevelUp'); | ||
this.levelUpFrames = lu.nChildren; | ||
|
||
PLAY_AUDIO(levelUpAudio); | ||
PLAY_AUDIO(levelUpAudio, AudioManager.SFXVolume); | ||
this.levelingUp = true; | ||
this.levelUpFrame = 0; | ||
this.levelUpDelay = 0; | ||
|
@@ -257,8 +258,8 @@ class MapleCharacter { | |
const twoChars = /.{1,2}/g; | ||
const [hat, faceAcc, ...equips] = this.equips; | ||
|
||
const hatVslot = !hat? '' : hat.info.vslot.nValue; | ||
const hatParts = !hat? [] : getParts(hat).filter(isDrawable); | ||
const hatVslot = !hat ? '' : hat.info.vslot.nValue; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These ternaries are the only places where VS autoformat is acceptable. See the other comment about style. |
||
const hatParts = !hat ? [] : getParts(hat).filter(isDrawable); | ||
const hatSmapValues = hatParts.reduce((acc, p) => { | ||
try { | ||
const part = p.nTagName === 'uol' ? p.nResolveUOL() : p; | ||
|
@@ -309,7 +310,7 @@ class MapleCharacter { | |
}); | ||
|
||
const originX = part.origin.nX; | ||
const adjustX = !flipped ? originX : (part.nWidth-originX); | ||
const adjustX = !flipped ? originX : (part.nWidth - originX); | ||
x -= adjustX; | ||
y -= part.origin.nY; | ||
|
||
|
@@ -432,7 +433,7 @@ class MapleCharacter { | |
align: 'center', | ||
}; | ||
const nameWidth = Math.ceil(MEASURE_TEXT(nameOpts).width + tagPadding); | ||
const nameTagX = Math.round(this.x - camera.x - nameWidth/2); | ||
const nameTagX = Math.round(this.x - camera.x - nameWidth / 2); | ||
DRAW_RECT({ | ||
x: nameTagX, | ||
y: Math.floor(this.y - camera.y + offsetFromY), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,9 +8,10 @@ | |
* @param {Audio} audio - The audio object. | ||
* @param {float} [volume=1] - Loudness of audio. | ||
*/ | ||
function PLAY_AUDIO(audio, volume=1) { | ||
|
||
function PLAY_AUDIO(audio, vol) { | ||
const concurrentAudio = audio.cloneNode(); | ||
concurrentAudio.volume = volume; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why change volume to vol? It's a good practice to be explicit in what you want to do, and abbreviating names could bad for readability There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Also, the default parameter is there for a good reason. |
||
concurrentAudio.volume = vol; | ||
concurrentAudio.play(); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
import AudioManager from './audiomanager'; | ||
import DRAW_IMAGE from './drawimage'; | ||
import GameCanvas from './gamecanvas'; | ||
import WZManager from './wzmanager'; | ||
import PLAY_AUDIO from './playaudio'; | ||
import WZManager from './wzmanager'; | ||
|
||
const UICommon = {}; | ||
|
||
UICommon.initialize = async function() { | ||
UICommon.initialize = async function () { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please no whitespace between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @johncintron according to airbnb styleguide, the space is correct: |
||
const cursor = await WZManager.get('UI.wz/Basic.img/Cursor'); | ||
|
||
this.cursorImg = cursor[0][0].nGetImage(); | ||
|
@@ -21,18 +22,18 @@ UICommon.initialize = async function() { | |
this.hoverAudio = sounds.BtMouseOver.nGetAudio(); | ||
}; | ||
|
||
UICommon.playMouseClickAudio = function() { | ||
PLAY_AUDIO(this.clickAudio); | ||
UICommon.playMouseClickAudio = function () { | ||
PLAY_AUDIO(this.clickAudio, AudioManager.SFXVolume); | ||
}; | ||
|
||
UICommon.playMouseHoverAudio = function() { | ||
PLAY_AUDIO(this.hoverAudio); | ||
UICommon.playMouseHoverAudio = function () { | ||
PLAY_AUDIO(this.hoverAudio, AudioManager.SFXVolume); | ||
}; | ||
|
||
UICommon.doUpdate = function(msPerTick) { | ||
UICommon.doUpdate = function (msPerTick) { | ||
}; | ||
|
||
UICommon.doRender = function(camera, lag, msPerTick, tdelta) { | ||
UICommon.doRender = function (camera, lag, msPerTick, tdelta) { | ||
const clicked = GameCanvas.clicked; | ||
const cursorImg = !clicked ? this.cursorImg : this.cursorDownImg; | ||
const cursorOrigin = !clicked ? this.cursorOrigin : this.cursorDownOrigin; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,7 +111,7 @@ UILogin.doUpdate = function(msPerTick, camera) { | |
this.loginButton.stance = 'normal'; | ||
|
||
if (this.activeButton === this.loginButton) { | ||
UICommon.playMouseHoverAudio(); | ||
UICommon.playMouseHoverAudio(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably forgot to remove, I was using during the test phase |
||
this.loginButton.stance = 'mouseOver'; | ||
} | ||
} | ||
|
@@ -129,7 +129,7 @@ UILogin.doUpdate = function(msPerTick, camera) { | |
this.loginButton.stance = 'mouseOver'; | ||
const trigger = releasedClick && originallyClickedLoginButton; | ||
if (trigger) { | ||
UICommon.playMouseClickAudio(); | ||
UICommon.playMouseClickAudio(1); | ||
console.log('login!'); | ||
} | ||
} | ||
|
@@ -141,7 +141,7 @@ UILogin.doUpdate = function(msPerTick, camera) { | |
if (releasedClick && originallyClickedDice && this.canClickDice) { | ||
this.canClickDice = false; | ||
this.updateDice = true; | ||
UICommon.playMouseClickAudio(); | ||
UICommon.playMouseClickAudio(1); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this VS config file here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest I don't know. He is on my .gitignore. Gotta remove for the next commit