Pārlūkot izejas kodu

SVI Change code for true work

SVI 3 mēneši atpakaļ
vecāks
revīzija
b98e2aea2a
4 mainītis faili ar 67 papildinājumiem un 28 dzēšanām
  1. 43 13
      src/nimcity.nim
  2. 9 0
      src/pong/font.nim
  3. 11 8
      src/pong/player.nim
  4. 4 7
      src/pong/pong.nim

+ 43 - 13
src/nimcity.nim

@@ -15,13 +15,11 @@ type
         isRun = true
         game:Pong
         dt: float32=0
-        counter: uint64
-        previousCounter: uint64=0
         event:Event
 
 proc NewApp():App=
     if_SDL_fail(not sdl2.init(INIT_VIDEO or INIT_TIMER or INIT_EVENTS)):
-        "SDL2 initialization failed"
+        "NewApp(): SDL2 initialization failed"
 
     let window = createWindow(
         title = "PingPong",
@@ -48,17 +46,18 @@ proc NewApp():App=
     let font=NewFont(font0, renderer)
 
     let game = NewPong(font, renderer)
-    let counter = getPerformanceCounter()
     let sf=App(
         window:window,
         renderer:renderer,
         font:font,
         game:game,
-        counter:counter,
         event:defaultEvent,
     )
     return sf
 
+var
+    keyUp, keyDown:bool
+
 proc loop(sf:var App){.inline.}=
     case sf.event.kind
     of QuitEvent:
@@ -69,21 +68,22 @@ proc loop(sf:var App){.inline.}=
         # Теперь безопасно проверяем конкретные клавиши
         case sf.event.key.keysym.scancode
         of SDL_SCANCODE_UP:
-            sf.game.keyUp(sf.dt)
+            keyUp=true
         of SDL_SCANCODE_DOWN:
-            sf.game.keyDown(sf.dt)
+            keyDown=true
         else:
             discard
     of KeyUp:
         # Останавливаем движение, когда стрелки отпущены
         case sf.event.key.keysym.scancode
-        of SDL_SCANCODE_UP, SDL_SCANCODE_DOWN:
-            sf.game.stopHuman()
+        of SDL_SCANCODE_UP:
+            keyUp=false
+        of SDL_SCANCODE_DOWN:
+           keyDown=false
         else:
             discard
     else:
         discard
-    sf.game.update(sf.dt)
 
 proc run(sf:var App)=
     defer: sdl2.quit()
@@ -91,16 +91,46 @@ proc run(sf:var App)=
     defer: sf.renderer.destroy()
     defer: ttfQuit()
 
+    var
+        lastTime = getTicks()      # Время на предыдущем кадре
+        fpsTimer = getTicks()      # Таймер для обновления счетчика FPS
+        frameCount = 0             # Счетчик отрисованных кадров
+        fps = 0                    # Итоговый FPS для вывода
+
     while sf.isRun:
-        sf.previousCounter = sf.counter
-        sf.counter = getPerformanceCounter()
+        # 1. Считаем время между кадрами (в миллисекундах)
+        let currentTime = getTicks()
 
-        sf.dt = (sf.counter - sf.previousCounter).float / getPerformanceFrequency().float
+        # Переводим в секунды (разделив на 1000), чтобы использовать как dt
+        sf.dt = (currentTime - lastTime).float / 1000.0
+        lastTime = currentTime
+
+        # 2. Считаем FPS (обновляем раз в секунду, чтобы текст не мерцал)
+        inc frameCount
+        if currentTime - fpsTimer >= 1000:
+            fps = frameCount
+            frameCount = 0
+            fpsTimer = currentTime
+
+            # Выводим FPS напрямую в заголовок окна для теста
+            sf.window.setTitle(("Pong Game | FPS: " & $fps).cstring)
 
         sf.event = defaultEvent
         while pollEvent(sf.event):
             sf.loop()
+        if keyUp:
+            sf.game.keyUp(sf.dt)
+        elif keyDown:
+            sf.game.keyDown(sf.dt)
+        else:
+            sf.game.stopHuman()
+        sf.game.update(sf.dt)
+        let
+            txtFps="FPS: " & $fps
+            color:Color=(r:255,g:255,b:0,a:255)
         sf.game.draw()
+        sf.font.text(txtFps, 50, 50, color)
+        sf.renderer.present()
 
 proc main =
     var app=NewApp()

+ 9 - 0
src/pong/font.nim

@@ -26,3 +26,12 @@ proc draw*(sf:Font, text:string, color:Color)=
     surface.freeSurface()
     texture.destroy()
 
+proc text*(sf:Font, text:string, x,y:cint, color:Color)=
+    let surface = ttf.renderTextSolid(sf.font, cstring text, color)
+    let texture = sf.renderer.createTextureFromSurface(surface)
+
+    var r = rect(x, y, TextWidth, TextHeight)
+    sf.renderer.copy(texture, nil, addr r)
+    surface.freeSurface()
+    texture.destroy()
+

+ 11 - 8
src/pong/player.nim

@@ -39,17 +39,18 @@ proc NewRobot*(x: float32=0, renderer:RendererPtr): Player =
 proc Stop*(sf:Player)=
     discard
 
-proc updateRobot(sf:var Player, dy: float32) =
-    sf.y = sf.y + dy
+proc update*(sf:var Player, dy, ballY: float32) =
+    let speed=300.0
+    if ballY>sf.y:
+        sf.y = sf.y + dy*speed
+    else:
+        sf.y = sf.y - dy*speed
     sf.y = max(sf.y, 0)
-    sf.y = min(sf.y, WindowHeight - PaddleWidth)
+    sf.y = min(sf.y, WindowHeight - PaddleHeight)
+    echo("ballY=", $ballY, " robotY=", $sf.y, " dy=", $dy)
 
 proc update*(sf:var Player, dt: float32)=
-    case sf.kind:
-    of Human:
-        discard
-    of Robot:
-        sf.updateRobot(dt)
+    discard
 
 
 proc draw*(sf: Player) =
@@ -80,9 +81,11 @@ proc control(sf:var Player){.inline.}=
         sf.y = WindowHeight - PaddleHeight
 
 proc Down*(sf:var Player, dt:float32){.inline.}=
+    # echo("Human.Down(): dt=", (dt*1000).int, " msec")
     sf.y -= PaddleSpeed * dt
     sf.control()
 
 proc Up*(sf:var Player, dt:float32){.inline.}=
+    # echo("Human.Up(): dt=", (dt*1000).int, " msec")
     sf.y += PaddleSpeed * dt
     sf.control()

+ 4 - 7
src/pong/pong.nim

@@ -34,10 +34,10 @@ proc NewPong*(font:Font, renderer:RendererPtr): Pong =
     )
 
 proc keyDown*(sf:var Pong, dt:float32)=
-    sf.human.Down(dt)
+    sf.human.Up(dt)
 
 proc keyUp*(sf:var Pong, dt:float32)=
-    sf.human.Up(dt)
+    sf.human.Down(dt)
 
 proc stopHuman*(sf: var Pong)=
   sf.human.Stop()
@@ -45,7 +45,7 @@ proc stopHuman*(sf: var Pong)=
 proc update*(sf:var  Pong, dt: float32) =
     sf.collision.update()
     sf.human.update(dt)
-    sf.robot.update(dt)
+    sf.robot.update(dt, sf.ball.y)
     let
         distRobot = (sf.ball.y + BallRadius) - (sf.robot.y + PaddleHeight / 2)
         req = BallUpdateReq(
@@ -58,13 +58,10 @@ proc update*(sf:var  Pong, dt: float32) =
         )
     sf.ball.update(req)
 
-
 proc draw*(sf:var Pong) =
   sf.renderer.setDrawColor 0, 0, 0, 255 # black
   sf.renderer.clear()
   sf.human.draw()
   sf.robot.draw()
   sf.ball.draw()
-  sf.scores.draw()
-
-  sf.renderer.present()
+  sf.scores.draw()