I don't know how to add a value in a textbox.
This is the code:
private void starecivilaComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (starecivilaComboBox.SelectedIndex == 0)
{
MessageBox.Show("This selection is not valid!");
}
else if (starecivilaComboBox.SelectedIndex == 1)
{
int score = 4;
}
else if (starecivilaComboBox.SelectedIndex == 2)
{
int score = 1;
}
else if (starecivilaComboBox.SelectedIndex == 3)
{
int score = 3;
}
else if (starecivilaComboBox.SelectedIndex == 4)
{
int score = 2;
}
}
I want to insert the value of score in a textbox, so it will show me the score of each item i've selected from combobox.
I tried with this:
private void scoringTextBox_TextChanged(object sender, EventArgs e)
{
scoringTextBox.Text = score.toString();
}
But it doesn't recognize it. The error is: The name 'score' does not exist in this context. How can I make this work ?
Thank you.
You must declare variable score outside of ComboBox SelectedIndexChanged handler. You're declaring it in the handler and it's being used only in the method, not in the whole class (not in the whole form in your case).
public class Form1
{
int score = 0;
//somewhere in the code
score = 1; //there is no need to specify 'int' here - you will create an local variable with the same name then
}
I recommend you to learn through tutorials, because the question is rather simple.
Though #psNytrancez answer is the simplest for you, you will not get far in C# without understanding how variables work.
The problem is with the lines that look like this:
else if (starecivilaComboBox.SelectedIndex == 1)
{
int score = 4;
}
it means that you create a variable "score", but that the variable will only exists between the two braces "{" and "}". In order to actually keep a value, you need to expand its scope (instruction video). if you edit all those lines to just read
else if (starecivilaComboBox.SelectedIndex == 1)
{
score = 4;
}
and instead put it outside the method declaration like this
int score =0;
private void starecivilaComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
//the rest of the method.
then you should be fine.
It is because you are declaring your score inside of the starecivilaComboBox_SelectedIndexChanged method so it is local to that method and cannot be accessed outside of it.
As stated above, you must declare score outside of your private method but inside your class. Code should look similar to this:
private int score = 0;
private void starecivilaComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (starecivilaComboBox.SelectedIndex == 0)
{
MessageBox.Show("This selection is not valid!");
}
else if (starecivilaComboBox.SelectedIndex == 1)
{
score = 4;
}
else if (starecivilaComboBox.SelectedIndex == 2)
{
score = 1;
}
else if (starecivilaComboBox.SelectedIndex == 3)
{
score = 3;
}
else if (starecivilaComboBox.SelectedIndex == 4)
{
score = 2;
}
}
private void scoringTextBox_TextChanged(object sender, EventArgs e)
{
scoringTextBox.Text = score.toString();
}
private void starecivilaComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (starecivilaComboBox.SelectedIndex == 0)
{
MessageBox.Show("This selection is not valid!");
}
else if (starecivilaComboBox.SelectedIndex == 1)
{
scoringTextBox.Text = "4";
}
else if (starecivilaComboBox.SelectedIndex == 2)
{
scoringTextBox.Text = "1";
}
else if (starecivilaComboBox.SelectedIndex == 3)
{
scoringTextBox.Text = "3";
}
else if (starecivilaComboBox.SelectedIndex == 4)
{
scoringTextBox.Text = "2";
}
}
Do it after this
else if (starecivilaComboBox.SelectedIndex == 4)
{
int score = 2;
}
Add this
scoringTextBox.Text = score.toString();
The scope for variable / object score is the problem
you are trying to access a variable that has limited scope (function level only)
simply create a private variable score so it can be accessed through the class.
Related
For a school project I need to develop a platform style game purely in C# Windows forms and cannot use any other languages. I have a gravity and movement system sorted already but my character is still able to jump off the map or jump through picture boxes. How would I go about making these objects solid so that the character cannot run through them. Here is my code
What my game looks like:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
bool left;
bool right;
int gravity = 20;
int force;
bool jump;
private void Timer(object sender, EventArgs e)
{
if (left == true)
{
Character.Left -= 15;
if (Character.Image != Properties.Resources.LeftChar)
{
Character.Image = Properties.Resources.LeftChar;
}
}
if (right == true)
{
Character.Left += 15;
if (Character.Image != Properties.Resources.RightChar)
{
Character.Image = Properties.Resources.RightChar;
}
}
if (jump == true)
{
Character.Top -= force;
force -= 1;
}
if (Character.Top + Character.Height >= GameBoundary.Height)
{
Character.Top = GameBoundary.Height - Character.Height;
jump = false;
}
else
{
Character.Top += 10;
}
}
private void keydown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
left = true;
if (e.KeyCode == Keys.D)
right = true;
if (jump != true)
{
if (e.KeyCode == Keys.W)
{
jump = true;
force = gravity;
}
}
}
private void keyup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
left = false;
if (e.KeyCode == Keys.D)
right = false;
}
}
I created an invisible panel that was the same size of the game called "Gameboundary", this made it possible for the player to walk on the bottom of the window, but I am not sure how I would apply this to the rest of the code. If anybody has any suggestions it will be greatly welcome. Not too good at C# just yet!
Here is a basic Collision Detection system:
public class CollisionDetection
{
public static bool ObjectTouchingOthers(Control Object, int SpaceBetweenObjects)
{
for (int i = 0; i < Object.Parent.Controls.Count; i++)
{
if (Object.Parent.Controls[i].Name != Object.Name)
{
if (Object.Left + Object.Width + SpaceBetweenObjects > Object.Parent.Controls[i].Left && Object.Top + Object.Height + SpaceBetweenObjects > Object.Parent.Controls[i].Top && Object.Left < Object.Parent.Controls[i].Left + Object.Parent.Controls[i].Width + SpaceBetweenObjects && Object.Top < Object.Parent.Controls[i].Top + Object.Parent.Controls[i].Height + SpaceBetweenObjects)
{
return true;
}
}
}
return false;
}
public static bool ObjectTouchingOthers(Control Object, int SpaceBetweenObjects, Control[] ControlsToExclude )
{
for (int i = 0; i < Object.Parent.Controls.Count; i++)
{
if (ControlsToExclude.Contains(Object.Parent.Controls[i]) == false && Object.Parent.Controls[i].Name != Object.Name)
{
if (Object.Left + Object.Width + SpaceBetweenObjects > Object.Parent.Controls[i].Left && Object.Top + Object.Height + SpaceBetweenObjects > Object.Parent.Controls[i].Top && Object.Left < Object.Parent.Controls[i].Left + Object.Parent.Controls[i].Width + SpaceBetweenObjects && Object.Top < Object.Parent.Controls[i].Top + Object.Parent.Controls[i].Height + SpaceBetweenObjects)
{
return true;
}
}
}
return false;
}
}
The first argument Object is the control you want collision detection for, and it will only detect other controls in the same container, so if you used it for a control in a panel, for example, it would only work with other controls in the panel, likewise with a Form or any other control. The second argument simply specifies how much distance you want between the controls when they are touching. If you're using the second overload, the third argument is an array of controls that you do not want collision detection for. This is how you would use the second overload:
private void btnMoveLeft_Click(object sender, EventArgs e)
{
btnPlayer.Left -= 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1, new Control[] {button1, button2}) == true)
{
btnPlayer.Left += 1;
}
}
With this overload, it will continue right through the controls you specified in the array.
And just to wrap it up, here's a basic example of how to set up collision detection:
private void btnMoveLeft_Click(object sender, EventArgs e)
{
btnPlayer.Left -= 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Left += 1;
}
}
private void btnMoveRight_Click(object sender, EventArgs e)
{
btnPlayer.Left += 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Left -= 1;
}
}
private void btnMoveUp_Click(object sender, EventArgs e)
{
btnPlayer.Top -= 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Top += 1;
}
}
private void btnMoveDown_Click(object sender, EventArgs e)
{
btnPlayer.Top += 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Top -= 1;
}
}
Just remember that you're going to have to change the names of the controls in the code I have here. And for reference, here is my test form:
You need to implement collision detection. Draw an imaginary box around your person and any objects you don't want him to pass through. Check if any of the boxes overlap. If they do, move one or both of the objects back until the boxes no longer overlap.
Picture boxes has a .Bounds with a .IntersectWith and this will take an object of type Rectangle.
In a game, you will typically have an ongoing timer, checking all sorts of stuff and progressing time.
In this timer i would make a:
if (pictureBox1.Bounds.IntersectsWith(pictureBox2.Bounds))
{
//They have collided
}
You might have a lot of objects, so you could make a List<PictureBox> and add those objects, then the list will have refferences to those PictureBoxes, that means that they will automatically be updated with the right bounds, when you go through the List.
Be sure to make the List a public property of your form class. Then before rolling through the List, instead set another List = to the public object List. This ensures that you can do a foreach() loop without getting exceptions.
I'm trying to display an image using a button click and increment a variable when a certain image is shown, but with the code below the variable num is always 0.
my code
int num = 0;
int i = 0;
int x = 0;
PictureBox[] pictureBoxs = new PictureBox[4];
Random rnd = new Random();
public UserControl1()
{
InitializeComponent();
pictureBoxs[0] = pbimg1;
pictureBoxs[1] = pbimg2;
pictureBoxs[2] = pbimg3;
pictureBoxs[3] = pbimg4;
x = rnd.Next(2);
}
public void displaypics()
{
pictureBoxs[i].Image = imageList1.Images[x];
}
private void btn2_Click(object sender, EventArgs e)
{
i=1;
displaypics();
if (pictureBoxs[i].Image == imageList1.Images[1])
{
num++;
}
if (num == 2)
{
tb1.Visible = true;
tb1.Text = "GAME OVER!" + num;
}
}
The reason is most likely that num is being instantiated to zero everytime the class is being instantiated
What happens when you set breakpoints and step through the code? Is the int set as 0, or does it contain the updated value?
I'm not sure what the context is in which that piece of code is used. So I guess what should solve this would be adding x = rnd.Next(2) to the btn2_Click method. Making it look like this:
private void btn2_Click(object sender, EventArgs e)
{
x = rnd.Next(2);
displaypics();
if (pictureBoxs[i].Image == imageList1.Images[1])
{
num++;
}
if (num == 2)
{
tb1.Visible = true;
tb1.Text = "GAME OVER!" + num;
}
i++;
}
Maybe you could give some more details on what that control should do/how it's used.
I have a ASP.Net application that is a simple number generator. People guess, and it tells them whether or not they are correct. The issue I am having is in order to keep the randNum from changing each time the button is clicked to submit the answer (the page is reloaded), it is placed inside a Page.IsPostBack statement. The problem is the randomNum generated within this If is not accessible outside the If.
How can I get this variable accessable to other areas of my code while retaining the original randomNum? I want to use IsPostBack.
protected void btnGuess_Click(object sender, EventArgs e)
{
if (Page.IsPostBack == false) //the code only runs once when the form is loaded.
{
Random myGenerator = new Random();
myGenerator = new Random();
int randomNum = myGenerator.Next(1, 50);
}
else //code can always run
{
int guessedNum = Convert.ToInt32(txtGuess.Text);
if (guessedNum < randomNum)
{
MessageBox.Show("No. Low.");
txtGuess.Text = "";
}
else if (guessedNum > randomNum)
{
MessageBox.Show("No. High.");
txtGuess.Text = "";
}
else
{
MessageBox.Show("Yes");
txtGuess.Text = "";
}
}
}
Also, I have tried storing the variable as seen below:
HttpContext.Current.Session["RANDOM"] = randomNum;
and passing it to the else as:
int randomNum = Convert.ToInt32(HttpContext.Current.Session["RANDOM"]);
But doing this always results in a value of 0.
This is the only page that needs to use the variable. It does not need passed across pages, just functions.
Page.IsPostBack does not belong in a button click event. It needs to be added to Page_Load.
The way you have it now, it will always hit the else. i.e. it's always a postback in a button click.
protected void btnGuess_Click(object sender, EventArgs e)
{
int randomNum = Convert.ToInt32(HttpContext.Current.Session["RANDOM"]);
int guessedNum = Convert.ToInt32(txtGuess.Text);
if (guessedNum < randomNum)
{
MessageBox.Show("No. Low.");
txtGuess.Text = "";
}
else if (guessedNum > randomNum)
{
MessageBox.Show("No. High.");
txtGuess.Text = "";
}
else
{
MessageBox.Show("Yes");
txtGuess.Text = "";
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack == false) //the code only runs once when the form is loaded.
{
Random myGenerator = new Random();
myGenerator = new Random();
int randomNum = myGenerator.Next(1, 50);
HttpContext.Current.Session["RANDOM"] = randomNum;
}
}
i'm new to C# (and programming at all) and i'm trying to write an 'XO' game along with ASP.NET
i'm getting a problem after the first player clicks a button.
turns doesn't switch and any click after the 1st does nothing. what is wrong with my code ?
public partial class GamePage : System.Web.UI.Page
{
Player player1 = new Player();
Player player2 = new Player();
int turn;
protected void Page_Load(object sender, EventArgs e)
{
this.turn = 0;
if (!IsPostBack)
{
Label1.Visible = true;
}
if (turn == 0)
{
Label1.Text = (Session["player1"] as Player).getname();
}
else
{
Label1.Text = (Session["player2"] as Player).getname();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["p1"] = player1;
Session["p2"] = player2;
player1.setsymbol("X");
player2.setsymbol("O");
if (Button1.Text == "")
{
if (turn == 0)
{
Button1.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button1.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button2_Click(object sender, EventArgs e)
{
if (Button2.Text == "")
{
if (turn == 0)
{
Button2.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button2.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button3_Click(object sender, EventArgs e)
{
if (Button3.Text == "")
{
if (turn == 0)
{
Button3.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button3.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
// this is an example - i have the same lines from button1 to 9
Everytime page renders, you set turn to 0 in Page_Load. Because Page_Load is executed upon every page load, you won't get any other value and this is probably the major issue here.
To properly support the lifetime of such variables that should keep value upon consecutive requests, wrap them in simple property:
public int turn
{
get
{
if ( Session["turn"] != null )
return (int)Session["turn"];
return 0; // default value if not set before
}
set
{
Session["turn"] = value;
}
}
This way everytime you refer to turn in your code, setting it to 0 or 1 or comparing the value to 0 or 1, you will refer to the same value, possibly stored during previous request(s).
this.turn=0; should be executed only when IsPostBack is false. Move this line inside if in your Page_Load.
When a user tries to move the last item down in a listbox, I need a messagebox to display that the item is already at the bottom. The app allows a user to enter more items to the list, so having the message display when a number is reached, like with the top, will not work, here is the code I currently have:
private void MoveUpButton()
{
if (selectedPlayersListBox.SelectedItem == null || selectedPlayersListBox.SelectedIndex < 0)
MessageBox.Show("A player under \"Selected Players\" must be selected");
if (selectedPlayersListBox.SelectedIndex == 0)
MessageBox.Show("Player is already at the top of the list.");
else
{
MoveItem(-1);
}
}
private void MoveDownButton()
{
if (selectedPlayersListBox.SelectedItem == null || selectedPlayersListBox.SelectedIndex < 0)
MessageBox.Show("A player under \"Selected Players\" must be selected");
else
{
MoveItem(1);
}
}
private void MoveItem(int direction)
{
int newIndex = selectedPlayersListBox.SelectedIndex + direction;
if (newIndex < 0 || newIndex >= selectedPlayersListBox.Items.Count)
return;
object selected = selectedPlayersListBox.SelectedItem;
selectedPlayersListBox.Items.Remove(selected);
selectedPlayersListBox.Items.Insert(newIndex, selected);
selectedPlayersListBox.SetSelected(newIndex, true);
}
As I mentioned above, the MoveUpButton works fine, but the MoveDownButton is giving me trouble.
Thanks for any help you are able to offer.
It would look just like the MoveUpButton, except you'd check to see if the SelectedIndex is equal to Count - 1:
private void MoveDownButton()
{
if (selectedPlayersListBox.SelectedItem == null || selectedPlayersListBox.SelectedIndex < 0)
MessageBox.Show("A player under \"Selected Players\" must be selected");
else if (selectedPlayersListBox.SelectedIndex == selectedPlayersListBox.Items.Count - 1)
MessageBox.Show("Player is already at the bottom of the list.");
else
{
MoveItem(1);
}
}
Another way for moving up/down
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
btnMoveUp.Enabled = false;
btnMoveDown.Enabled = false;
}
private void lstPlayers_SelectedIndexChanged(object sender, EventArgs e) {
btnMoveUp.Enabled = (lstPlayers.SelectedIndex != 0);
btnMoveDown.Enabled = (lstPlayers.SelectedIndex != lstPlayers.Items.Count - 1);
}
private void btnMoveUp_Click(object sender, EventArgs e) {
var index = lstPlayers.SelectedIndex;
var item = lstPlayers.SelectedItem;
lstPlayers.Items.Insert(index - 1, item);
lstPlayers.Items.RemoveAt(index + 1);
lstPlayers.SetSelected(index - 1, true);
}
private void btnMoveDown_Click(object sender, EventArgs e) {
var index = lstPlayers.SelectedIndex;
var item = lstPlayers.SelectedItem;
lstPlayers.Items.Insert(index + 2, item);
lstPlayers.Items.RemoveAt(index);
lstPlayers.SetSelected(index + 1, true);
}
}