Running a Method from SoundEngine class's object anywhere - c#

I am struggeling with getting my SoundEngine class's function PlaySound to be played where I want it.
The function needs to be a global function but I can't make it static as the function refers to an object that the SoundEngine makes.
I'll show the snippets that are important:
In my GameWorld class:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;
using System;
using SoundEngineSpace;
public GameWorld(int width, int height, ContentManager Content)
{
screenWidth = width;
screenHeight = height;
random = new Random();
gameState = GameState.Playing;
block = Content.Load<Texture2D>("block");
font = Content.Load<SpriteFont>("SpelFont");
SoundEffect blockFallSE = Content.Load<SoundEffect>("BlockFallSE");
Song BuildingWallsintheCold = Content.Load<Song>("91 Building Walls in the Cold");
soundEngine = new SoundEngine();
soundEngine.addSound(blockFallSE);
soundEngine.addSong(BuildingWallsintheCold);
soundEngine.SetSoundVolume(20);
soundEngine.SetSongVolume(5);
soundEngine.PlaySong(0);
grid = new TetrisGrid(block);
}
In my TetrisGrid class
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SoundEngineSpace;
...
public void TetNaarBeneden()
{
soundEngine.PlaySound(0);
InPlayGrid.Velocity = new Vector2(0, gridblock.Height);
CheckValidLocation();
}//Moves tet down
And the soundEngine class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
namespace SoundEngineSpace
{
public class SoundEngine
{
private void soundEngine()
{
}
BackgroundSound backgroundSound = new BackgroundSound();
SoundEffects soundEffects = new SoundEffects();
public void addSong(Song s)
{
backgroundSound.AddBackgroundSound(s);
}
public void addSound(SoundEffect s)
{
soundEffects.AddSound(s);
}
public void PlaySong(int s)
{
backgroundSound.PlayBackgroundSound(s);
}
public void PlaySound(int s)
{
soundEffects.PlaySound(s);
}
public void SetSongVolume(int v)
{
backgroundSound.SetBackGroundSoundVolume(v);
}
public void SetSoundVolume(int v)
{
soundEffects.SetSoundEffectVolume(v);
}
}
}
class BackgroundSound
{
public static void backGroundSound()
{
}
private List<Song> BackgroundSoundEffects = new List<Song>();
private bool PlayingBackGroundSound = false;
public void AddBackgroundSound(Song s)//addsongs to the list
{
BackgroundSoundEffects.Add(s);
}
public void PlayBackgroundSound(int s)//plays BackgroundSound based on location in the list
{
MediaPlayer.IsRepeating = true;//If I use this exact soundengine again, move this to it's own function instead!
if (BackgroundSoundEffects.Count() > s)
{
if (PlayingBackGroundSound)
MediaPlayer.Stop();
MediaPlayer.Play(BackgroundSoundEffects.ElementAt(s));
PlayingBackGroundSound = true;
}
else
{
Console.WriteLine("Couldent find the BackgroundSound");
}
}
public void SetBackGroundSoundVolume(int v)
{
MediaPlayer.Volume = (float)v/100;
}
}
class SoundEffects
{
public static void soundeffects()
{
}
private List<SoundEffect> soundEffects = new List<SoundEffect>();
public void AddSound(SoundEffect s)//addsongs to the list
{
soundEffects.Add(s);
}
public void PlaySound(int s)//plays sound based on location in the list
{
if (soundEffects.Count() > s)
{
SoundEffect ToPlaySound = soundEffects.ElementAt(s);
ToPlaySound.Play();
}
else
{
Console.WriteLine("Couldent find the sound");
}
}
public void SetSoundEffectVolume(int v)
{
SoundEffect.MasterVolume = (float)v/100;
}
}

I ended up making the constructor of objects that needed acces to the SounEngine pass the SoundEngine as a paramter.
Then I could create a new soundEngine within the object I needed it to exsist and call: this.soundEngine = soundEngine.
That succesfully copied the soundEngine and let me use it's fucntions.

Related

Problems with opening a window - Forms

I'm trying to make a simple 2d game with C# using forms but when i run it at 60 fps it uses 50% of my CPU and doesn't use my GPU at all. I've been looking for hours and can't find another way to do it. How do i get it to run on my GPU?
Also I'm using a thread to wait in between frames with Thread.Sleep(15). I don't know if this is a good way to do it.
I was following this video for the window https://www.youtube.com/watch?v=JnGM1p2vsbE
This is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
namespace RadiantEngine
{
class Canvas : Form
{
public Canvas()
{
this.DoubleBuffered = true;
}
}
public abstract class RadiantWindow
{
public Vector2 ScreenSize;
public string Title;
private Canvas Window;
private Thread GameLoopThread;
public float num;
Bitmap image = (Bitmap)Image.FromFile("F:/VS/RadiantEngine/RadiantEngine/dog.png");
public RadiantWindow(Vector2 ScreenSize, string Title)
{
this.ScreenSize = ScreenSize;
this.Title = Title;
EngineInit();
}
public RadiantWindow(float x, float y, string Title)
{
Vector2 _ScreenSize = new Vector2();
this.ScreenSize = _ScreenSize;
this.Title = Title;
EngineInit();
}
void EngineInit()
{
Window = new Canvas();
Window.Text = Title;
Window.Size = new Size((int)ScreenSize.x, (int)ScreenSize.y);
Window.Paint += Renderer;
GameLoopThread = new Thread(GameLoop);
GameLoopThread.Start();
Application.Run(Window);
}
private void Renderer(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(Color.Aqua);
g.DrawImage(RadiantEngine.engine.renderer.FrameRender(), 0, 0);
}
void GameLoop()
{
OnLoad();
while (GameLoopThread.IsAlive)
{
try
{
OnDraw();
Window.BeginInvoke((MethodInvoker)delegate { Window.Refresh(); });
}
catch
{
Console.WriteLine("Game Is Loading");
}
Thread.Sleep(15);
}
}
public abstract void OnDraw();
public abstract void OnLoad();
}
}
Thanks for any help.

Missing bracket in C# because of Windows IoT background task?

I have created a test app for my first Windows IoT project with raspberry pi and an ultrasonic sensor.
I have placed some sample code in it. Visual Studio tells me that I am missing a curly bracket in "public void run…", but that doesn't seem to be the problem.
Is it because of the public class within the BackgroundTaskInstance?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;
using Windows.ApplicationModel.Background;
using Windows.Devices.Gpio;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
// The Background Application template is documented at http://go.microsoft.com/fwlink/?LinkID=533884&clcid=0x409
namespace IoTtest
{
public sealed class StartupTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
public class HCSR04
{
private GpioPin triggerPin { get; set; }
private GpioPin echoPin { get; set; }
private Stopwatch timeWatcher;
public HCSR04(int triggerPin, int echoPin)
{
GpioController controller = GpioController.GetDefault();
timeWatcher = new Stopwatch();
//initialize trigger pin.
this.triggerPin = controller.OpenPin(triggerPin);
this.triggerPin.SetDriveMode(GpioPinDriveMode.Output);
this.triggerPin.Write(GpioPinValue.Low);
//initialize echo pin.
this.echoPin = controller.OpenPin(echoPin);
this.echoPin.SetDriveMode(GpioPinDriveMode.Input);
}
public double GetDistance()
{
ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne(500);
timeWatcher.Reset();
//Send pulse
this.triggerPin.Write(GpioPinValue.High);
mre.WaitOne(TimeSpan.FromMilliseconds(0.01));
this.triggerPin.Write(GpioPinValue.Low);
return this.PulseIn(echoPin, GpioPinValue.High);
}
private double PulseIn(GpioPin echoPin, GpioPinValue value)
{
var t = Task.Run(() =>
{
//Recieve pusle
while (this.echoPin.Read() != value)
{
}
timeWatcher.Start();
while (this.echoPin.Read() == value)
{
}
timeWatcher.Stop();
//Calculating distance
double distance = timeWatcher.Elapsed.TotalSeconds * 17000;
return distance;
});
bool didComplete = t.Wait(TimeSpan.FromMilliseconds(100));
if (didComplete)
{
return t.Result;
}
else
{
return 0.0;
}
}
}
}
}
I took the code and reformatted it for you. Please change the namespace to the value you would like
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace MyIotNamespace
{
public sealed class StartupTask :IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
}
}
public class HCSR04
{
private GpioPin triggerPin { get; set; }
private GpioPin echoPin { get; set; }
private Stopwatch timeWatcher;
public HCSR04(int triggerPin, int echoPin)
{
GpioController controller = GpioController.GetDefault();
timeWatcher = new Stopwatch();
//initialize trigger pin.
this.triggerPin = controller.OpenPin(triggerPin);
this.triggerPin.SetDriveMode(GpioPinDriveMode.Output);
this.triggerPin.Write(GpioPinValue.Low);
//initialize echo pin.
this.echoPin = controller.OpenPin(echoPin);
this.echoPin.SetDriveMode(GpioPinDriveMode.Input);
}
public double GetDistance()
{
ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne(500);
timeWatcher.Reset();
//Send pulse
this.triggerPin.Write(GpioPinValue.High);
mre.WaitOne(TimeSpan.FromMilliseconds(0.01));
this.triggerPin.Write(GpioPinValue.Low);
return this.PulseIn(echoPin, GpioPinValue.High);
}
private double PulseIn(GpioPin echoPin, GpioPinValue value)
{
var t = Task.Run(() =>
{
//Recieve pusle
while(this.echoPin.Read() != value)
{
}
timeWatcher.Start();
while(this.echoPin.Read() == value)
{
}
timeWatcher.Stop();
//Calculating distance
double distance = timeWatcher.Elapsed.TotalSeconds * 17000;
return distance;
});
bool didComplete = t.Wait(TimeSpan.FromMilliseconds(100));
if(didComplete)
{
return t.Result;
}
else
{
return 0.0;
}
}
}
}
Nested class can't exist inside functions. Place HCSR04 inside StartupTask instead.
See https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/nested-types

Draw Line & Thickness in a Class: method group / OverLoad issue

I'm trying to set up the code for a Line class with it's own thickness besides the DefaultLineThickness I have for my squares and circles. As much as I would like to use g.DrawLine(Pens.Black, 25, 40, 126, 126); it needs to be in it's own class and inherited which I've done with the other shapes. I found this topic closest to my issue but its in XAML and anywhere else it's just simple g.DrawLine
http://www.c-sharpcorner.com/uploadfile/mahesh/line-in-wpf/
Trying to make a crude bike out of circles, squares, and lines.
*edit
After enough times of playing around I'm on the brink of my goal. My only problem is that after I plug everything in and set the line thickness to x-number, it's giving me an error that it can't assign the number because of a 'method group'
Form1 Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Bicycle
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
LineOne l1 = new LineOne(new PointF(50, 40));
l1.setFilledState(false);
l1.setLineColor(Color.Black);
l1.setLineThickness = (6);
//cannot assign to 'setLineThickness' because it is a method group'
l1.Draw(g);
sRectangle r2 = new sRectangle(new PointF(151, 160));
r2.setFilledState(true);
r2.setLineColor(Color.Green);
r2.setFilledColor(Color.Honeydew);
r2.Draw(g);
sRectangleEmpty r1 = new sRectangleEmpty(new PointF(150, 150));
r1.setFilledState(false);
r1.setLineColor(Color.Blue);
r1.Draw(g);
sCircle c1 = new sCircle(new PointF(180, 130));
c1.setFilledState(true);
c1.setLineColor(Color.Orange);
c1.setFilledColor(Color.Ivory);
c1.Draw(g);
sCircleEmpty c2 = new sCircleEmpty(new PointF(120, 130));
c2.setFilledState(false);
c2.setLineColor(Color.Black);
c2.Draw(g);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
The Line Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Bicycle
{
class LineOne : sRectangle
{
private void setDrawingAttributes()
{
const int lenght = 10;
Pen SmallPen = new Pen(Brushes.DeepSkyBlue);
SmallPen.LineJoin = System.Drawing.Drawing2D.LineJoin.Bevel;
PointF p1 = PointF.Add(location, new Size(-lenght / 2, 0));
}
private void init()
{
setDrawingAttributes();
}
public LineOne()
{
init();
}
public LineOne(PointF p)
: base(p)
{
init();
}
public override void Draw(Graphics g)
{
g.DrawEllipse(pen, rect);
}
}
}
The Shape Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Bicycle
{
class Shape
{
private Color DefaultLineColor = Color.Black;
private Color DefaultFillColor = Color.Blue;
private float DefaultLineThickness = 2;
protected bool bOutLine;
protected bool bFilled;
protected Pen pen;
protected Brush brush;
protected PointF location;
private void setDrawingAttributes()
{
pen = new Pen(DefaultLineColor, DefaultLineThickness);
brush = new SolidBrush(DefaultFillColor);
}
private void init()
{
bOutLine = true;
setDrawingAttributes();
}
public Shape()
{
init();
}
public Shape(PointF p)
{
location = p;
init();
}
public Color getFillColor()
{
return (DefaultFillColor);
}
public bool getFilledState()
{
return (bFilled);
}
public Color getLineColor()
{
return (DefaultLineColor);
}
public float getLineThickness()
{
return (DefaultLineThickness);
}
public bool getOutLineState()
{
return (bOutLine);
}
public bool isOutLine()
{
return (bOutLine);
}
public bool isFilled()
{
return (bFilled);
}
public void setFilledColor(Color C)
{
DefaultFillColor = C;
setDrawingAttributes();
}
public void setLineColor(Color C)
{
DefaultLineColor = C;
setDrawingAttributes();
}
public void setLineThickness(float value)
{
DefaultLineThickness = value;
setDrawingAttributes();
}
public void setFilledState(bool value)
{
bFilled = value;
}
public void setOutLineState(bool value)
{
bOutLine = value;
}
}
}
setLineThickness is a method, not a property.
Change l1.setLineThickness = (6); to l1.setLineThickness(6); (i.e. remove the equals sign)
Found it, after reviewing a article in regards of Overloads my Line code should had been
public override void Draw(Graphics g)
{
g.DrawLine(pen, new Point(0, 0), new Point(120, 95));
}
I'm now getting different strokes of lines when I play with the l1.setLineThickness(1); in my form code.
Thank you for your assist Mr.Williams on the clarification about LineThickness.

how can I add items to my ListView

I keep getting this error and I know why but I need help figuring out how I can solve it. The only way I have been able to add my items it to make a new form but that seems silly.
It wont work if I make all my methods static =(
I keep getting,
"An object reference is required for the non-static field, method, or
property 'Handicap_Calculator.FormMain.listViewLog'
\Form1.cs 74 13 Handicap Calculator"
Here´s my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Handicap_Calculator
{
public partial class FormMain : Form
{
//FormAddScore FormAddNewScore = new FormAddScore();
public static bool addScoreIsShown = false;
public static FormAddScore _FormAddScore;
public static ListViewItem Item;
//public static List<string> ScoreInfo = new List<string>();
public FormMain()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
try
{
if (_FormAddScore == null || _FormAddScore.IsDisposed)
{
_FormAddScore = new FormAddScore();
}
_FormAddScore.Show();
if (_FormAddScore.WindowState == FormWindowState.Minimized)
{
_FormAddScore.WindowState = FormWindowState.Normal;
}
_FormAddScore.BringToFront();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public static void AddScore()
{
int Round = 1;
DateTime date = _FormAddScore.date;
string course = _FormAddScore.course;
int holes = _FormAddScore.holes;
int score = _FormAddScore.score;
float courseRating = _FormAddScore.courseRating;
float slopeRating = _FormAddScore.slopeRating;
string[] ScoreInfo = new string[7];
ScoreInfo[0] = Round.ToString();
ScoreInfo[1] = date.ToString();
ScoreInfo[2] = course;
ScoreInfo[3] = holes.ToString();
ScoreInfo[4] = score.ToString();
ScoreInfo[5] = courseRating.ToString();
ScoreInfo[6] = slopeRating.ToString();
AddToList(ScoreInfo);
}
public static void AddToList(string[] ScoreInfo)
{
Item = new ListViewItem(ScoreInfo);
//listViewLog.Items.Add(Item);
}
}
}
Edit...
Here is the class im calling it from:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Handicap_Calculator
{
public partial class FormAddScore : Form
{
public DateTime date;
public string course;
public int holes;
public int score;
public float courseRating;
public float slopeRating;
public FormAddScore()
{
InitializeComponent();
}
private void FormAddScore_FormClosing(object sender, FormClosingEventArgs e)
{
FormMain.addScoreIsShown = false;
}
public void getscore()
{
try
{
date = dateTimePicker1.Value;
course = textBoxCourse.Text;
holes = Convert.ToInt16(textBoxHoles.Text);
score = Convert.ToInt16(textBoxScore.Text);
courseRating = Convert.ToSingle(textBoxCourseRating.Text);
slopeRating = Convert.ToSingle(textBoxSlopeRating.Text);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void button1_Click(object sender, EventArgs e)
{
getscore();
FormMain.AddScore();
}
}
}
The simple solution is to define your methods AddScore and AddToList as non-static.
public void AddScore()
{
//your code
}
public void AddToList(string[] ScoreInfo)
{
// your code
}
If you want to use static methods you should pass the instance of your Form to the method, on which you want to add items to the ListView.
public static void AddScore(FormMain mainForm)
{
//your code
AddToList(mainForm, ScoreInfo);
}
public static void AddToList(FormMain mainForm, string[] ScoreInfo)
{
// your code
}
Update:
According to your updated code the solution is to pass the instance of your FormMain to your FormAddScore when you create it. In FormAddScore you store the reference to the FormMain instance to call the methods on.
public partial class FormAddScore : Form
{
// your code
private FormMain _mainForm;
public FormAddScore(){
InitializeComponent();
}
public FormAddScore(FormMain mainForm) : this(){
_mainForm = mainForm;
}
In your FormMain when you create the instance of FormAddScore you should use the constructor that expects an instance of FormMain
_FormAddScore = new FormAddScore(this);
With this setup you can change your methods to non-static and you can call the methods of FormMain in your FormAddScore, by using the stored reference in variable _mainForm.
_mainForm.AddScore();

Noob Concern: Assigning a value to variable from new class object. C#

DinnerFun dinnerFun = new DinnerFun { PeepQty = (int)nudPeepQty.Value };
I am creating a new object of the DinnerFun class and trying to assign the value from the numeric up down object from the form to the int variable PeepQty.
When I go into debug mode, I can see that sure enough nudPeepQty has a numeric value, but it is never assigned to PeepQty, and my ending calculation always ends as 0.
As the problem might be something related to something I've done outside this line of code, I will add the rest of my project below:
DinnerParty.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MonuEventPlanning
{
class DinnerFun
{
const int FoodCost = 25;
public int PeepQty;
decimal CostOfBeverage;
decimal CostOfDecorations;
decimal TotalCost;
public void CalcDrinks(bool HealthOption)
{
if (HealthOption)
{
CostOfBeverage = 5M;
}
else
{
CostOfBeverage = 20M;
}
}
public void CalcDecorations(bool FancyOption)
{
if (FancyOption)
{
CostOfDecorations = (PeepQty * 15M) + 50M;
}
else
{
CostOfDecorations = (PeepQty * 7.5M) + 30M;
}
}
public decimal CalcTotalCost(bool HealthyOption)
{
if (HealthyOption)
{
TotalCost = (CostOfDecorations + CostOfBeverage) * .95M;
return TotalCost;
}
else
{
TotalCost = (CostOfBeverage + CostOfDecorations) + (PeepQty*25M);
return TotalCost;
}
}
}
}
------------Form1.cs -------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MonuEventPlanning
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCalc_Click(object sender, EventArgs e)
{
DinnerFun dinnerFun = new DinnerFun { PeepQty = (int)nudPeepQty.Value };
dinnerFun.CalcDrinks(cbxHealthy.Checked);
dinnerFun.CalcDrinks(cbxFancy.Checked);
DisplayCost();
}
public void DisplayCost()
{
DinnerFun dinnerFun = new DinnerFun();
tbxDisplayCost.Text = dinnerFun.CalcTotalCost(cbxHealthy.Checked).ToString("c");
}
}
}
The issue is that you are creating another DinnerFun that is not the same as the first one. Naturally the DinnerFun object in DisplayCost will have zero for the property value. Perhaps you meant this...
private void btnCalc_Click(object sender, EventArgs e)
{
DinnerFun dinnerFun = new DinnerFun { PeepQty = (int)nudPeepQty.Value };
dinnerFun.CalcDrinks(cbxHealthy.Checked);
dinnerFun.CalcDrinks(cbxFancy.Checked);
DisplayCost(dinnerFun);
}
public void DisplayCost(DinnerFun dinnerFun)
{
tbxDisplayCost.Text = dinnerFun.CalcTotalCost(cbxHealthy.Checked).ToString("c");
}

Categories

Resources