diff --git a/package.json b/package.json
index eda1baf10..3fa6ec5b4 100644
--- a/package.json
+++ b/package.json
@@ -74,6 +74,7 @@
"audio-context": "^0.1.0",
"bluebird": "^2.9.6",
"bms": "^0.2.0",
+ "chance": "^0.7.3",
"co": "^4.3.1",
"debug": "^2.1.1",
"jquery": "^2.1.3",
diff --git a/public/skins/default/Note/DX.png b/public/skins/default/Note/DX.png
index 079e5c51b..7df10cc2c 100644
Binary files a/public/skins/default/Note/DX.png and b/public/skins/default/Note/DX.png differ
diff --git a/public/skins/default/skin.xml b/public/skins/default/skin.xml
index 7f707e131..9889a90be 100644
--- a/public/skins/default/skin.xml
+++ b/public/skins/default/skin.xml
@@ -17,192 +17,190 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/skins/default/skin_data.yml b/public/skins/default/skin_data.yml
index 8bc381d8d..ac25438da 100644
--- a/public/skins/default/skin_data.yml
+++ b/public/skins/default/skin_data.yml
@@ -5,7 +5,7 @@ styles:
mode:
iidx_l:
- - { style: 'scratch', channel: 'sc' }
+ - { style: 'scratch', channel: 'SC' }
- { style: 'white', channel: '1' }
- { style: 'blue', channel: '2' }
- { style: 'white', channel: '3' }
diff --git a/public/skins/default/skin_template.jade b/public/skins/default/skin_template.jade
index d6aec3a81..ed3a85625 100644
--- a/public/skins/default/skin_template.jade
+++ b/public/skins/default/skin_template.jade
@@ -12,17 +12,17 @@ skin(width='1280' height='720')
// body
sprite(image='Note/DX.png'
frame=(cur.width + 'x64+' + cur.x + '+' + (22 + add))
- x=(x) y='y+4' width=(cur.width) height='height'
+ x=(x) y='y+4-12' width=(cur.width) height='height'
visible=visible)
// tail
sprite(image='Note/DX.png'
frame=(cur.width + 'x8+' + cur.x + '+' + (104 + add))
- x=(x) y='y+height+4'
+ x=(x) y='y+height+4-12'
visible=visible)
// head
sprite(image='Note/DX.png'
frame=(cur.width + 'x8+' + cur.x + '+' + (12 + add))
- x=(x) y='y'
+ x=(x) y='y-12'
visible=visible)
mixin notes(columns)
@@ -32,7 +32,7 @@ skin(width='1280' height='720')
- var ch = column.channel
object(key='note_' + ch)
sprite(image='Note/DX.png' frame=(cur.width + 'x12+' + cur.x + '+0')
- x=(x) y='y')
+ x=(x) y='y - 12')
object(key='longnote_' + ch)
+longnote(x, cur, 0, '!active && !missed')
+longnote(x, cur, 100, '!!active && !missed')
@@ -50,8 +50,7 @@ skin(width='1280' height='720')
sprite(image='NoteArea/Flash.png' x='1' y='476' blend='screen'
alpha='1 - (t % 0.4) / 0.4')
group(x='1' mask='283x550+1+0')
- group(y='(t * 500 % 1500) - 500')
- +notes(mode.iidx_l)
+ +notes(mode.iidx_l)
// info panel
sprite(image='InfoPanel/Background.png' y='616')
diff --git a/src/app/index.js b/src/app/index.js
index 7c678c068..d67e5e7f5 100644
--- a/src/app/index.js
+++ b/src/app/index.js
@@ -4,46 +4,44 @@ import * as Scintillator from 'bemuse/scintillator'
import co from 'co'
import $ from 'jquery'
+import Chance from 'chance'
+
+import NoteArea from 'bemuse/game/note-area'
export function main() {
co(function*() {
let skin = yield Scintillator.load('/skins/default/skin.xml')
let context = new Scintillator.Context(skin)
+ let notes = generateRandomNotes()
+ let area = new NoteArea(notes)
+
let data = { }
+ let columns = ['SC', '1', '2', '3', '4', '5', '6', '7']
+
+ function updateNotes() {
+ let p = data.t * 180 / 60
+ let entities = area.getVisibleNotes(p, p + (5 / 3), 550)
+ for (let column of columns) {
+ data[`note_${column}`] = entities.filter(entity =>
+ !entity.height && entity.column === column)
+ data[`longnote_${column}`] = entities.filter(entity =>
+ entity.height && entity.column === column)
+ .map(entity => Object.assign({ }, entity, {
+ active: entity.y + entity.height > 550
+ }))
+ }
+ }
- data['note_sc'] = [ { key: 1, y: 10 }, { key: 2, y: 160 } ]
- data['note_1'] = [ { key: 1, y: 20 }, { key: 2, y: 150 } ]
- data['note_2'] = [ { key: 1, y: 30 }, { key: 2, y: 140 } ]
- data['note_3'] = [ { key: 1, y: 40 }, { key: 2, y: 130 } ]
- data['note_4'] = [ { key: 1, y: 50 }, { key: 2, y: 120 } ]
- data['note_5'] = [ { key: 1, y: 60 }, { key: 2, y: 110 } ]
- data['note_6'] = [ { key: 1, y: 70 }, { key: 2, y: 90 } ]
- data['note_7'] = [ { key: 1, y: 80 } ]
-
- data['longnote_sc'] = [ { key: 1, active: false, y: 210, height: 0 },
- { key: 3, active: true, y: 40, height: 100,
- missed: true, }, ]
- data['longnote_1'] = [ { key: 1, active: false, y: 220, height: 10 } ]
- data['longnote_2'] = [ { key: 1, active: false, y: 230, height: 20 } ]
- data['longnote_3'] = [ { key: 1, active: false, y: 240, height: 40,
- missed: true, } ]
- data['longnote_4'] = [ { key: 1, active: false, y: 250, height: 60 } ]
- data['longnote_5'] = [ { key: 1, active: false, y: 260, height: 80 } ]
- data['longnote_6'] = [ { key: 1, active: false, y: 270, height: 70,
- missed: true, } ]
- data['longnote_7'] = [ { key: 1, active: false, y: 280, height: 60 } ]
-
- for (let i of ['longnote_sc', 'longnote_1', 'longnote_2', 'longnote_3',
- 'longnote_4', 'longnote_5', 'longnote_6', 'longnote_7', ]) {
- let y = data[i][0].y + data[i][0].height + 50
- let height = 450 - y
- data[i].push({ key: 2, y, height, active: true })
+ for (let column of columns) {
+ data[`note_${column}`] = []
+ data[`longnote_${column}`] = []
}
let started = new Date().getTime()
let draw = () => {
data.t = (new Date().getTime() - started) / 1000
+ updateNotes()
context.render(data)
}
draw()
@@ -57,6 +55,30 @@ export function main() {
}
+function generateRandomNotes() {
+ let notes = []
+ let chance = new Chance(1234)
+ let columns = ['SC', '1', '2', '3', '4', '5', '6', '7']
+ let nextId = 1
+ for (let column of columns) {
+ let position = 4
+ for (let j = 0; j < 2000; j ++) {
+ position += chance.integer({ min: 1, max: 6 }) / 8
+ let length = chance.bool({ likelihood: 20 }) ?
+ chance.integer({ min: 1, max: 8 }) / 8 : 0
+ let id = nextId++
+ if (length > 0) {
+ let end = { position: position + length }
+ notes.push({ position: position, end, column, id })
+ position = end.position
+ } else {
+ notes.push({ position: position, column, id })
+ }
+ }
+ }
+ return notes
+}
+
function showCanvas(view) {
var { width, height } = view
diff --git a/src/game/note-area.js b/src/game/note-area.js
new file mode 100644
index 000000000..3d7b090e8
--- /dev/null
+++ b/src/game/note-area.js
@@ -0,0 +1,36 @@
+
+import R from 'ramda'
+
+export class NoteArea {
+ constructor(notes) {
+ this._notes = R.sortBy(position, notes)
+ }
+ getVisibleNotes(lower, upper, height) {
+ return this._notes.filter(note =>
+ note.end ?
+ !(note.position > upper || note.end.position < lower) :
+ !(note.position > upper || note.position < lower))
+ .map(note => {
+ if (!note.end) {
+ return { key: note.id, y: y(lower, upper, note.position, height),
+ column: note.column, }
+ } else {
+ let head = y(lower, upper, note.position, height)
+ let tail = y(lower, upper, note.end.position, height)
+ return { key: note.id, y: Math.min(head, tail),
+ height: Math.abs(head - tail),
+ column: note.column, }
+ }
+ })
+ }
+}
+
+export default NoteArea
+
+function y(lower, upper, position, height) {
+ return height - (position - lower) / (upper - lower) * height
+}
+
+function position(event) {
+ return event.position
+}
diff --git a/src/scintillator/expression/index.js b/src/scintillator/expression/index.js
index 608fd2c28..cca63e565 100644
--- a/src/scintillator/expression/index.js
+++ b/src/scintillator/expression/index.js
@@ -5,7 +5,9 @@ let log = debug('scintillator:expression')
import parser from './parser.pegjs'
function createFunction(code) {
- return eval('(function(get) { return ' + code + ' })')
+ let fn = eval('(function(get) { return ' + code + ' })')
+ fn.displayName = '(' + code + ')'
+ return fn
}
export function Expression(text) {
diff --git a/src/scintillator/nodes/lib/instance.js b/src/scintillator/nodes/lib/instance.js
index 1a9c15a44..3e63d7c1c 100644
--- a/src/scintillator/nodes/lib/instance.js
+++ b/src/scintillator/nodes/lib/instance.js
@@ -17,8 +17,9 @@ export function Instance(context, callback) {
},
bind(...pipeline) {
let sideEffect = onChange(pipeline.pop())
- helper.onData(function(value) {
- for (let f of pipeline) value = f(value)
+ helper.onData(function applyBinding(value) {
+ // using var here to optimize
+ for (var i = 0; i < pipeline.length; i ++) value = pipeline[i](value)
sideEffect(value)
})
},