P2: Multiplayer improvements
This commit is contained in:
parent
1619622257
commit
25d705ffcf
@ -32,3 +32,8 @@
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
}
|
||||
#p2-cancel-button{
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: -55px;
|
||||
}
|
||||
|
@ -170,6 +170,7 @@ kbd{
|
||||
}
|
||||
.taibtn{
|
||||
display: inline-block;
|
||||
background: #f6ead4;
|
||||
padding: 0.4em 0.4em;
|
||||
border-radius: 0.5em;
|
||||
border: 0.1em rgba(218, 205, 178, 1) solid;
|
||||
|
@ -16,6 +16,7 @@ class Circle{
|
||||
this.lastFrame = this.ms + 100
|
||||
this.animationEnded = false
|
||||
this.timesHit = 0
|
||||
this.timesKa = 0
|
||||
this.requiredHits = config.requiredHits || 0
|
||||
this.rendaPlayed = false
|
||||
this.gogoTime = config.gogoTime
|
||||
@ -57,8 +58,11 @@ class Circle{
|
||||
this.score = score
|
||||
this.isPlayed = score <= 0 ? score - 1 : (big ? 2 : 1)
|
||||
}
|
||||
hit(){
|
||||
hit(keysKa){
|
||||
this.timesHit++
|
||||
if(keysKa){
|
||||
this.timesKa++
|
||||
}
|
||||
}
|
||||
getScore(){
|
||||
return this.score
|
||||
|
@ -32,13 +32,13 @@ class Controller{
|
||||
run(syncWith){
|
||||
this.game.run()
|
||||
this.view.run()
|
||||
this.startMainLoop()
|
||||
if(syncWith){
|
||||
syncWith.run()
|
||||
syncWith.game.elapsedTime = this.game.elapsedTime
|
||||
syncWith.game.startDate = this.game.startDate
|
||||
this.syncWith = syncWith
|
||||
}
|
||||
this.startMainLoop()
|
||||
if(!this.multiplayer){
|
||||
debugObj.controller = this
|
||||
if(debugObj.debug){
|
||||
|
@ -54,7 +54,9 @@ class Game{
|
||||
this.checkPlays()
|
||||
// Event operations
|
||||
this.whenFadeoutMusic()
|
||||
this.whenLastCirclePlayed()
|
||||
if(this.controller.multiplayer !== 2){
|
||||
this.whenLastCirclePlayed()
|
||||
}
|
||||
}
|
||||
getCircles(){
|
||||
return this.songData.circles
|
||||
@ -91,9 +93,13 @@ class Game{
|
||||
circle.played(-1, false)
|
||||
this.updateCurrentCircle()
|
||||
if(this.controller.multiplayer === 1){
|
||||
p2.send("drumroll", {
|
||||
var value = {
|
||||
pace: (ms - circle.getMS()) / circle.timesHit
|
||||
})
|
||||
}
|
||||
if(type === "drumroll" || type === "daiDrumroll"){
|
||||
value.kaAmount = circle.timesKa / circle.timesHit
|
||||
}
|
||||
p2.send("drumroll", value)
|
||||
}
|
||||
}else{
|
||||
var currentScore = 0
|
||||
@ -207,11 +213,15 @@ class Game{
|
||||
this.updateGlobalScore(score, typeDai && keyDai ? 2 : 1, circle.gogoTime)
|
||||
this.updateCurrentCircle()
|
||||
if(this.controller.multiplayer == 1){
|
||||
p2.send("note", {
|
||||
var value = {
|
||||
score: score,
|
||||
ms: circle.getMS() - currentTime,
|
||||
dai: typeDai ? keyDai ? 2 : 1 : 0
|
||||
})
|
||||
}
|
||||
if((!keysDon || !typeDon) && (!keysKa || !typeKa)){
|
||||
value.reverse = true
|
||||
}
|
||||
p2.send("note", value)
|
||||
}
|
||||
}else{
|
||||
if(circle.getMS() > currentTime || currentTime > circle.getEndTime()){
|
||||
@ -223,9 +233,9 @@ class Game{
|
||||
this.checkBalloon(circle)
|
||||
}
|
||||
}else if((keysDon || keysKa) && (type === "drumroll" || type === "daiDrumroll")){
|
||||
this.checkDrumroll(circle)
|
||||
this.checkDrumroll(circle, keysKa)
|
||||
if(keyDai){
|
||||
this.checkDrumroll(circle)
|
||||
this.checkDrumroll(circle, keysKa)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -249,11 +259,11 @@ class Game{
|
||||
this.globalScore.drumroll ++
|
||||
this.globalScore.points += score
|
||||
}
|
||||
checkDrumroll(circle){
|
||||
checkDrumroll(circle, keysKa){
|
||||
var ms = this.elapsedTime
|
||||
var dai = circle.getType() === "daiDrumroll"
|
||||
var score = 100
|
||||
circle.hit()
|
||||
circle.hit(keysKa)
|
||||
var keyTime = this.controller.getKeyTime()
|
||||
if(circle.getType() === "drumroll"){
|
||||
var sound = keyTime["don"] > keyTime["ka"] ? "don" : "ka"
|
||||
@ -275,11 +285,24 @@ class Game{
|
||||
this.globalScore.points += score * (dai ? 2 : 1)
|
||||
}
|
||||
whenLastCirclePlayed(){
|
||||
var circles = this.songData.circles
|
||||
var lastCircle = circles[circles.length - 1]
|
||||
var ms = this.elapsedTime
|
||||
if(!this.fadeOutStarted && ms >= lastCircle.getEndTime() + 2000){
|
||||
if(!this.lastCircle){
|
||||
var circles = this.songData.circles
|
||||
this.lastCircle = circles[circles.length - 1].getEndTime()
|
||||
if(this.controller.multiplayer){
|
||||
var syncWith = this.controller.syncWith
|
||||
var syncCircles = syncWith.game.songData.circles
|
||||
var syncLastCircle = syncCircles[syncCircles.length - 1].getEndTime()
|
||||
if(syncLastCircle > this.lastCircle){
|
||||
this.lastCircle = syncLastCircle
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!this.fadeOutStarted && ms >= this.lastCircle + 2000){
|
||||
this.fadeOutStarted = ms
|
||||
if(this.controller.multiplayer){
|
||||
this.controller.syncWith.game.fadeOutStarted = ms
|
||||
}
|
||||
}
|
||||
}
|
||||
whenFadeoutMusic(){
|
||||
|
@ -65,12 +65,18 @@ class loadSong{
|
||||
loadingText.firstChild.data = waitingText
|
||||
loadingText.setAttribute("alt", waitingText)
|
||||
|
||||
this.cancelButton = document.getElementById("p2-cancel-button")
|
||||
this.cancelButton.style.display = "inline-block"
|
||||
pageEvents.add(this.cancelButton, ["mousedown", "touchstart"], this.cancelLoad.bind(this))
|
||||
|
||||
this.song2Data = this.songData
|
||||
this.selectedSong2 = this.selectedSong
|
||||
pageEvents.add(p2, "message", event => {
|
||||
if(event.type === "gameload"){
|
||||
this.cancelButton.style.display = ""
|
||||
|
||||
if(event.value === this.selectedSong.difficulty){
|
||||
p2.send("gamestart")
|
||||
this.startMultiplayer()
|
||||
}else{
|
||||
this.selectedSong2 = {
|
||||
title: this.selectedSong.title,
|
||||
@ -80,13 +86,13 @@ class loadSong{
|
||||
offset: this.selectedSong.offset
|
||||
}
|
||||
if(this.selectedSong.type === "tja"){
|
||||
p2.send("gamestart")
|
||||
this.startMultiplayer()
|
||||
}else{
|
||||
loader.ajax(this.getSongPath(this.selectedSong2)).then(data => {
|
||||
this.song2Data = data.replace(/\0/g, "").split("\n")
|
||||
p2.send("gamestart")
|
||||
this.startMultiplayer()
|
||||
}, () => {
|
||||
p2.send("gamestart")
|
||||
this.startMultiplayer()
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -97,6 +103,9 @@ class loadSong{
|
||||
var taikoGame1 = new Controller(this.selectedSong, this.songData, false, 1, this.touchEnabled)
|
||||
var taikoGame2 = new Controller(this.selectedSong2, this.song2Data, true, 2, this.touchEnabled)
|
||||
taikoGame1.run(taikoGame2)
|
||||
}else if(event.type === "left" || event.type === "gameend"){
|
||||
this.clean()
|
||||
new SongSelect(false, false, this.touchEnabled)
|
||||
}
|
||||
})
|
||||
p2.send("join", {
|
||||
@ -110,7 +119,37 @@ class loadSong{
|
||||
taikoGame.run()
|
||||
}
|
||||
}
|
||||
startMultiplayer(repeat){
|
||||
if(document.hasFocus()){
|
||||
p2.send("gamestart")
|
||||
}else{
|
||||
if(!repeat){
|
||||
for(var i = 0; i < 3; i++){
|
||||
assets.sounds["note_don"].play(i * 0.2)
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.startMultiplayer(true)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
cancelLoad(event){
|
||||
if(event.type === "mousedown"){
|
||||
if(event.which !== 1){
|
||||
return
|
||||
}
|
||||
}else{
|
||||
event.preventDefault()
|
||||
}
|
||||
p2.send("leave")
|
||||
assets.sounds["don"].play()
|
||||
this.cancelButton.style.pointerEvents = "none"
|
||||
}
|
||||
clean(){
|
||||
pageEvents.remove(p2, "message")
|
||||
if(this.cancelButton){
|
||||
pageEvents.remove(this.cancelButton, ["mousedown", "touchstart"])
|
||||
delete this.cancelButton
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,15 +20,19 @@ class Mekadon{
|
||||
this.playAt(circle, 0, 450)
|
||||
}
|
||||
}
|
||||
playAt(circle, ms, score, dai){
|
||||
playAt(circle, ms, score, dai, reverse){
|
||||
var currentMs = circle.getMS() - this.getMS()
|
||||
if(ms > currentMs - 10){
|
||||
return this.playNow(circle, score, dai)
|
||||
return this.playNow(circle, score, dai, reverse)
|
||||
}
|
||||
}
|
||||
playDrumrollAt(circle, ms, pace){
|
||||
playDrumrollAt(circle, ms, pace, kaAmount){
|
||||
if(pace && this.getMS() >= this.lastHit + pace){
|
||||
this.playAt(circle, ms)
|
||||
var score = 1
|
||||
if(kaAmount > 0){
|
||||
score = Math.random() > kaAmount ? 1 : 2
|
||||
}
|
||||
this.playAt(circle, ms, score)
|
||||
}
|
||||
}
|
||||
miss(circle){
|
||||
@ -41,7 +45,7 @@ class Mekadon{
|
||||
return true
|
||||
}
|
||||
}
|
||||
playNow(circle, score, dai){
|
||||
playNow(circle, score, dai, reverse){
|
||||
var kbd = this.controller.getBindings()
|
||||
var type = circle.getType()
|
||||
var keyDai = false
|
||||
@ -54,12 +58,19 @@ class Mekadon{
|
||||
var ms = circle.getMS()
|
||||
}
|
||||
|
||||
if(reverse){
|
||||
if(type === "don" || type === "daiDon"){
|
||||
type = "ka"
|
||||
}else if(type === "ka" || type === "daiKa"){
|
||||
type = "don"
|
||||
}
|
||||
}
|
||||
if(type == "daiDon" && playDai){
|
||||
this.setKey(kbd["don_l"], ms)
|
||||
this.setKey(kbd["don_r"], ms)
|
||||
this.lr = false
|
||||
keyDai = true
|
||||
}else if(type == "don" || type == "daiDon" || drumrollNotes){
|
||||
}else if(type == "don" || type == "daiDon" || drumrollNotes && score !== 2){
|
||||
this.setKey(this.lr ? kbd["don_l"] : kbd["don_r"], ms)
|
||||
this.lr = !this.lr
|
||||
}else if(type == "daiKa" && playDai){
|
||||
@ -67,7 +78,7 @@ class Mekadon{
|
||||
this.setKey(kbd["ka_r"], ms)
|
||||
this.lr = false
|
||||
keyDai = true
|
||||
}else if(type == "ka" || type == "daiKa"){
|
||||
}else if(type == "ka" || type == "daiKa" || drumrollNotes){
|
||||
this.setKey(this.lr ? kbd["ka_l"] : kbd["ka_r"], ms)
|
||||
this.lr = !this.lr
|
||||
}
|
||||
@ -77,7 +88,7 @@ class Mekadon{
|
||||
}
|
||||
this.game.checkBalloon(circle)
|
||||
}else if(type === "drumroll" || type === "daiDrumroll"){
|
||||
this.game.checkDrumroll(circle)
|
||||
this.game.checkDrumroll(circle, score === 2)
|
||||
}else{
|
||||
this.controller.displayScore(score)
|
||||
this.game.updateCombo(score)
|
||||
|
@ -106,6 +106,7 @@ class P2Connection{
|
||||
this.notes = []
|
||||
this.drumrollPace = 45
|
||||
this.dai = 2
|
||||
this.kaAmount = 0
|
||||
this.results = false
|
||||
break
|
||||
case "gameend":
|
||||
@ -130,6 +131,9 @@ class P2Connection{
|
||||
break
|
||||
case "drumroll":
|
||||
this.drumrollPace = response.value.pace
|
||||
if("kaAmount" in response.value){
|
||||
this.kaAmount = response.value.kaAmount
|
||||
}
|
||||
break
|
||||
case "session":
|
||||
this.clearMessage("users")
|
||||
@ -160,7 +164,7 @@ class P2Connection{
|
||||
}
|
||||
|
||||
if(drumrollNotes){
|
||||
mekadon.playDrumrollAt(circle, 0, this.drumrollPace)
|
||||
mekadon.playDrumrollAt(circle, 0, this.drumrollPace, type === "drumroll" || type === "daiDrumroll" ? this.kaAmount : 0)
|
||||
}else if(this.notes.length === 0){
|
||||
mekadon.play(circle)
|
||||
}else{
|
||||
@ -170,7 +174,7 @@ class P2Connection{
|
||||
if(circle.getType() === "daiDon" || circle.getType() === "daiKa"){
|
||||
dai = this.dai
|
||||
}
|
||||
if(mekadon.playAt(circle, note.ms, note.score, dai)){
|
||||
if(mekadon.playAt(circle, note.ms, note.score, dai, note.reverse)){
|
||||
this.notes.shift()
|
||||
}
|
||||
}else{
|
||||
|
@ -2,5 +2,6 @@
|
||||
<div id="loading-song">
|
||||
<div id="loading-don"></div>
|
||||
<div class="loading-text stroke-sub" alt="Loading...">Loading...</div>
|
||||
<div id="p2-cancel-button" class="taibtn stroke-sub" alt="Cancel">Cancel</div>
|
||||
</div>
|
||||
</div>
|
||||
|
31
server.py
31
server.py
@ -145,15 +145,30 @@ async def connection(ws, path):
|
||||
await ws.send(msgobj("gameend"))
|
||||
elif action == "waiting" or action == "loading" or action == "loaded":
|
||||
# Waiting for another user
|
||||
if type == "leave" and not user["session"]:
|
||||
if type == "leave":
|
||||
# Stop waiting
|
||||
del server_status["waiting"][user["gameid"]]
|
||||
del user["gameid"]
|
||||
user["action"] = "ready"
|
||||
await asyncio.wait([
|
||||
ws.send(msgobj("left")),
|
||||
notify_status()
|
||||
])
|
||||
if user["session"]:
|
||||
if "other_user" in user and "ws" in user["other_user"]:
|
||||
user["action"] = "songsel"
|
||||
await asyncio.wait([
|
||||
ws.send(msgobj("left")),
|
||||
user["other_user"]["ws"].send(msgobj("users", []))
|
||||
])
|
||||
else:
|
||||
user["action"] = "ready"
|
||||
user["session"] = False
|
||||
await asyncio.wait([
|
||||
ws.send(msgobj("gameend")),
|
||||
ws.send(status_event())
|
||||
])
|
||||
else:
|
||||
del server_status["waiting"][user["gameid"]]
|
||||
del user["gameid"]
|
||||
user["action"] = "ready"
|
||||
await asyncio.wait([
|
||||
ws.send(msgobj("left")),
|
||||
notify_status()
|
||||
])
|
||||
if action == "loading":
|
||||
if type == "gamestart":
|
||||
user["action"] = "loaded"
|
||||
|
Loading…
Reference in New Issue
Block a user