mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-17 16:50:31 +00:00
Merge branch 'chim2'
This commit is contained in:
commit
1718af5ba4
5 changed files with 110 additions and 66 deletions
111
index.html
111
index.html
|
|
@ -10,9 +10,10 @@ textarea {
|
|||
<div id="remoteVideos" ></div> <br />
|
||||
<div>
|
||||
Use Up, Down, Left, Right to Move <br />
|
||||
Space to jump <br />
|
||||
Ctrl to sprint <br />
|
||||
Enter to select in menu <br />
|
||||
Z to jump (A) <br />
|
||||
X to sprint (B) <br />
|
||||
C is start button <br />
|
||||
V is select button <br />
|
||||
|
||||
Fullscreen media for better gaming experience<br />
|
||||
</div>
|
||||
|
|
@ -76,7 +77,6 @@ pc.ontrack = function (event) {
|
|||
document.getElementById('remoteVideos').appendChild(el)
|
||||
}
|
||||
|
||||
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
|
||||
pc.onicecandidate = event => {
|
||||
if (event.candidate === null) {
|
||||
var session = btoa(JSON.stringify(pc.localDescription));
|
||||
|
|
@ -115,7 +115,7 @@ keyMap = {
|
|||
}
|
||||
|
||||
INPUT_FPS = 100;
|
||||
INPUT_STATE_PACKET = 10;
|
||||
INPUT_STATE_PACKET = 5;
|
||||
|
||||
stateUnchange = true;
|
||||
unchangePacket = INPUT_STATE_PACKET;
|
||||
|
|
@ -137,7 +137,6 @@ document.body.onkeyup = function(e){
|
|||
};
|
||||
|
||||
|
||||
|
||||
window.startSession = () => {
|
||||
let sd = remoteSessionDescription
|
||||
if (sd === '') {
|
||||
|
|
@ -145,55 +144,65 @@ window.startSession = () => {
|
|||
}
|
||||
|
||||
try {
|
||||
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))),
|
||||
|
||||
// success
|
||||
() => {
|
||||
|
||||
setInterval(() => {
|
||||
// prepare key
|
||||
/*
|
||||
const (
|
||||
ButtonA = iota
|
||||
ButtonB
|
||||
ButtonSelect
|
||||
ButtonStart
|
||||
ButtonUp
|
||||
ButtonDown
|
||||
ButtonLeft
|
||||
ButtonRight
|
||||
)
|
||||
*/
|
||||
|
||||
if (stateUnchange || unchangePacket > 0) {
|
||||
st = "";
|
||||
["a", "b", "select", "start", "up", "down", "left", "right"].forEach(elem => {
|
||||
st += keyState[elem]?1:0;
|
||||
});
|
||||
ss = parseInt(st, 2);
|
||||
console.log(`Key state string: ${st} ==> ${ss}`);
|
||||
|
||||
// send
|
||||
inputChannel.send(ss);
|
||||
|
||||
stateUnchange = false;
|
||||
unchangePacket--;
|
||||
}
|
||||
|
||||
}, 1000 / INPUT_FPS)
|
||||
|
||||
|
||||
},
|
||||
|
||||
// error callback
|
||||
(exp) => {
|
||||
console.log("setRemoteDescription failed, we are doomed");
|
||||
console.log(exp);
|
||||
});
|
||||
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))));
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
}
|
||||
|
||||
var timer = null;
|
||||
function sendInput() {
|
||||
// prepare key
|
||||
/*
|
||||
const (
|
||||
ButtonA = iota
|
||||
ButtonB
|
||||
ButtonSelect
|
||||
ButtonStart
|
||||
ButtonUp
|
||||
ButtonDown
|
||||
ButtonLeft
|
||||
ButtonRight
|
||||
)
|
||||
*/
|
||||
|
||||
if (stateUnchange || unchangePacket > 0) {
|
||||
st = "";
|
||||
["a", "b", "select", "start", "up", "down", "left", "right"].forEach(elem => {
|
||||
st += keyState[elem]?1:0;
|
||||
});
|
||||
ss = parseInt(st, 2);
|
||||
console.log(`Key state string: ${st} ==> ${ss}`);
|
||||
|
||||
// send
|
||||
inputChannel.send(ss);
|
||||
|
||||
stateUnchange = false;
|
||||
unchangePacket--;
|
||||
}
|
||||
}
|
||||
|
||||
function startInput() {
|
||||
if (timer == null) {
|
||||
timer = setInterval(sendInput, 1000 / INPUT_FPS)
|
||||
}
|
||||
}
|
||||
|
||||
function endInput() {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
|
||||
pc.oniceconnectionstatechange = e => {
|
||||
log(pc.iceConnectionState);
|
||||
if (pc.iceConnectionState === "connected") {
|
||||
startInput();
|
||||
}
|
||||
else if (pc.iceConnectionState === "disconnected") {
|
||||
endInput();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</html>
|
||||
|
|
|
|||
43
main.go
43
main.go
|
|
@ -6,7 +6,8 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
// "time"
|
||||
|
||||
"github.com/giongto35/game-online/ui"
|
||||
"github.com/giongto35/game-online/util"
|
||||
|
|
@ -14,33 +15,37 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var webRTC *webrtc.WebRTC
|
||||
// var webRTC *webrtc.WebRTC
|
||||
var width = 256
|
||||
var height = 240
|
||||
var gameName = "Legend of Pokemon.nes"
|
||||
|
||||
// var FPS = 60
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
func startGame(path string, imageChannel chan *image.RGBA, inputChannel chan int) {
|
||||
ui.Run([]string{path}, imageChannel, inputChannel)
|
||||
func startGame(path string, imageChannel chan *image.RGBA, inputChannel chan int, webRTC *webrtc.WebRTC) {
|
||||
ui.Run([]string{path}, imageChannel, inputChannel, webRTC)
|
||||
}
|
||||
|
||||
func main() {
|
||||
imageChannel := make(chan *image.RGBA, 100)
|
||||
// imageChannel := make(chan *image.RGBA, 100)
|
||||
fmt.Println("http://localhost:8000")
|
||||
webRTC = webrtc.NewWebRTC()
|
||||
// webRTC = webrtc.NewWebRTC()
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/", getWeb).Methods("GET")
|
||||
router.HandleFunc("/session", postSession).Methods("POST")
|
||||
|
||||
go http.ListenAndServe(":8000", router)
|
||||
// go http.ListenAndServe(":8000", router)
|
||||
http.ListenAndServe(":8000", router)
|
||||
|
||||
// start screenshot loop, wait for connection
|
||||
go screenshotLoop(imageChannel)
|
||||
startGame("games/"+gameName, imageChannel, webRTC.InputChannel)
|
||||
time.Sleep(time.Minute)
|
||||
|
||||
// go screenshotLoop(imageChannel)
|
||||
// startGame("games/"+gameName, imageChannel, webRTC.InputChannel)
|
||||
// time.Sleep(time.Minute)
|
||||
}
|
||||
|
||||
func getWeb(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -58,20 +63,34 @@ func postSession(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
r.Body.Close()
|
||||
|
||||
webRTC := webrtc.NewWebRTC()
|
||||
|
||||
localSession, err := webRTC.StartClient(string(bs), width, height)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
imageChannel := make(chan *image.RGBA, 100)
|
||||
go screenshotLoop(imageChannel, webRTC)
|
||||
go startGame("games/"+gameName, imageChannel, webRTC.InputChannel, webRTC)
|
||||
|
||||
w.Write([]byte(localSession))
|
||||
}
|
||||
|
||||
func screenshotLoop(imageChannel chan *image.RGBA) {
|
||||
// func screenshotLoop(imageChannel chan *image.RGBA) {
|
||||
func screenshotLoop(imageChannel chan *image.RGBA, webRTC *webrtc.WebRTC) {
|
||||
for image := range imageChannel {
|
||||
// Client stopped
|
||||
if webRTC.IsClosed() {
|
||||
break
|
||||
}
|
||||
|
||||
// encode frame
|
||||
if webRTC.IsConnected() {
|
||||
yuv := util.RgbaToYuv(image)
|
||||
webRTC.ImageChannel <- yuv
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
// time.Sleep(time.Duration(1000 / FPS) * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/giongto35/game-online/nes"
|
||||
"github.com/giongto35/game-online/webrtc"
|
||||
)
|
||||
|
||||
type View interface {
|
||||
|
|
@ -20,14 +21,16 @@ type Director struct {
|
|||
timestamp float64
|
||||
imageChannel chan *image.RGBA
|
||||
inputChannel chan int
|
||||
webRTC *webrtc.WebRTC
|
||||
}
|
||||
|
||||
func NewDirector(imageChannel chan *image.RGBA, inputChannel chan int) *Director {
|
||||
func NewDirector(imageChannel chan *image.RGBA, inputChannel chan int, webRTC *webrtc.WebRTC) *Director {
|
||||
// func NewDirector(audio *Audio, imageChannel chan *image.RGBA, inputChannel chan int) *Director {
|
||||
director := Director{}
|
||||
// director.audio = audio
|
||||
director.imageChannel = imageChannel
|
||||
director.inputChannel = inputChannel
|
||||
director.webRTC = webRTC
|
||||
return &director
|
||||
}
|
||||
|
||||
|
|
@ -61,6 +64,11 @@ func (d *Director) Start(paths []string) {
|
|||
|
||||
func (d *Director) Run() {
|
||||
for {
|
||||
// quit game
|
||||
if d.webRTC.IsClosed() {
|
||||
break
|
||||
}
|
||||
|
||||
d.Step()
|
||||
}
|
||||
d.SetView(nil)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"runtime"
|
||||
|
||||
// "github.com/gordonklaus/portaudio"
|
||||
"github.com/giongto35/game-online/webrtc"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -23,7 +24,7 @@ func init() {
|
|||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
func Run(paths []string, imageChannel chan *image.RGBA, inputChannel chan int) {
|
||||
func Run(paths []string, imageChannel chan *image.RGBA, inputChannel chan int, webRTC *webrtc.WebRTC) {
|
||||
// initialize audio
|
||||
// portaudio.Initialize()
|
||||
// defer portaudio.Terminate()
|
||||
|
|
@ -35,7 +36,7 @@ func Run(paths []string, imageChannel chan *image.RGBA, inputChannel chan int) {
|
|||
// defer audio.Stop()
|
||||
|
||||
// run director
|
||||
director := NewDirector(imageChannel, inputChannel)
|
||||
director := NewDirector(imageChannel, inputChannel, webRTC)
|
||||
// director := NewDirector(audio, imageChannel, inputChannel)
|
||||
director.Start(paths)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ type WebRTC struct {
|
|||
connection *webrtc.PeerConnection
|
||||
encoder *vpxEncoder.VpxEncoder
|
||||
isConnected bool
|
||||
isClosed bool
|
||||
// for yuvI420 image
|
||||
ImageChannel chan []byte
|
||||
InputChannel chan int
|
||||
|
|
@ -164,6 +165,7 @@ func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, e
|
|||
w.StopClient()
|
||||
}
|
||||
})
|
||||
|
||||
//w.listenInputChannel()
|
||||
// Data channel
|
||||
w.connection.OnDataChannel(func(d *webrtc.DataChannel) {
|
||||
|
|
@ -210,6 +212,7 @@ func (w *WebRTC) StopClient() {
|
|||
w.connection.Close()
|
||||
}
|
||||
w.connection = nil
|
||||
w.isClosed = true
|
||||
}
|
||||
|
||||
// IsConnected comment
|
||||
|
|
@ -217,6 +220,10 @@ func (w *WebRTC) IsConnected() bool {
|
|||
return w.isConnected
|
||||
}
|
||||
|
||||
func (w *WebRTC) IsClosed() bool {
|
||||
return w.isClosed
|
||||
}
|
||||
|
||||
func (w *WebRTC) startStreaming(vp8Track *webrtc.Track) {
|
||||
fmt.Println("Start streaming")
|
||||
// send screenshot
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue