Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
표시
레이아웃
나란히 보기
합쳐 보기
실시간 편집
공백 변경 숨기기
변경 없는 행 숨기기
줄바꿈 비활성화
비교 단위
스마트
구문
없음
모양 변경
처리
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
Untitled diff
생성일
11년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
1 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
802 행
복사
17 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
816 행
복사
SeedRnd MilliSecs()
SeedRnd MilliSecs()
Const gameLogicFPS = 60
Const gameLogicFPS = 60
복사
복사됨
복사
복사됨
Include "Hex8.bb"
Include "UDPNetwork_lib.bb"
Include "UDPNetwork_lib.bb"
Global localID
Global localID
Global localName$ = Input("Enter your name : ")
Global localName$ = Input("Enter your name : ")
If localName = "" Then localName = "player" + Rand(100,999)
If localName = "" Then localName = "player" + Rand(100,999)
Global localPlayerMesh
Global localPlayerMesh
Type player
Type player
Field id
Field id
Field name$
Field name$
Field ping
Field ping
Field life
Field life
Field kills
Field kills
Field deaths
Field deaths
Field mesh
Field mesh
Field r,g,b
Field r,g,b
Field nextX#,nextY#,nextZ#
Field nextX#,nextY#,nextZ#
Field previousX#,previousY#,previousZ#
Field previousX#,previousY#,previousZ#
Field nextYaw#
Field nextYaw#
Field previousYaw#
Field previousYaw#
Field nextTime
Field nextTime
Field previousTime
Field previousTime
Field lastPacket
Field lastPacket
Field currentY#
Field currentY#
Field velocityY#
Field velocityY#
End Type
End Type
Type bullet
Type bullet
Field mesh
Field mesh
Field angle#
Field angle#
Field time
Field time
Field id ; id of player who fired
Field id ; id of player who fired
End Type
End Type
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Camera code from jfk EO-11110, thanks
; Camera code from jfk EO-11110, thanks
Global bounce_cam=1 ; smooth camera motion? (0/1)
Global bounce_cam=1 ; smooth camera motion? (0/1)
Global bounce_div#=10.0 ; the higher, the more sluggish the camera will follow. Recc: 3.0 to 20.0
Global bounce_div#=10.0 ; the higher, the more sluggish the camera will follow. Recc: 3.0 to 20.0
; some globals used by ChaseCam
; some globals used by ChaseCam
Global old_x#,old_y#,old_z#
Global old_x#,old_y#,old_z#
; desired distance between camera and player mesh
; desired distance between camera and player mesh
Global x_dis#=7.0,y_dis#=3,z_dis#=7.0,y_dis_or#=y_dis#
Global x_dis#=7.0,y_dis#=3,z_dis#=7.0,y_dis_or#=y_dis#
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; network init ----------------------------------------;
; network init ----------------------------------------;
Global localMode = Net_StartInput() ; bring the library "console" to connect
Global localMode = Net_StartInput() ; bring the library "console" to connect
If localMode = 1 Or localMode = 2 ; 1 means we are client, 2 means we are server
If localMode = 1 Or localMode = 2 ; 1 means we are client, 2 means we are server
localId = Net_CreatePlayer(localName) ; this command inits the server or local client
localId = Net_CreatePlayer(localName) ; this command inits the server or local client
If localId = 0 ; error
If localId = 0 ; error
Net_StopNetwork() ; close the network properly
Net_StopNetwork() ; close the network properly
RuntimeError("Failed to create player.")
RuntimeError("Failed to create player.")
EndIf
EndIf
If localMode = 1 Then AppTitle("Client : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
If localMode = 1 Then AppTitle("Client : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
If localMode = 2 Then AppTitle("Server : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
If localMode = 2 Then AppTitle("Server : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
Else ; error
Else ; error
Net_StopNetwork()
Net_StopNetwork()
RuntimeError("Failed to start game.")
RuntimeError("Failed to start game.")
EndIf
EndIf
;------------------------------------------------------;
;------------------------------------------------------;
Graphics3D 640,480,32,2
Graphics3D 640,480,32,2
SetBuffer BackBuffer()
SetBuffer BackBuffer()
CreateScene()
CreateScene()
Global camera = CreateCamera()
Global camera = CreateCamera()
CameraRange camera,0.1,1000
CameraRange camera,0.1,1000
; create our own local player
; create our own local player
localPlayerMesh = CreatePlayer(localID,localName)
localPlayerMesh = CreatePlayer(localID,localName)
old_x = EntityX(localPlayerMesh):old_y = EntityY(localPlayerMesh):old_z = EntityZ(localPlayerMesh) ; update camera position
old_x = EntityX(localPlayerMesh):old_y = EntityY(localPlayerMesh):old_z = EntityZ(localPlayerMesh) ; update camera position
; we send our color to the server
; we send our color to the server
p.player = Object.player(GetPlayer(localID))
p.player = Object.player(GetPlayer(localID))
Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b)
Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b)
복사
복사됨
복사
복사됨
Global cR = p\r
Global cG = p\g
Global cB = p\b
; variables used to send our positions at a constant delay (saves bandwidth but makes a constant ping)
; variables used to send our positions at a constant delay (saves bandwidth but makes a constant ping)
Global updatePosition = MilliSecs()
Global updatePosition = MilliSecs()
Global updateTick = 50
Global updateTick = 50
저장된 비교 결과
원본
파일 열기
SeedRnd MilliSecs() Const gameLogicFPS = 60 Include "UDPNetwork_lib.bb" Global localID Global localName$ = Input("Enter your name : ") If localName = "" Then localName = "player" + Rand(100,999) Global localPlayerMesh Type player Field id Field name$ Field ping Field life Field kills Field deaths Field mesh Field r,g,b Field nextX#,nextY#,nextZ# Field previousX#,previousY#,previousZ# Field nextYaw# Field previousYaw# Field nextTime Field previousTime Field lastPacket Field currentY# Field velocityY# End Type Type bullet Field mesh Field angle# Field time Field id ; id of player who fired End Type ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Camera code from jfk EO-11110, thanks Global bounce_cam=1 ; smooth camera motion? (0/1) Global bounce_div#=10.0 ; the higher, the more sluggish the camera will follow. Recc: 3.0 to 20.0 ; some globals used by ChaseCam Global old_x#,old_y#,old_z# ; desired distance between camera and player mesh Global x_dis#=7.0,y_dis#=3,z_dis#=7.0,y_dis_or#=y_dis# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; network init ----------------------------------------; Global localMode = Net_StartInput() ; bring the library "console" to connect If localMode = 1 Or localMode = 2 ; 1 means we are client, 2 means we are server localId = Net_CreatePlayer(localName) ; this command inits the server or local client If localId = 0 ; error Net_StopNetwork() ; close the network properly RuntimeError("Failed to create player.") EndIf If localMode = 1 Then AppTitle("Client : " + localName + " (port:" + net_port + "/ ID=" + localID + ")") If localMode = 2 Then AppTitle("Server : " + localName + " (port:" + net_port + "/ ID=" + localID + ")") Else ; error Net_StopNetwork() RuntimeError("Failed to start game.") EndIf ;------------------------------------------------------; Graphics3D 640,480,32,2 SetBuffer BackBuffer() CreateScene() Global camera = CreateCamera() CameraRange camera,0.1,1000 ; create our own local player localPlayerMesh = CreatePlayer(localID,localName) old_x = EntityX(localPlayerMesh):old_y = EntityY(localPlayerMesh):old_z = EntityZ(localPlayerMesh) ; update camera position ; we send our color to the server p.player = Object.player(GetPlayer(localID)) Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b) ; variables used to send our positions at a constant delay (saves bandwidth but makes a constant ping) Global updatePosition = MilliSecs() Global updateTick = 50 ; chat Global messageDisplayNumber = 10 Global messageOffset Dim message$(messageDisplayNumber) Global chatMode Global chatMessage$ = localName + "> " Global chatMillisecs = MilliSecs() Global chatCursor ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; tweeningPeriod = 1000 / gameLogicFPS tweeningTime = MilliSecs() - tweeningPeriod ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; While Not KeyHit(1) ;; I use tweening from castle demo here : ;; ;; - this allows to have very fast execution outside the tweening loop, ;; so the network is updated as fast as possible (needs Flip False) ;; ;; - this makes the game logic updated at a constant rate (Const FPS=) ;; so no need to set deltatime (and it saves CPU time for other things) ;; -------------------------------------------------------------------------------------------------; FAST EXECUTION (outside of tweening) ;; -------------------------------------------------------------------------------------------------; ; see the function, the interpolation variables are set properly here UpdateNetwork() ;; -------------------------------------------------------------------------------------------------; Repeat tweeningElapsed = MilliSecs() - tweeningTime Until tweeningElapsed tweeningTicks = tweeningElapsed / tweeningPeriod tweeningRate# = Float(tweeningElapsed Mod tweeningPeriod)/Float(tweeningPeriod) For k = 1 To tweeningTicks tweeningTime = tweeningTime + tweeningPeriod If k = tweeningTicks Then CaptureWorld ;; ---------------------------------------------------------------------------------------------; MAIN UPDATE ;; ---------------------------------------------------------------------------------------------; ; update our player UpdateLocalPlayer() ; the interpolation is made in this function UpdatePlayers() ; update the bullets... only the server check for player kills UpdateBullets() UpdateWorld() UpdateChaseCam(camera,localPlayerMesh) ;; ---------------------------------------------------------------------------------------------; Next RenderWorld tweeningRate ;; -------------------------------------------------------------------------------------------------; 2D UPDATE ;; -------------------------------------------------------------------------------------------------; DrawPlayersNames() If KeyHit(28) And chatMode = 0 Then chatMode = 1:FlushKeys() If chatMode = 1 Then UpdateChat() DrawMessages() If KeyDown(15) Then DrawScoreTable() ;; -------------------------------------------------------------------------------------------------; Flip Wend ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Net_StopNetwork() End ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateNetwork() ; update incoming packets (better check ALL incoming messages so use While Wend) While Net_CheckMessage() ; will check for a new message and fill Net_MsgType, Net_MsgString$, Net_MsgFrom and Net_MsgTo variables so we can read it p.player = Object.player(GetPlayer(Net_MsgFrom)) ; get the player handle If Handle(p) = 0 And Net_MsgType < 100 ; we received an update packet from a player we don't know ; so we ask the server who he is and return because we can't update him for now ; the server will resend us the info in a new player "100" message Net_RequestPlayer(Net_MsgFrom) Return EndIf Select Net_MsgType ; check the type of message Case 1 ; chat message NewMessage(Net_MsgString) Case 2 ; player position and angle, example of packing data into string offset1 = Instr(Net_MsgString,"/",1) offset2 = Instr(Net_MsgString,"/",offset1+1) offset3 = Instr(Net_MsgString,"/",offset2+1) p\previousX = p\nextX p\previousY = p\nextY p\previousZ = p\nextZ p\previousYaw = p\nextYaw p\nextX = Left(Net_MsgString,offset1-1) p\nextY = Mid(Net_MsgString,offset1+1,offset2-offset1-1) p\nextZ = Mid(Net_MsgString,offset2+1,offset3-offset2-1) p\nextYaw = Right(Net_MsgString,Len(Net_MsgString)-offset3) p\previousTime = p\nextTime p\nextTime = MilliSecs() Case 3 ; update player colors offset1 = Instr(Net_MsgString,"/",1) offset2 = Instr(Net_MsgString,"/",offset1+1) p\r = Left(Net_MsgString,offset1-1) p\g = Mid(Net_MsgString,offset1+1,offset2-offset1-1) p\b = Right(Net_MsgString,Len(Net_MsgString)-offset2) EntityColor p\mesh,p\r,p\g,p\b Case 4 ; a player fired CreateBullet(Net_MsgFrom) Case 5 ; a player lost some life p\life = Net_MsgString Case 6 ; a player killed another one k.player = Object.player(GetPlayer(Net_MsgString)) ; killed player ID in MsgData NewMessage(p\name + " killed " + k\name) ResetPlayer(k\id) Case 7 ; the server sends us score update for a player offset = Instr(Net_MsgString,"/",1) p\kills = Left(Net_MsgString,offset-1) p\deaths = Right(Net_MsgString,Len(Net_MsgString)-offset) Case 100 ; new player connected, OR the server tells us who is already connected so we can create players when joining the game If localMode = 2 For p.player = Each player Net_SendMessage(2,p\nextX + "/" + p\nextY + "/" + p\nextZ + "/" + p\nextYaw,p\id,Net_MsgFrom) Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b,p\id,Net_MsgFrom) Net_SendMessage(5,p\life,p\id,Net_MsgFrom) Net_SendMessage(7,p\kills+"/"+p\deaths,p\id,Net_MsgFrom) Next EndIf NewMessage(Net_MsgString + " connected") CreatePlayer(Net_MsgFrom,Net_MsgString) Case 101 ; a player has quit For p.player = Each player If Net_MsgFrom = p\id NewMessage(p\name + " disconnected") FreeEntity p\mesh Delete p EndIf Next Case 102 ; host has changed For p.player = Each player If Net_MsgFrom = p\id If p\id = localID AppTitle("Server : " + localName + " (port:" + net_port + ")") NewMessage("You are the new host") localMode = 2 Else NewMessage(p\name + " is the new host") EndIf EndIf Next Case 103 ; ping update For p.player = Each player If Net_MsgFrom = p\id p\ping = Net_MsgString EndIf Next End Select Wend End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateLocalPlayer() ; update our player p.player = Object.player(GetPlayer(localID)) ; get our player ; inputs If KeyDown(200) Then MoveEntity p\mesh,0,0,0.3 If KeyDown(208) Then MoveEntity p\mesh,0,0,-0.3 If KeyDown(203) Then TurnEntity p\mesh,0,3,0 If KeyDown(205) Then TurnEntity p\mesh,0,-3,0 ; fire If MouseHit(1) Net_SendMessage(4,"") CreateBullet(localID) EndIf ; jump If MouseHit(2) ; check if player is one the ground LinePick(EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh),0,-1.2,0) If PickedEntity() p\velocityY = 0.5 ; set "inverse" of gravity velocity EndIf EndIf ; we create a message type "2" for player position If MilliSecs()-updatePosition > updateTick Net_SendMessage(2,EntityX(p\mesh) + "/" + EntityY(p\mesh) + "/" + EntityZ(p\mesh) + "/" + EntityYaw(p\mesh)) updatePosition = MilliSecs() EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdatePlayers() For p.player = Each player If p\id <> localID ; update other players only ;; LINEAR INTERPOLATION ;;;;;;;;;; If p\nextTime <> p\previousTime ; if both packets arrived at the same time, we can't interpolate curTime# = Float(MilliSecs()-p\nextTime) / Float(p\nextTime-p\previousTime) ; curTime will be ideally 0.0-1.0, if it's > 1.0 then it performs extrapolation If curTime > 1 Then curTime = 1 ; extrapolation gives anoying jittering effects ; special fix for yaw as EntityYaw returns a value beetween +180 ans -180, the interpolation can go backward If p\previousYaw < 0 Then p\previousYaw = p\previousYaw + 360 If p\nextYaw < 0 Then p\nextYaw = p\nextYaw + 360 If Abs(p\nextYaw-p\previousYaw) > 180 If p\nextYaw > p\previousYaw p\previousYaw = p\previousYaw + 360 Else p\previousYaw = p\previousYaw - 360 EndIf EndIf PositionEntity p\mesh,p\previousX+(p\nextX-p\previousX)*curTime,p\previousY+(p\nextY-p\previousY)*curTime,p\previousZ+(p\nextZ-p\previousZ)*curTime RotateEntity p\mesh,0,p\previousYaw+(p\nextYaw-p\previousYaw)*curTime,0 Else PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ RotateEntity p\mesh,0,p\nextYaw,0 EndIf ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ResetEntity p\mesh ; reset entity is useful here because of collisions Else ; update our player, basically it just compute gravity p\velocityY = p\velocityY - 0.03 ; fake gravity If EntityY(p\mesh) - p\currentY >= 0 ; if player is not falling we limit the gravity If p\velocityY < -0.03 Then p\velocityY = -0.03 EndIf p\currentY = EntityY(p\mesh) TranslateEntity p\mesh,0,p\velocityY,0 EndIf Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CreatePlayer(id,name$) For p.player = Each player If p\id = id Then Return ; player already connected Next p.player = New player p\id = id p\name = name p\life = 100 p\mesh = CreateSphere() EntityType p\mesh,2 EntityRadius p\mesh,1 NameEntity p\mesh,Handle(p) nose = CreateSphere(8,p\mesh):EntityColor nose,255,0,0 PositionEntity nose,0,0,1 ScaleEntity nose,0.3,0.3,0.3 eyeLeft = CreateSphere(8,p\mesh):EntityColor eyeLeft,255,255,255 PositionEntity eyeLeft ,.29,.4,.7;1 ScaleEntity eyeLeft ,0.2,0.2,0.2 pupilLeft = CreateSphere(8,p\mesh):EntityColor pupilLeft ,0,0,0 PositionEntity pupilLeft ,.3,.4,.9;1 ScaleEntity pupilLeft ,0.05,0.05,0.02 eyeRight = CreateSphere(8,p\mesh):EntityColor eyeRight ,255,255,255 PositionEntity eyeRight ,-.29,.4,.7;1 ScaleEntity eyeRight ,0.2,0.2,0.2 pupilRight = CreateSphere(8,p\mesh):EntityColor pupilRight ,0,0,0 PositionEntity pupilRight ,-.3,.4,.9;1 ScaleEntity pupilRight ,0.05,0.05,0.02 unaBrow = CreateCone(8,1,p\mesh):EntityColor unaBrow ,0,0,0 PositionEntity unaBrow ,0,.45,.7 RotateEntity unaBrow ,-180,0,0 ScaleEntity unaBrow ,.7,.2,.3 p\nextX = -20 p\nextY = 1 p\nextZ = -20 p\nextYaw = -45 p\previousX = p\nextX p\previousY = p\nextY p\previousZ = p\nextZ p\previousYaw = p\nextYaw p\r = Rand(255) p\g = Rand(255) p\b = Rand(255) EntityColor p\mesh,p\r,p\g,p\b PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ RotateEntity p\mesh,0,p\nextYaw,0 ResetEntity p\mesh p\currentY = p\nextY p\previousTime = MilliSecs() p\nextTime = MilliSecs()+1 Return p\mesh End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function ResetPlayer(id) p.player = Object.player(GetPlayer(id)) p\life = 100 p\nextX = -20 p\nextY = 1 p\nextZ = -20 p\nextYaw = -45 p\previousX = p\nextX p\previousY = p\nextY p\previousZ = p\nextZ p\previousYaw = p\nextYaw PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ RotateEntity p\mesh,0,p\nextYaw,0 ResetEntity p\mesh p\currentY = p\nextY p\previousTime = MilliSecs() p\nextTime = MilliSecs()+1 End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function GetPlayer(id) For p.player = Each player If p\id = id Return Handle(p) EndIf Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function DrawPlayersNames() For p.player = Each player Color 255,255,255 CameraProject(camera,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh)) If p\id <> localID Then Text ProjectedX(),ProjectedY()-60,p\name,1,1 Color 255,(255./100.)*p\life,(255./100.)*p\life Text ProjectedX(),ProjectedY()-40,p\life,1,1 Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CreateBullet(id) p.player = Object.player(GetPlayer(id)) b.bullet = New bullet b\id = p\id b\mesh = CreateSphere(2) ScaleEntity b\mesh,0.2,0.2,0.2 EntityColor b\mesh,255,0,0 PositionEntity b\mesh,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh) RotateEntity b\mesh,0,EntityYaw(p\mesh),0 EntityType b\mesh,3 EntityRadius b\mesh,0.2 b\time = MilliSecs() End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateBullets() For b.bullet = Each bullet MoveEntity b\mesh,0,0,1 If CountCollisions(b\mesh) If localMode = 2 ; only the server compute bullets collision with player If GetEntityType(CollisionEntity(b\mesh,1)) = 2 ; a player is hit touchedPlayer.player = Object.player(EntityName(CollisionEntity(b\mesh,1))) touchedPlayer\life = touchedPlayer\life - 10 If touchedPlayer\life > 0 ; touched Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id) Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id,touchedPlayer\id) Else ; killed killerPlayer.player = Object.player(GetPlayer(b\id)) killerPlayer\kills = killerPlayer\kills + 1 touchedPlayer\deaths = touchedPlayer\deaths + 1 Net_SendMessage(6,touchedPlayer\id,killerPlayer\id) Net_SendMessage(6,touchedPlayer\id,killerPlayer\id,killerPlayer\id) Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id) Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id,killerPlayer\id) Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id) Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id,touchedPlayer\id) NewMessage(killerPlayer\name + " killed " + touchedPlayer\name) ResetPlayer(touchedPlayer\id) EndIf EndIf EndIf FreeEntity b\mesh Delete b ElseIf MilliSecs()-b\time > 2000 FreeEntity b\mesh Delete b EndIf Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function NewMessage(msg$) messageOffset = messageOffset + 1 If messageOffset > messageDisplayNumber messageOffset = messageOffset - 1 For i = 2 To messageDisplayNumber message(i-1) = message(i) Next message(messageDisplayNumber) = msg Else message(messageOffset) = msg EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function DrawMessages() Color 255,255,255 For i = 1 To messageOffset Text 0,(i-1)*15,message(i) Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateChat() key = GetKey() If key If key = 13 If chatMessage <> localName + "> " For i = Len(localName + "> ") To Len(chatMessage) If Mid(chatMessage,i,1) <> " " Net_SendMessage(1,chatMessage) NewMessage(chatMessage) Exit EndIf Next EndIf chatMessage = localName + "> " chatMode = 0 ElseIf key = 8 And Len(chatMessage) > Len ( localName + "> " ) chatMessage = Left(chatMessage,Len(chatMessage)-1) ElseIf key > 31 And key < 127 chatMessage = chatMessage + Chr(key) EndIf EndIf Color 255,255,255 Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,1 Color 0,0,0 Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,0 If MilliSecs()-chatMillisecs > 500 chatCursor = Not chatCursor chatMillisecs = MilliSecs() EndIf If chatCursor Text 5,GraphicsHeight()-17,chatMessage + "|" Else Text 5,GraphicsHeight()-17,chatMessage EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function DrawScoreTable() For p.player = Each player count = count + 1 Next baseX = (GraphicsWidth()-350)/2 baseY = (GraphicsHeight()-(35+20*count))/2 Color 0,0,0 Rect baseX,baseY,350,35+20*count,1 Color 255,192,0 Rect baseX,baseY,350,35+20*count,0 Text baseX+10,baseY+10,"Player Kills Deaths Ping" Line baseX,baseY+25,baseX+349,baseY+25 For p.player = Each player Color 255,255,255 If p\id = localID Then Color 255,100,100 i = i + 1 Text baseX+10,baseY+10+20*i,p\name Text baseX+157,baseY+10+20*i,p\kills,1,0 Text baseX+240,baseY+10+20*i,p\deaths,1,0 Text baseX+322,baseY+10+20*i,p\ping,1,0 Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateChaseCam(camera,player) ; thanks to jfk EO-11110 on bb forums for this function ! PositionEntity camera,EntityX(player,1),EntityY(player,1),EntityZ(player,1) ResetEntity camera x#=EntityX(player)+Sin(-EntityYaw(player)+180)*x_dis# y#=EntityY(player)+y_dis# z#=EntityZ(player)+Cos(-EntityYaw(player)+180)*z_dis# obstacle=LinePick(EntityX(player),EntityY(player),EntityZ(player),(x-EntityX(player)),y_dis#,(z-EntityZ(player)),0.1) If obstacle=0 new_x#=x new_y#=y new_z#=z Else new_x#=PickedX() new_y#=PickedY() new_z#=PickedZ() EndIf If bounce_cam=0 PositionEntity camera,new_x,new_y,new_z Else x=old_x+((New_x-old_x)/bounce_div#) y=old_y+((New_y-old_y)/bounce_div#) z=old_z+((New_z-old_z)/bounce_div#) PositionEntity camera,x,y,z EndIf PointEntity camera,player TurnEntity camera,-20,0,0 ; if you want the player mesh more on the bottom of the screen old_x#=EntityX(camera) old_y#=EntityY(camera) old_z#=EntityZ(camera) End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CreateScene() texture = TextureCreate(128) ground = CreatePlane() EntityColor ground,150,150,150 EntityTexture ground,texture cube = CreateCube():EntityColor cube,150,200,150 ScaleEntity cube,5,5,5:PositionEntity cube,0,5,0 EntityTexture cube,texture sphere = CreateSphere(16):EntityColor sphere,200,150,150 ScaleEntity sphere,3,1,3:PositionEntity sphere,0,9.7,0 platform = CreateCube():EntityColor platform,150,150,200 ScaleEntity platform,3,1,10:PositionEntity platform,0,4.13,-13.15 TurnEntity platform,-30,0,0 EntityTexture platform,texture FreeTexture texture EntityType ground,1:EntityPickMode ground,2 EntityType cube,1:EntityPickMode cube,2 EntityType sphere,1:EntityPickMode sphere,2 EntityType platform,1:EntityPickMode platform,2 light = CreateLight() TurnEntity light,30,70,0 ;; COLLISIONS Collisions 2,1,2,3 ; player to scene Collisions 2,2,1,3 ; player to player Collisions 3,1,2,1 ; bullet to scene Collisions 3,2,1,1 ; bullet to player End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function TextureCreate(size) texture = CreateTexture(size,size,9) SetBuffer TextureBuffer(texture) Color 255,255,255 Rect 0,0,size,size,1 Color 0,0,0 Rect 0,0,size,size,0 Line 0,0,size,size Line 0,size,size,0 SetBuffer BackBuffer() Return texture End Function
수정본
파일 열기
SeedRnd MilliSecs() Const gameLogicFPS = 60 Include "Hex8.bb" Include "UDPNetwork_lib.bb" Global localID Global localName$ = Input("Enter your name : ") If localName = "" Then localName = "player" + Rand(100,999) Global localPlayerMesh Type player Field id Field name$ Field ping Field life Field kills Field deaths Field mesh Field r,g,b Field nextX#,nextY#,nextZ# Field previousX#,previousY#,previousZ# Field nextYaw# Field previousYaw# Field nextTime Field previousTime Field lastPacket Field currentY# Field velocityY# End Type Type bullet Field mesh Field angle# Field time Field id ; id of player who fired End Type ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Camera code from jfk EO-11110, thanks Global bounce_cam=1 ; smooth camera motion? (0/1) Global bounce_div#=10.0 ; the higher, the more sluggish the camera will follow. Recc: 3.0 to 20.0 ; some globals used by ChaseCam Global old_x#,old_y#,old_z# ; desired distance between camera and player mesh Global x_dis#=7.0,y_dis#=3,z_dis#=7.0,y_dis_or#=y_dis# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; network init ----------------------------------------; Global localMode = Net_StartInput() ; bring the library "console" to connect If localMode = 1 Or localMode = 2 ; 1 means we are client, 2 means we are server localId = Net_CreatePlayer(localName) ; this command inits the server or local client If localId = 0 ; error Net_StopNetwork() ; close the network properly RuntimeError("Failed to create player.") EndIf If localMode = 1 Then AppTitle("Client : " + localName + " (port:" + net_port + "/ ID=" + localID + ")") If localMode = 2 Then AppTitle("Server : " + localName + " (port:" + net_port + "/ ID=" + localID + ")") Else ; error Net_StopNetwork() RuntimeError("Failed to start game.") EndIf ;------------------------------------------------------; Graphics3D 640,480,32,2 SetBuffer BackBuffer() CreateScene() Global camera = CreateCamera() CameraRange camera,0.1,1000 ; create our own local player localPlayerMesh = CreatePlayer(localID,localName) old_x = EntityX(localPlayerMesh):old_y = EntityY(localPlayerMesh):old_z = EntityZ(localPlayerMesh) ; update camera position ; we send our color to the server p.player = Object.player(GetPlayer(localID)) Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b) Global cR = p\r Global cG = p\g Global cB = p\b ; variables used to send our positions at a constant delay (saves bandwidth but makes a constant ping) Global updatePosition = MilliSecs() Global updateTick = 50 ; chat Global messageDisplayNumber = 10 Global messageOffset Dim message$(messageDisplayNumber) Global chatMode Global chatMessage$ = localName + "> " Global chatMillisecs = MilliSecs() Global chatCursor ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; tweeningPeriod = 1000 / gameLogicFPS tweeningTime = MilliSecs() - tweeningPeriod ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; While Not KeyHit(1) ;; I use tweening from castle demo here : ;; ;; - this allows to have very fast execution outside the tweening loop, ;; so the network is updated as fast as possible (needs Flip False) ;; ;; - this makes the game logic updated at a constant rate (Const FPS=) ;; so no need to set deltatime (and it saves CPU time for other things) ;; -------------------------------------------------------------------------------------------------; FAST EXECUTION (outside of tweening) ;; -------------------------------------------------------------------------------------------------; ; see the function, the interpolation variables are set properly here UpdateNetwork() ;; -------------------------------------------------------------------------------------------------; Repeat tweeningElapsed = MilliSecs() - tweeningTime Until tweeningElapsed tweeningTicks = tweeningElapsed / tweeningPeriod tweeningRate# = Float(tweeningElapsed Mod tweeningPeriod)/Float(tweeningPeriod) For k = 1 To tweeningTicks tweeningTime = tweeningTime + tweeningPeriod If k = tweeningTicks Then CaptureWorld ;; ---------------------------------------------------------------------------------------------; MAIN UPDATE ;; ---------------------------------------------------------------------------------------------; ; update our player UpdateLocalPlayer() ; the interpolation is made in this function UpdatePlayers() ; update the bullets... only the server check for player kills UpdateBullets() UpdateWorld() UpdateChaseCam(camera,localPlayerMesh) ;; ---------------------------------------------------------------------------------------------; Next RenderWorld tweeningRate ;; -------------------------------------------------------------------------------------------------; 2D UPDATE ;; -------------------------------------------------------------------------------------------------; DrawPlayersNames() If KeyHit(28) And chatMode = 0 Then chatMode = 1:FlushKeys() If chatMode = 1 Then UpdateChat() DrawMessages() If KeyDown(15) Then DrawScoreTable() ;; -------------------------------------------------------------------------------------------------; Flip Wend ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Net_StopNetwork() End ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateNetwork() ; update incoming packets (better check ALL incoming messages so use While Wend) While Net_CheckMessage() ; will check for a new message and fill Net_MsgType, Net_MsgString$, Net_MsgFrom and Net_MsgTo variables so we can read it p.player = Object.player(GetPlayer(Net_MsgFrom)) ; get the player handle If Handle(p) = 0 And Net_MsgType < 100 ; we received an update packet from a player we don't know ; so we ask the server who he is and return because we can't update him for now ; the server will resend us the info in a new player "100" message Net_RequestPlayer(Net_MsgFrom) Return EndIf Select Net_MsgType ; check the type of message Case 1 ; chat message NewMessage(Net_MsgString) Case 2 ; player position and angle, example of packing data into string offset1 = Instr(Net_MsgString,"/",1) offset2 = Instr(Net_MsgString,"/",offset1+1) offset3 = Instr(Net_MsgString,"/",offset2+1) p\previousX = p\nextX p\previousY = p\nextY p\previousZ = p\nextZ p\previousYaw = p\nextYaw p\nextX = Left(Net_MsgString,offset1-1) p\nextY = Mid(Net_MsgString,offset1+1,offset2-offset1-1) p\nextZ = Mid(Net_MsgString,offset2+1,offset3-offset2-1) p\nextYaw = Right(Net_MsgString,Len(Net_MsgString)-offset3) p\previousTime = p\nextTime p\nextTime = MilliSecs() Case 3 ; update player colors offset1 = Instr(Net_MsgString,"/",1) offset2 = Instr(Net_MsgString,"/",offset1+1) p\r = Left(Net_MsgString,offset1-1) p\g = Mid(Net_MsgString,offset1+1,offset2-offset1-1) p\b = Right(Net_MsgString,Len(Net_MsgString)-offset2) EntityColor p\mesh,p\r,p\g,p\b Case 4 ; a player fired CreateBullet(Net_MsgFrom) Case 5 ; a player lost some life p\life = Net_MsgString Case 6 ; a player killed another one k.player = Object.player(GetPlayer(Net_MsgString)) ; killed player ID in MsgData NewMessage(p\name + " killed " + k\name) ResetPlayer(k\id) Case 7 ; the server sends us score update for a player offset = Instr(Net_MsgString,"/",1) p\kills = Left(Net_MsgString,offset-1) p\deaths = Right(Net_MsgString,Len(Net_MsgString)-offset) Case 100 ; new player connected, OR the server tells us who is already connected so we can create players when joining the game If localMode = 2 For p.player = Each player Net_SendMessage(2,p\nextX + "/" + p\nextY + "/" + p\nextZ + "/" + p\nextYaw,p\id,Net_MsgFrom) Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b,p\id,Net_MsgFrom) Net_SendMessage(5,p\life,p\id,Net_MsgFrom) Net_SendMessage(7,p\kills+"/"+p\deaths,p\id,Net_MsgFrom) Next EndIf NewMessage(Net_MsgString + " connected") CreatePlayer(Net_MsgFrom,Net_MsgString) Case 101 ; a player has quit For p.player = Each player If Net_MsgFrom = p\id NewMessage(p\name + " disconnected") FreeEntity p\mesh Delete p EndIf Next Case 102 ; host has changed For p.player = Each player If Net_MsgFrom = p\id If p\id = localID AppTitle("Server : " + localName + " (port:" + net_port + ")") NewMessage("You are the new host") localMode = 2 Else NewMessage(p\name + " is the new host") EndIf EndIf Next Case 103 ; ping update For p.player = Each player If Net_MsgFrom = p\id p\ping = Net_MsgString EndIf Next End Select Wend End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateLocalPlayer() ; update our player p.player = Object.player(GetPlayer(localID)) ; get our player ; inputs If KeyDown(200) Then MoveEntity p\mesh,0,0,0.3 If KeyDown(208) Then MoveEntity p\mesh,0,0,-0.3 If KeyDown(203) Then TurnEntity p\mesh,0,3,0 If KeyDown(205) Then TurnEntity p\mesh,0,-3,0 ; fire If MouseHit(1) Net_SendMessage(4,"") CreateBullet(localID) EndIf ; jump If MouseHit(2) ; check if player is one the ground LinePick(EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh),0,-1.2,0) If PickedEntity() p\velocityY = 0.5 ; set "inverse" of gravity velocity EndIf EndIf ; we create a message type "2" for player position If MilliSecs()-updatePosition > updateTick Net_SendMessage(2,EntityX(p\mesh) + "/" + EntityY(p\mesh) + "/" + EntityZ(p\mesh) + "/" + EntityYaw(p\mesh)) updatePosition = MilliSecs() EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdatePlayers() For p.player = Each player If p\id <> localID ; update other players only ;; LINEAR INTERPOLATION ;;;;;;;;;; If p\nextTime <> p\previousTime ; if both packets arrived at the same time, we can't interpolate curTime# = Float(MilliSecs()-p\nextTime) / Float(p\nextTime-p\previousTime) ; curTime will be ideally 0.0-1.0, if it's > 1.0 then it performs extrapolation If curTime > 1 Then curTime = 1 ; extrapolation gives anoying jittering effects ; special fix for yaw as EntityYaw returns a value beetween +180 ans -180, the interpolation can go backward If p\previousYaw < 0 Then p\previousYaw = p\previousYaw + 360 If p\nextYaw < 0 Then p\nextYaw = p\nextYaw + 360 If Abs(p\nextYaw-p\previousYaw) > 180 If p\nextYaw > p\previousYaw p\previousYaw = p\previousYaw + 360 Else p\previousYaw = p\previousYaw - 360 EndIf EndIf PositionEntity p\mesh,p\previousX+(p\nextX-p\previousX)*curTime,p\previousY+(p\nextY-p\previousY)*curTime,p\previousZ+(p\nextZ-p\previousZ)*curTime RotateEntity p\mesh,0,p\previousYaw+(p\nextYaw-p\previousYaw)*curTime,0 Else PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ RotateEntity p\mesh,0,p\nextYaw,0 EndIf ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ResetEntity p\mesh ; reset entity is useful here because of collisions Else ; update our player, basically it just compute gravity p\velocityY = p\velocityY - 0.03 ; fake gravity If EntityY(p\mesh) - p\currentY >= 0 ; if player is not falling we limit the gravity If p\velocityY < -0.03 Then p\velocityY = -0.03 EndIf p\currentY = EntityY(p\mesh) TranslateEntity p\mesh,0,p\velocityY,0 EndIf Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CreatePlayer(id,name$) For p.player = Each player If p\id = id Then Return ; player already connected Next p.player = New player p\id = id p\name = name p\life = 100 p\mesh = CreateSphere() EntityType p\mesh,2 EntityRadius p\mesh,1 NameEntity p\mesh,Handle(p) nose = CreateSphere(8,p\mesh):EntityColor nose,255,0,0 PositionEntity nose,0,0,1 ScaleEntity nose,0.3,0.3,0.3 eyeLeft = CreateSphere(8,p\mesh):EntityColor eyeLeft,255,255,255 PositionEntity eyeLeft ,.29,.4,.7;1 ScaleEntity eyeLeft ,0.2,0.2,0.2 pupilLeft = CreateSphere(8,p\mesh):EntityColor pupilLeft ,0,0,0 PositionEntity pupilLeft ,.3,.4,.9;1 ScaleEntity pupilLeft ,0.05,0.05,0.02 eyeRight = CreateSphere(8,p\mesh):EntityColor eyeRight ,255,255,255 PositionEntity eyeRight ,-.29,.4,.7;1 ScaleEntity eyeRight ,0.2,0.2,0.2 pupilRight = CreateSphere(8,p\mesh):EntityColor pupilRight ,0,0,0 PositionEntity pupilRight ,-.3,.4,.9;1 ScaleEntity pupilRight ,0.05,0.05,0.02 unaBrow = CreateCone(8,1,p\mesh):EntityColor unaBrow ,0,0,0 PositionEntity unaBrow ,0,.45,.7 RotateEntity unaBrow ,-180,0,0 ScaleEntity unaBrow ,.7,.2,.3 p\nextX = -20 p\nextY = 1 p\nextZ = -20 p\nextYaw = -45 p\previousX = p\nextX p\previousY = p\nextY p\previousZ = p\nextZ p\previousYaw = p\nextYaw p\r = Rand(255) p\g = Rand(255) p\b = Rand(255) EntityColor p\mesh,p\r,p\g,p\b PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ RotateEntity p\mesh,0,p\nextYaw,0 ResetEntity p\mesh p\currentY = p\nextY p\previousTime = MilliSecs() p\nextTime = MilliSecs()+1 Return p\mesh End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function ResetPlayer(id) p.player = Object.player(GetPlayer(id)) p\life = 100 p\nextX = -20 p\nextY = 1 p\nextZ = -20 p\nextYaw = -45 p\previousX = p\nextX p\previousY = p\nextY p\previousZ = p\nextZ p\previousYaw = p\nextYaw PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ RotateEntity p\mesh,0,p\nextYaw,0 ResetEntity p\mesh p\currentY = p\nextY p\previousTime = MilliSecs() p\nextTime = MilliSecs()+1 End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function GetPlayer(id) For p.player = Each player If p\id = id Return Handle(p) EndIf Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function DrawPlayersNames() For p.player = Each player Color 255,255,255 CameraProject(camera,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh)) If p\id <> localID Then Text ProjectedX(),ProjectedY()-60,p\name,1,1 Color 255,(255./100.)*p\life,(255./100.)*p\life Text ProjectedX(),ProjectedY()-40,p\life,1,1 Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CreateBullet(id) p.player = Object.player(GetPlayer(id)) b.bullet = New bullet b\id = p\id b\mesh = CreateSphere(2) ScaleEntity b\mesh,0.2,0.2,0.2 EntityColor b\mesh,255,0,0 PositionEntity b\mesh,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh) RotateEntity b\mesh,0,EntityYaw(p\mesh),0 EntityType b\mesh,3 EntityRadius b\mesh,0.2 b\time = MilliSecs() End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateBullets() For b.bullet = Each bullet MoveEntity b\mesh,0,0,1 If CountCollisions(b\mesh) If localMode = 2 ; only the server compute bullets collision with player If GetEntityType(CollisionEntity(b\mesh,1)) = 2 ; a player is hit touchedPlayer.player = Object.player(EntityName(CollisionEntity(b\mesh,1))) touchedPlayer\life = touchedPlayer\life - 10 If touchedPlayer\life > 0 ; touched Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id) Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id,touchedPlayer\id) Else ; killed killerPlayer.player = Object.player(GetPlayer(b\id)) killerPlayer\kills = killerPlayer\kills + 1 touchedPlayer\deaths = touchedPlayer\deaths + 1 Net_SendMessage(6,touchedPlayer\id,killerPlayer\id) Net_SendMessage(6,touchedPlayer\id,killerPlayer\id,killerPlayer\id) Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id) Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id,killerPlayer\id) Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id) Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id,touchedPlayer\id) NewMessage(killerPlayer\name + " killed " + touchedPlayer\name) ResetPlayer(touchedPlayer\id) EndIf EndIf EndIf FreeEntity b\mesh Delete b ElseIf MilliSecs()-b\time > 2000 FreeEntity b\mesh Delete b EndIf Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function NewMessage(msg$) messageOffset = messageOffset + 1 If messageOffset > messageDisplayNumber messageOffset = messageOffset - 1 For i = 2 To messageDisplayNumber message(i-1) = message(i) Next message(messageDisplayNumber) = msg Else message(messageOffset) = msg EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function DrawMessages() Color 255,255,255 For i = 1 To messageOffset loc = Instr (message(i), "¿",1) If loc > 1 Then colorMessage$ = Mid$(message(i), 1, Len(message(i)) - 7 ) Hex$ = Right$(message(i),6) Set_Color_Hex(Hex$) Text 0,(i-1)*15,colorMessage$ Else Color 255,255,255 Text 0,(i-1)*15,message(i) End If Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateChat() key = GetKey() If key If key = 13 If chatMessage <> localName + "> " For i = Len(localName + "> ") To Len(chatMessage) If Mid(chatMessage,i,1) <> " " chatColor$ = RGB_To_TriHex(cR,cG,cB) chatMessage = chatMessage + "¿" + chatColor$ Net_SendMessage(1,chatMessage) NewMessage(chatMessage) Exit EndIf Next EndIf chatMessage = localName + "> " chatMode = 0 ElseIf key = 8 And Len(chatMessage) > Len ( localName + "> " ) chatMessage = Left(chatMessage,Len(chatMessage)-1) ElseIf key > 31 And key < 127 chatMessage = chatMessage + Chr(key) EndIf EndIf Color 255,255,255 Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,1 Color 0,0,0 Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,0 If MilliSecs()-chatMillisecs > 500 chatCursor = Not chatCursor chatMillisecs = MilliSecs() EndIf If chatCursor Text 5,GraphicsHeight()-17,chatMessage + "|" Else Text 5,GraphicsHeight()-17,chatMessage EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function DrawScoreTable() For p.player = Each player count = count + 1 Next baseX = (GraphicsWidth()-350)/2 baseY = (GraphicsHeight()-(35+20*count))/2 Color 0,0,0 Rect baseX,baseY,350,35+20*count,1 Color 255,192,0 Rect baseX,baseY,350,35+20*count,0 Text baseX+10,baseY+10,"Player Kills Deaths Ping" Line baseX,baseY+25,baseX+349,baseY+25 For p.player = Each player Color 255,255,255 If p\id = localID Then Color 255,100,100 i = i + 1 Text baseX+10,baseY+10+20*i,p\name Text baseX+157,baseY+10+20*i,p\kills,1,0 Text baseX+240,baseY+10+20*i,p\deaths,1,0 Text baseX+322,baseY+10+20*i,p\ping,1,0 Next End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function UpdateChaseCam(camera,player) ; thanks to jfk EO-11110 on bb forums for this function ! PositionEntity camera,EntityX(player,1),EntityY(player,1),EntityZ(player,1) ResetEntity camera x#=EntityX(player)+Sin(-EntityYaw(player)+180)*x_dis# y#=EntityY(player)+y_dis# z#=EntityZ(player)+Cos(-EntityYaw(player)+180)*z_dis# obstacle=LinePick(EntityX(player),EntityY(player),EntityZ(player),(x-EntityX(player)),y_dis#,(z-EntityZ(player)),0.1) If obstacle=0 new_x#=x new_y#=y new_z#=z Else new_x#=PickedX() new_y#=PickedY() new_z#=PickedZ() EndIf If bounce_cam=0 PositionEntity camera,new_x,new_y,new_z Else x=old_x+((New_x-old_x)/bounce_div#) y=old_y+((New_y-old_y)/bounce_div#) z=old_z+((New_z-old_z)/bounce_div#) PositionEntity camera,x,y,z EndIf PointEntity camera,player TurnEntity camera,-20,0,0 ; if you want the player mesh more on the bottom of the screen old_x#=EntityX(camera) old_y#=EntityY(camera) old_z#=EntityZ(camera) End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CreateScene() texture = TextureCreate(128) ground = CreatePlane() EntityColor ground,150,150,150 EntityTexture ground,texture cube = CreateCube():EntityColor cube,150,200,150 ScaleEntity cube,5,5,5:PositionEntity cube,0,5,0 EntityTexture cube,texture sphere = CreateSphere(16):EntityColor sphere,200,150,150 ScaleEntity sphere,3,1,3:PositionEntity sphere,0,9.7,0 platform = CreateCube():EntityColor platform,150,150,200 ScaleEntity platform,3,1,10:PositionEntity platform,0,4.13,-13.15 TurnEntity platform,-30,0,0 EntityTexture platform,texture FreeTexture texture EntityType ground,1:EntityPickMode ground,2 EntityType cube,1:EntityPickMode cube,2 EntityType sphere,1:EntityPickMode sphere,2 EntityType platform,1:EntityPickMode platform,2 light = CreateLight() TurnEntity light,30,70,0 ;; COLLISIONS Collisions 2,1,2,3 ; player to scene Collisions 2,2,1,3 ; player to player Collisions 3,1,2,1 ; bullet to scene Collisions 3,2,1,1 ; bullet to player End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function TextureCreate(size) texture = CreateTexture(size,size,9) SetBuffer TextureBuffer(texture) Color 255,255,255 Rect 0,0,size,size,1 Color 0,0,0 Rect 0,0,size,size,0 Line 0,0,size,size Line 0,size,size,0 SetBuffer BackBuffer() Return texture End Function
비교하기