2013-05-10 32 views
10

Tôi mới bắt đầu với lập trình trong C# và tôi chỉ đang làm một trò chơi pingpong. Tôi đang sử dụng các chủ đề - một cho va chạm, một cho di chuyển, một cho bức tranh.trò chơi pingpong chạy nhanh hơn khi tôi mở STEAM - tại sao?

Câu hỏi của tôi là lý do tại sao chương trình chạy nhanh hơn, khi tôi mở hơi nước: D với tôi, nó có vẻ như một ý nghĩa vô nghĩa.Chúng tôi chậm hơn - quả bóng chậm hơn và các miếng đệm quá. Có vẻ như bộ xử lý là lười biếng để làm công việc hoặc một cái gì đó như thế. Nó đang xảy ra trong thời gian thực - tôi mở trò chơi, nó là chậm, tôi mở hơi nước, nó là nhanh hơn và sau đó tôi gần hơi nước và nó là chậm một lần nữa.

Suy nghĩ đầu tiên của tôi là vì thẻ đồ họa kép nhưng làm cho nó sử dụng thẻ nvidia không được trợ giúp.

tình huống khác: tôi mở trò chơi - chậm, mở skype - trò chơi là nhanh hơn, skype được nạp - Trò chơi được chậm, đóng skype - trò chơi là nhanh chóng, đóng skype - trò chơi là chậm ..

Làm thế nào để làm cho các trò chơi để sử dụng bộ vi xử lý luôn giống nhau?

mã của tôi tôi di chuyển phương pháp là

public void move() 
    { 
     DelegateSetScore d = new DelegateSetScore(SetScore); 

     while (!isDisposing) 
     { 
      pad1.Y = pad1.Y + 4 * pad1Down + 4 * pad1Up; 
      if (pad1.Y < 0) { pad1.Y = 0; } 
      if (pad1.Y + pad1.Height > HEIGHT) { pad1.Y = HEIGHT - pad1.Height; } 

      pad2.Y = pad2.Y + 4 * pad2Down + 4 * pad2Up; 
      if (pad2.Y < 0) { pad2.Y = 0; } 
      if (pad2.Y + pad2.Height > HEIGHT) { pad2.Y = HEIGHT - pad2.Height; } 

      ball.X = ball.X + 6 * ballXDirection; 
      ball.Y = ball.Y + 2 * ballYDirection; 

Dưới đây là một số mã thêm về vụ va chạm với biên giới và các điểm đếm ... và nó và với waitevent.

  waitevent.WaitOne(5); 

Tôi đoán đó là vì việc ép xung tự động của bộ xử lý, nhưng tôi là một newbie ..: D

Dưới đây là toàn bộ điều trong một thread

public void bigthread() 
    { 

     DelegateSetScore d = new DelegateSetScore(SetScore); 

     while (!isDisposing) 
     { 
      //move 

      pad1.Y = pad1.Y + 4 * pad1Down + 4 * pad1Up; 
      if (pad1.Y < 0) { pad1.Y = 0; } 
      if (pad1.Y + pad1.Height > HEIGHT) { pad1.Y = HEIGHT - pad1.Height; } 

      pad2.Y = pad2.Y + 4 * pad2Down + 4 * pad2Up; 
      if (pad2.Y < 0) { pad2.Y = 0; } 
      if (pad2.Y + pad2.Height > HEIGHT) { pad2.Y = HEIGHT - pad2.Height; } 

      ball.X = ball.X + 6 * ballXDirection; 
      ball.Y = ball.Y + 2 * ballYDirection; 

      if (ball.X < 0) 
      { 
       ballXDirection = 1; 
       intScorePlayer2++; 
       this.BeginInvoke(d, intScorePlayer2, 2); 
      } 

      if (ball.X + ball.Width > WIDTH) 
      { 
       ballXDirection = -1; 
       intScorePlayer1++; 
       this.BeginInvoke(d, intScorePlayer1, 1); 
      } 

      if (ball.Y < 0) 
      { 
       ballYDirection = 1; 
      } 

      if (ball.Y + ball.Height > HEIGHT) 
      { 
       ballYDirection = -1; 
      } 

      //collision 

      if ((pad1.X + pad1.Width > ball.X) && (ball.X + ball.Width > pad1.X)) 
       if ((pad1.Y + pad1.Height > ball.Y) && (ball.Y + ball.Height > pad1.Y)) 
       { 
        ballXDirection = 1; 
        if (pad1Down == 1) { ballYDirection = 1; } 
        if (pad1Up == -1) { ballYDirection = -1; } 
       } 

      if ((pad2.X + pad2.Width > ball.X) && (ball.X + ball.Width > pad2.X)) 
       if ((pad2.Y + pad2.Height > ball.Y) && (ball.Y + ball.Height > pad2.Y)) 
       { 
        ballXDirection = -1; 
        if (pad2Down == 1) { ballYDirection = 1; } 
        if (pad2Up == -1) { ballYDirection = -1; } 
       } 

      //paint - platno is graphics from picturebox 
      Platno.Clear(Color.Black); 
      Platno.FillRectangle(Brushes.Orange, pad1); 
      Platno.FillRectangle(Brushes.Orange, pad2); 
      Platno.FillRectangle(Brushes.Green, ball); 

      waitevent.WaitOne(10); 
     } 
    } 
+0

đây chính là loại điều khiến Windows rất rất, rất đáng sợ ... – wroniasty

+2

Bạn nên giải thích chính xác những gì diễn ra nhanh hơn và chậm hơn. Do nhiều khung hình hơn có được hiển thị hay không, hoặc mã 'move()' của bạn chỉ hoạt động với các giá trị lớn hơn của 'pad1N' để bạn thấy các miếng đệm di chuyển nhanh hơn? – CodeCaster

+0

Giá trị của pad1Down, pad2Up luôn là 0, -1 hoặc 1. Vì vậy, các chủ đề phải được nhanh hơn - nó lặp lại thường xuyên hơn –

Trả lời

3

Điều đó gần như chắc chắn vì các ứng dụng đó lập trình lại bộ đếm thời gian gián đoạn xảy ra thường xuyên hơn. Theo mặc định, chế độ Sleep, waits và context switch kiểm tra xảy ra trong khoảng 10 hoặc 15 mili giây, tùy thuộc vào phiên bản Windows, nhưng có thể thay đổi bằng cách gọi hàm timeBeginPeriod API với đối số là 1 (một).

Xem this question để biết cách thực hiện điều đó trong đơn đăng ký của bạn.

+0

Cảm ơn rất nhiều! Theo mặc định tôi có 15ms. Nó có thể làm hại một số chương trình hoặc máy tính khác bằng cách đặt nó vào 1 ms không? Bởi vì đó là cách duy nhất để làm cho chương trình của tôi không thể thay đổi được bởi người khác. –

+0

@Zail Có vẻ như chương trình của bạn sau đó sẽ thay đổi hành vi của các chương trình khác (như các trò chơi pingpong khác ...) giống hệt như cách STEAM thay đổi hành vi của các chương trình khác. –

+0

Điều này sẽ không gây hại gì. Sẽ có một chi phí cao hơn một chút O/S và mức tiêu thụ điện sẽ tăng nhẹ, đó là vấn đề nhiều hơn nếu chạy trên máy tính xách tay. –

2

này sức vì bộ xử lý của bạn chuyển trạng thái nguồn. Hãy thử giữ CPU-Z mở trong khi bạn mở và đóng ứng dụng của bạn và Skype/Steam và quan sát những gì xảy ra với bộ xử lý của bạn.

+1

Đây là một đoán tốt, nhưng nó là đủ của một đoán rằng tôi không muốn upvote nó chỉ được nêu ra. Nhưng nếu anh ta xác nhận đây là vấn đề, @ tôi một bình luận và tôi sẽ upvote này và tìm thấy một câu trả lời 9-bỏ phiếu xứng đáng để cũng upvote và cung cấp cho bạn một huy hiệu cho việc này. –

+0

Tôi đã cố gắng để thiết lập máy tính xách tay của tôi để chế độ powersaving - frequncy của proccesor đã luôn luôn 1100 và vẫn còn với hơi nước mở nó chạy faste. Tôi có thể tìm thấy trạng thái nguồn xử lý trong CPU Z ở đâu? –

+0

@Zail: tắt chế độ tiết kiệm năng lượng trên máy. Hơi nước, theo hiểu biết của tôi, thực sự thực hiện điều này khi ra mắt. – NotMe

3

Để đảm bảo cảm giác trò chơi/mô phỏng không thay đổi với tính khả dụng của CPU/GPU, tốc độ hiển thị, v.v., bạn cần sử dụng thời gian trôi qua để kiểm soát mọi thứ chứ không phải vòng lặp. Trong mẫu mã bạn có, tôi không thấy bạn tính đến thời gian trôi qua kể từ lần thực thi cuối cùng. Vì vậy, bạn muốn tốc độ của bạn là một hàm thời gian, ví dụ: 5 pixel (đơn vị khoảng cách sắp xếp)/giây. Sau đó, trong mỗi lần thực hiện, bạn tính toán thời gian đã trôi qua kể từ lần cuối cùng vòng lặp được thực thi và bao gồm khoảng cách đó bạn cần di chuyển bằng cách nhân nó với tốc độ của bạn.

Một điều bạn nên làm là giới hạn số lần làm mới trò chơi của bạn hoạt động. tức là nếu kết xuất đã xảy ra ít hơn X mili giây trước, thì bạn sẽ không hiển thị cho đến khi một khoảng thời gian nhất định trôi qua. Bạn có thể sử dụng FPS mục tiêu và tính toán thời gian cần thiết từ đó. Ví dụ. nếu bạn muốn giới hạn ứng dụng của mình thành 40 FPS, thì nếu vòng lặp kết xuất của bạn được thực hiện trong chưa đầy 25ms kể từ lần render cuối cùng, bạn chỉ cần ngủ cho đến khi 25ms trôi qua.

Sử dụng thời gian làm hướng dẫn thay vì thực hiện vòng lặp hoặc chờ đợi cố định sẽ ngăn trò chơi của bạn hiển thị nhanh hơn hoặc chậm hơn bất kể những gì đang xảy ra trên hệ thống của bạn. Tất nhiên nếu bạn hoàn toàn không có CPU/GPU và quá trình render mất quá nhiều thời gian, FPS của bạn sẽ giảm xuống đến mức bạn có thể thấy sự chậm chạp nhưng với một trò chơi pong-clone, bạn thực sự không nên đến điểm đó. :)

+0

Tôi đã cố gắng một lần để làm điều này. Tôi đo thời gian vòng lặp với đồng hồ bấm giờ - bắt đầu từ lúc bắt đầu và dừng ở cuối. Sau đó, tôi chờ đợi (thời gian đo thời gian). Mỗi lopp + "chờ sau" sau đó nên sử dụng cùng một lượng thời gian. Nhưng - đồng hồ bấm giờ hầu như tất cả mọi thứ tính 0 ms cho vòng lặp .. vì vậy nó là vô nghĩa. –

+0

Và cũng - điều này sẽ được thực hiện chính để làm chậm vòng lặp để làm cho tất cả mọi người cùng dài. Nhưng trước tiên tôi cần phải làm cho nó nhanh hơn nếu như "hơi nước đang chạy" –

+0

Bạn không thể sử dụng đồng hồ bấm giờ. Nó không có độ phân giải đủ cao để đo thời gian theo cách bạn cần. Xem [đây] (http://stackoverflow.com/questions/1825720/c-high-precision-time-measurement-in-windows) để thảo luận về chủ đề. – Tombala

Các vấn đề liên quan