Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Anteara

Pages: [1] 2 3
1
DotNet / Re: Using events, confusion
« on: July 29, 2013, 07:27:44 pm »
Okay, so i looked at the wiki, tutorials and documentation.

The only thing i can think of is that I have to define the event handler myself? I can't just do if event = whatever... I just make a function to perform if that event is ever fired?

            rw = new RenderWindow(new VideoMode(800, 600), "Game");
            rw.Closed += (s, a) => rw.Close();
            rw.MouseMoved += rw_MouseMoved;
            rw.Resized += rw_Resized;

This is from the example.

        void rw_Resized(object sender, SizeEventArgs e)
        {
            var view = rw.GetView();
            view.Size = new Vector2f(e.Width, e.Height);
            rw.SetView(view);
        }

So this part would basically be the same as the tutorial but in c#?

2
DotNet / Using events, confusion
« on: July 29, 2013, 06:52:59 pm »
Hi all, I've made my program functional without the need to use Event. However, as I've noticed the c# version of SFML doesn't have pollEvent. It does however have DispatchEvent, but it takes no arguments, so I'm unsure as to know it will know which event variable to check.

I'm trying to get my level editor to show more on resize - instead of stretching it. The tutorial at
http://www.sfml-dev.org/tutorials/2.0/graphics-view.php poses a solution, however I'm not totally sure how I can get this to work in c# (no pollEvents, and when I check my event.Type - it always returns 'Closed'.)

Could you please point me in the right direction?

This is the code I'm referring to:

// the event loop
sf::Event event;
while (window.pollEvent(event))
{
    ...

    // catch the resize events
    if (event.type == sf::Event::Resized)
    {
        // update the view to the new size of the window
        sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
        window.setView(sf::View(visibleArea));
    }
}

3
Quote
gridWindow.DefaultView.Center =
This is not supposed to work:
- you can't modify the default view, it's supposed to be read-only
- you must call SetView everytime your view changes, so that the window gets the updated view

That's strange, because it works perfectly; however, i don't know about the first point you made, but to the second one I'm only using one view, as I have another SFML window attached to a seperate panel, because I have winforms controls wrapped around them.

Quote
Quote
implementing a conditional (which might reduce speed by a tiny bit)?
Are you serious? :P

Are you laughing at me because any performance hit wouldn't be noticeable? I'm still new to writing code to make it fast lol.

4
Ah okay, sorry I missed that - Thanks, that will solve it :)

Edit: Okay cool, I got it working as per your suggestion, and I think the implementation is quite good (to my novice eyes at least  :-X) :D

private void mapXScrollbar_Scroll(object sender, ScrollEventArgs e)
{
    gridWindow.DefaultView.Center = new Vector2f(Constants.ViewXCenter + Constants.TileSize * e.NewValue, gridWindow.DefaultView.Center.Y);
}

private void mapYScrollbar_Scroll(object sender, ScrollEventArgs e)
{
    gridWindow.DefaultView.Center = new Vector2f(gridWindow.DefaultView.Center.X, Constants.ViewYCenter + Constants.TileSize * e.NewValue);
}

If you don't mind, I have one more question. Essentially, I've got a panel for my container, another panel for my sfml window, and two scrollbars for the scrolling, I did this so I can scale the window at runtime. It all works good and scales well.

One struggle I'm having however is that mouse clicks are registered even when I'm outside of the sfml window, but still in the WinForms window (Note that this happened in my c++ version when I used one window and multiple views, as opposed to one winforms window).

Basically, I think I need a way to stop events from being registered when the mouse is out of context, i.e. If i'm scrolling on the scrollbar, and the mouse is raised on to the map, since I'm holding down left click, It will go ahead and place tiles, even though I'm scrolling. This is not what I want, I want it to essentially "ignore" the map, while I'm scrolling.

A solution could be while scrolling implement a boolean... if not scrolling then allow tile placement, however I don't want to add a conditional check unless it's vital.

What i'm kind of looking for is something like:
*Scroll function called
*Disable view input
*Scroll function returns
*Enable view input

Or something similar. I also need the input to not register if the click is not within the view, at the moment it does.

        public void ChangeCurrentTileTemp(ref RenderWindow window, ref int tile, ref int mouseX, ref int mouseY)
        {
            Vector2f mouse = window.MapPixelToCoords(Mouse.GetPosition(window));

That's the start of the function, so I could add a conditional if not scrolling && if mouse within viewport x and y, but I just want to see if there's a more elegant solution first.

Do you know anything that I could do instead of implementing a conditional (which might reduce speed by a tiny bit)?

Edit, as per http://www.sfml-dev.org/tutorials/2.0/window-events.php I may be able to use LostFocus, and GainedFocus for the scrollbar scenario.

5
Graphics / Move view by xy coordinate position as opposed to offset
« on: July 24, 2013, 07:05:52 am »
Hi, I'm using Winforms with the c# binding (not posting this in the c# binding forum as it's relevant to all of the c++ and others too) and have a question about moving the view.

I know that I can move it by offset, like 16, 0 to move it 16 on the X and 0 on the Y.

I'm doing that here, for my scrollbar:

        private void mapYScrollbar_Scroll(object sender, ScrollEventArgs e)
        {
            Console.WriteLine("Scrolling {0}, Old value {1}, New value {2}", mapHScrollbar.Value, e.OldValue, e.NewValue);
            if (e.OldValue < e.NewValue) //going up
            {
                Console.WriteLine("Going up!");
                gridWindow.DefaultView.Move(new Vector2f(0f, Constants.TileSize));
            }
            else if (e.OldValue > e.NewValue) //going down
            {
                Console.WriteLine("Going down!");
                gridWindow.DefaultView.Move(new Vector2f(0f, Constants.TileSize * -1)); //multiply by -1 to get a negative
            }
        }

However, It works most of the time, but I noticed that if I "jump" the scrollbar, i.e. change the value from 30 to 35, it still only moves 16 pixels, so its actually 16 * 4 pixels off of where the map should be, which bugs it out.

A solution could be to set the relative position to the scrollbar. i.e. if the value is 33 on the scrollbar, then the position is TileSize (16) * 33.

So basically if I move the Y scrollbar to the 33rd value, it would be at 528 on the Y axis. However, I'm not sure how I can specify exactly where I want it to be, as Move uses offset, and not a relative position.

Do you know how I could implement this? Thanks! :)

6
Alright thanks, when i get a working version I think i'll upload that on GitHub and make revisions so I don't end up in the same situation and I can debug when something bad happens.

I started Implementing IDisposable to try and fix the problem. Dispose calls ReleaseManagedResources().

And I indeed found exactly where my error comes from:

void ReleaseManagedResources()
{
    Console.WriteLine("Releasing Managed Resources");
    if (MVertices != null)
    {
        MVertices.Dispose();
    }
    if (MTileset != null)
    {
        MTileset.Dispose();
        //Exception - Attempted to read or write on protected memory.
    }
    if (TransformInstance != null)
    {
        TransformInstance.Dispose();
    }
}

MTileset is a Texture. I don't change MTileset in any way.

Any ideas? If not; i'll try and make a small example with the error happening.

Edit: This also happens when I try to dispose of a VertexArray, but my program doesn't crash; it only crashes with the texture.

http://i.imgur.com/dkssvv9.png

Edit 2: I seem to have fixed it. Instead of disposing it when I don't need it anymore, I dispose it inside the WinForms dispose method, and it fixes it, my only hypothesis of why this fixes it is because even though it was disposed, the checks done by SFML somehow referenced it and tried to read it in some way, so by disposing it after everything else fixes it because there's now nothing to check

...or something.

7
Alright, well i guess i can always just do this until I decide I want to fix it, lol.

        private void OnProcessExit(object sender, EventArgs e)
        {
            //crashes on exit if i dont do this
            Environment.Exit(1);
        }

8
Hey, I have one more question if that's okay:

Since editing my code greatly to try and improve the speed, etc (I didn't save a backup :/) I've now  been getting this error:

$exception{System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at SFML.Graphics.Context.sfContext_create()
at SFML.Graphics.Context..ctor()
at SFML.Graphics.Context.get_Global()
at SFML.Graphics.Texture.Destroy(Boolean disposing)
at SFML.ObjectBase.Dispose(Boolean disposing)
at SFML.ObjectBase.Finalize()}

I only get this error on exit. It doesn't affect my program at all, I just can't exit without getting the error.

It seems to reference Graphics and ObjectBase a lot, however I have no idea what is causing the error, so I can't make a complete and minimal example. Do you have any idea what might be causing this?

Otherwise, I guess i'll have to backtrack and remove code until it stops getting the error, and re-add that part.

Thanks.

9
Yeah I'm zoomed in when I'm trying to move it like that, I think i'll use a scrollbar or something from windows forms and implement a variable to position the middle of the view relative to the scrollbar, or something...

haha.

10
Alright, thanks.

So what I've done is whenever the window is activated, the timer is set to true, otherwise, it's set to false.

Then, I do my drawing in the timer tick function. I set the interval of Timer Tick to 1; but it still does not call anywhere near as often as my while loop did. However, this works for me as because it doesn't tick often, it gives me an effective framerate of 64 FPS.

However, Because my game doesn't draw at 500 fps anymore, It's quite jumpy to move the view so i can see all parts of the map.

Previously this would result in a clean movement of the map:

if (Keyboard.IsKeyPressed(Keyboard.Key.Left))  
    view.Move(new Vector2f(1.25f, 0));

However, the only way I can produce a scrolling speed that I'm happy with is to do this:

if (Keyboard.IsKeyPressed(Keyboard.Key.Left))
    view.Move(new Vector2f(10.0f, 0));

But it is quite 'jumpy', so I need a way to smooth it out. Since my timer is a millisecond timer, and I already have it set to 1, that's as fast as I can get the timer to tick.

Do you have any idea how I could do this?

P.S. by doing this, I've got my engine down from 12-17% CPU usage to less than 0.1% CPU usage.

11
Ah, Okay. So I think I understand what your saying:

Because I've implemented my loop in Form1_Load, which will only stop looping if the form is closed, nothing will ever be executed below the loop, so the function can never exit and return void; and some events may be waiting for Form1_Load to return void.

Instead, I should use a main loop in a less traditional sense; have no while loop at all, instead rely on constantly firing events to execute my game code, such as the ReDraw event. If i put my loop inside the ReDraw event function, it essentially acts as a loop as ReDraw is always being called.

OR, use a Timer and in the timer_tick (or whatever its called) implement my loop there (again, without a technical while loop)

Did I interpret that correctly?


12
Yeah everything is responsive and runs fine. I'm not running my game loop from Form1_Load, I'm calling it there though. I should probably have specified that my Form1 class is also serving as my 'Engine' class to which everything else is created.

Here's a video showing what it working:



p.s. what exactly do youm ean by "so it never returns?"?

13
How do you trigger refresh cycles for your widget? A fixed timer? A "repaint" event?

Well, I don't really rely on events from the winforms to do the refreshing; only for other things (like responding to button click events etc)

So, in the form_load function I initiate the window and loop:
I *think* form_load function is called only once, on initial startup.

        private void Form1_Load(object sender, EventArgs e)
        {
            Init();
            //create the window to bind to the form
            SFMLWindow = new RenderWindow(this.Handle); // Create the SFMLWindow from the handle of any control. In this example we will use our current forms handle
            //SFMLWindow.SetVerticalSyncEnabled(true);
            //SFMLWindow.SetFramerateLimit(60);
            //start the game loop
            MainLoop();
        }

In my main loop, I do all the normal stuff, but use while formopen instead of the normal way, as It didn't seem to work, probably because it's within a form:

 while (FormOpen)
            {
                ProcessInput();
                window.Clear(SFML.Graphics.Color.White);
                ...
            }

Perhaps I could use a timer to only have it called 60 times per second, I'll look in to that.

14
Tried all of that and it doesn't change my fps unfortunately.

15
Do you activate vertical synchronization in your program?

I set vertical sync to enabled on my RenderWindow, however I'm using the handle of a panel in WinForms.

After your comment i checked fraps and in fact the window is at 500 FPS, I'm not sure, however, if that means that my main loop is being executed far too many times, since I did apply vertical sync to the RenderWindow.

I'll try and see if I can figure out how to limit the framerate of the WinForm.

Pages: [1] 2 3