Re: CoolBasic & netti = cbNetwork
Posted: Sat Feb 07, 2009 10:57 am
hmm... Ohjelma kaatuu erroriin "MakeImage failed"Valtzu wrote:Koska SCREEN-komento poistaa kaikki kuvat muistista.
Game Making Should Be Easy...
https://www.coolbasic.com/phpBB3/
hmm... Ohjelma kaatuu erroriin "MakeImage failed"Valtzu wrote:Koska SCREEN-komento poistaa kaikki kuvat muistista.
No enpä osaa sanoa tuohon mitään. Itselläni koodi toimii hyvin kun poistaa tuon SCREEN -rivinJani wrote:hmm... Ohjelma kaatuu erroriin "MakeImage failed"
zHelmet wrote:Mitä ClientState() funktio kertoo??
Meillähän on täällä oikein kunnon koodari. Siis jos aikoo jotakin tehdä niin ota ny selvää mitä funktios edes tekee!Jani wrote:Enpä tiedä...
Tuo "Enpä tiedä..." oli ihan vain siihen minun viestiin.temu92 wrote:zHelmet wrote:Mitä ClientState() funktio kertoo??Meillähän on täällä oikein kunnon koodari. Siis jos aikoo jotakin tehdä niin ota ny selvää mitä funktios edes tekee!Jani wrote:Enpä tiedä...
Sinun pitää tehdä clienteille joku type/taulukko, johon sitten tallennat niiden ID:n. Sen ID:n perusteella sitten lähetät viestejä eteenpäin, kuten chat-esimerkissä. Menee katsos vaikeaksi kun clientteja on enemmän kuin yksi.Jani wrote:Yritin tehdä for...next rakenteella .
Miten se siis tehdään?
Paras tapa toteuttaa räiskintäpelin datan lähetys? Lisäät lähetettävien listaan tarvittavan datan ja lähetettäessä tarkistat kyseiselle clientille osoitetut viestit ja laitat ne menemään. Tarkenna vaikkapa vähän kysymystäsi niin voin vastailla tarkemmin itsekin [/edit]zHelmet wrote:Millä tyylillä olisi paras tapa toteuttaa räiskintä pelin datan lähetys???
Tarkoititko:VesQ wrote:Sinun pitää tehdä clienteille joku type/taulukko, johon sitten tallennat niiden ID:n. Sen ID:n perusteella sitten lähetät viestejä eteenpäin, kuten chat-esimerkissä. Menee katsos vaikeaksi kun clientteja on enemmän kuin yksi.Jani wrote:Yritin tehdä for...next rakenteella .
Miten se siis tehdään?
EDIT:Paras tapa toteuttaa räiskintäpelin datan lähetys? Lisäät lähetettävien listaan tarvittavan datan ja lähetettäessä tarkistat kyseiselle clientille osoitetut viestit ja laitat ne menemään. Tarkenna vaikkapa vähän kysymystäsi niin voin vastailla tarkemmin itsekin [/edit]zHelmet wrote:Millä tyylillä olisi paras tapa toteuttaa räiskintä pelin datan lähetys???
Code: Select all
For client.CLIENTS = Each CLIENTS
//koodia
Next client
Juu, tuota tarkoitin. Tuossa "//koodia" kohdassa sitten lisätään toiseen typeen tietoa että lähetettävää tavaraa olisi olemassa ja lähetyksen kohdassa koodia sitten laitetaan kaikki varsinaisesti menemään.Jani wrote:Tarkoititko:
Kun client joinaa, niin se lähettää ns. join-tavun.
Sitten server lisää typeen CLIENTS uuden clientin.
Sen jälkeen lähetetään kaikille tieto uudesta tähän tyyliin:Ihan vain varmistuksena.Code: Select all
For client.CLIENTS = Each CLIENTS //koodia Next client
Juup.VesQ wrote:Juu, tuota tarkoitin. Tuossa "//koodia" kohdassa sitten lisätään toiseen typeen tietoa että lähetettävää tavaraa olisi olemassa ja lähetyksen kohdassa koodia sitten laitetaan kaikki varsinaisesti menemään.Jani wrote:Tarkoititko:
Kun client joinaa, niin se lähettää ns. join-tavun.
Sitten server lisää typeen CLIENTS uuden clientin.
Sen jälkeen lähetetään kaikille tieto uudesta tähän tyyliin:Ihan vain varmistuksena.Code: Select all
For client.CLIENTS = Each CLIENTS //koodia Next client
no katos kun olen tehnyt jonkun näköisen sotapelin rungon ja alkeelisen nettipalikka rungon mutta kun clienttejä alkaa tulemaan roimasti lisää niin alkaa tippumaan kaikilta fps ja syy on varmaankin että jokainen clientti lähettää tiedon serverille joka ikinen frame.. Eli pitäiskö tehdä että serveri joka lähettää kyseiselle clientille tiedon että nyt saat antaa tietoa ja sitten clientti lähettää sen vaiko miten?EDIT:Paras tapa toteuttaa räiskintäpelin datan lähetys? Lisäät lähetettävien listaan tarvittavan datan ja lähetettäessä tarkistat kyseiselle clientille osoitetut viestit ja laitat ne menemään. Tarkenna vaikkapa vähän kysymystäsi niin voin vastailla tarkemmin itsekin [/edit]zHelmet wrote:Millä tyylillä olisi paras tapa toteuttaa räiskintä pelin datan lähetys???
Tarkoitatkos tällä nyt sitten ylhäältä päin kuvattua räiskintäpeliä? Jos näin on, niin joka framessa pitää todellakin lähettää vähintään se IDLE-tavu ja liikuttaessa lähetetään koordinaatit ja kääntymiskulma, ammuttaessa tietenkin tieto siitä. Muista vain sitten optimointi: jos voit käyttää tavun kokoisia (As Byte) lähetyksiä (esim. aseen tyyppi) niin käytä niitä. Ei serverille pitäisi tulla hirveää ruuhkaa, jos olet tehnyt nettipalikan pohjan järkevästi, etkä tunge sinne hirmuisesti Goto/GoSubeja & muita hitaita ja turhia tavaroita.zHelmet wrote:no katos kun olen tehnyt jonkun näköisen sotapelin rungon ja alkeelisen nettipalikka rungon mutta kun clienttejä alkaa tulemaan roimasti lisää niin alkaa tippumaan kaikilta fps ja syy on varmaankin että jokainen clientti lähettää tiedon serverille joka ikinen frame.. Eli pitäiskö tehdä että serveri joka lähettää kyseiselle clientille tiedon että nyt saat antaa tietoa ja sitten clientti lähettää sen vaiko miten?EDIT:Paras tapa toteuttaa räiskintäpelin datan lähetys? Lisäät lähetettävien listaan tarvittavan datan ja lähetettäessä tarkistat kyseiselle clientille osoitetut viestit ja laitat ne menemään. Tarkenna vaikkapa vähän kysymystäsi niin voin vastailla tarkemmin itsekin [/edit]zHelmet wrote:Millä tyylillä olisi paras tapa toteuttaa räiskintä pelin datan lähetys???
No tällä jatketaan ehdottomasti, mutta entäs sitten miten tuo palvelimen rasitus eli rasittaako liukuluvut eniten palvelinta?VesQ wrote:Tarkoitatkos tällä nyt sitten ylhäältä päin kuvattua räiskintäpeliä? Jos näin on, niin joka framessa pitää todellakin lähettää vähintään se IDLE-tavu ja liikuttaessa lähetetään koordinaatit ja kääntymiskulma, ammuttaessa tietenkin tieto siitä. Muista vain sitten optimointi: jos voit käyttää tavun kokoisia (As Byte) lähetyksiä (esim. aseen tyyppi) niin käytä niitä. Ei serverille pitäisi tulla hirveää ruuhkaa, jos olet tehnyt nettipalikan pohjan järkevästi, etkä tunge sinne hirmuisesti Goto/GoSubeja & muita hitaita ja turhia tavaroita.
Pähkinänkuoressa: purkka on hyvin huono idea nettipalikassa & rasita palvelinta niin vähän kuin vain voit.
EDIT: Palvelimesta ei kannata tehdä hienoa, eikä siinä kannata käyttää joka framessa DrawScreenia. Parhaimman tuloksen saa, kun käyttää vain Print & muita komentoja, jotka toimivat ilman DrawScreenia, näin saa palvelimen FPS:n jopa yli tuhanteen. Toisin sanoen: grafiikat huitsiin palvelimesta. Jätä vaikka siitä pois myös omien komentojen kirjoittaminen, ellet saa sitä toimimaan järkevästi. (käytä vaikka jotain nappulaa jolla DrawScreen & Input yhdistelmä on päällä, muutoin poissa)
Liukuluvut rasittivat muistaakseni lähes/aivan saman määrän kuin normaalit kokonaislukumuuttujatkin, koska nehän vievät yhtä paljon muistia... en sitten tarkemmin tiedä. Ilmoittele sitten että miten optimointi sujuu, niin voin tarvittaessa autella koodin kanssa yksityisestikin, en minä sitä (koodia siis :p) varastazHelmet wrote:No tällä jatketaan ehdottomasti, mutta entäs sitten miten tuo palvelimen rasitus eli rasittaako liukuluvut eniten palvelinta?
Code: Select all
Include "cbNetwork.CB"
InitServer( 1337, 1000 )
Const INFO_STARTING_CONNECTION = 255
Const INFO_CLOSING_CONNECTION = 254
Const INFO_GET_PLAYERLIST = 253 // Esimerkki
_Net_InitMemBlock()
_Net_PutByte(2)
ServerSend()
Dim nRet As Integer
// Luetaan dataa
nRet = ServerRead()
// Tuli joku virhe. Esimerkiksi timeout eli dataa ei tullut määräaikaan mennessä.
If nRet <> 0 Then x=False
// Muistipalan alussa on aina luetun datan pituus joka luetaan tässä pois
_Net_GetInt()
// Jos datan vastaanotto onnistui
Repeat
While nRet=0
// Mitä dataa on tulossa
netmsg = _Net_GetByte()
// Onko joku liittymässä keskusteluun
If netmsg = 1 Then _Net_PutByte(3)
Wend
Forever
CloseServer()
Code: Select all
Include "cbNetwork.CB"
Const INFO_STARTING_CONNECTION = 255
Const INFO_CLOSING_CONNECTION = 254
Const INFO_GET_PLAYERLIST = 253 // Esimerkki
Dim rtn As Integer
// Käynnistetään client
rtn = InitClient( "localhost", 1337, 1000 ) // timeOut millisekunteina (1000ms = 1s)
// Jos jokin meni vikaan, lopetetaan virheilmoitukseen
If rtn2 <> 0 Then MakeError GetNetErrorString( rtn )
// Alustetaan muistipala
_Net_InitMemBlock()
// Lähetetään serverille tavu, josta se tietää, että client on uusi.
// INFO_STARTING_CONNECTION = 255
_Net_PutByte(1)
ClientSend()
Repeat
rtn = ClientRead()
// Luetaan muistipalan alusta sen koko
_Net_GetInt()
// Luetaan "infotavu"
infoByte = _Net_GetByte()
If infobyte=2 Then
Text 0,0,"I DID IT!!"
EndIf
If infobyte=3 Then
Text 160,0,"THIS IS AWSOM!!"
EndIf
If KeyHit(cbkeyreturn) Then
_Net_PutByte(1)
EndIf
// Jos tietojen luku onnistui
If infobyte<>0 Then Text 100,100,"sgr"
DrawScreen
Until EscapeKey()
_Net_PutByte(INFO_CLOSING_CONNECTION)
ClientSend()
Tuossahan pitää serveri ja client käynnistää tismalleen samaan aikaanphons wrote:EII!! Miten nää toimii!?! Mulla on serveri ja client mutta ne ei toimi yhdessä. HELP!
servu:client:Code: Select all
Include "cbNetwork.CB" InitServer( 1337, 1000 ) Const INFO_STARTING_CONNECTION = 255 Const INFO_CLOSING_CONNECTION = 254 Const INFO_GET_PLAYERLIST = 253 // Esimerkki _Net_InitMemBlock() _Net_PutByte(2) ServerSend() Dim nRet As Integer // Luetaan dataa nRet = ServerRead() // Tuli joku virhe. Esimerkiksi timeout eli dataa ei tullut määräaikaan mennessä. If nRet <> 0 Then x=False // Muistipalan alussa on aina luetun datan pituus joka luetaan tässä pois _Net_GetInt() // Jos datan vastaanotto onnistui Repeat While nRet=0 // Mitä dataa on tulossa netmsg = _Net_GetByte() // Onko joku liittymässä keskusteluun If netmsg = 1 Then _Net_PutByte(3) Wend Forever CloseServer()
Ei ole sisennettyä, kun olen jonkin verran vetänyt copy-pastea sry...Code: Select all
Include "cbNetwork.CB" Const INFO_STARTING_CONNECTION = 255 Const INFO_CLOSING_CONNECTION = 254 Const INFO_GET_PLAYERLIST = 253 // Esimerkki Dim rtn As Integer // Käynnistetään client rtn = InitClient( "localhost", 1337, 1000 ) // timeOut millisekunteina (1000ms = 1s) // Jos jokin meni vikaan, lopetetaan virheilmoitukseen If rtn2 <> 0 Then MakeError GetNetErrorString( rtn ) // Alustetaan muistipala _Net_InitMemBlock() // Lähetetään serverille tavu, josta se tietää, että client on uusi. // INFO_STARTING_CONNECTION = 255 _Net_PutByte(1) ClientSend() Repeat rtn = ClientRead() // Luetaan muistipalan alusta sen koko _Net_GetInt() // Luetaan "infotavu" infoByte = _Net_GetByte() If infobyte=2 Then Text 0,0,"I DID IT!!" EndIf If infobyte=3 Then Text 160,0,"THIS IS AWSOM!!" EndIf If KeyHit(cbkeyreturn) Then _Net_PutByte(1) EndIf // Jos tietojen luku onnistui If infobyte<>0 Then Text 100,100,"sgr" DrawScreen Until EscapeKey() _Net_PutByte(INFO_CLOSING_CONNECTION) ClientSend()
Luet serverissä dataa vain kerran ja sen jälkeen et lue uudestaan?phons wrote:Code: Select all
Dim nRet As Integer // Luetaan dataa nRet = ServerRead() // Tuli joku virhe. Esimerkiksi timeout eli dataa ei tullut määräaikaan mennessä. If nRet <> 0 Then x=False // Muistipalan alussa on aina luetun datan pituus joka luetaan tässä pois _Net_GetInt() // Jos datan vastaanotto onnistui Repeat While nRet=0 // Mitä dataa on tulossa netmsg = _Net_GetByte() // Onko joku liittymässä keskusteluun If netmsg = 1 Then _Net_PutByte(3) Wend Forever CloseServer()
Code: Select all
Dim nRet As Integer
// Luetaan dataa
Repeat
nRet = ServerRead()
// Tuli joku virhe. Esimerkiksi timeout eli dataa ei tullut määräaikaan mennessä.
If nRet = 0 then
// Muistipalan alussa on aina luetun datan pituus joka luetaan tässä pois
_Net_GetInt()
// Jos datan vastaanotto onnistui
netmsg = _Net_GetByte()
// Onko joku liittymässä keskusteluun
If netmsg = 1 Then _Net_PutByte(3)
Forever
CloseServer()
Älä copypastea, vaan ymmärrä. Ei ihmekään ettei koodisi toiminnut, kun et laiskuuttasi jaksanut sitä itse kirjoittaa, vaan pistit vaan suoraan menemään. Nämä nettihöskelit ovat VAIKEITA, niitä ei tehdä copy-pastella!phons wrote:Jani: Mitä sitten? Kyllä minä sen tiedän että molemmat ajetaan .exe tiedostoiksi ja sitten avetaan molemmat...
zHelmet: Okei kokeilen tuota. Hope it works...
Edit: Ei auttanut mitenkään...
Edit2: Voisiko joku lähetää TOIMIVAT: clientti(vastaannottaa 1 inttinä) ja serveri(lähettää 1 inttinä)? Haluaisin tämän oikeasti toimimaan...
Code: Select all
'*** CLIENT ***
SCREEN 640, 480
Include "cbNetwork.cb"
Include "NET_Constants.cb"
Const ADDRESS = "localhost" 'mihin yhdistetään
'PORT <-- määritelty "NET_Constants.cb" tiedostossa
Const TIMEOUT = 1000 'kauan dataa odotellaan
SetWindow "cbNetwork-esimerkki (client)"
// Käynnistetään client.
nRet = InitClient(ADDRESS, PORT, TIMEOUT)
If nRet <> 0 Then
// Tuli joku virhe
errMsg$ = "(" + nRet + ") " + GetNetErrorString(nRet)
MakeError errMsg
EndIf
Global gClientDataSended 'Onko dataa lähetetty?
gClientDataSended = False
Global gInt 'Tallennetaan tähän se kokonaisluku mitä haluttiin
gInt = 0
Repeat
ReadDataFromServer() 'luetaan palvelimelta
SendDataToServer() 'lähetetään palvelimelta
Wait 5 'annetaan prosessorille hengähdystauko
Until EscapeKey() Or gInt <> 0
MakeError "Palvelin lähetti kokonaisluvun "+gInt
//================================================================================
// Luetaan serverin lähettämää dataa
//================================================================================
Function ReadDataFromServer()
// Ei jäädä lukemaan dataa jos mitään ei ole lähetettykään
If gClientDataSended = False Then Return True
// Nyt luetaan
nRet = ClientRead()
// Jos paluuarvo on alle 0 niin kaikki data ei ole vielä tullut palvelimelta
If nRet < 0 Then Return True
// Lukemisessa tuli joku virhe
If nRet <> 0 Then
// Jos virhe oli "Connection timed out" niin ei välitetä siitä
If nRet = 10060 Then Return True
errMsg$ = "(" + nRet + ") " + GetNetErrorString(nRet)
MakeError errMsg
EndIf
//Nollataan muuttuja joka antaa luvan lähettää lisää dataa serverille.
gClientDataSended = False
// Muistipalan alussa on aina saapuneen datan pituus joka luetaan tässä pois
_Net_GetInt()
// Luetaan kaikki viestit läpi
While True
netmsg = _Net_GetByte() 'minkä tyyppinen viesti
If netmsg = NET_INTMSG Then
'SIELTÄ TULEE SE KOKONAISLUKUMUUTTUJA!! Jesh...
gInt = _Net_GetInt()
Else
Exit
EndIf
Wend
Return True
EndFunction
//================================================================================
// Lähetetään serverille dataa
//================================================================================
Function SendDataToServer()
// Jos viesti on jo lähetetty mutta vastausta ei ole luettu niin ei lähetetä uudestaan
If gClientDataSended = True Then Return False
// Muistipalan alustus ensin
_Net_InitMemBlock()
// Lähetetään JOTAIN serverille, että se tietääettä täällä ollaan paikalla!
_Net_PutByte(NET_IDLE)
'viestin loppumerkki vielä.
_Net_PutByte(NET_END)
// ClientSendBack lähettää datan serverille ja jää heti odottamaan vastausta
// mutta palauttaa kuitenkin kontrollin heti tänne. Vastausta siis odotellaan "taustalla".
ClientSendBack() '<-- lähetetään muistipala matkaan siis
// Laitetaan muuttujaan tieto että dataa on lähetetty.
gClientDataSended = True
EndFunction
Code: Select all
'*** PALVELIN ***
SCREEN 640,480
Include "cbNetwork.cb"
Include "NET_Constants.cb"
SetWindow "cbNetwork-esimerkki (server)",0,"Sammuta mielummin ESCistä (eli paina peruuta)"
// Käynnistetään palvelin.
// Koska tiedon lukeminen keskeyttää tämän ohjelman suorituksen niin
// asetetaan timeoutiksi 200 millisekuntia. Dataa siis odotellaan vain 200 ms
// jonka jälkeen kotrolli palaa DLL:stä tähän ohjelmaan.
nRet = InitServer(PORT, 200)
If nRet <> 0 Then
// Tuli joku virhe
errMsg$ = "(" + nRet + ") " + GetNetErrorString(nRet)
MakeError errMsg
EndIf
Global gSendInt 'tämä muuttuja lähetetään clientille
gSendInt = 12512746
SAFEEXIT OFF 'palvelin pitää sammuttaa erikseen, eikä vain murjoa alas
Repeat
If EsimerkkiErkki() <> 0 Then Exit
Until EscapeKey()
// Suljetaan palvelin
CloseServer()
//================================================================================
// Luetaan dataa clientiltä.
//================================================================================
Function EsimerkkiErkki()
// Luetaan dataa
nRet = ServerRead()
// Tuli joku virhe. Esimerkiksi timeout eli dataa ei tullut määräaikaan mennessä.
If nRet <> 0 Then Return False
// Muistipalan alussa on aina luetun datan pituus joka luetaan tässä pois
_Net_GetInt()
'luetaan viestit läpi
While True
// Mitä dataa on tulossa
netmsg = _Net_GetByte()
If netmsg = NET_IDLE Then
'client idlaa? ei tehä mitään :)
ElseIf netmsg = NET_END Then
'viestin lopetus
Exit
Else
'ei loputonta looppia
Exit
EndIf
Wend
_Net_InitMemBlock() // Datapaketin alustus
_Net_PutByte(NET_INTMSG) 'viestin tyyppi
_Net_PutString(gSendInt) 'itse lähetettävä
_Net_PutByte(NET_END) 'viestin lopetus
ServerSend() 'lähetetään...
Return True 'noniin, ohjelma on hommansa tehnyt.
EndFunction
Code: Select all
'*** NET_Constants.cb ***
' Samat vakiot clientilla ja palvelimella.
Const NET_IDLE = 1
Const NET_INTMSG = 2
Const NET_END = 255
Const PORT = 10999
Jes!! sain sen toimii, kun siirsin serverissä datan lähetystä.Ongelma oli siinä että kukaan ei ehtinyt lähettää mitään. ja client veti itsensä irti kun ei saatu mitään vaikka se serveri vasta tarkisteli siellä...