C'est vrai que ce serait peut-être le mieux non ?Sinon , un simple jeu de bataille navale pour se faire la main ?
autre projet en commun , à définir ensemble
oui , j'étais en train de regarder pour débuter avec une bataille navale
on compliquera après quand on se sera fait la main
.
j'ai installé la 3.89 beta2 sur mes deux pcs , et j'ai voulu tester l'exemple serveur , client que l'on trouve dans l'aide ,mais pas de pot , il faut changer la gestion d'allocatememory() , bon c'est pas compliqué, mais je voulais juste faire un test rapide , en copiant collant du code sans l'analyser pour l'adapter
je vais peut-être repasser en 3.81 pour faire mes essais.
si j'ai le temps , je me plongerai dedans ce week-end .
on compliquera après quand on se sera fait la main

j'ai installé la 3.89 beta2 sur mes deux pcs , et j'ai voulu tester l'exemple serveur , client que l'on trouve dans l'aide ,mais pas de pot , il faut changer la gestion d'allocatememory() , bon c'est pas compliqué, mais je voulais juste faire un test rapide , en copiant collant du code sans l'analyser pour l'adapter

je vais peut-être repasser en 3.81 pour faire mes essais.
si j'ai le temps , je me plongerai dedans ce week-end .
bon je me suis remis à coder un peu dimanche , et j'ai commencé par la gestion du réseau .
C'est le même programme pour le serveur , et pour le client
celui qui met son pc en serveur démarre le prog en premier , les IP de son PC s'affiche , il indique le bon IP à son petit camarade qui se connecte en client ( en répondant "non" à la première question ).
Ensuite chacun peut envoyer un message à l'autre par l'intermédiaire du menu déroulant.
Avant d'aller plus loin ( commencer la prog du jeu ) j'aimerais améliorer la partie réseau .
Alors ce qui serait bien , c'est que le client puisse détecter le serveur sans saisir l'IP . Comment faire ça ?
Et ce qui serait encore mieux , c'est de détecter si un ami est connecté , à la façon d'ICQ ou MSN.
Ensuite ,je n'utilise qu'un port ,mais si ce port est occupé ,on sort du prog , il faudrait peut-être en tester une série avant de déclarer que c'est impossible de créer une connexion ??
Quelle est la bonne pratique dans ce domaine ??
scruter une centaine de port ? si aucun n'est libre alors c'est qu'il y a vraiment un problème ?
Voila toutes les idées sont les bienvenues pour faire évoluer ce code , et la gestion du réseau
ici ça parle de trucs que je ne comprends pas ,mais qui semble correspondre à ce que je voudrais faire ?
http://purebasic.myforums.net/viewtopic ... ght=socket
A suivre...
C'est le même programme pour le serveur , et pour le client
celui qui met son pc en serveur démarre le prog en premier , les IP de son PC s'affiche , il indique le bon IP à son petit camarade qui se connecte en client ( en répondant "non" à la première question ).
Ensuite chacun peut envoyer un message à l'autre par l'intermédiaire du menu déroulant.
Avant d'aller plus loin ( commencer la prog du jeu ) j'aimerais améliorer la partie réseau .
Alors ce qui serait bien , c'est que le client puisse détecter le serveur sans saisir l'IP . Comment faire ça ?
Et ce qui serait encore mieux , c'est de détecter si un ami est connecté , à la façon d'ICQ ou MSN.
Ensuite ,je n'utilise qu'un port ,mais si ce port est occupé ,on sort du prog , il faudrait peut-être en tester une série avant de déclarer que c'est impossible de créer une connexion ??
Quelle est la bonne pratique dans ce domaine ??
scruter une centaine de port ? si aucun n'est libre alors c'est qu'il y a vraiment un problème ?
Voila toutes les idées sont les bienvenues pour faire évoluer ce code , et la gestion du réseau

ici ça parle de trucs que je ne comprends pas ,mais qui semble correspondre à ce que je voudrais faire ?
http://purebasic.myforums.net/viewtopic ... ght=socket
A suivre...
Code : Tout sélectionner
;Bataille navale en réseau
;03/05/04
;3.90
;
;{-Les constantes
;/les fenêtres
Enumeration
#FenetrePrincipale
#FenetreEnvoiMessage
EndEnumeration
;/les images
Enumeration
#ImageJeu
#ImageDansEau
#ImageTouche
#ImageCoule
#ImageBateau
EndEnumeration
;/Les gadgets
Enumeration
#GDGT_Image
#GDGT_BoutonOk
#GDGT_BoutonEnvoi
#GDGT_StringEnvoi
#GDGT_StringReception
EndEnumeration
;/Le menu
Enumeration
#MenuNouvellePartie
#MenuQuitter
#MenuEnvoyerMessage
EndEnumeration
;/Divers
#NbCaseX=12
#NbCaseY=12
#LargeurCase=32
#HauteurCase=32
#Yes=6
#No=7
#Cancel=2
#ModeClient=1
#ModeServeur=2
;}
;{-Les variables
Global Gris,Blanc,Rouge,Vert,Bleu
Global ServeurID,ServeurDistantID,ClientID,ModeReseau
Global rc.s
Gris=RGB(175,175,175)
Blanc=RGB(255,255,255)
Rouge=RGB(255,0,0)
Vert=RGB(0,255,0)
Bleu=RGB(0,0,255)
rc=Chr(13) + Chr(10)
Dim MapJoueur(#NbCaseX,#NbCaseY)
Dim MapControle(#NbCaseX,#NbCaseY)
;}
;-Mémoire
*Buffer=AllocateMemory(2000)
;{-Initialisation
;/Réseau
If InitNetwork() = 0
MessageRequester("Erreur","Impossible d'initialiser les fonctions réseaux",#MB_ICONERROR)
End
EndIf
;/Creation du serveur
Reponse=MessageRequester("Connexion...","créer le serveur sur ce PC ?", #PB_MessageRequester_YesNoCancel)
If Reponse=#Yes
ServeurID = CreateNetworkServer(6250)
If ServeurID = 0
MessageRequester("Erreur","Impossible de créer le serveur",#MB_ICONERROR)
End
EndIf
;Cherche les IP dispos sur le serveur
ExamineIPAddresses()
ip=NextIPAddress()
While ip
Ipadresse$=Ipadresse$+IPString(ip)+rc
ip=NextIPAddress()
Wend
MessageRequester("Serveur ok","Liste des IP disponibles sur le serveur"+rc+rc+Ipadresse$,0)
ModeReseau=#ModeServeur
ElseIf Reponse=#No
; Connection au serveur
Ipserveur.s=InputRequester("Connexion...","Indiquez l'IP du serveur sous la forme xxx.xxx.xxx.xxx ","")
ServeurDistantID=OpenNetworkConnection(Ipserveur,6250)
If ServeurDistantID=0
MessageRequester("Erreur","Impossible de se connecter au serveur.",#MB_ICONERROR)
End
EndIf
ModeReseau=#ModeClient
Else
End
EndIf
;/Fenetre et gadgets
FenetreFlag=#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget
If OpenWindow(#FenetrePrincipale, 0, 0, 500, 450, FenetreFlag, "Bataille navale")=0 Or CreateGadgetList(WindowID(#FenetrePrincipale))=0
MessageRequester("Pas de pot","Quand ça ne veut pas ça ne veut pas",#PB_MessageRequester_Ok)
End
EndIf
;/ un petit menu
If CreateMenu(0,WindowID(#FenetrePrincipale))
MenuTitle("Partie")
MenuItem(#MenuNouvellePartie,"Nouvelle Partie")
MenuItem(#MenuQuitter,"Quitter")
MenuTitle("Réseau")
MenuItem(#MenuEnvoyerMessage,"Envoyer un message")
EndIf
;/une barre
HandleStatBar.l = CreateStatusBar(0,WindowID(#FenetrePrincipale))
If HandleStatBar
AddStatusBarField(WindowWidth())
SendMessage_(HandleStatBar,#SB_GETRECT,0,@StatBarValue.RECT)
StatBarHeight.l= StatBarValue\bottom - StatBarValue\top
EndIf
;/fond du jeu
CreateImage(#ImageJeu,#NbCaseX*#LargeurCase,#NbCaseY*#HauteurCase)
StartDrawing(ImageOutput())
Box(0,0,ImageWidth() ,ImageHeight(),Gris)
For x=0 To #NbCaseX-1
For y=0 To #NbCaseY-1
DrawingMode(4)
Box(x*#LargeurCase,y*#HauteurCase,#LargeurCase,#HauteurCase,Blanc)
Next y
Next x
StopDrawing()
DebutX=(WindowWidth()-ImageWidth())/2
DebutY=(WindowHeight()-ImageHeight()-MenuHeight()-StatBarHeight)/2
ImageGadget(#GDGT_Image,DebutX,DebutY,ImageWidth(),ImageHeight(),ImageID())
;}
;-Les procedures
Procedure GetMouseX(gadget)
GetCursorPos_(mouse.POINT)
MapWindowPoints_(0,GadgetID(gadget),mouse,1)
ProcedureReturn mouse\x
EndProcedure
Procedure GetMouseY(gadget)
GetCursorPos_(mouse.POINT)
MapWindowPoints_(0,GadgetID(gadget),mouse,1)
ProcedureReturn mouse\y
EndProcedure
;-Boucle Principale
Repeat
;affiche la position de la souris
StatusBarText(0,0,Str(GetMouseX(#ImageJeu))+" / " + Str(GetMouseY(#ImageJeu)))
Select WindowEvent()
Case #PB_Event_CloseWindow : Quit=1
Case #PB_Event_Menu
Select EventMenuID()
;/Partie
Case #MenuQuitter : Quit=1
Case #MenuEnvoyerMessage
Texte$=""
If ModeReseau=#ModeServeur
If ClientID > 0
Texte$=InputRequester("Message","Texte à envoyer ","")
SendNetworkString(ClientID,Texte$)
Else
MessageRequester("Erreur","il n'y a personne qui joue avec toi !")
EndIf
Else
Texte$=InputRequester("Message","Texte à envoyer ","")
SendNetworkString(ServeurDistantID,Texte$)
EndIf
EndSelect
EndSelect
;/Test si le prog est lancé en tant que serveur
If ModeReseau=#ModeServeur
;/Ici c'est le serveur
ServeurEvent = NetworkServerEvent()
If ServeurEvent
Select ServeurEvent
;/Connexion d'un client
Case 1
ClientID = NetworkClientID()
MessageRequester("Client connecté","on va pouvoir commencer !",0)
SendNetworkString(ClientID,"connexion réussie, on va pouvoir commencer !")
;/Réception des datas
Case 2
PokeL(*Buffer,500)
ReceiveNetworkData(NetworkClientID(),*Buffer,2000)
MessageRequester("Message reçu",PeekS(*Buffer),0)
EndSelect
EndIf
;/Ici c'est un client
Else
ClientEvent = NetworkClientEvent(ServeurDistantID)
If ClientEvent
Select ClientEvent
;/Réception des datas
Case 2
PokeL(*Buffer,500)
ReceiveNetworkData(ServeurDistantID,*Buffer,2000)
MessageRequester("Message reçu",PeekS(*Buffer),0)
EndSelect
EndIf
EndIf
Until Quit = 1
CloseNetworkServer() ; est-ce utile avec End ? peut-être que End s'en charge ??
End
Je n'ai pas eu trop le temps de regarder mais tout d'abord:
Il faudrait que quelqu'un utilise par exemple son FTP et le serveur se connecte dessus et donne son IP : pas pratique si plusieures parties sont lancées. Pour ICQ ou MSN, il faudrait que quelqu'un héberge 24H/24 le serveur et là c'est pas trouvé...Alors ce qui serait bien , c'est que le client puisse détecter le serveur sans saisir l'IP . Comment faire ça ?
Et ce qui serait encore mieux , c'est de détecter si un ami est connecté , à la façon d'ICQ ou MSN.
A quoi sert le PokeL(*Buffer,500) ? Pourquoi mettre le nombre 500 dans le buffer pour le supprimer après ? De plus, il faut faire;/Réception des datas
Case 2
PokeL(*Buffer,500)
ReceiveNetworkData(NetworkClientID(),*Buffer,2000)
MessageRequester("Message reçu",PeekS(*Buffer),0)
car sinon si on envoi "Et toi ?" et ensuite "Bien" on aura le message "Bienoi ?" car l'ancien contenu du buffer n'aura pas été effacé;/Réception des datas
Case 2
FreeMemory(*Buffer)
*Buffer = AllocateMemory(2000)
ReceiveNetworkData(NetworkClientID(),*Buffer,2000)
MessageRequester("Message reçu",PeekS(*Buffer),0)
Ok dans ce cas ,je crois que je vais m'en passerOliv a écrit :Il faudrait que quelqu'un utilise par exemple son FTP et le serveur se connecte dessus et donne son IP : pas pratique si plusieures parties sont lancées. Pour ICQ ou MSN, il faudrait que quelqu'un héberge 24H/24 le serveur et là c'est pas trouvé...

Merci pour l'info , je vais donc pour l'instant me contenter d'améliorer la présentation de ce qui est déjà fait ( pour sélectionner le mode serveur ou client au démarrage ).
C'est une modif de dernière minute que je n'ai pas pris le temps de tester , et effectivement ça n'a pas lieu d'être , du moins sous cette formeA quoi sert le PokeL(*Buffer,500) ? Pourquoi mettre le nombre 500 dans le buffer pour le supprimer après ?

oui j'ai remarqué ça , mais seulement pour le premier message ,ensuite , les messages s'échangent correctement .Bon j'ai testé ça rapidement dimanche soir , et je voulais éviter de passer par;/Réception des datas
Case 2
FreeMemory(*Buffer)
*Buffer = AllocateMemory(2000)
ReceiveNetworkData(NetworkClientID(),*Buffer,2000)
MessageRequester("Message reçu",PeekS(*Buffer),0)
car sinon si on envoi "Et toi ?" et ensuite "Bien" on aura le message "Bienoi ?" car l'ancien contenu du buffer n'aura pas été effacé
Donc je vais faire encore quelques tests pour confirmer ce que je dis , à savoir que le problème du Buffer qui ne se vide pas n'existe que pour le premier message .C'est étonnant , j'ai sûrement mal testéFreeMemory(*Buffer)
*Buffer = AllocateMemory(2000)

pourtant j'alternais des messages longs avec des messages courts , et chaque message arrivait correctement , à suivre.
Et merci pour tes remarques .
salut 
il y a le CloseNetworkServer() a la fin qui ne sert a rien quand on est en client lol
Sinon, je te conseil de bient separer la partie reseau et le jeu en lui meme, mettre plutot la partie reseau dans un thread. Et surtout, fait en sorte que le serveur ne recoit des truc du client seulement lorsqu'il a fini de traité ce qu'il lui avais envoier avant sinon il vas tres vite surcharger, bouffer pas mal de memoire, et ce melanger les pinceaux dans la reception
(encor quoique pour un jeu a 2 seulement, je pense pa que se sera tres souvent... enfin on sais jamais.. suffit que le serveur ram un bon coup pendant 10 secondes, 10 secondes pendant lesquelles le client vas le tartiné de message...)
voilou

il y a le CloseNetworkServer() a la fin qui ne sert a rien quand on est en client lol
Sinon, je te conseil de bient separer la partie reseau et le jeu en lui meme, mettre plutot la partie reseau dans un thread. Et surtout, fait en sorte que le serveur ne recoit des truc du client seulement lorsqu'il a fini de traité ce qu'il lui avais envoier avant sinon il vas tres vite surcharger, bouffer pas mal de memoire, et ce melanger les pinceaux dans la reception

voilou

cederavic a écrit :salut
il y a le CloseNetworkServer() a la fin qui ne sert a rien quand on est en client lol
oui , oui , c'est un premier bout de code qui demande encore à être travaillé , je vais en tenir compte

Je me demandais si End ne gérait pas ça tout seul ? que fait exactement End ??
oui tu as raison , d'ailleurs je devrais tester le réception de la réception si c'est égal à la longueur indiquée , c'est qu'il y en a encore ,et je devrais boucler pour tout récupérer , c'est à faire pour la prochaine versionSinon, je te conseil de bient separer la partie reseau et le jeu en lui meme, mettre plutot la partie reseau dans un thread. Et surtout, fait en sorte que le serveur ne recoit des truc du client seulement lorsqu'il a fini de traité ce qu'il lui avais envoier avant sinon il vas tres vite surcharger, bouffer pas mal de memoire, et ce melanger les pinceaux dans la reception

c'est ce point là qui m'ennuie , dans un jeu comme une bataille navale ce n'est pas gênant si ça rame un peu par moment , mais ensuite je pensais faire un jeu qui demande des rafraichissement plus fréquent ( une bataille temps réelle (style FPS ) entre deux à 4 joueurs ) , et je me demandais comment synchroniser la partie , bon , ça viendra après , chaque chose en son temps , d'abord un truc simple , on compliquera peut-être après .suffit que le serveur ram un bon coup pendant 10 secondes, 10 secondes pendant lesquelles le client vas le tartiné de message...)
voilou
Merci pour tes mises en garde

j'ai oublié de te dire que c'était une excellente suggestion !mettre plutot la partie reseau dans un thread
Comme je n'ai encore jamais utilisé les threads ,c'est l'occasion d'apprendre sur ce projet

et c'est aussi l'occasion de commencer à utiliser les gadgets , je vais en coller un peu , histoire de me faire la main , fini la 3D , place aux gadgets

oui j'avais commencé à en faire un , et puis j'étais bloqué avec les gadgets , mais je vais le ressortir , j'ai commencé à le reprendre en utilisant le MDIGadget ,c'est exactement ce dont j'avais besoin 
maintenant mon problème c'est la gestion des tiles dans une fenêtre ( j'utilisais une ListIconGadget pour la simplicitée)
Je voudrais avoir le même comportement d'affichage , mais avec des images d'une taille supérieure à 32x32 ! .
là je pense que j'aurai à le gérer entièrement , puisqu'apparemment la listeicone est limitée pour la dimension des images ( pour les images de taille supérieure à 32x32 , je doublais les images , en faisant un resize pour la liste icone, et quand je sélectionnais une icone , j'affichais l'image dans sa dimension réelle , solution pas très satisfaisante .
Je n'ai pas encore cherché comment faire autrement, c'est une autre histoire ,j'en reparlerai plus tard .

maintenant mon problème c'est la gestion des tiles dans une fenêtre ( j'utilisais une ListIconGadget pour la simplicitée)
Je voudrais avoir le même comportement d'affichage , mais avec des images d'une taille supérieure à 32x32 ! .
là je pense que j'aurai à le gérer entièrement , puisqu'apparemment la listeicone est limitée pour la dimension des images ( pour les images de taille supérieure à 32x32 , je doublais les images , en faisant un resize pour la liste icone, et quand je sélectionnais une icone , j'affichais l'image dans sa dimension réelle , solution pas très satisfaisante .
Je n'ai pas encore cherché comment faire autrement, c'est une autre histoire ,j'en reparlerai plus tard .
comtois a écrit : maintenant mon problème c'est la gestion des tiles dans une fenêtre ( j'utilisais une ListIconGadget pour la simplicitée)
Je voudrais avoir le même comportement d'affichage , mais avec des images d'une taille supérieure à 32x32 ! .
là je pense que j'aurai à le gérer entièrement , puisqu'apparemment la listeicone est limitée pour la dimension des images ( pour les images de taille supérieure à 32x32 , je doublais les images , en faisant un resize pour la liste icone, et quand je sélectionnais une icone , j'affichais l'image dans sa dimension réelle , solution pas très satisfaisante .
Je n'ai pas encore cherché comment faire autrement, c'est une autre histoire ,j'en reparlerai plus tard .
L'affichage des images dans la listIcon (pour les éléments) se fait en utilisant une imageList dont la taille des icônes est définie une fois pour toute pour toutes les images, en général la taille est définie en utilisant l'API GetSystemMetrics avec les paramètres SM_CXICON et SM_CYICON.
On peut définir une autre taille même non symétrique pour les icônes.
L'API ImageList_SetIconSize permet de définir une autre taille pour les images de la liste mais son inconvénient est de supprimer toutes les images de la liste.
PB va créer l'ImageLIst lorsque tu assigne la première image à un élément. Essaye ceci : lorsque tu assigne l'iamge au premier élément, utilise l'API ImageList_SetIconSize pour redéfinir la taille et réassigne la même image à ce premier élément. Maintenant, il y aura peut-être un problème car la première image de la liste est une image transparente. Elle aura peut-être disparue.
Sinon on peut avant d'assigner la première image, créer une listImage avec l'API ImageList_Create en fixant la taille voulue pour les images.
J'ai posté quelques exemples sur le forum anglais y compris pour les afficher des images pour les éléments des colonnes autre que la 1ere.
http://purebasic.myforums.net/viewtopic ... listcreate
http://purebasic.myforums.net/viewtopic ... c&start=15
Ces exemples ne sont pas parfaits mais donne une idée.