这是我遇到的一个相当具体的问题。该故障似乎只出现在最新的 Android 版 Chrome 更新中,因此规格如下:
应用版本:Chrome 45.0.2454.84
操作系统:安卓4.4.4;XT1031 内部版本/KXB21.14-L2.4
我使用的是 Moto G,但故障也发生在运行相同版本 Chrome 的三星上。无论如何,问题显然是touchstart事件中断了我的window.setTimeout游戏循环。这是代码:
(
function rafTouchGlitch() {
/////////////////
/* FUNCTIONS. */
///////////////
function touchStartWindow(event_) {
event_.preventDefault();
}
///////////////////////
/* OBJECT LITERALS. */
/////////////////////
var engine = {
/* FUNCTIONS. */
start : function(interval_) {
var handle = this;
(function update() {
handle.timeout = window.setTimeout(update, interval_);
/* Draw the background and the red square. */
display.fillStyle = "#303030";
display.fillRect(0, 0, display.canvas.width, display.canvas.height);
display.fillStyle = "#f00000";
display.fillRect(red_square.x, …Run Code Online (Sandbox Code Playgroud) 我想在go(lang)中创建游戏循环,所以我尝试了这个:
package main
import (
"fmt"
// "runtime"
"sync"
"time"
)
var v = 0
var wg sync.WaitGroup
var sec = 5
func main() {
wg.Add(1)
gameLoop()
wg.Wait()
}
func gameLoop() {
time.AfterFunc(16*time.Millisecond, gameLoop)
v++
fmt.Println(v)
if v == sec*60 {
// fmt.Println("Goroutines: ", runtime.NumGoroutine())
panic("err")
wg.Done()
}
}
Run Code Online (Sandbox Code Playgroud)
该程序以62.5Hz运行(16*time.Millisecond),var sec用于wg.Done()在5秒后调用并导致var v打印300次.
调用这样panic("err")的结果:
panic: err
goroutine 314 [running]:
panic(0x493c60, 0xc420094370)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
main.gameLoop()
/home/billyzaelani/Desktop/main.go:26 +0x11f
created by time.goFunc
/usr/local/go/src/time/sleep.go:154 +0x44
exit status …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Servant构建基于浏览器的游戏的后端,我希望有一种游戏循环让我每秒发出请求x.我已经将一些游戏状态包含在一个中IORef,并且作为初始尝试使某些东西工作我试图每2秒更新一次状态值.这是我有的:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Prelude ()
import Prelude.Compat
import Control.Concurrent(forkIO, threadDelay)
import Control.Monad(forever)
import Control.Monad.Reader
import Data.Aeson.Compat
import Data.Aeson.Types
import Data.Maybe
import Data.IORef
import GHC.Generics
import Network.Wai.Handler.Warp
import Servant
import Servant.Utils.StaticFiles (serveDirectory)
type Api = "players" :> Get '[JSON] [Player]
:<|> "tick" :> Get '[JSON] Integer
type Game = Api :<|> …Run Code Online (Sandbox Code Playgroud) 我已经看到了关于同一主题的问题,但无法弄清楚如何解决这个问题.在我的游戏中,我使用两个线程一个Logic线程和UI线程.这是我遇到的问题
System.InvalidOperationException: Object is currently in use elsewhere.
at System.Drawing.Graphics.FromImage(Image image)
at GECS.Core.Game.UpdateLoop() in c:\Us....ore\Game.cs:line 82
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Run Code Online (Sandbox Code Playgroud)
我只在UI线程上渲染.这是我的渲染循环.我把它放在构造函数中.
while (true) {
if (!Created) {
break;
}
if (Win32.PeekMessage(out msg, IntPtr.Zero, 0, 0, (uint)Win32.PM.REMOVE)) {
if (msg.message == (uint)Win32.WindowsMessage.WM_QUIT) {
break;
} else {
Win32.TranslateMessage(ref msg);
Win32.DispatchMessage(ref msg);
}
} else {
Text = Global.TITLE;
now = …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习如何使用 java 创建一个游戏循环并每秒绘制一个新屏幕一定次数。游戏循环工作正常,但是当我尝试使用 repaint() 调用paint方法时,未调用paint方法。这是我的代码:
import javax.swing.JButton;
import javax.swing.JComponent;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.image.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class mainFrame extends Thread{
static boolean gameIsRunning = false;
MyCanvas2 myCanvas2 = new MyCanvas2();
static final int TARGET_FPS = 1;
static int x = 10;
static int y = 10;
static long startTime = 0;
static long elapsedTime = 0;
static long waitTime = 0;
public void createFrame(){
JFrame window = new JFrame("Out from …Run Code Online (Sandbox Code Playgroud) 这是我的游戏循环代码:
while (shouldUpdate)
{
timeSinceLastUpdate = 0;
startTime = clock();
while (timeAccumulator >= timeDelta)
{
listener.handle();
em.update();
timeAccumulator -= timeDelta;
timeSinceLastUpdate += timeDelta;
}
rm.beginRender();
_x->draw();
rm.endRender();
timeAccumulator += clock() - startTime;
}
Run Code Online (Sandbox Code Playgroud)
它几乎完美地运行,但它有一些抖动,每秒几次而不是_x(一个测试实体,它在更新中所做的全部是x ++)向右移动1个像素,它实际上向右移动2个像素这是一个明显的滞后/抖动效应.我猜时钟()不够准确.那么我该怎么做才能改善这个游戏循环呢?
如果重要,我使用SDL和SDL_image.
编辑:做一些比时钟更精确的事情没有任何改变.但是,我已经想到的是,这一切都归功于timeDelta.这就是我发这篇文章时timeDelta的定义方式:
double timeDelta = 1000/60;
Run Code Online (Sandbox Code Playgroud)
但当我把它定义为别的东西时,却一直在搞乱......
double timeDelta = 16.666666;
Run Code Online (Sandbox Code Playgroud)
我注意到比赛开始的前几秒,它像黄油一样光滑.但就在几秒钟之后,游戏结结巴巴,然后又恢复了平稳,并重复了这样.我添加了更多的6(或真正的)之后的任何东西,游戏最初平滑的时间越长,并且它的延迟越大.似乎浮动错误正在攻击.那我该怎么办呢?
编辑2:我已经尝试了很多东西,现在它甚至都不好笑......有人可以帮助我完成循环的数学部分吗?既然这就是造成这种情况的原因......
EDIT3:我给一些人发了一个测试程序,有人说它非常顺利,有些人说它像我描述的那样紧张.对于愿意在这里测试它的人来说,它是(src):https://www.mediafire.com/?vfpy4phkdj97q9j
EDIT4:我改变了源代码的链接.
我最初使用glfw编写游戏。但是由于缺少android的可移植性,我不得不用SDL替换所有glfw代码,因为SDL更易于移植。
我使用glfw框架工作的原始游戏循环非常出色。这里是:
// game loop
while (!glfwWindowShouldClose(window)) {
//if-else statements that create
//the games state machine
//player input is received here
//rendering done here
}
Run Code Online (Sandbox Code Playgroud)
好。编写此游戏循环可能有更好的方法,但重点是适用于游戏原型的代码。
但是,现在我切换到SDL时遇到了一个问题。似乎必须将SDL_Event放入while循环中以不断检查事件。并且此while_loop在另一个while_loop中。所以我的代码看起来像这样:
while(!Quit) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
//if-else statements that create
//the games state machine
//player input is received here
//rendering done here
}
}
Run Code Online (Sandbox Code Playgroud)
但是while_loop中的while_loop完全弄乱了游戏的渲染!我现在忽隐忽现!是否有其他方法可以像我之前使用glfw一样在单个while_loop中表达此代码。还是有任何方法可以在不使用嵌入式while_loop的情况下检查事件
我正在尝试使用 Rust 中的 glium 来制作游戏循环。我的目标是让屏幕每秒重绘 60 次。使用我当前的事件循环代码,只有当窗口大小发生变化时才会重新绘制框架。我在 glutin 文档中读到,我需要在某处调用 request_redraw,但我不确定如何/在哪里。到目前为止,这是我的代码:
event_loop.run(move |event, _target, control_flow| match event {
Event::LoopDestroyed => return,
Event::WindowEvent {
window_id: _window_id,
event: winevent,
} => match winevent {
WindowEvent::Resized(physical_size) => display.gl_window().resize(physical_size),
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
_ => {}
},
Event::RedrawRequested(_window_id) => {
let mut target = display.draw();
target.clear_color_srgb(rng.gen(), rng.gen(), rng.gen(), 1.0);
target.finish().unwrap();
}
_ => {}
});
Run Code Online (Sandbox Code Playgroud) 我一直试图为我的游戏创建一个计时器,我听说过QueryPerformanceCounter和QueryPerformanceFrequency.有人可以解释一下这些可以用来计算游戏循环中的时间/ fps /滴答吗?
所以我正在将这款智能手机应用程序模拟到Windows.这是一个运行它的逻辑和绘制方法的游戏1/60.这是毫秒16.6667
我实现了这个游戏循环:
private const double UPDATE_RATE = 1000d / 60d;
private void GameLoop()
{
double startTime;
while (GetStatus() != GameStatus.NotConnected)
{
startTime = Program.TimeInMillis;
//Update Logic
while (Program.TimeInMillis - startTime <= UPDATE_RATE)
{
//Thread.Yield(); it consumed CPU before adding this too, adding this had no effect
Thread.Sleep(TimeSpan.FromTicks(1));//don't eat my cpu
}
}
Debug.WriteLine("GameLoop shutdown");
}
Run Code Online (Sandbox Code Playgroud)
Program.TimeInMillis来自一个NanoStopwatch班级,以毫秒为单位返回时间double.这很有用,因为这个游戏循环必须非常准确才能使一切正常.
你可能知道,这里Thread.Sleep会耗费大量的CPU.可能是因为它需要int millis将我转换TimeSpan为0毫秒.
我最近遇到了这个叫做的东西WaitHandle,但我看到的一切都用了int millis.我真的需要让这个准确,所以我真的需要double millis …