Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
biznatchio
Mar 31, 2001


Buglord

Rocko Bonaparte posted:

I mean, yeah, but that "easily" there is doing a lot of work.

Not really; it took about 10 minutes. (But about twice as long to write the unit tests.)

Adbot
ADBOT LOVES YOU

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
God drat. I'd have looked at it already but it was 1:30AM and I was telling myself if I touched that, I wouldn't be going to bed until 3AM, and I'm trying to actually wake up at a normal time again.

biznatchio
Mar 31, 2001


Buglord
If you grabbed it, I just pushed a couple changes to brush it up, correct some minor issues, and add documentation.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Imma try but it'll probably be my self-imposed bedtime again before I can crack the lid on it.

Edit: Got my paws on it but my scheduler implementation is borked thanks to Newtonsoft.Json dependency hell with Unity and I hit my quota for the night dealing with that. I'm going to try my best to compare the implementations over the extended weekend.

Rocko Bonaparte fucked around with this message at 08:39 on Nov 10, 2022

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Hey all, got a C# question hoping someone can help out!

I'm trying to store some data in a similiar manner to a JSON object ala:
code:
{
  "beat": "00:00",
  "note": 2,
  "loc": [200, 400],
  "powerup": true
This seems to be harder than I thought it would be in C# or something with my IDE is up. I tried google searching it and came to a conclusion similiar to this:

code:
Dictionary<string, List<int>> BeatMap = new Dictionary<string, List<int>>();
        BeatMap.Add("00:02", new List<int> {1,200,150})
but this doesn't work either (or atleast, BeatMap.Add doesn't, the declaration does work.)

so i'm hoping somoene can point me in the right direction or help me out as to what I need to do :D

thanks goons

nielsm
Jun 1, 2009



Is it for a one-off thing or a program you expect to be using and extending a lot in the future?
What will be consuming the data, your own program or something else that you don't control? Will you be reading the data or only writing?

If it's something you expect to be developing further and using/extending, it's probably worth it to design a data model in C# classes that describes the data, and then set up serialization with some JSON library.
If it's just a one-off, maybe you're fine just doing something with lists of dictionaries or similar awkward stuff.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
I guess it's for a long term project - it's a little game I'm working on. Basically these objects tie to a songs run time and when the time comes up, I have it reference this table.

That said if there's a different better way to do it I'm all ears

nielsm
Jun 1, 2009



If it's only for your own use, and not making data for someone else's game, then definitely start out defining an object model for your data in C# that makes sense to use for your game code.

When you have the object model, you can look at ways to serialize it using standard libraries.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

worms butthole guy posted:

I'm trying to store some data in a similiar manner to a JSON object--

I would personally recommend using Newtonsoft's Json.NET until you reach a point that you know you have a reason not to use it (which does happen).

TheBlackVegetable
Oct 29, 2006

worms butthole guy posted:

I guess it's for a long term project - it's a little game I'm working on. Basically these objects tie to a songs run time and when the time comes up, I have it reference this table.

That said if there's a different better way to do it I'm all ears

Even if it's just once off, it's often better to have a clearly specified data structure.

code:

{
  "beat": "00:00",
  "note": 2,
  "loc": [200, 400],
  "powerup": true,
...
}

maps more or less to:

code:

record Beat (Timespan beat, int note, List<int> loc, bool powerup); 

var beatMap = new Dictionary<Timespan, Beat>();
beat = new Beat(...);
beatMap[beat.beat] = beat;

var json= System.Text.Serialization.(something I forget) Serialize(beatMap); 

TheBlackVegetable fucked around with this message at 09:24 on Nov 11, 2022

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Sweet thank you all so much. When I try it out later I'll report back :D

worms butthole guy
Jan 29, 2021

by Fluffdaddy
So I tried the above suggestions and I think I got closer to what I was trying to accomplish...I think. And i'm stuck again :v:. So I ended up with:

code:
List<ChartMap> Gems = new List<ChartMap>() { new ChartMap() {
            Beat = "00:00",
            Note = 2,
            loc = new List<int> {200, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:05",
            Note = 1,
            loc = new List<int> {100, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:08",
            Note = 2,
            loc = new List<int> {200, 200},
            PowerUp = false
        },
        new ChartMap() {
            Beat = "00:12",
            Note = 1,
            loc = new List<int> {200, 400},
            PowerUp = false
        }};
The issue i'm having now is trying to find something in this List using like:

code:
// beat = "00:05";
Debug.WriteLine(Gems.Contains(new ChartMap { Beat = beat }));
But I don't get any result for that except false. So hoping one of you kind goons can help me out again! :v

Just-In-Timeberlake
Aug 18, 2003

worms butthole guy posted:

So I tried the above suggestions and I think I got closer to what I was trying to accomplish...I think. And i'm stuck again :v:. So I ended up with:

code:
List<ChartMap> Gems = new List<ChartMap>() { new ChartMap() {
            Beat = "00:00",
            Note = 2,
            loc = new List<int> {200, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:05",
            Note = 1,
            loc = new List<int> {100, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:08",
            Note = 2,
            loc = new List<int> {200, 200},
            PowerUp = false
        },
        new ChartMap() {
            Beat = "00:12",
            Note = 1,
            loc = new List<int> {200, 400},
            PowerUp = false
        }};
The issue i'm having now is trying to find something in this List using like:

code:
// beat = "00:05";
Debug.WriteLine(Gems.Contains(new ChartMap { Beat = beat }));
But I don't get any result for that except false. So hoping one of you kind goons can help me out again! :v

shouldn’t that be Beat == beat?

insta
Jan 28, 2009
No, he's newing up an object with the idea of using it as an equality test, but there aren't correct equality operators on the object. I can add more tomorrow but I have to get to bed

spaced ninja
Apr 10, 2009


Toilet Rascal

worms butthole guy posted:

So I tried the above suggestions and I think I got closer to what I was trying to accomplish...I think. And i'm stuck again :v:. So I ended up with:

code:
List<ChartMap> Gems = new List<ChartMap>() { new ChartMap() {
            Beat = "00:00",
            Note = 2,
            loc = new List<int> {200, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:05",
            Note = 1,
            loc = new List<int> {100, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:08",
            Note = 2,
            loc = new List<int> {200, 200},
            PowerUp = false
        },
        new ChartMap() {
            Beat = "00:12",
            Note = 1,
            loc = new List<int> {200, 400},
            PowerUp = false
        }};
The issue i'm having now is trying to find something in this List using like:

code:
// beat = "00:05";
Debug.WriteLine(Gems.Contains(new ChartMap { Beat = beat }));
But I don't get any result for that except false. So hoping one of you kind goons can help me out again! :v

It won’t match a new instance of a class.

use .Any() or Where()

code:
Gems.Any(x => x.Beat == beat); // true/false if it is in the list
Gems.Where(x => x.Beat == beat); // returns an IEnumerable of your class

beuges
Jul 4, 2005
fluffy bunny butterfly broomstick

worms butthole guy posted:

So I tried the above suggestions and I think I got closer to what I was trying to accomplish...I think. And i'm stuck again :v:. So I ended up with:

code:
List<ChartMap> Gems = new List<ChartMap>() { new ChartMap() {
            Beat = "00:00",
            Note = 2,
            loc = new List<int> {200, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:05",
            Note = 1,
            loc = new List<int> {100, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:08",
            Note = 2,
            loc = new List<int> {200, 200},
            PowerUp = false
        },
        new ChartMap() {
            Beat = "00:12",
            Note = 1,
            loc = new List<int> {200, 400},
            PowerUp = false
        }};
The issue i'm having now is trying to find something in this List using like:

code:
// beat = "00:05";
Debug.WriteLine(Gems.Contains(new ChartMap { Beat = beat }));
But I don't get any result for that except false. So hoping one of you kind goons can help me out again! :v

That’s not going to work. You’re creating a new ChartMap and asking the Gems list if it contains this new object you just created, which it won’t. The Contains method doesn’t know you just want to compare on the Beat field, and compares actual objects to each other. What you want instead is
Gems.Any(gem => gem.Beat == beat)

Here you’re invoking a different method, Any, and specifying a comparison operation which will return true as soon as it’s met. The Any method iterates over all the gems in your Gems list, puts the current one in the gem variable that’s been defined inside the call to Any, and invokes the comparison you defined, which is to compare the beat of the current gem to the beat that you’re comparing against. As soon as that’s true, it breaks out and returns true.

If you want the actual gem which matches your beat, then instead of Any, which will just tell you that a match exists, you can call FirstOrDefault instead, which will give you the actual gem which matches the beat tier looking for, or null if there’s no match

zokie
Feb 13, 2006

Out of many, Sweden
My brain is screaming at me: will the loc ever change or be more than two values? Because why is it a list and not an array (immutable even)? If it’s [beginning, end] then being able to use deconstruction and having more guarantees it’s going to be just those two elements will probably be nice to have.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Throw my sleep schedule under the bus so here I am:

biznatchio posted:

If you grabbed it, I just pushed a couple changes to brush it up, correct some minor issues, and add documentation.

I started screwing around with it in earnest. A superficial experiment with it and the PriorityQueue's GenericPriorityQueue had the generic queue running six times as fast for me. This was with a test where I pre-loaded each with 50 entries of the same random garbage, and then ran each 100,000 times. In the iteration, I'd give them each 50 more of the matching random garbage, and then dequeue 50 entries.

I was kind of surprised since a basic read of .NET's own PriorityQueue states it's "an array-backed, quaternary min-heap." I guess I was focusing on the "array-backed" part of that instead of the "quaternary min-heap" part of that. The GenericPriorityQueue is just using a flat array. I had to pre-set it with a capacity and the world ends if I exceed it. That's RAM I'm eating no matter what and maybe I should reconsider that. So I guess there's some apples-to-oranges going on here.

Edit: I should probably just favor the FxPriorityQueue unless I find a specific reason I really need a straight array-based heap.

Freaksaus
Jun 13, 2007

Grimey Drawer

worms butthole guy posted:

So I tried the above suggestions and I think I got closer to what I was trying to accomplish...I think. And i'm stuck again :v:. So I ended up with:

code:
List<ChartMap> Gems = new List<ChartMap>() { new ChartMap() {
            Beat = "00:00",
            Note = 2,
            loc = new List<int> {200, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:05",
            Note = 1,
            loc = new List<int> {100, 400},
            PowerUp = false
        }, new ChartMap() {
            Beat = "00:08",
            Note = 2,
            loc = new List<int> {200, 200},
            PowerUp = false
        },
        new ChartMap() {
            Beat = "00:12",
            Note = 1,
            loc = new List<int> {200, 400},
            PowerUp = false
        }};

Apart from the other advice, I see that you're using a List<int> for what I assume to be a coordinate? Depending on what you want to do with it I'd say you might want to change that to a Point so you can actually use X/Y coords.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Thank you all for the help. Yeah I have no idea about the types and such in C# so any area of "you should do it this way" is very very helpful lol.

Essentially the goal is that anytime the times pan changes it looks up this table of data, gets the equivalent time span (concerted to string) and then returns the data back for it to render at the loc and the note corresponds to what sprite. With JavaScript ID do it with a json object but I wasn't sure what the best way was to do it in c# either by efficiency or in general structure.

That said I also don't have much knowledge in OOP so I'm using this as a opportunity to learn that too lol.

Thanks goons

edit:

This is what I did and it works!

code:
  List<ChartMap> Gems = new List<ChartMap>() { new ChartMap() {
            Beat = "0:02",
            Note = 2,
            loc = new Point(200,400),
            PowerUp = false
        }, new ChartMap() {
            Beat = "0:05",
            Note = 1,
            loc = new Point(100, 400),
            PowerUp = false
        }, new ChartMap() {
            Beat = "0:08",
            Note = 2,
            loc = new Point(200, 200),
            PowerUp = false
        },
        new ChartMap() {
            Beat = "0:12",
            Note = 1,
            loc = new Point(200, 400),
            PowerUp = false
        }};


        public object[] GrabNote(string beat)
        {
            
            if (Gems.FirstOrDefault(gem => gem.Beat == beat) != null)
            {
                ChartMap FoundBeat = new ChartMap();
                FoundBeat = Gems.FirstOrDefault(gem => gem.Beat == beat);

                
                return new object[] { FoundBeat.Note, FoundBeat.loc.X, FoundBeat.loc.Y };
            }
            else
            {
                return new object[] {0, new Point(0,0)};
            }
        }
and then this is how I acces it (which I admit, is probably not the best way but I got stuck here):

code:
 object[] beatTF = new object[] {  };

            beatTF = sentSong.GrabNote(GetHumanReadableTime(time));

             // Check Note
            if ((int)beatTF[0] == 1)
            {
                _spriteBatch.Draw(gemLeft, new Vector2((int)beatTF[1], (int)beatTF[2]), Color.White);
                
            }
            if ((int)beatTF[0] == 2)
            {
                _spriteBatch.Draw(gemRight, new Vector2((int)beatTF[1], (int)beatTF[2]), Color.White);
                
            }
I have concerns with object[] though...it seems unsafe and potentially slow? I also couldn't figure out how to read a Point when its apart of a array so I cheated and just split the point into 2 sections of the array lol

worms butthole guy fucked around with this message at 15:42 on Nov 12, 2022

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
does the "else" clause in GrabNote() ever get exercised? GrabNote() has two different behaviours. One of them leads to it returning an object[] with three elements that are all integers. The other one leads to it returning an object[] with two elements; the first is an integer and the second one is a Point.

The other code snippet you shared is going to break if the "else" branch is chosen, because it tries to cast beatTF[1] to an int (which will fail) and because it tries to access beatTF[2] (which doesn't exist).

Should the else clause perhaps return new object[] {0, 0, 0} instead? At that point you could dispense with the casting to integers because you could just declare it as returning int[] instead. To hazard a guess, you changed the return-type declaration to object[] because the compiler was telling you that you couldn't return a mixed-type array without doing that.

You could even dispense with arrays and declare it as returning (int Note, int X, int Y).

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
code:
public (int Note, int X, int Y) GrabNote(string beat)
{
    var found = Gems.FirstOrDefault(gem => gem.Beat == beat);

    if (found != null)
    {
        ChartMap FoundBeat = new ChartMap();
        FoundBeat = Gems.FirstOrDefault(gem => gem.Beat == beat);

        return (FoundBeat.Note, FoundBeat.loc.X, FoundBeat.loc.Y);
    }
    else
    {
        return (0, 0, 0);
    }
}
code:
var beatTF = sentSong.GrabNote(GetHumanReadableTime(time));

// Check Note
if (beatTF.Note == 1)
{
    _spriteBatch.Draw(gemLeft, new Vector2(beatTF.X, beatTF.Y), Color.White);
}
if (beatTF.Note == 2)
{
    _spriteBatch.Draw(gemRight, new Vector2(beatTF.X, beatTF.Y), Color.White);
}

Hammerite fucked around with this message at 16:09 on Nov 12, 2022

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Wow good catch and yeah 100% thank you.

I think I could nix the else statement tbh cuz it wouldn't use that data.

I tried using vars before but got errors. Although maybe I didn't import a library to use them or something.

Thank you so mucj

insta
Jan 28, 2009
"var" is native to C# itself, and is cool and good to use as often as you can. It tells the language "use the best datatype you can for this", and the only real complaint against it is developers have to actually mouse-over the word "var" to see what the compiler is choosing.

If you're getting errors, it's because you're trying to assign incompatible things to it in different branches, and that's an actual error. It's far better to catch those at compile time instead of runtime.

As for your project, if these gems are supposed to be appearing at timestamps, it makes sense to me anyway to use a Stack, ordered by timestamp. You can continually Peek() the top item on the Stack, and look at its timestamp value. If the timestamp hasn't passed yet, move on. If it is time to do something with it, Pop that item and get to work rendering your gem. This will help prevent looking at items that have already been rendered (since you've Popped them), and will also stop you from looking ahead on items that aren't anywhere ready to be rendered (since you only ever Peek at the first item that's remaining).

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Thanks insta. I went back in and var worked this time so I used that more. I didn't know it was so "acceptable" to use it alot, figured it was the C# equivalent of "any" which is kinda shunned upon lol.

Didn't know about Stacks either, will check that out. Thank you!

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

worms butthole guy posted:

Thanks insta. I went back in and var worked this time so I used that more. I didn't know it was so "acceptable" to use it alot, figured it was the C# equivalent of "any" which is kinda shunned upon lol.

Didn't know about Stacks either, will check that out. Thank you!

You actually might want a Queue, which is the opposite order: First in, first out. Stacks are first in, last out. It depends on what you're doing with the contents of the data structure. Stacks and queues are appropriate for guaranteed ordering based on insertion sequence, which certainly sounds like your use case.

var just means "let the compiler figure it out". It's still typed. You can also do instantiation without specifying the type on the right hand side if you provide it on the left-hand side: List<int> foo = new().

worms butthole guy
Jan 29, 2021

by Fluffdaddy
drat it's crazy how many types C# has lol. Yeah I was wondering if a stack would work but good to know about queue

insta
Jan 28, 2009
Really the point I was going for was to add them to an ordered data structure and only Peek the first element. Pop it when it's time to actually use it, then resume Peeking again. You never have to actually traverse the storage and you're only comparing one item per game loop instead of potentially hundreds. You're also not looking at items you've already used, nor are you going to be looking at items later on than the next one (if you're only 2 minutes into the game, why are you caring about any of the gems with a 4 minute timestamp?)

Fiend
Dec 2, 2001

New Yorp New Yorp posted:

Stacks are first in, last out.
* LIFO?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Fiend posted:

* LIFO?

Yeah wtf is wrong with me :doh:

worms butthole guy
Jan 29, 2021

by Fluffdaddy
hello back with a stupid question :v


I have a bit of code that does this (the below is pseudo code):

code:

public class Sky : Game{

 private Gem gem;


	public Sky(){
		gem = new Gem();
	}
	
	public void CheckKey(){
		if (state.IsKeyDown(Keys.Enter)){
			gem.Activated = true;
			Debug.WriteLine("Gem status: {0}", gem.Activated);
			// Gem status: true
		}
	}

	protected override void Update(GameTime gametime){
		CheckKey();
	}
	
}
code:

public class Gem{
          public bool Activated {get; set;}

	public Gem(){
           this.Activated = false;
	}
}
The issue i'm having is that if I run this code, I can see the "Activated" property being changed to true, however it doesn't persist outside of that function. I tried returning the gem object also but no dice....what am I missing? :v:

Thanks Goons

LongSack
Jan 17, 2003

worms butthole guy posted:

The issue i'm having is that if I run this code, I can see the "Activated" property being changed to true, however it doesn't persist outside of that function. I tried returning the gem object also but no dice....what am I missing? :v:

Thanks Goons

What do you mean by “doesn’t persist”? Does gem.Activated return false? If so, the gem object is encapsulated in the Sky class, is that being persisted?

Or are you talking about something like a data binding not being updated? If that’s the case, it’s because the Activated property is not observable, so when its value changes bindings are not updated. It needs to implement INotifyPropertyChanged.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
That shouldn't happen based on the code you posted. I suspect that one of two things is happening:

1. you are setting gem.Activated somewhere else and that code is running before you inspect the state
2. you are overwriting Sky.gem somewhere else and that code is running before you inspect the state

To test for (1), one approach you could take is to make gem.Activated's setter private*, build, and check all the lines that are broken. To test for (2), make Sky.gem readonly** and then do the same thing.

* public bool Activated {get; private set;}
** private readonly Gem gem;

worms butthole guy
Jan 29, 2021

by Fluffdaddy
doh I think I figured it out thanks to both of you - I realized i'm overwriting gem every draw update. I still haven't figured out the best way to spawn something and not have it keep spawning over itself but that's my bad lol. still need to figure out OOP better.

Thanks you two!

Kyte
Nov 19, 2013

Never quacked for this

worms butthole guy posted:

doh I think I figured it out thanks to both of you - I realized i'm overwriting gem every draw update. I still haven't figured out the best way to spawn something and not have it keep spawning over itself but that's my bad lol. still need to figure out OOP better.

Thanks you two!

Add a flag to the object that holds your thing so you can do if (!thingHasSpawned && otherRelevantConditions) { spawnTheThing(); }; // we assume spawnTheThing() sets thingHasSpawned to true.
If your program is particularly simple the flag could be the variable itself, like if (this.thing is null && otherRelevant conditions) { spawnTheThing(); };

worms butthole guy
Jan 29, 2021

by Fluffdaddy

Kyte posted:

Add a flag to the object that holds your thing so you can do if (!thingHasSpawned && otherRelevantConditions) { spawnTheThing(); }; // we assume spawnTheThing() sets thingHasSpawned to true.
If your program is particularly simple the flag could be the variable itself, like if (this.thing is null && otherRelevant conditions) { spawnTheThing(); };

Thank you for this!

Doing some research it seems like most things say to add your object to a List and render based off of that ala:

code:
private List<Gem> ActiveGems = new List<Gem>{};


 protected void AddGem(bool gemType)
        {
            // True is gem type 1, False is 2
            testGem = new Gem(gemLeft, new Vector2(0, 0));
            ActiveGems.Add(testGem);
        }

protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            _spriteBatch.Begin();
            
            foreach(Gem gems in ActiveGems)
            {
                gems.Draw(_spriteBatch);
            }

            _spriteBatch.End();
            base.Draw(gameTime);
        }
    }
so using your advice I presume the smart thing to do would be to add a bool to each Gem that says "isRendered" and have that foreach loop check if its been rendered or not?

sorry for all the questions but you folks have been tremendously helpful in this little pet project of mine :)

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I don't know what framework you're using to implement this project so I can't really comment on the best way to use that framework.

It seems to me, based on what you've posted, that you may be trying to keep track of the business logic of the game from within the graphics code and/or the user input code. I don't know what a Gem or a Sky represents so it's difficult to say that with confidence, but that is what it looks like. You might benefit from separating the state of the game world from the graphics and user interaction code more than you currently are. Hopefully your framework has an established way of doing that. Perhaps you can find documentation (from the framework authors or from other users) discussing this sort of thing.

This idea of separating concerns is a well-established principle in modern programming and comes in various flavours. For example, in WPF it is common to use the MVVM (model-view-viewmodel) approach, and in web programming the MVC (model-view-controller) approach is well known. They are different, but similar in that the basic goal is to decouple presentation and user interaction from the core logic of the application.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Huh yeah I deal with MVC daily in my professional life, not sure why I didn't apply it to this. That would seem to solve some of the issues lol. I guess that's also where the ECS system could come into play also. I did run into that stupid issue of things not updating again and i'm pretty sure it's now due to that and like you said - tieing it to the game logic instead of render logic.

Sweet thanks all. I shouldve made my fun project learnign WPF lmao.

worms butthole guy
Jan 29, 2021

by Fluffdaddy

Hammerite posted:

I don't know what framework you're using to implement this project so I can't really comment on the best way to use that framework.

It seems to me, based on what you've posted, that you may be trying to keep track of the business logic of the game from within the graphics code and/or the user input code. I don't know what a Gem or a Sky represents so it's difficult to say that with confidence, but that is what it looks like. You might benefit from separating the state of the game world from the graphics and user interaction code more than you currently are. Hopefully your framework has an established way of doing that. Perhaps you can find documentation (from the framework authors or from other users) discussing this sort of thing.

This idea of separating concerns is a well-established principle in modern programming and comes in various flavours. For example, in WPF it is common to use the MVVM (model-view-viewmodel) approach, and in web programming the MVC (model-view-controller) approach is well known. They are different, but similar in that the basic goal is to decouple presentation and user interaction from the core logic of the application.

omg you're a genious that did it. Everything just works now hell ya. I just had to put another layer in between the game itself (which is SKY) and the gems.

Adbot
ADBOT LOVES YOU

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Hey all, got a question about the Command Pattern. https://refactoring.guru/design-patterns/command/csharp/example

I'm trying to wrap my head around this. Someone on the gaming side said to equate it to the MVC pattern which was extremely helpful for me as a web dev, but one thing i'm not really getting is "the point" of receivers in this example.

The way i'm reading it is you would have a command like "Punch". It would work as follows according to this (pseudocode):

code:
public void MoveList(){
      public void Punch(){
           // do punch
      }
}


public void Punch:ICommand(MoveList moveList){

      private MoveList moveList = moveList;

       public void execute(){
				this.moveList.Punch();
        }
}


public void Invoker(){
    public void SetFunction1(ICommand func){
		func();
	}

	public void RunFuncs(){
               SetFunction1();
       }
}


private Punch _punch = new Punch();
private Invoker _invoker = new Invoker();


public void Update(){
	_invoker.SetFunction1(new Punch(new MoveList))
        _invoker.RunFuncs();
}
my question, and I hope I explain this correctly, is - why would pass the receiver to the command instead of just calling the function on the receiver in the first place? I.e. why do:

code:
_invoker.SetFunction1(newPunch(new MoveList))
instead of just doing something like:

code:
MoveList _moveList = new MoveList();
_moveList.Punch()
thanks

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply