Skip to content

Instantly share code, notes, and snippets.

@chiepomme
Last active December 19, 2015 18:48
Show Gist options
  • Save chiepomme/6000978 to your computer and use it in GitHub Desktop.
Save chiepomme/6000978 to your computer and use it in GitHub Desktop.
package Mascotty
import javafx.application.Application
import javafx.stage.StageStyle
import javafx.stage.Stage
import javafx.scene.Scene
import javafx.scene.layout.VBox
import javafx.scene.paint.Color
import javafx.scene.image.ImageView
import javafx.scene.image.Image
import javafx.scene.control.TextField
import javafx.scene.input.KeyCode
import kotlin.dom.parseXml
import java.util.ArrayList
import org.w3c.dom.Node
import java.util.regex.Pattern
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeType
import org.w3c.dom.Element
import java.io.File
import javax.sound.sampled.AudioSystem
import javax.sound.sampled.Clip
fun main(args:Array<String>){
Application.launch(Mascotty.javaClass)
}
fun org.w3c.dom.Node.getAttribute(name:String):String?{
return this.getAttributes().getNamedItem(name)?.getNodeValue()
}
fun org.w3c.dom.Node.childs():ArrayList<Node>{
val result = ArrayList<Node>()
val children = this.getChildNodes()
for(i in 0..children.getLength()){
val item = children.item(i)
if(item is Element) result.add(item)
}
return result
}
data class Rule(
val pattern :Pattern,
val audio :String? = null,
val image :String? = null
)
object Mascotty :Application(){
var line :Clip? = null
override fun start(stage :Stage?){
if(stage == null) return
val ruleFile = File("rule.xml")
if(!ruleFile.canRead()) throw RuntimeException("rule.xml が存在しません。")
val rules = ArrayList<Rule>()
val element = parseXml(ruleFile).getDocumentElement()!!
val ruleNodes = element.childs()
for(ruleNode in ruleNodes){
val message = ruleNode.getAttribute("message")
if(message == null) continue
val children = ruleNode.childs()
val audioNodes = children.filter { (node) -> node.getNodeName() == "audio" }
val audioRelPath = audioNodes.firstOrNull()?.getAttribute("path")
val audioAbsPath = if(audioRelPath != null) File(ruleFile.getParent(), audioRelPath).getCanonicalPath() else null
val imageNodes = children.filter { (node) -> node.getNodeName() == "image" }
val imageRelPath = imageNodes.firstOrNull()?.getAttribute("path")
val imageAbsPath = if(imageRelPath != null) File(ruleFile.getParent(), imageRelPath).getCanonicalPath() else null
rules.add(Rule(message.toRegex(), audioAbsPath, imageAbsPath))
}
println(rules)
val mainContainer = VBox()
val scene = Scene(mainContainer)
scene.setFill(Color.color(1.0, 1.0, 1.0, 0.0))
val imageView = ImageView(File("default.png").toURI().toString())
val textBox = TextField("話しかけたい言葉を入れてEnterを押してね")
mainContainer.getChildren()?.add(imageView)
mainContainer.getChildren()?.add(textBox)
var initialX = 0.0
var initialY = 0.0
imageView.setOnMousePressed({(e) ->
initialX = e?.getX()!!
initialY = e?.getY()!!
})
imageView.setOnMouseDragged({(e) ->
stage.setX(e?.getScreenX()!! - initialX)
stage.setY(e?.getScreenY()!! - initialY)
})
textBox.setOnKeyPressed(
{(keyEvent) ->
if(keyEvent?.getCode() == KeyCode.ENTER){
val rule = rules.find { (rule) -> rule.pattern.matcher(textBox.getText()!!).matches() }
if(rule != null){
textBox.setText("")
if(rule.image != null) setImage(imageView, rule.image)
if(rule.audio != null) playAudio(rule.audio)
}
}
}
)
stage.setTitle("Mascotty")
stage.setScene(scene)
stage.setMinWidth(100.0)
stage.initStyle(StageStyle.TRANSPARENT)
stage.show()
}
fun setImage(imageView:ImageView, path:String){
val file = File(path)
if(!file.canRead()) return
imageView.setImage(Image(file.toURI().toString()))
}
fun playAudio(path:String){
val file = File(path)
if(!file.canRead()) return
if(line != null){
line?.stop()
}
val ais = AudioSystem.getAudioInputStream(file)
line = AudioSystem.getClip()!!
line?.open(ais)
line?.start()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment