I'm actually coding a pacman (C# Console) i would like to know how to move my ghost each seconds, but i would also like to be able to move my pacman whenever i want.
I would like my ghost keep mooving each second whatever pacman do, i should be able to move pacman when ever i want, and ghosts just have to move every second.
I guess i have to use Thread system, so i would like to know if you know how i have to proceed and how thread works, can't find any information about that :s.
You do not need to use different threads for each ghost. This can all be done on one thread using a Game Loop
The central component of any game, from a programming standpoint, is
the game loop. The game loop allows the game to run smoothly
regardless of a user's input or lack thereof.
Most traditional software programs respond to user input and do
nothing without it. For example, a word processor formats words and
text as a user types. If the user doesn't type anything, the word
processor does nothing. Some functions may take a long time to
complete, but all are initiated by a user telling the program to do
something.
Games, on the other hand, must continue to operate regardless of a
user's input. The game loop allows this. A highly simplified game
loop, in pseudocode, might look something like this:
while( user doesn't exit )
check for user input
run AI
move enemies
resolve collisions
draw graphics
play sounds
end while
The game loop may be refined and modified as game development
progresses, but most games are based on this basic idea.
Follow that pattern and your game will be much easier to write.
You're probably confused because Console.ReadKey() is blocking...so your game loop would be stuck waiting for the user to press a key right? What you do is only grab the keystroke with ReadKey() if there is already one in the queue. This can be checked with Console.KeyAvailable which returns true if a key is already there. This way the game loop just keeps looping around if no key has been pressed...but you can still trap it and do something with it. Try this quick example out and see what happens:
class Program
{
static void Main(string[] args)
{
while (true)
{
System.Threading.Thread.Sleep(250);
Console.Write(".");
if (Console.KeyAvailable)
{
ConsoleKeyInfo key = Console.ReadKey(true); // read key without displaying it
Console.WriteLine("");
Console.WriteLine("Key Pressed: " + key.KeyChar.ToString());
}
}
}
}
Finally found what i do need :
Threads and Thread Synchronization in C#
Related
I am working on a kind of (at least closely related) Virtual Keyboard and want to include some clicking Sound. For testing I have just used
SoundPlayer player = new SoundPlayer(Resource2.click);
player .PlaySync();
Now I obviously do not want it to be Sync since it would freeze the keyboard.
Instead, if a new button gets clicked while the previous click-Sound is still playing, I would prefer the first one to stop and just start over with the new click. It is always the same sound for every button, approx. 1 sec long, but there might be a lot of events (typing speed)
So I planned to just go with
//Startup
SoundPlayer player = new SoundPlayer(Resource2.click);
player.Load();
and
//ButtonClickEvent
player.Stop()
player.Play()
//More stuff
Though while looking around I found this thread:
How to use System.Media.SoundPlayer to asynchronously play a sound file?
My way of doing it would be his Attempt #1, but he seems to have a problem:"SoundPlayer and the embedded resource stream are not immediately disposed".
Now I am not quite sure what is meant by this. Does this only concern memory issues if I have many different SoundPlayer objects? Or is this something else which might give me problems on the long term, which I did not see in my first tests. This is my main question. Additionally: Is there something else I overlooked that might give problems once in a while? E.g. stopping the player while it is not running multiple times?
I'm doing a chess game with AI in it.
There are some functions that handle the rule of game, like DoMove(), DoSkill().
But for some reasons (most for display cool effects), the function return type is IEnumerator instead of void. So the usage of the function look like this :
yield return StartCoroutine(DoSkill());
Now the problem comes, AI is a heavy work, but I've heard that Unity's Coroutines is not suitable for heavy calculating. When I change functions to IEnumerator, the speed of AI obviously getting very slow.
I'm sure that there isn't any WaitForSeconds(someFloat) will be execute in AI(I use some parameter & if/else to skip it), it just seems like the performance is really poor if I continuously call StartCoroutine again and again.
The possible solution I can think of is write two kind of DoSkill() funtion, one's return type is void , the other is IEnumerator. but it's really not a good way. because I have to maintain lots of similar functions, and it's ugly too.
Any suggestions would be greatly appreciated.
Coroutines are nothing magical - they are a way to have a function keep giving up control mid-execution, and continuing on next time they are pumped. They exist really to allow developers to avoid writing multi-threaded code.
The reason they don't work for heavy calculations is that they are executed in the main thread, so any long running code would effectively kill your frame rate.
They do work where you know you can do a small deterministic pieces of work and defer for next time - such as processing downloaded byte streams, copying data, etc. So if you are running smoothly at 60FPS you know you have 16 ms to do everything in a frame, and heavy calculations might be variable in time and hard to know ahead. If you exceed 16 ms in total (everything including your calculation) the FPS will slow down and the game will appear jerky.
I suggest in your case you run the calculations in a background thread. It's basically:
using UnityEngine;
using System.Threading;
public class ChessAI : MonoBehaviour
{
Thread aiThread;
void StartAI()
{
aiThread = new Thread(new ThreadStart(AIThread));
aiThread.Start();
}
void AIServer()
{
// do stuff here - be careful of accessing data being changed by main thread
}
public void OnApplicationQuit()
{
// It is crucial in the editor that we stop the background thread when we exit play mode
aiThread.Abort();
}
}
How can I make a game to restart when I lose? My game is structured in 3 parts: mainMenu,Game and the end (when you lose). So I divided the Update and draw method in 3 parts. Now I need the option to restart the game if I lose.
bool lost=false; //when it is "true" I lost
if(lost==true)
{
if(Keyboard.GetState().IsKeyDown(Keys.Enter))
{
// Restart game
}
}
you need to make sure you set lost = false when you restart
You'd have to show more for anyone to be able to give more specific help, so all I can say is that you need to somehow reset your game state in that event right there -- and this depends heavily on how you yourself built it. For example, a common scheme is to have an IScreen interface that all screens implement, and the Game class simply holds one of these. To switch from one to another (e.g. from a, say, "WorldScreen" to a "MainScreen"), you'd simply initialize the MainScreen and throw away the WorldScreen object.
I am a bit new to threading (not new to C#, just haven't done much threading). Can someone explain to me why this does not work?
I have a thread which calls a method I will call "Loop". Loop contains a while loop which will continuously run, and on every loop of the while I want it to check if the A Key is down (using Microsoft's Keyboard class within the XNA Framework). But for some reason it never registers that anything is being pressed.
static Thread thread = new Thread(Loop);
static bool abort = false;
public static void Begin()
{
thread.Start();
}
private static void Loop()
{
while (!abort)
{
if (Keyboard.GetState().IsKeyDown(Keys.A))
Console.WriteLine("A pressed.");
}
}
Might anyone know why the Console.WriteLine() is never being called?
EDIT:
I guess I should explain a little bit. What I am actually trying to do is create something similar to ActionScript's events in C#. So I want to pass a "condition" and an "action" to call if that condition is met in this separate class which contains this thread. What this would do would allow me to just add "event listeners" to objects and it would automatically constantly check if one of the events gets triggered, rather than leave it to me to write If statements in code to check for the events.
Upon trying to do so, the first thing I tested was regarding this XNA Keyboard stuff, because it was one of the reasons I originally wanted to build this system, but it didn't work. So I created the standalone code which i posted above to see if I had made an error in my previous code and it still didn't work.
I never use XNA so I didn't really "know" but I've run into similar situations where you can't get keyboard (and other) input from a worker thread. I googled and found that in XNA this does seem to be the case. See this for example
So you need to (and probably want to) process your game input in the GUI thread. Just checking for input on each update tick should be fine. I doubt even if it did work, you would gain any performance - and you might introduce some interesting synchronization bugs ;-)
It does look like your creating your worker thread properly - this just isn't an application for it.
I've modified my physics from the last post: Updating physics engine ina separate thread, is this wise? like so:
public void PhysicsThread()
{
int milliseconds = TimeSpan.FromTicks(333333).Milliseconds;
while(true)
{
System.Threading.Thread.Sleep(milliseconds);
world.Step(milliseconds / 1000.0f);
}
}
As before it's running in its own thread. I'm finding something odd which I'm not sure I quite understand, it's a bit difficult to explain so I made a video recording of it: http://www.youtube.com/watch?v=qFf6oSRfVt8
If you look carefully you can see the object being fired from the cannon occasionally stutters and appears to move backwards a set amount of distance. This is only noticable on fast moving objects (such as the projectile being fired).
This has baffled me completely. I've even created a system where I cache the position of bodies in the game logic thread so that as the physics thread may update bodies positions it won't affect the positions being read in by the game logic until an update function is called within the game logic thread which updates the physics bodies positions for the game logic to read.
Any ideas what aspect of multithreading may be causing this issue? I don't think it's the physics engine updating the bodies positions during game logic and drawing as I've alrady mentioned I cache that and it remains constant throughout...
My first guess is that you may have a classic race condition, where multiple threads are competing to update the object's position without locking or ordering guarantees.
You can check Wikipedia to learn more about race conditions, locking, and other fundamentals of multithreading/multiprocessing.
It's hard to say more without seeing more of your code, especially the part that does the update.
Edit: One thing you can do is to store DateTime.Now on each loop, and compare it with the previous value. If your time delays are inconsistent you'll see it.
Another thing to check is to see how long your world.Step() function is taking to execute (again using DateTime.Now and some logging, or whatever).
If both of these indicate consistent timing, then my suspicion would fall on the physics engine. Check the position of the object before and after calling world.Step(), and if you see any weird jumps that should tell you where to look.
This should probably be a comment, but it would be difficult to post code. If you're trying to do realtime then this code is prone to time jitter as there's no guarantee that Thread.Sleep will sleep for the perscribed time. I'd use a stopwatch to measure elapsed time and use that to drive your world.
public void PhysicsThread()
{
int milliseconds = TimeSpan.FromTicks(333333).Milliseconds;
var stopwatch=System.Diagnostics.Stopwatch.StartNew();
while(true)
{
System.Threading.Thread.Sleep(milliseconds );
world.Step(stopwatch.ElapsedTicks);
stopwatch.Restart();
}
}