我正在做一个简单的游戏,这是我的第一个游戏项目.
我找到的大多数样本都有一个渲染循环,其中所有的游戏逻辑也是如此,我只是不喜欢这样.假设我有一个X = 0的球,一个X = 10的墙和一个慢机器,第一个循环将球置于X = 7,而在第二个循环中,它将球置于X = 14.它会让游戏崩溃!
这个"渲染循环"是制作游戏的正确方法吗?我应该编写代码来检查每一帧中的这类事情吗?例如,新帧X = 14,最后一帧有X = 7,所以我应该检查是否有从X = 7到X = 14的任何东西?
我当时认为我应该为游戏逻辑和渲染循环设置一个独立的线程,我应该只是"拍摄当前游戏逻辑的快照"并显示,不是吗?
你们这些经验丰富的游戏开发者如何解决这个问题呢?
谢谢!
我正在试图找出用于管理两个交互对象之间"竞争"的最佳设计模式.例如,如果我想要Fox一个Rabbit通过简单环境追逐类的类.我想让他们"竞争"并找出哪一个获胜.最终它将成为学生可以用来试验继承和其他OO编程技能的教学工具.
这个用例是否有既定的设计模式?
这是我能想到的最好的:一个表示托管其他对象的环境的类.我保持它非常简单,并假设动物只是直线运行而狐狸抓住兔子,如果他足够接近咬兔子.这是一些代码,展示了我所描述的内容.我使用PHP是因为我可以快速编写它,但我不想专注于语言的细节.我的问题是关于设计模式/架构.
class Forrest() {
public $fox;
public $rabbit;
public $width = 100; //meters?
public $length = 100;
__construct() {
$this->fox = new Fox();
$this->rabbit = new Rabbit();
$this->theChase();
}
public function theChase() {
while (!$this->rabbit->isBitten) {
$this->rabbit->react($fox);
$this->fox->react($rabbit);
}
log('The fox got the rabbit!');
}
}
abstract class Animal() {
public $speed;
public $hasTeeth = false;
public $position;
public $direction;
public $isBitten = false;
public function run($distance) {
// update coordinates based on direction …Run Code Online (Sandbox Code Playgroud) events design-patterns software-design game-engine game-loop
我已经阅读了关于在Silverlight中使用CompositionTarget.Rendering Timer进行主要游戏循环的内容.用于任何语言的命中测试和一般游戏逻辑.
这说我想知道最好一次在这个x像素内移动物体(作为任何其他语言的游戏),还是可以更好地利用silverlight动画并使用缓和等功能?
我所指的对象将在诸如俄罗斯方块和乒乓球之类的游戏中,而不是用户正在移动角色的平台游戏.
另一个区域是精灵动画.例如,使用游戏循环更改框架或关键帧silvrelight动画最佳地完成步行动画?
我正在开发一款Android游戏.在这个游戏中,有火车运行的轨道.这是运行线程.我想在两者之间发生碰撞时显示警告对话框.当我正在应用警告对话框时显示错误无法在未调用的线程内创建处理程序looper.prepare().
我最近尝试进入游戏编程.我对Java很有经验,但对游戏编程却没有.我阅读http://www.koonsolo.com/news/dewitters-gameloop/并使用以下代码实现了那里提出的游戏循环:
private static int UPDATES_PER_SECOND = 25;
private static int UPDATE_INTERVAL = 1000 / UPDATES_PER_SECOND * 1000000;
private static int MAX_FRAMESKIP = 5;
public void run() {
while (true) {
int skippedFrames = 0;
while (System.nanoTime() > this.nextUpdate && skippedFrames < MAX_FRAMESKIP) {
this.updateGame();
this.nextUpdate += UPDATE_INTERVAL;
skippedFrames++;
}
long currentNanoTime = System.nanoTime();
double interpolation = (currentNanoTime + UPDATE_INTERVAL - this.nextUpdate) / UPDATE_INTERVAL;
this.repaintGame(interpolation);
}
}
Run Code Online (Sandbox Code Playgroud)
循环看起来很有前途和容易,但现在我实际上正在尝试用它做点什么我不再那么肯定了.如果我没有完全错误地updateGame()处理诸如计算位置,移动敌人,计算碰撞等事情,......?由于插值没有传递给updateGame(),这是否意味着我们假设每秒updateGame()精确稳定地调用UPDATES_PER_SECOND?这是否意味着我们所有的计算都基于这个假设?如果 - 无论出于何种原因 - …
我目前正在Firemonkey中为我的Android手机制作2D游戏,使用一些TImage控件并控制它们的位置和角度.就那么简单.我尝试使用我正常的循环方式,在Windows中运行良好/完美但在Android上运行失败.
方法#1:"无结束"循环(坏)
我的主要问题是我想通过使用这样的"无端循环"来避免不必要的/意外的行为,我必须调用它Application.ProcessMessages():
while (Game.IsRunning()) do
begin
{ Update game objects and stuff }
World.Update();
{ Process window messages, or the window will not respond anymore obviously }
Application.ProcessMessages(); { And thats what i want to avoid }
end;
Run Code Online (Sandbox Code Playgroud)
问题是,当我陷入循环并调用过程来处理消息时,我可能遇到很多问题,而且我也不认为这是一个好方法.
方法#2:TTimer(甚至不考虑它;-))
由于TTimer在很多方面都很糟糕而且并不意味着用于这样的事情,我只是将TTimer与最小间隔放在一起的方法就会失效.此外,我从未尝试过其他计时器,但如果有一个真正的游戏,我会尝试它当然:)
方法#3:OnIdle - 我在Windows上通常如何操作
在Windows上,我可以使用Application.OnIdle-Event.
procedure GameLoop(Sender: TObject; var Done: Boolean);
begin
{ Update game objects and stuff }
World.Update();
{ Set done to false }
Done := False;
end;
...
Application.OnIdle := GameLoop;
Run Code Online (Sandbox Code Playgroud)
每次应用程序在Windows消息上空闲时都会调用它.与#1相比,性能似乎相同或稍差,整体架构更可靠,这也是我通常使用此方法的原因.然而,在Android上,当与TForm.MouseMove结合使用时,它似乎被称为不同.在Windows OnIdle保持完美工作的地方,在Android上,它将滞后/停止,而TForm.MouseMove是从触摸输入调用的(RAD Studio自动将其编译为触摸事件) …
我在win32 GDI中创建游戏马里奥.我已经实现了游戏的新循环:
PeekMessage(&msg,NULL,0,0,PM_NOREMOVE);
while (msg.message!=WM_QUIT)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else // No message to do
{
gGameMain->GameLoop();
}
}
Run Code Online (Sandbox Code Playgroud)
但是我的游戏一直在运行,直到我按下Ctrl + Alt + Del(鼠标光标正在滚动).
http://gafferongames.com/game-physics/fix-your-timestep/
http://www.koonsolo.com/news/dewitters-gameloop/
在 Glenn Fiedler 的Fix Your Timestep的最后一个游戏循环中!在文章中,他使用了一个更新循环,将游戏逻辑推进了一个固定的增量时间。既然delta时间是固定的,那他为什么要根据delta时间来积分呢?在基于固定时间步长的游戏中,移动不能像以下那样简单:
if ( keyboard pressing "W" ) {
velocity += acceleration
}
position += velocity
Run Code Online (Sandbox Code Playgroud)
而不是传入增量时间变量:
if ( keyboard pressing "W" ) {
velocity += integrated(acceleration, delta_time)
}
position += velocity * delta_time
Run Code Online (Sandbox Code Playgroud)
因为“固定”时间步长循环中的增量时间没有意义,它就像将所有内容乘以 1。在基于“可变”时间步长的游戏中,您必须使用增量时间并整合运动,但在这种情况下,这无关紧要. 请注意 delta time 的变量如何设置为常数并且从未改变,游戏逻辑已经是确定性的,而且似乎不需要在代码的任何地方将速度和加速度乘以 delta 时间。我从这篇文章中学到的是“修复你的时间步长!”,顾名思义,所以你有确定性的游戏逻辑,而不是浮点不准确和随着可变时间步长而来的爆炸物理。我只是对为什么将增量时间传递到更新函数中感到困惑,因为它似乎与本文的目的背道而驰。
double t = 0.0;
double dt = 0.01;
double currentTime = hires_time_in_seconds();
double accumulator = 0.0;
State previous;
State current;
while ( !quit )
{
double newTime = …Run Code Online (Sandbox Code Playgroud) 如果您不熟悉 Gaffer on Games 文章“修复您的时间步长”,您可以在这里找到它:https : //gafferongames.com/post/fix_your_timestep/
我正在构建一个游戏引擎,为了让 std::chrono 更加舒适,我一直在尝试使用 std::chrono 实现一个固定的时间步长......几天了,但我不能似乎把我的头环绕在它周围。这是我正在努力的伪代码:
double t = 0.0;
double dt = 0.01;
double currentTime = hires_time_in_seconds();
double accumulator = 0.0;
State previous;
State current;
while ( !quit )
{
double newTime = time();
double frameTime = newTime - currentTime;
if ( frameTime > 0.25 )
frameTime = 0.25;
currentTime = newTime;
accumulator += frameTime;
while ( accumulator >= dt )
{
previousState = currentState;
integrate( currentState, t, dt );
t += …Run Code Online (Sandbox Code Playgroud) 我正在尝试用 Java 制作一个简单的 2D 游戏。
据我所知,我的游戏应该由两个线程组成:“事件调度线程”(用于 GUI 操作)和“游戏线程”(用于游戏循环)。
我创建了一个大纲,但找不到放置游戏循环的位置。
简而言之,我正在尝试在不冻结 UI 线程的情况下创建游戏循环。
如果您能提供有关我做错的事情的任何信息,我将不胜感激。
这是我的游戏循环(您也可以提供提示以创建更好的游戏循环):
while(true) {
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Forge …Run Code Online (Sandbox Code Playgroud) game-loop ×10
game-engine ×6
c++ ×3
android ×2
java ×2
c ×1
c++-chrono ×1
c++11 ×1
delphi ×1
events ×1
firemonkey ×1
frame-rate ×1
gdi+ ×1
silverlight ×1
swing ×1
timer ×1
winapi ×1