Beginner troubles

Started by
21 comments, last by Slateboard 13 years, 4 months ago
Ok so, here I am, focusing on learning C#. Following a game making tutorial in a book.

Problem is, I come across code with dozens of numbers, x's, y's, etc. How am I supposed to remember/know all of this? I for the life of me, can barely understand it, seeing as it's being thrown at me all at once. And secondly, how in the hell am I supposed to remember everything needed to fully put the game together when it comes time to try remaking the game without looking at the book?

My memory sucks, everything I read tends to go in one ear and out the other.
I have no idea how I'm going to get any of this to stick :(.
Advertisement
Quote:Original post by GraySnakeGenocide
Ok so, here I am, focusing on learning C#. Following a game making tutorial in a book.

Problem is, I come across code with dozens of numbers, x's, y's, etc. How am I supposed to remember/know all of this? I for the life of me, can barely understand it, seeing as it's being thrown at me all at once. And secondly, how in the hell am I supposed to remember everything needed to fully put the game together when it comes time to try remaking the game without looking at the book?

My memory sucks, everything I read tends to go in one ear and out the other.
I have no idea how I'm going to get any of this to stick :(.


a) game design document
b) source code comments
c) well named variables (with good naming convention)
d) there's no secret, you don't remember everything. it's like driving, you can't jot down everything from A to Z from memory, but as you drive, you will realize that scenery and sign will help you arrive at your destination.

your current self and your past self can be treated as different team member in a large company, where you will do things using their code without even looking into the code, only the function names - and trust the rest.

I've been programming for well over a decade. I constantly look at manuals. Sometimes I review them in more detail, including methods I've used a hundred times, to make sure I'm only invoking defined behavior.

A lot of programming techniques are focused around reducing complexity of what you have to think about.

This is why there are "private" members, for example. When I use a JButton class, I don't want to have in my head how the guts work or how it renders. I just want to use a few interfaces; setText, addActionListener, and use another kit to set it into a panel. All the internal machinations are hidden from me behind a carefully defined interface.

This is called "information hiding".

After all that, there's still a lot of complexiy. Having a brain for that is part of being a programmer.

Quote:well named variables (with good naming convention)


QFT. In the PHP language, the naming is very haphazard, so if you know you want to call "string split", you don't know of it's going to be splitstring, spltstr, split_string or split_str. It might as well be pictograms. If you know that "split string" will be "splitString" because you always name things with the same convention, you avoid a lot of pain.
Writing down when needs to be implemented, and doing each method individually helped for the smaller project, but this next project has like, a million int x's, a million int y's, Vectors, etc. All of it is making my head spin >_<.

I'm going to try the one method at a time bit once I finish the game via following the book, and hopefully i'll do it enough times where I will remember each method the I previously forgot, if that makes sense >_<.
My issue is, I am following a book, and it's having me do a FloodControl game.

There are 3 classes:

Game1
using System;using System.Collections.Generic;using System.Linq;using Microsoft.Xna.Framework;using Microsoft.Xna.Framework.Audio;using Microsoft.Xna.Framework.Content;using Microsoft.Xna.Framework.GamerServices;using Microsoft.Xna.Framework.Graphics;using Microsoft.Xna.Framework.Input;using Microsoft.Xna.Framework.Media;namespace Flood_Control{    /// <summary>    /// This is the main type for your game    /// </summary>    public class Game1 : Microsoft.Xna.Framework.Game    {        GraphicsDeviceManager graphics;        SpriteBatch spriteBatch;        Texture2D playingPieces;        Texture2D backgroundScreen;        Texture2D titleScreen;        GameBoard gameBoard;        Vector2 gameBoardDisplayOrigin = new Vector2(70, 89);        int playerScore = 0;        enum GameStates { TitleScreen, Playing };        GameStates gameState = GameStates.TitleScreen;        Rectangle EmptyPiece = new Rectangle(1, 247, 40, 40);        const float MinTimeSinceLastInput = 0.25f;        float timeSinceLastInput = 0.0f;        public Game1()        {            graphics = new GraphicsDeviceManager(this);            Content.RootDirectory = "Content";        }        /// <summary>        /// Allows the game to perform any initialization it needs to before starting to run.        /// This is where it can query for any required services and load any non-graphic        /// related content.  Calling base.Initialize will enumerate through any components        /// and initialize them as well.        /// </summary>        protected override void Initialize()        {            // TODO: Add your initialization logic here            this.IsMouseVisible = true;            graphics.PreferredBackBufferWidth = 800;            graphics.PreferredBackBufferHeight = 600;            graphics.ApplyChanges();            gameBoard = new GameBoard();            base.Initialize();        }        /// <summary>        /// LoadContent will be called once per game and is the place to load        /// all of your content.        /// </summary>        protected override void LoadContent()        {            // Create a new SpriteBatch, which can be used to draw textures.            spriteBatch = new SpriteBatch(GraphicsDevice);            playingPieces = Content.Load<Texture2D>(@"Textures\Tile_Sheet");            backgroundScreen = Content.Load<Texture2D>(@"Textures\Background");            titleScreen = Content.Load<Texture2D>(@"Textures\TitleScreen");            // TODO: use this.Content to load your game content here        }        /// <summary>        /// UnloadContent will be called once per game and is the place to unload        /// all content.        /// </summary>        protected override void UnloadContent()        {            // TODO: Unload any non ContentManager content here        }        private int DetermineScore(int SquareCount)        {            return (int)((Math.Pow((SquareCount / 5), 2) + SquareCount) * 10);        }        private void CheckScoringChain(List<Vector2> WaterChain)        {            if (WaterChain.Count > 0)            {                Vector2 LastPipe = WaterChain[WaterChain.Count - 1];                if (LastPipe.X == GameBoard.GameBoardWidth - 1)                {                    if (gameBoard.HasConnector(                        (int)LastPipe.X, (int)LastPipe.Y, "Right"))                    {                        playerScore += DetermineScore(WaterChain.Count);                        foreach (Vector2 ScoringSquare in WaterChain)                        {                            gameBoard.SetSquare((int)ScoringSquare.X,                                (int)ScoringSquare.Y, "Empty");                        }                    }                }            }        }        private void HandleMouseInput(MouseState mouseState)        {            int x = ((mouseState.X -                (int)gameBoardDisplayOrigin.X) / GamePiece.PieceWidth);            int y = ((mouseState.Y -                (int)gameBoardDisplayOrigin.Y) / GamePiece.PieceHeight);            if ((x >= 0) && (x < GameBoard.GameBoardWidth) &&              (y >= 0) && (y < GameBoard.GameBoardHeight))            {                if (mouseState.LeftButton == ButtonState.Pressed)                {                    gameBoard.RotatePiece(x, y, false);                    timeSinceLastInput = 0.0f;                }                if (mouseState.RightButton == ButtonState.Pressed)                {                    gameBoard.RotatePiece(x, y, true);                    timeSinceLastInput = 0.0f;                }            }        }        /// <summary>        /// Allows the game to run logic such as updating the world,        /// checking for collisions, gathering input, and playing audio.        /// </summary>        /// <param name="gameTime">Provides a snapshot of timing values.</param>        protected override void Update(GameTime gameTime)        {            // Allows the game to exit            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)                this.Exit();            // TODO: Add your update logic here            switch (gameState)            {                case GameStates.TitleScreen:                    if (Keyboard.GetState().IsKeyDown(Keys.Space))                    {                        gameBoard.ClearBoard();                        gameBoard.GenerateNewPieces(false);                        playerScore = 0;                        gameState = GameStates.Playing;                    }                    break;                case GameStates.Playing:                    timeSinceLastInput +=                      (float)gameTime.ElapsedGameTime.TotalSeconds;                    if (timeSinceLastInput >= MinTimeSinceLastInput)                    {                        HandleMouseInput(Mouse.GetState());                    }                    gameBoard.ResetWater();                    for (int y = 0; y < GameBoard.GameBoardHeight; y++)                    {                        CheckScoringChain(gameBoard.GetWaterChain(y));                    }                    gameBoard.GenerateNewPieces(true);                    break;            }            base.Update(gameTime);        }        /// <summary>        /// This is called when the game should draw itself.        /// </summary>        /// <param name="gameTime">Provides a snapshot of timing values.</param>        protected override void Draw(GameTime gameTime)        {            GraphicsDevice.Clear(Color.CornflowerBlue);            // TODO: Add your drawing code here            if (gameState == GameStates.TitleScreen)            {                spriteBatch.Begin();                spriteBatch.Draw(titleScreen,                    new Rectangle(0, 0,                        this.Window.ClientBounds.Width,                        this.Window.ClientBounds.Height),                    Color.White);                spriteBatch.End();            }            if (gameState == GameStates.Playing)            {                spriteBatch.Begin();                spriteBatch.Draw(backgroundScreen,                    new Rectangle(0, 0,                        this.Window.ClientBounds.Width,                        this.Window.ClientBounds.Height),                    Color.White);                for (int x = 0; x < GameBoard.GameBoardWidth; x++)                    for (int y = 0; y < GameBoard.GameBoardHeight; y++)                    {                        int pixelX = (int)gameBoardDisplayOrigin.X +                            (x * GamePiece.PieceWidth);                        int pixelY = (int)gameBoardDisplayOrigin.Y +                            (y * GamePiece.PieceHeight);                        spriteBatch.Draw(                            playingPieces,                            new Rectangle(                              pixelX,                              pixelY,                              GamePiece.PieceWidth,                              GamePiece.PieceHeight),                            EmptyPiece,                            Color.White);                        spriteBatch.Draw(                            playingPieces, new Rectangle(                                pixelX,                                pixelY,                                GamePiece.PieceWidth,                                GamePiece.PieceHeight),                            gameBoard.GetSourceRect(x, y),                            Color.White);                    }                this.Window.Title = playerScore.ToString();                spriteBatch.End();            }            base.Draw(gameTime);        }    }}



GamePiece
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Microsoft.Xna.Framework.Graphics;using Microsoft.Xna.Framework;namespace Flood_Control{    class GamePiece    {        public static string[] PieceTypes =         {             "Left,Right",             "Top,Bottom",             "Left,Top",             "Top,Right",            "Right,Bottom",             "Bottom,Left",            "Empty"         };        public const int PieceHeight = 40;        public const int PieceWidth = 40;        public const int MaxPlayablePieceIndex = 5;        public const int EmptyPieceIndex = 6;        private const int textureOffsetX = 1;        private const int textureOffsetY = 1;        private const int texturePaddingX = 1;        private const int texturePaddingY = 1;        private string pieceType = "";        private string pieceSuffix = "";        public string PieceType        {            get { return pieceType; }        }        public string Suffix        {            get { return pieceSuffix; }        }        public GamePiece(string type, string suffix)        {            pieceType = type;            pieceSuffix = suffix;        }        public GamePiece(string type)        {            pieceType = type;            pieceSuffix = "";        }        public void SetPiece(string type, string suffix)        {            pieceType = type;            pieceSuffix = suffix;        }        public void SetPiece(string type)        {            SetPiece(type, "");        }        public void AddSuffix(string suffix)        {            if (!pieceSuffix.Contains(suffix))                pieceSuffix += suffix;        }        public void RemoveSuffix(string suffix)        {            pieceSuffix = pieceSuffix.Replace(suffix, "");        }        public void RotatePiece(bool Clockwise)        {            switch (pieceType)            {                case "Left,Right":                    pieceType = "Top,Bottom";                    break;                case "Top,Bottom":                    pieceType = "Left,Right";                    break;                case "Left,Top":                    if (Clockwise)                        pieceType = "Top,Right";                    else                        pieceType = "Bottom,Left";                    break;                case "Top,Right":                    if (Clockwise)                        pieceType = "Right,Bottom";                    else                        pieceType = "Left,Top";                    break;                case "Right,Bottom":                    if (Clockwise)                        pieceType = "Bottom,Left";                    else                        pieceType = "Top,Right";                    break;                case "Bottom,Left":                    if (Clockwise)                        pieceType = "Left,Top";                    else                        pieceType = "Right,Bottom";                    break;                case "Empty":                    break;            }        }        public string[] GetOtherEnds(string startingEnd)        {            List<string> opposites = new List<string>();            foreach (string end in pieceType.Split(','))            {                if (end != startingEnd)                    opposites.Add(end);            }            return opposites.ToArray();        }        public bool HasConnector(string direction)        {            return pieceType.Contains(direction);        }        public Rectangle GetSourceRect()        {            int x = textureOffsetX;            int y = textureOffsetY;            if (pieceSuffix.Contains("W"))                x += PieceWidth + texturePaddingX;            y += (Array.IndexOf(PieceTypes, pieceType) *                 (PieceHeight + texturePaddingY));            return new Rectangle(x, y, PieceWidth, PieceHeight);        }    }}


GameBoard
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Microsoft.Xna.Framework;namespace Flood_Control{    class GameBoard    {        Random rand = new Random();        public const int GameBoardWidth = 8;        public const int GameBoardHeight = 10;        private GamePiece[,] boardSquares =          new GamePiece[GameBoardWidth, GameBoardHeight];        private List<Vector2> WaterTracker = new List<Vector2>();        public GameBoard()        {            ClearBoard();        }        public void ClearBoard()        {            for (int x = 0; x < GameBoardWidth; x++)                for (int y = 0; y < GameBoardHeight; y++)                    boardSquares[x, y] = new GamePiece("Empty");        }        public void RotatePiece(int x, int y, bool clockwise)        {            boardSquares[x, y].RotatePiece(clockwise);        }        public Rectangle GetSourceRect(int x, int y)        {            return boardSquares[x, y].GetSourceRect();        }        public string GetSquare(int x, int y)        {            return boardSquares[x, y].PieceType;        }        public void SetSquare(int x, int y, string pieceName)        {            boardSquares[x, y].SetPiece(pieceName);        }        public bool HasConnector(int x, int y, string direction)        {            return boardSquares[x, y].HasConnector(direction);        }        public void RandomPiece(int x, int y)        {            boardSquares[x, y].SetPiece(GamePiece.PieceTypes[rand.Next(0,               GamePiece.MaxPlayablePieceIndex + 1)]);        }        public void FillFromAbove(int x, int y)        {            int rowLookup = y - 1;            while (rowLookup >= 0)            {                if (GetSquare(x, rowLookup) != "Empty")                {                    SetSquare(x, y,                      GetSquare(x, rowLookup));                    SetSquare(x, rowLookup, "Empty");                    rowLookup = -1;                }                rowLookup--;            }        }        public void GenerateNewPieces(bool dropSquares)        {            if (dropSquares)            {                for (int x = 0; x < GameBoard.GameBoardWidth; x++)                {                    for (int y = GameBoard.GameBoardHeight - 1; y >= 0; y--)                    {                        if (GetSquare(x, y) == "Empty")                        {                            FillFromAbove(x, y);                        }                    }                }            }            for (int y = 0; y < GameBoard.GameBoardHeight; y++)                for (int x = 0; x < GameBoard.GameBoardWidth; x++)                {                    if (GetSquare(x, y) == "Empty")                    {                        RandomPiece(x, y);                    }                }        }        public void ResetWater()        {            for (int y = 0; y < GameBoardHeight; y++)                for (int x = 0; x < GameBoardWidth; x++)                    boardSquares[x, y].RemoveSuffix("W");        }        public void FillPiece(int X, int Y)        {            boardSquares[X, Y].AddSuffix("W");        }        public void PropagateWater(int x, int y, string fromDirection)        {            if ((y >= 0) && (y < GameBoardHeight) &&                (x >= 0) && (x < GameBoardWidth))            {                if (boardSquares[x, y].HasConnector(fromDirection) &&                    !boardSquares[x, y].Suffix.Contains("W"))                {                    FillPiece(x, y);                    WaterTracker.Add(new Vector2(x, y));                    foreach (string end in                             boardSquares[x, y].GetOtherEnds(fromDirection))                        switch (end)                        {                            case "Left": PropagateWater(x - 1, y, "Right");                                break;                            case "Right": PropagateWater(x + 1, y, "Left");                                break;                            case "Top": PropagateWater(x, y - 1, "Bottom");                                break;                            case "Bottom": PropagateWater(x, y + 1, "Top");                                break;                        }                }            }        }        public List<Vector2> GetWaterChain(int y)        {            WaterTracker.Clear();            PropagateWater(0, y, "Left");            return WaterTracker;        }    }}


I have no clue how I am supposed to break all this stuff down and understand it. I have practically no clue what a Vector is, even though I looked it up on this site. I don't know how they came up with some of those numbers. I have never been good at math, so I don't know how I am supposed to manage this.
The book breaks each thing into sections, but still.
Many of the actual numbers in there are ass-pulls. Why a game board with of 8? Why not?

It sounds to me like you don't understand what you're doing at the most basic level.

Understanding a vector is easy if you understand what an array is.

Take an array, like:

int[] myArray = new int[5];


I have an array with five slots. I can edit them.

But can't resize the array. I can't just say "add this, add that, and this" arbitrarily without writing functions like this:

int currentIndex = 0;int[] myArray = new int[5];public void addAnInt(int i){ myArray[currentIndex] = i; currentIndex++;}


And if I used that function (addAnInt) too many times, it'd throw an ArrayIndexOutOfBounds exception because it overflowed.

And if it was written in a lower level language like C that doesn't keep track of such things, it'd just plain blow up in my face, or worse.

So a Vector does all that for me. It handles the resizing and everything, so I can do this:

Vector myVector = new Vector();myVector.add(someCrap); //I can call add as many times as I want,//It'll handle the gruntwork. I can also remove things from the//middle and there won't be gaps.


In other words, a vector is a kit that takes care of a bunch of tedious crap that has to be done, and that you'd be doing yourself manually if there were no such thing as vectors.

If you don't understand any of that, you've jumped into the deep end before learning to tread water.

Learn the basics; get a book on programming C# for beginners. One of the boring-looking O'Reilly books with an random-ass animal on the cover that talks about Winforms. Those are fantastic.

Then get into game kits.
I have "Sams Teach Yourself the C# Language in 21 Days"

Is that a good enough book?
"I have practically no clue what a Vector is, even though I looked it up on this site"

Vector2 gameBoardDisplayOrigin = new Vector2(70, 89);
i assume its this line that you are talking about?

Vector2 is simply an object that holds 2 numbers. they are usually used as coordinates on a graph (the screen) so this is storing the x and y coordinates for something called gameBoardDisplayOrigin. So when we try to draw the board its going to ask need to know where to draw it ... we are going to draw it at x coordinate 70 and y coordinate 89.
This is a simplified explanation there is more to it.

If you are struggling with c# i can help i am starting some small c# xna projects myself and wouldnt mind helping you at all. Im no guru but we should be able to make some small stuff to help you understand some of the concepts.

Send me a private message if you want to i have AIM (rarely use) Yahoo IM facebook just let me know.
"choices always were a problem for you......" Maynard James Keenan
A short bit of advise which might be easier said than done:

Don't try to memorize what they're telling you to write. Instead, try to learn why you're writing the code that they're telling you to.

You might know how to declare a variable or create a vector but if you don't know why you want to use one then you're not really learning anything.
The key to learning a language is not to learn the "api" or "framework" that it can us. Learn just the basic language.

For C# this is the list of keyword. Now there might be a new ones but this is a pretty good basic list.


abstract
as
base
bool
break
Byte
case
catch
char
checked
class
const
continue
decimal
default
delegate
do
double
else
enum
event
explicit
extern
false
finally
fixed
float
for
foreach
goto
if
implicit
in
int
interface
internal
is
lock
long
namespace
new
null
object
operator
out
override
params
private
protected
public
readonly
ref
return
sbyte
sealed
short
sizeof
stackalloc
static
string
struct
switch
this
throw
true
try
typeof
uint
ulong
unchecked
unsafe
ushort
using
virtual
volatile
void
while


So the first thing you need to do is understand those words, and how to use them to create classes and control the flow of the application.

After you learn that, then all the crazy things you see, Vector2 and the likes are just classes that you will be able to look at and understand how to use.

Learn to crawl before you try flying.

theTroll

This topic is closed to new replies.

Advertisement