| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import sdl2
- import sdl2/ttf
- # import sdl2/private/keycodes
- from ./pong/cons import nil
- import ./pong/pong
- import ./pong/tmpl
- import ./pong/font
- type
- App {.requiresInit.}= object
- window:WindowPtr
- renderer:RendererPtr
- font:Font
- isRun = true
- game:Pong
- dt: float32=0
- event:Event
- proc NewApp():App=
- if_SDL_fail(not sdl2.init(INIT_VIDEO or INIT_TIMER or INIT_EVENTS)):
- "NewApp(): SDL2 initialization failed"
- let window = createWindow(
- title = "PingPong",
- x = SDL_WINDOWPOS_CENTERED,
- y = SDL_WINDOWPOS_CENTERED,
- w = cons.WindowWidth,
- h = cons.WindowHeight,
- flags = SDL_WINDOW_SHOWN
- )
- if_SDL_fail(window.isNil, "NewApp(): window could not be created")
- let renderer = createRenderer(
- window = window,
- index = -1,
- flags = Renderer_Accelerated or Renderer_PresentVsync or Renderer_TargetTexture
- )
- if_SDL_fail(renderer.isNil, "NewApp(): renderer could not be created")
- if_SDL_fail(not ttfInit()): "NewApp(): SDL_TTF initialization failed"
- let font0 = ttf.openFont("./assets/UbuntuMono-R.ttf", cons.TextHeight)
- if_SDL_fail(font0.isNil, "NewApp(): font could not be created")
- let font=NewFont(font0, renderer)
- let game = NewPong(font, renderer)
- let sf=App(
- window:window,
- renderer:renderer,
- font:font,
- game:game,
- event:defaultEvent,
- )
- return sf
- var
- keyUp, keyDown:bool
- proc loop(sf:var App){.inline.}=
- case sf.event.kind
- of QuitEvent:
- sf.isRun = false
- of KeyDown:
- # game.sdlInput[event.key.keysym.scancode.toInput] = true
- # game.sdlInput[event.key.keysym.scancode.toInput] = false
- # Теперь безопасно проверяем конкретные клавиши
- case sf.event.key.keysym.scancode
- of SDL_SCANCODE_UP:
- keyUp=true
- of SDL_SCANCODE_DOWN:
- keyDown=true
- else:
- discard
- of KeyUp:
- # Останавливаем движение, когда стрелки отпущены
- case sf.event.key.keysym.scancode
- of SDL_SCANCODE_UP:
- keyUp=false
- of SDL_SCANCODE_DOWN:
- keyDown=false
- else:
- discard
- else:
- discard
- proc run(sf:var App)=
- defer: sdl2.quit()
- defer: sf.window.destroy()
- defer: sf.renderer.destroy()
- defer: ttfQuit()
- var
- lastTime = getTicks() # Время на предыдущем кадре
- fpsTimer = getTicks() # Таймер для обновления счетчика FPS
- frameCount = 0 # Счетчик отрисованных кадров
- fps = 0 # Итоговый FPS для вывода
- while sf.isRun:
- # 1. Считаем время между кадрами (в миллисекундах)
- let currentTime = getTicks()
- # Переводим в секунды (разделив на 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()
- app.run()
- main()
|