Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi DelphiX alle 1/30 Sek was tun im timer mit anderem Intervall (https://www.delphipraxis.net/39889-delphix-alle-1-30-sek-tun-im-timer-mit-anderem-intervall.html)

Delphi-Noobie 8. Feb 2005 17:22


DelphiX alle 1/30 Sek was tun im timer mit anderem Intervall
 
huhu,

Ich hab nen Dxtimer auffen Formular mit dem Intervall 0 (durläuft sich sich ca. 320 mal inna Sekunde)
und will in diesem Timer eine Procedure nur alle 1/30 seks aufrufen lassen (spriteengine.move(1)):
Delphi-Quellcode:
procedure TForm1.TimerTimer(Sender: TObject; LagCount: Integer);
begin
// viel Code

Dxspriteengine1.move(1) // <- die will ich nur alle 1/30 seks aufrufen, da sie sich
                        // in Realtime bewegen sollen (sonst würden die sprites
                        // sich 320 mal inna Sekunde bewegen)

.
.
.
Dxspriteengine.draw;

// viel Code
end;
Und außerdem, wenn der Timer nicht hinterherkommt (auf langsamen rechnern) und nur mit beispielsweise 25 Fps läuft dann soll es trotzdem "gleich sein"^^, also irgendwie irgendwann die Procedure 2 mal aufrufen aber das is erstmal nebensächlich.

Gruß Delphi-Noobie

sniper_w 8. Feb 2005 20:02

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Also du brauchst Zeitabhängige Bewegungen zu implementieren. Da brauchst du nicht jede 1/30 sekunde eine Prozedur aufzurufen, sondern kannst auch 320 mal pro Sekunde diese "Draw" Prozedure aufrufen. Das Hacken ist dass du die Koordinaten der zu bewegenden Objekt Zeitabhängig machst.

Beispiel :

v = s / t;


Delphi-Quellcode:
//---
var FPS: int64 = 0;
    framesPerSecond : int64 = 0; // This will store our fps
    frameTime : int64 = 0 ;     // This stores the last frame's time
    Freq : int64;
    lastTime : int64  = 0; // This will hold the time from the last frame

//---
procedure Tform1.create(sender:tobject);
begin
 QueryPerformanceFrequency( Freq );
end;
///-----
function speed() : double;
 var currentTime : int64;
begin
// Get the current time in seconds
 QueryPerformanceCounter( currentTime );

// Here we store the elapsed time between the current and last frame,
  g_FrameInterval := currentTime - frameTime;
  frameTime := currentTime;

// Increase the frame counter
  inc(framesPerSecond);

  result := g_FrameInterval / Freq ;

// Now we want to subtract the current time by the last time that was stored
// to see if the time elapsed has been over a second, which means we found our FPS.
    if ( currentTime - lastTime > Freq ) then
    begin
      // Here we set the lastTime to the currentTime
        lastTime := currentTime;
        FPS := framesPerSecond ;
      // Reset the frames per second
        framesPerSecond := 0;
    end;
end;

malo 8. Feb 2005 20:05

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Was hälst du davon, einen zweiten Timer aufs Form zu ziehen? :gruebel:

Delphi-Noobie 8. Feb 2005 20:18

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
@ malo: würde gehen aber ich will nur 1 timer verwenden(weiß auch net ob der dann auch langsamer wird)

@ sniper: die framespersecond kann ich auch so ermitteln (dxtimer.framerate)
wozu dient die Procedure da noch? Ich dachte an so nen Bsp. wie:
x:=x+(2*100) / FPS, jedoch in dem timer und nicht in move Methode der sprites
Wenn das mit deiner Procedure da irgendwie klappt poste doch mal nen Beispielcode damit in der Form:
Delphi-Quellcode:
//Wenn dein Code irgendwas erreicht hat, dann
Dxspriteengine1.move(1);
Er soll also die move-procedure nach Realtime aufrufen nicht nach timerspeed(also soll sich das sprite beispielsweise 10 Pixel pro Sekunde bewegen).

sakura 8. Feb 2005 20:20

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Zitat:

Zitat von Delphi-Noobie
@ malo: würde gehen aber ich will nur 1 timer verwenden(weiß auch net ob der dann auch langsamer wird)

Nur mal allgemein, ein Timer mit Intervall auf 0 killt Dir das System, da der Prozessor voll ausgelastet ist, denke da mal über einen anderen Ansatz nach.

...:cat:...

sniper_w 8. Feb 2005 20:35

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Delphi-Quellcode:
      QueryPerformanceCounter( currentTime );
      // currentFrame - frameTime >>> g_FrameInterval !!!!!!!!!!!
      speed := (currentTime - frameTime) / Freq;
      frameTime := currentTime;

         // now we have a TIME BASED rotation
         angx := angx + (170 + rot_speed )* speed;
         if angx>359 then angx := 0;

         angy := angy + (160 + rot_speed ) * speed;
         if angy>359 then angy := 0;

         angz := angz + (150 + rot_speed ) * speed;
         if angz>359 then angz := 0;
So werden die 3 Variablen angx, angy und angz ABHÄNGIG von der ZEIT addiert.

rot_speed ist eine beliebige Zahl / Konstante...

So "schnell" muss du dich bewegen, rotieren, etc.. pro Prozedur Afuruf.
Delphi-Quellcode:
var speed : double;

Delphi-Noobie 8. Feb 2005 20:44

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Nur das ich das verstehe: Die Funktion setzt den speed? Das heißt ich müsste das alles in die domove Methode der einzelnen Sprites reinhauen um dort die Geschwindigkeit anzupassen?(die 1 bei engine.move(1) is nur fake, die hat keinen Sinn, da ich alles überschrieben habe).

@ sakura: Wie soll man sonst nen Spiel mit hoher framezahl machen, wenn man keinen sehr schnellen Timer verwendet(Dxtimer)? Würde ich ihn auf 100ms senken is die framezahl auch viel zu niedrig. gibts denn ne andere Möglichkeit außer Timer?

sniper_w 8. Feb 2005 20:58

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Nun wenn du ein Spiel machen willst, dann bitte nicht mit irgendwelchem Timer, davon rate ich dich herzlichst ab.

So, wenn du mit VLC was machst, dann benutze Application.OnIdle event (siehe Hife von Delphi). Drin musst du nur Variable Done auf Fales setzten.

An sonsten, gebe ich hier mal ein Code s. aus meiner Game "funny toggle".

Delphi-Quellcode:
//------------------------------------------------------------------------
//
// Author     : Haris Katura / SNIPER
// Email      : [email]haris_201@hotmail.com[/email]
// Website    :
// Date       : 10.01 Januar 2005, Montag
// Version    : 1.0
// Description : FunnyToggle
//
//------------------------------------------------------------------------
program FunnyToggle;

uses
  Windows,
  Messages,
  dglOpenGL,
  glFont in 'glFont.pas',
  Game in 'Game.pas',
  gl_ref in 'gl_ref.pas',
  glMenu in 'glMenu.pas';
//  MenuData in 'MenuData.pas';

{$R FrameWork.RES}

{--------------------------------------------------------------------}
{  Main message loop for the application                            }
{--------------------------------------------------------------------}
function WinMain(hInstance : HINST; hPrevInstance : HINST;
                 lpCmdLine : PChar; nCmdShow : Integer) : Integer; stdcall;
var
  msg : TMsg;
  finished : Boolean;
  currentTime, frameTime,Freq : Int64;
  speed : Single;
begin
  finished := False;

  // Perform application initialization:
  if not glCreateWnd(800, 600, TRUE, 32) then // TRUE for Fullscreen
  begin
    Result := 0;
    Exit;
  end;

  QueryPerformanceFrequency(Freq);
  frameTime := 0;

  GameStart( nVeliki, 5);

//  InitMenues();// !!!!!!!

  // Main message loop:
  while not finished do
  begin

    if (PeekMessage(msg, 0, 0, 0, PM_REMOVE)) then // Check if there is a message for this window
      if (msg.message = WM_QUIT) then    // If WM_QUIT message received then we are done
                 finished := True
             else
                 DispatchMessage(msg);

    begin   // idle proc...
     if (TheKey = VK_ESCAPE) then finished := true
           else ProcessKeys;                    // Check for any other key Pressed

      Inc(FPSCount);                     // Increment FPS Counter

      QueryPerformanceCounter( currentTime );
      // currentFrame - frameTime >>> g_FrameInterval !!!!!!!!!!!
      speed := (currentTime - frameTime) / Freq;
      frameTime := currentTime;

         // now we have a TIME BASED rotation
         angx := angx + (170 + rot_speed )* speed;
         if angx>359 then angx := 0;

         angy := angy + (160 + rot_speed ) * speed;
         if angy>359 then angy := 0;

         angz := angz + (150 + rot_speed ) * speed;
         if angz>359 then angz := 0;

      if FGame.GameOver then
        begin
                angGlob := angGlob + (50 + rot_speed) * speed;
                if angGlob>359 then angGlob := 0;

                glDraw_OutGame();   // Draw the scene and display it
        end
         else
                glDraw_InGame(); // Draw the scene and display it

    end; // idle proc
  end;   // while not finished .....
 
  glKillWnd();
  ClearExtensions();
  Result := msg.wParam;
end;


begin
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
  WinMain( hInstance, hPrevInst, CmdLine, CmdShow );
end.

Delphi-Noobie 8. Feb 2005 21:20

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Naja der Code sagt mir persönlich nicht viel. Aber ich hab jetzt alles im mom auf Timer basierend gemacht(so is DelphiX). ausprobieren könnte ich den Code auch net, da ich nich mal die units habe.
Auch wenn ich mir das vielleicht mal angucken werde mir dem onidle (kannst ja mal das prog mit units zum runterladen geben) mache ich diese Prog mit timer zuende, habe bis jetzt keine Probs gehabt. Deswegen will ich erstmal nur ne Lösung dafür. Kann man denn net abfragen, ob jedesmal eine bestimmte Zeit vergangen ist nachdem das letzte mal engine.move(1) aufgerufen wurde und wenn diese bestimmte Zeit erreicht is, dann rufe sie wieder auf?? Irgendwas mit Gettickcount oder mod oder so?

Also nochmal sry @ sniper aber der Code von dir hilft mir bei diesem Problem nicht zwingend weiter (wegen Timer^^).

sniper_w 8. Feb 2005 21:51

Re: DelphiX alle 1/30 Sek was tun im timer mit anderem Inter
 
Sinn der Sache ist so:
Du machst eine , sag ma´ so, MainLOOP, in der du alles was zu erledigen ist , erledigst. Zum B., wenn ein Objekt jede 1/n Sekunde bewegt sein muss, dann tust du es und merskt dir die Zeit des Geschehens, beim nächsten Mal überprüfst du ob genug Zeit vergangen ist, wenn ja , beweg es, merk wieder die Zeit usw.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz