I need to Have Integers that change in the Background while the GameWindow is Open in OpenTK i tested Some Things and It Totaly didn't work, after this code:
GameWindow polyWindow = new GameWindow(1024, 768);
polyWindow.Run(200);
the Folowwing Code:
if (Gamesets.Polygon.Playfield.timer == 2)
{
polyWindow.Close();
}
Does Not Execute, its Just a Basic Timer that Closes the Window after 2
Seconds, The Code for That is Here:
public static int timer;
public static int ms_timer;
public static void playfield()
{
while (true)
{
ms_timer = + ms_timer + 1;
System.Threading.Thread.Sleep(10);
Console.WriteLine(timer + "S"+ms_timer + "MS");
if (ms_timer == 100) { timer = timer + 1; ms_timer = 0; }
if (timer == 10)
{
}
and it Does Not Work after the GameWindow is Shown
Any code written after the GameWindow.Run() statement will not be executed until after the window has been closed. So the code checking if the time is equal to 2 will not run until polywindow.close() has already been executed or you manualy close the window.
Alternatively what you could do, is check the timer from within the Opentk window in the Update or Render methods and execute the Close() method there.
For example:
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
if (Gamesets.Polygon.Playfield.timer == 2)
{
Close();
}
}
Related
I am making a platformer game where you have to dodge spikes, and I tried to use the transform.position method, but it gave too many bugs. With rigidbodies(rb.addforce), it has acceleration, and I saw somewhere that you could use getaxisraw to do it. Is there any way that I could add this to my current script without deviating too much (still being able to use wasd and arrow keys)?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerscript : MonoBehaviour
{
public float movespeed = 0.01f;
public Rigidbody2D rb;
public bool isgrounded = true;
public float jumpheight = 500f;
public float level = 1;
// Start is called before the first frame update
void Start()
{
rb = this.gameObject.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void FixedUpdate()
{
if (Input.GetKey(KeyCode.A) || (Input.GetKey(KeyCode.LeftArrow)))
{
rb.AddForce(-Vector2.right * movespeed);
}
if (Input.GetKey(KeyCode.W) && isgrounded || (Input.GetKey(KeyCode.UpArrow) && isgrounded))
{
rb.AddForce(transform.up * jumpheight);
isgrounded = false;
}
if (Input.GetKey(KeyCode.D)||(Input.GetKey(KeyCode.RightArrow)))
{
rb.AddForce(Vector2.right * movespeed);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "enemy")
{
Debug.Log("hio");
if (level == 1)
{
Debug.Log("resetpos");
transform.position = new Vector3((float)-11.343, (float)-0.49, 0);
}
}
}
private void OnCollisionStay2D(Collision2D collision)
{
if (collision.gameObject.tag == "ground")
{
isgrounded = true;
}
}
}
From https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html, I think that Input.GetAxisRaw("Horizontal") will return -1 if the user presses in left or a, 0 if the user is not pressing left or right or a or d, and 1 if the user presses right or d. Similarly, this also occurs for Input.GetAxisRaw("Vertical"). I think it will return -1 if the user wants to go down, 0 if the user is not pressing up or down, and 1 if the user wants to go up.
In FixedUpdate(), you can get Input.GetAxisRaw("Horizontal") to get whether they want to move right or left, and Input.GetAxisRaw("Vertical") to get whether they want to move down or up. Then, you can handle it by moving the character appropriately.
For example, you can do this:
void FixedUpdate()
{
if (Input.GetAxisRaw("Horizontal") == -1)
{
// Code to move left
}
else if (Input.GetAxisRaw("Horizontal") == 1) {
// Code to move right
}
if (Input.GetAxisRaw("Vertical") == -1)
{
// Code to move down or squat
}
else if (Input.GetAxisRaw("Vertical") == 1)
{
// Code to move up or jump
}
}
Please excuse me if I made any C# syntax errors.
This is a simplified snippet of a larger WPF project to illustrate the problem.
When the play button is pressed, this code plays the mp3's "1, 2, 3, 4, 5" then stops.
When the play button is pressed, the dispatch timer starts. On every Tick, the Metronome_Run event is called. The Metronome_Run event assigns a mp3 to play by indexing an array.
The problem is, it works fine the first time you press play, you get 1,2,3,4,5, but when pressing play again, you get 2,4,5, then pressing play again, you get 3,5! As if the indexing of the files seems to be offset each time play is pressed somehow.
When stepping through with the debugger, it runs perfect every time, yet without any breakpoints set, (like in the build), it works correctly only the first time and does not work correctly on further play button presses.
Any help is appreciated!
public partial class MainWindow : Window
{
private MediaPlayer mediaPlayer = new MediaPlayer();
List<int> NoteValArray = new List<int>() { 1,2,3,4,5 };
private DispatcherTimer timer1;
int numVal = 0;
int numIndex = 0;
private float tempo = 35f;
public MainWindow()
{
InitializeComponent();
timer1 = new DispatcherTimer();
}
private void Metronome_Run(object sender, EventArgs e)
{
if (NoteValArray.Count > numIndex) // if we are not outside the list bounds
{
numVal = NoteValArray[numIndex]; // get the value at this list index and place it in numVal
numIndex ++; // increment
}
else { timer1.Stop(); return; }
// Load the mp3 indicated by numVal
if (numVal == 1) { mediaPlayer.Open(new Uri("1.mp3", UriKind.Relative)); }
else if (numVal == 2) { mediaPlayer.Open(new Uri("2.mp3", UriKind.Relative)); }
else if (numVal == 3) { mediaPlayer.Open(new Uri("3.mp3", UriKind.Relative)); }
else if (numVal == 4) { mediaPlayer.Open(new Uri("4.mp3", UriKind.Relative)); }
else if (numVal == 5) { mediaPlayer.Open(new Uri("5.mp3", UriKind.Relative)); }
mediaPlayer.Play(); // play whats loaded
}
private void Start_Button_Click(object sender, RoutedEventArgs e)
{
numIndex = 0;
timer1.Tick += Metronome_Run; // run this at each tick
timer1.Interval = TimeSpan.FromMilliseconds(10000 / (tempo / 6));
timer1.Start();
}
}
}
Solved!
I moved "timer1 = new DispatcherTimer();" from the mainwindow function, and placed it in the "Start_Button_Click" event with the other timer code.
My guess is I was starting more than 1 timer with each play press, and that was causing the bug. Thanks to all who took time to look at my problem.
I have a timer for a game in Unity and I have it carrying across to each new scene and working. The issue is I also want the timer to reset when the MainMenu scene has loaded and I can not for the life of me get this to work. Help would be appreciated, code's below -
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Timer : MonoBehaviour
{
public Text TimerText;
public float StartTime = 0f;
// Start is called before the first frame update
void Start()
{
string Scene = SceneManager.GetActiveScene().name;
if (Scene == "MainMenu")
{
Destroy(this.gameObject);
}
else
{
DontDestroyOnLoad(this.gameObject);
}
}
void Update()
{
float t = Time.time - StartTime;
string minutes = ((int)t / 60).ToString();
string seconds = (t % 60).ToString("f2");
TimerText.text = minutes + ":" + seconds;
}
}
1 SceneManager.sceneLoaded += OnSceneLoaded;
2 public void OnSceneLoaded(Scene scene, LoadSceneMode mode)
3 {
4 }
Then check the current scene, and reset the timer if the new scene is the menu
Don't destroy the game object when main menu is loaded. Just set the time to 0 and make the game object last for all the scenes. Thus since the game object is available to all the scenes, create a bool variable called shouldCountTime. In the update function, just say if shouldCountTime == true then timer code is executed else not. When main menu is loaded, set time to zero and shouldCountTime to false. In start check if the scene loaded is not the main menu, then set shouldCountTime to true.
Code should look like:
void Start() {
if(SceneManager.getActiveScene.name != "MainMenu") {
shouldCountTime = true;
} else {
shouldCountTime = false;
Time = 0;
}
void Update(){
if(shouldCountTime){
Time += Time.deltaTime;
//All the timer code
}}
I have a function (lets call it function A) that 0 to many threads can access it (at the same time, no shared resources). At any given time, the user can use to stop the process. The stop functionality needs to make sure that there are threads accessing function A, so that a graceful shutdown can be performed. Is there a native procedure to do so?
What I was going to do is have an InterlockedIncrement an integer everytime function A is called (and a corresponding InterlockedDecrement on said integer when function A exists). When an InterlockedDecrement takes place, it checks the value of the integer, if it's set to zero, a event is set to signalled. If the value is not zero, the event is set to nonsignalled.
This makes sense in my mind, but I'm curious whether there is a more native structure / functionality adapted to do so.
I still have to thing about the fact the "stop" function may get starved (in the sense, the said integer may never be set to zero). A sidenote: when the stop event takes place, the InterlockedIncrement process shall be stopped, to reduce said starvation.
what you need and want implement is called Run-Down Protection. unfortunately it supported only in kernel mode, but not hard implement it yourself in user mode too.
the simplest implementation is next:
HANDLE ghStopEvent;
LONG gLockCount = 1;
BOOLEAN bStop = FALSE;
void unlock()
{
if (!InterlockedDecrement(&gLockCount)) SetEvent(ghStopEvent);
}
BOOL lock()
{
LONG Value = gLockCount, NewValue;
for ( ; !bStop && Value; Value = NewValue)
{
NewValue = InterlockedCompareExchange(&gLockCount, Value + 1, Value);
if (NewValue == Value) return TRUE;
}
return FALSE;
}
void funcA();
void UseA()
{
if (lock())
{
funcA();
unlock();
}
}
and when you want begin rundown - once call
bStop = TRUE; unlock();
how you can see lock function is interlocked increment gLockCount on 1 but only if it not 0.
in kernel mode you can call instead
EX_RUNDOWN_REF gRunRef;
void UseA()
{
if (ExAcquireRundownProtection(&gRunRef))
{
funcA();
ExReleaseRundownProtection(&gRunRef)
}
}
and on place final unlock - ExWaitForRundownProtectionRelease
some more complex and scalable implementation of rundown-protection:
#define RUNDOWN_INIT_VALUE 0x80000000
#define RUNDOWN_COMPLETE_VALUE 0
class __declspec(novtable) RUNDOWN_REF
{
LONG _LockCount;
protected:
virtual void RundownCompleted() = 0;
public:
BOOL IsRundownBegin()
{
return 0 <= _LockCount;
}
void Reinit()
{
if (InterlockedCompareExchange(&_LockCount, RUNDOWN_INIT_VALUE, RUNDOWN_COMPLETE_VALUE) != RUNDOWN_COMPLETE_VALUE)
{
__debugbreak();
}
}
RUNDOWN_REF()
{
_LockCount = RUNDOWN_INIT_VALUE;
}
BOOL AcquireRundownProtection()
{
LONG Value = _LockCount, NewValue;
for ( ; Value < 0; Value = NewValue)
{
NewValue = InterlockedCompareExchange(&_LockCount, Value + 1, Value);
if (NewValue == Value) return TRUE;
}
return FALSE;
}
void ReleaseRundownProtection()
{
if (RUNDOWN_COMPLETE_VALUE == InterlockedDecrement(&_LockCount))
{
RundownCompleted();
}
}
void BeginRundown()
{
if (AcquireRundownProtection())
{
_interlockedbittestandreset(&_LockCount, 31);
ReleaseRundownProtection();
}
}
};
and use it like:
class MY_RUNDOWN_REF : public RUNDOWN_REF
{
HANDLE _hEvent;
virtual void RundownCompleted()
{
SetEvent(_hEvent);
}
// ...
} gRunRef;
void UseA()
{
if (gRunRef.AcquireRundownProtection())
{
funcA();
gRunRef.ReleaseRundownProtection();
}
}
and when you want stop:
gRunRef.BeginRundown();// can be safe called multiple times
// wait on gRunRef._hEvent here
interesting that in kernel exist else one (more old - from win2000, when rundown protection from xp) api Remove Locks. it do almost the same. different only in internal implementation and usage. with remove locks code will be look like this:
IO_REMOVE_LOCK gLock;
void UseA()
{
if (0 <= IoAcquireRemoveLock(&gLock, 0))
{
funcA();
IoReleaseRemoveLock(&gLock, 0);
}
}
and when we want stop - call
IoAcquireRemoveLock(&gLock, 0);
IoReleaseRemoveLockAndWait(&gLock, 0);
my first code spinet by implementation near remove locks implementation, when second near rundown-protection implementation. but by sense both do the same
For the last couple of days I've been trying to find out why my gwt application is leaking on IE 9.
I want to share one of my findings with you and maybe someone can give me a clue about what is going one here...
I wrote this small test:
public class Memory implements EntryPoint
{
FlowPanel mainPanel = new FlowPanel();
FlowPanel buttonsPanel = new FlowPanel();
FlowPanel contentPanel = new FlowPanel();
Timer timer;
Date startDate;
public void onModuleLoad()
{
mainPanel.setWidth("100%");
mainPanel.setHeight("100%");
RootPanel.get().add(mainPanel);
Button startBtn = new Button("start test");
startBtn.addClickHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event)
{
startDate = new Date();
System.out.println("Started at " + startDate);
timer = new Timer()
{
public void run()
{
Date now = new Date();
if(isWithin5Minutes(startDate, now))
{
manageContent();
}
else
{
System.out.println("Complete at " + new Date());
timer.cancel();
contentPanel.clear();
}
}
};
timer.scheduleRepeating(50);
}
});
buttonsPanel.add(startBtn);
mainPanel.add(buttonsPanel);
mainPanel.add(contentPanel);
}
private void manageContent()
{
if(contentPanel.getWidgetCount() > 0)
{
contentPanel.clear();
}
else
{
for(int i =0; i < 20; i++)
{
Image image = new Image();
image.setUrl("/images/test.png");
contentPanel.add(image);
}
}
}
private boolean isWithin5Minutes(Date start, Date now)
{
//true if 'now' is within 5 minutes of 'start' date
}
}
So, I have this Timer that runs every 50 ms (during around 5 minutes) and executes the following:
- if the panel has content, clear it;
- if the panel has no content add 20 png images (30x30 with transparency) to it.
Using the Process Explorer from sysInternals I got the following results:
IE 9:
Firefox 21.0:
I ran the same program with some changes (.jpg images instead of .png, create the images only once and use them as member variables, create the images using a ClientBundle) but the result was the same. Also, I ran the application in production mode.
Is there something wrong with my code that could cause this behavior in IE?
Shouldn't the Garbage Collector (GC) free some of the used memory at least when the timer ends?
Any of you came across this problem before?
Garbage collector in IE is quite strange thing. E.g. you can force it to run by simply minimizing browser window. I guess leaks in your case are images that weren't removed properly by browser when you clear container. Try to remove them by using JS "delete" operation, like that:
private native void utilizeElement(Element element) /*-{
delete element;
}-*/;
Then change your manageContent a little:
if(contentPanel.getWidgetCount() > 0)
{
for (Iterator<Widget> it = contentPanel.iterator(); it.hasNext();)
utilizeElement(it.next().getElement());
contentPanel.clear();
}
Hope this helps.