I'm trying to make my first game, a console tetris.
I have a class Block, that contains x and y integers. Then I have a class Piece : List<Block>, and a class Pieces : List<Piece>.
I can already randomly generate pieces, and make them fall one row per second. I still didn't get to collisions detection, but I think that I already know how to work it out later.
The problem is that I don't know how to control the pieces. I've read a bit about keyboard hooking and checked some tetris tutorials, but most of them are for windows forms, which really simplifies events handling and the such.
So... Could you please point me the beginning of the path to controlling the pieces on a console? Thanks!
public class Program
{
static void Main(string[] args)
{
const int limite = 60;
Piezas listaDePiezas = new Piezas(); //list of pieces
bool gameOver = false;
Pieza pieza; //piece
Console.CursorVisible = false;
while (gameOver != true)
{
pieza = CrearPieza(); //Cretes a piece
if (HayColision(listaDePiezas, pieza) == true) //if there's a collition
{
gameOver = true;
break;
}
else
listaDePiezas.Add(pieza); //The piece is added to the list of pieces
while (true) //This is where the piece falls. I know that I shouldn't use a sleep. I'll take care of that later
{
Thread.Sleep(1000);
pieza.Bajar(); //Drop the piece one row.
Dibujar(listaDePiezas); //Redraws the gameplay enviroment.
}
}
}
What you are looking for is non-blocking console input.
Here is an example:
http://www.dutton.me.uk/2009/02/24/non-blocking-keyboard-input-in-c/
Basically, you would check Console.KeyAvailable in your while loop and then move the piece according to what key was pressed.
if (Console.KeyAvailable)
{
ConsoleKeyInfo cki = Console.ReadKey();
switch (cki.Key)
{
case ConsoleKey.UpArrow:
// not used in tetris game?
break;
case ConsoleKey.DownArrow:
// drop piece
break;
case ConsoleKey.LeftArrow:
// move piece left
break;
case ConsoleKey.RightArrow:
// move piece right
break;
}
}
You could use a Low-Level Keyboard Hook as shown here
Related
I am very new to programming in C# so bare with me.
I am currently trying to make a block of code for a BMI Calculator within a menu based Console that allows the user to select from different options and it gives them different results.
I have not completed my code yet but everything has been relatively smooth sailing until I got to the point where I have been told -
"There should also be an option to ’exit‘ or terminate at any stage when the program is running."
I have looked on multiple forums and have tried to find an answer, none of which I have been able to get to work with my code.
I was hoping someone here would be able to help me out and point me in the right direction.
Here is the code I am currently working with.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BMI_Application
{
class Program
{
static void Main(string[] args)
{
bool showMenu = true;
while (showMenu)
{
showMenu = MainMenu();
}
}
private static void Calculator()
{
}
private static bool MainMenu()
{
string bmi = "You have selected the BMI Calculator";
float height;
float weight;
float sum1; // Heightx2
float sum2; // Weight / sum1
Console.WriteLine("Please select an option");
Console.WriteLine("1: BMI Calculator");
Console.WriteLine("2: Membership Rates");
Console.WriteLine("3: Close Menu");
Console.WriteLine("\r\nPlease enter 1, 2 or 3");
Console.WriteLine("\r\nYou can also write 'bye' at any time to leave");
switch (Console.ReadLine())
{
case "1":
Console.Clear();
Console.WriteLine(bmi);
Console.WriteLine("Please enter your Height in Metres");
height = float.Parse(Console.ReadLine());
Console.WriteLine("Please enter your Weight in Kilograms");
weight = float.Parse(Console.ReadLine());
sum1 = height * height;
sum2 = weight / sum1;
Console.WriteLine("Your BMI is : {0}", sum2); // Next part is - based on their BMI Level, writing if they are underweight etc
if (sum2 <= 18.5)
{
Console.WriteLine("Your BMI level indicates that your are 'Underweight' "); // Underweight
}
if (sum2 >= 18.5 && sum2 <= 25)
{
Console.WriteLine("Your BMI level indicates that you are 'Normal' weight"); // Normal
}
if (sum2 >= 25 && sum2 <= 30)
{
Console.WriteLine("Your BMI level indicates that you are 'Overweight' ");// Overweight
}
if (sum2 >= 30)
{
Console.WriteLine("Your BMI level indicates that you are 'Obese' "); // Obese
}
Console.WriteLine("\r\nPress any key to return back to main menu");
Console.ReadKey();
Console.Clear();
return true;
case "2":
Console.Clear();
Console.WriteLine("You have selected the Membership Rates");
Console.WriteLine("What Membership would you like?");
return true;
case "3":
Console.WriteLine("You have selected to close the menu, press any key to continue"); // Terminate
Console.ReadKey();
return false;
case "bye":
Console.WriteLine("Goodbye! Push any key to get out of here!");
Console.ReadKey();
return false;
default:
Console.Clear();
Console.WriteLine("That is not a valid number, please enter 1, 2 or 3"); // Not valid entry
Console.WriteLine(" ");
return true;
}
}
}
}
Any ideas of how I would be able to get a user to exit out of the console by entering the word 'exit' for example?
Thanks very much
So if you want to allow the user to enter a text such as "exit" to quit the program at any stage, then at every point where you read input you need to support this.
The way your code is structured at the moment then this is difficult as you basically have 1 method in your code which is doing everything. And you are actually mixing your "calculator" together with your "menu", which should be separated.
And if you look at your code then you will actually see that you are repeating sections of code multiple times with just slight differences (Writing and reading to/from console).
Instead, you need to structure your code so that you have less repeat of code and instead split this out into separate methods.
This is actually the crux of your program. Because the way your code is structured, you can't easily adapt it to support the new requirement without re-writing it.
Now I'm not going to re-write your code for you, but I will give you hints on one way to partly do this (there are other ways!)
Try and separate out the writing & reading into a separate method. Then you can also check for the word "exit" in a separate method.
So Pseudo code would be like this;
//do something in your method
var inputText = WriteAndGetInput("Please select option 1,2,3\r\nBlah blah blah \r\n");
CheckForExit(inputText);
//If you reach here, then Exit was not entered so carry on with your program and check for your real input.
//Try to use methods as to not repeat code.
//Method to write to console and get input
private static string WriteAndGetInput(string textToOutput)
{
Console.WriteLine(textToOutput);
return Console.ReadLine();
}
//method to check if user typed exit
private static void CheckForExit(string inputText)
{
if (inputText.Equals("exit"))
{
Console.WriteLine("You chose to exit. Goodbye!");
System.Environment.Exit(0);
}
}
I am having some issues with regards to making a picturebox display.
I am working on a simple RPG type game (a prototype), and the player can make a character. The character class has a picturebox attached to it, and when they create a character, an image is selected for this picturebox.
Once the game starts, the character spawns on a location. However, the picturebox doesn't show. Whilst on a location, the character can move around. After a random number of steps, combat is initiated, and the combat screen loads. Even though the picturebox doesn't load, the character seems to move around, and combat does get initiated.
When I leave combat and return to the form, the picturebox for the character appears. I have other pictureboxes on the location form, and they load.
The constructor for a location has a call to a method called initialise. Here is some relevant code from this method:
public void Initialise()
{
c = StateManager.C;
StepCount = 0;
SetStepsTillCombat();
EntranceLocation = "";
SetStartPosition();
c.Pic.Location = NewLocation ;//c.Pic is the picturebox
this.Controls.Add(c.Pic);
The set start position method aims to determine where the player should spawn. The code for this is as follows:
public void SetStartPosition()
{
switch (EntranceLocation)
{
case "North":
StartLocation.X = this.Width/2;
StartLocation.Y=10;
NewLocation = StartLocation;
break;
case "South":
StartLocation.X = this.Width/2;
StartLocation.Y=this.Height - c.Pic.Height;
NewLocation = StartLocation;
break;
case "West":
StartLocation.X = 10;
StartLocation.Y=this.Height/2;
NewLocation = StartLocation;
break;
case "East":
StartLocation.X = this.Width-c.Pic.Height;
StartLocation.Y=this.Height/2;
NewLocation = StartLocation;
break;
case "":
StartLocation.X = this.Width / 2;
StartLocation.Y = this.Height / 2;
NewLocation = StartLocation;
break;
}
}
I can't remember why I am even using startlocation, instead of setting newlocation directly, there was a reason, and then I removed the feature. Anyway, depending on where the player enters the location, their spawn point will differ, or if the player enters the first location when starting the game, they start at a set point. I call this method first, before assigning the location of the player picturebox.
When first entering a location, there is no picture. When I leave combat, I have the following code:
public void EndClick(object sender, EventArgs e)
{
this.Hide();
c.NumberOfBattles++;
returnLocation.Spawn(c.Location);//Coordinates for where to spawn the player
returnLocation.SetStepsTillCombat();
returnLocation.StepCount = 0;
returnLocation.Show();//Load the location I entered combat from
}
The spawn method looks like:
public void Spawn(Point p)
{
c.Location = p;
c.Pic.Location = c.Location;
this.Controls.Add(c.Pic);
}
When doing this, c.Pic does display.
I can't see what I am doing wrong here, any input would be appreciated. I think I have included all relevant code.
EDIT:
I found a work around, whereby each time I move the character, I call the spawn method, though this seems like an inefficient way to do things.
I have a loop and inside it a switch case which is basicly an user interface which lets people choose yes and now to continue a game with the left and right arrows.
i also added a Console.Beep() to give some feedback to the user. for some reason once the game ends(the game uses the arrows(its snake)) the option yes and no keep switching and i hear beeping about 10 to 20 times and then it stops.
Does anyone know the reason?
this is the code :
while (true)
{
Console.Clear();
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~\n\n~~~~~~~~You Lost!~~~~~~~~\n\n~~~~~~~~~~~~~~~~~~~~~~~~~\nYour score was: " + SnakeBody.Count);
Console.WriteLine("\nDo you want to continue?\n\n " + (Continue ? ">YES / No" : " Yes / >NO"));
switch (Console.ReadKey().Key)
{
case ConsoleKey.LeftArrow:
if (!Continue)
{
Console.Beep(SoundFrequency, SoundLength);
Continue = true;
}
continue;
case ConsoleKey.RightArrow:
if (Continue)
{
Console.Beep(SoundFrequency, SoundLength);
Continue = false;
}
continue;
case ConsoleKey.Enter:
Console.Beep(SoundFrequency + 200, SoundLength);
if (Continue)
SnakeGame();
break;
default: continue;
}
break;
}
When you press and hold a key, it generates repeating keystrokes with a certain frequency and puts them into an input queue. It looks that when you play your game, you generate a lot of keystrokes this way, your application is unable to process them in time so even when you think you've completed playing, your application still has a lot (about 10 to 20 times as you write) of keys yet to process, that's the reason.
To say I'm fresh off the boat would be an understatement. I think this solution is extremely simple for an experienced programmer, but I'm completely new to C# and coding in general, so I apologize if I offend anybody with my utter lack of comprehension. That being said, answers geared towards somebody completely new to coding would be appreciated. Basically, please assume no prior knowledge.
I'm working on a short text adventure as a learning experience. I'm trying to make a dialogue system where the player can choose three dialogue options:
Player says something -> NPC responds -> Player responds to NPC's response -> NPC responds again -> options cycle back to the three initial dialogue options
Player says something -> NPC responds -> options cycle back to the three initial dialogue options
Player ends dialogue -> options return to main dialogue options (which encases the following code)
This is what I've come up with so far:
//Talk to Smith
if (Input == "TALK TO SMITH")
{
{
Console.Clear();
Console.WriteLine("Initial discussion and character introduction");
Console.WriteLine("(Enter the corresponding number with what you want to say)");
Console.WriteLine("What would you like to discuss with Smith?");
}
do
{
correct = 0;
Console.WriteLine("1. Dialogue Option #1");
Console.WriteLine("2. Dialogue Option #2");
Console.WriteLine("3. Dialogue Option #3");
Input = Console.ReadLine().ToUpper();
if (Input == "1")
{
Console.Clear();
dialogue = 1;
correct = 1;
Console.WriteLine("Dialogue Option #1");
Console.WriteLine("Response #1");
Console.WriteLine("1. Dialogue Option #1A");
Console.WriteLine("2. Dialogue Option #1B");
Input = Console.ReadLine().ToUpper();
do
{
if (Input == "1")
{
dialogue = 0;
Console.Clear();
Console.WriteLine("Dialogue Option #1A");
Console.WriteLine("Response #1A");
Console.ReadKey();
correct = 1;
}
if (Input == "2")
{
dialogue = 0;
Console.Clear();
Console.WriteLine("Dialogue Option #1B");
Console.WriteLine("Response #1B");
Console.ReadKey();
correct = 1;
}
} while (correct == 1 && dialogue == 0);
}
if (Input == "2" && dialogue == 0)
{
Console.Clear();
dialogue = 1;
correct = 1;
Console.WriteLine("Response #2");
Input = Console.ReadLine().ToUpper();
}
if (Input == "3")
{
Console.Clear();
dialogue = 1;
correct = 0;
Console.WriteLine("Response #3");
Input = Console.ReadLine().ToUpper();
}
} while (correct == 1 && location == 1);
}
(This is only a part of the game's code, not the entire program itself)
The issue is that once I've chosen options #1A, #1B, or #2 the program does not cycle back to the dialogue with the NPC, but the main menu that I've set up. I've tried multiple methods, but none seem to work.
There's actually a formal concept in Computer Science that maps very well to what you're trying to do: a Finite State Machine.
The idea of a Finite State Machine is that it's a system that has a finite number of States that it can be in, the system is always in exactly one State, and each State contains a certain number of defined Transitions that put the system into a new State.
Dialogue trees are a very good fit for the FSM concept. The initial State of the system is the start of the dialogue, and each of the player's possible responses cause a Transition to a new State. It helps to formally model it like this:
State 0:
MessageBox(NPC001, "Is there anything else you need to know?")
Response "Where is the castle located?":
GotoState 1
Response "What sort of defenses does the castle have?":
GotoState 2
Response "Are we sure the Princess is being held in this castle?":
GotoState 3
Response "No, I think that's all.":
GotoState 4
State 1:
MessageBox(NPC001, "It is located two days' journey to the north, on the other side of the Dark Forest")
GotoState 0
State 2:
MessageBox(NPC001, "The castle is defended by monsters conjured forth by the Sorcerer King. Be sure to bring plenty of healing potions!")
GotoState 0
State 3:
MessageBox(NPC001, "Of course! What do you think this is, a Mario game?")
GotoState 0
State 4:
MessageBox(NPC001, "Farewell, heroes. May the Gods be with you on your journey!")
//no state transition here, so execution of the state machine ends at this point
Translating this outline into actual C# code is left as an exercise to the reader, but the basic idea is that each State is a method on the state machine object, and it continues running one method after another until it executes a method that does not end up telling it what the next State should be. (If you were using Boo, you could define a state machine macro and the outline above could literally be the code of your dialogue tree, but that's a whole other matter.)
Do a bit of research on the theory behind how a Finite State Machine works, and you'll find implementing things like this gets a whole lot easier.
EDIT:
Here's one way to implement a FSM for something like this.
class DialogueTree {
public void Execute()
{
int state = 0;
while (state >= 0)
{
switch (state)
{
case 0:
state = this.State0();
break;
case 1:
state = this.State1();
break;
//and so on
}
}
}
}
Each method would display some dialogue and choices, and return the next state for the state machine to go into based on the choice the player makes. To exit the conversation, a method should return -1. Does that help?
Remember, this is one possible way to do it. There are other implementations, some of which can be better or worse for certain applications of the State Machine concept.
It would require a restructuring of code, in particular to change the "linear" or "if then else" flow into a "display - response" loop.
The next dialog to be shown is captured in a state variable.
In each "display - response" cycle,
A prompt is displayed;
User response is captured;
Changes to program states are made, in order to encode the "knowledge" into the "story line";
The next dialog is chosen.
A simplified sketch of the code would look like this:
/// somewhere else
enum NextDialog
{
Smith,
Anderson,
Finished
}
NextDialog nextDialog = NextDialog.Smith;
while (nextDialog != NextDialog.Finished)
{
NextDialog nextNextDialog;
switch (nextDialog)
{
case NextDialog.Smith:
// Each handler is responsible for:
// (1) printing the prompt
// (2) getting the user response
// (3) converting the user response into state (program variable) changes, as well as determine the next dialog.
// Each handler will need access to object fields;
// these typically do not appear on the arguments list because
// all instance methods can access all object fields.
nextNextDialog = ProcessDialogSmith( ... );
break;
case NextDialog.Anderson:
nextNextDialog = ProcessDialogAnderson( ... );
break;
default:
throw new UnhandledException();
}
nextDialog = nextNextDialog;
}
I need help with a game I am creating. I am building the game with the Unity engine and am pretty new to C# coding. I am creating a 2d game where the player controls the color of a square and must change it to the correct color as when it passes a certain colored object. The player changes colors great and the objects are triggers. When a player passes the trigger if its not the right color the player dies. Well that works perfect but only for the first object the next one no matter the color of the player the object dies. I have tried if's in if statements and else if's I can't seem to figure it out. Your help would be greatly appreciated!
Here is the code for the player
void OnTriggerEnter (Collider other)
{
if (other.transform.tag == "Blue") {
blue = true;
}
else {
blue=false;
}
if (other.transform.tag == "Red") {
red = true;
}
else {
red =false;
}
if (other.transform.tag == "Blue" && GameObject.Find ("Blue").GetComponent<Blue> ().mb == false) {
yield return 0;
Die ();
} else if (other.transform.tag == "Red" && GameObject.Find ("Red").GetComponent<Red> ().mr == false) {
Die ();
}
}
Here is the code for each different colored object. This one happens to be blue.
void Update () {
if (GameObject.Find ("Player").GetComponent<Movement> ().blue == true && GameObject.Find ("Player").GetComponent<Movement> ().playerBlue == true) {
mb = true;
} else {
mb = false;
}
if (!GameObject.Find("Player").GetComponent<Movement>().blue) {
mb = false;
}
}
Your execution order is a little messy, that's probably why it's not working. Try to make all your logic follow one path, not two. Right now, you are:
(1)Colliding, (2) setting some boolean variables, (3)checking some variables, (4)optionally dying.
At a separate time in a separate class, set the boolean that was set in step 1 and setting the variable that's checked in step 3
This is what we call spaghetti code. It's all twisted together. Can you think of a way to untangle it, so the two bits of logic don't mutually depend on each other?
For example, I see in the latter block of code, you're checking whether the player is blue. Could you instead run that code when the player sets blue (or sets blue=false)?
Edit: I know this isn't strictly answering your question, but this untangling is the first step of the problem solving process.