Hi
I want to keep up a score in the game.
I have this:
[code]
public int Score { get; private set; }
public Invader(Type invaderType, Point location, int score)
{
//this.image = StarInvader2.Properties.Resources.bug1;
this.InvaderType = invaderType;
this.Location = location;
this.Score = score;
this.Score = GameConstants.BugScore;
this.Score = GameConstants.SatelliteScore;
this.Score = GameConstants.SaucerScore;
this.Score = GameConstants.SpaceshipScore;
this.Score = GameConstants.StarScore;
//image = InvaderImageBlock(0);
//SetupImage();
//InvaderImage();
//this.image = InvaderImageBlock[(int)invaderType][0]; //Object is null.
this.image = InvaderImage(0);
}//End constructor.
[/code]
And this are the constants:
[code]
//Invader scores
public const int BugScore = 25;
public const int SaucerScore = 20;
public const int SatelliteScore = 15;
public const int SpaceshipScore = 10;
public const int StarScore = 5;
[/code]
And I have this in the class Game:
[code]
public void gameScore(Graphics g)
{
Font drawfont = new Font("Arial", 16);
g.DrawString(score.ToString(), drawfont, Brushes.White, 10f, 15f);
}
[/code]
I see a white zere in the upper left corner. But If I shoot an invader out of the sky the counter doesn't count.
Thx for helping me.
Loading
albert albertPosted Mar 28, 2011, 5:38 AM
Game class:
[code]
private void InvaderRow(Type invaderType,int Score, int startX, int startY)
{
int currentX = startX;
//int currentY = startY;
for (int i = 0; i < GameConstants.InvadersPerRow; i++)
{
//Create new invader
Point invaderLocation = new Point(currentX, startY);
Invader newInvader = new Invader( invaderType ,/* Type.Bug,*/ invaderLocation, score);
//Add it into our list
invaders.Add(newInvader); //Add eatch invader to the row
currentX += GameConstants.HorizontalInterval;
//currentY += GameConstants.VerticalInterval;
}
}//End method
private void InitialPopulateInvaders()
{
int left = GameConstants.InitialLeft;
int fromTop = GameConstants.InvaderVertSpacing;
InvaderRow(Type.Bug,GameConstants.BugScore, left, fromTop);//First row of invader are type:Bug.
fromTop += GameConstants.InvaderVertSpacing;
InvaderRow(Type.Saucer,GameConstants.SaucerScore, left, fromTop);
fromTop += GameConstants.InvaderVertSpacing;
InvaderRow(Type.satelite,GameConstants.SatelliteScore, left, fromTop);
fromTop += GameConstants.InvaderVertSpacing;
InvaderRow(Type.Spaceship,GameConstants.SpaceshipScore, left, fromTop);
fromTop += GameConstants.InvaderVertSpacing;
InvaderRow(Type.star,GameConstants.StarScore, left, fromTop);
fromTop += GameConstants.InvaderVertSpacing;
}//End method
[/code]
and for the GameScore:
[code]
public void gameScore(Graphics g, Invader invader)
{
Font drawfont = new Font("Arial", 16);
g.DrawString(invader.Score.ToString(), drawfont, Brushes.White, 10f, 15f);
}
[/code]
[code]
public void StartGame()
{
// SetupStartScreen(g);
this.playerShip = new PlayerShip(new Point(boundaries.Width / 2, boundaries.Height - 45));
//invader.SetupImage();
InitialPopulateInvaders();
UpdateInvaderCell(animationCell);
AnimateObject();
//MoveInvaders();
// MoveInvaderReal();
//invaders.Clear();
playerShots.Clear();
invaderShots.Clear();
this.score = 0;
this.wave = 0;
}
[/code]
Still no changing in score :(
albert albertPosted Mar 28, 2011, 4:21 AM
the reason is that the score is in Game is that because not only the invaders use the score also the starship.
But oke. I have now put the call for the score method temporarily in the Invader class, like this:
[code]
public void Draw(Graphics g, int animationCell)
{
g.DrawImage(this.image, this.Location);
Font drawfont = new Font("Arial", 16);
g.DrawString(this.Score.ToString(), drawfont, Brushes.White, 10f, 15f);
}//End method
[/code]
and the consturctor:
[code]
public Invader(Type invaderType, Point location, int score)
{
//this.image = StarInvader2.Properties.Resources.bug1;
this.InvaderType = invaderType;
this.Location = location;
//this.Score = score;
this.image = InvaderImage(0);
//ScoreInvader(Score);
//gameScore(g);
}//End constructor.
[/code]
But the score is counting back!! and not up. If I shoot all the invaders out of the sky the score dissapear.
VulpesPosted Mar 27, 2011, 7:17 PM
As the project is becoming quite convoluted, it might be a good time to review the whole thing from scratch and see if you can do anything to simplify the logic. The way the score is kept certainly needs looking at.
albert albertPosted Mar 27, 2011, 6:44 PM
in this piece of code the invaders are shooting down:
[code]
private void ReturnFire()
{
if (invaderShots.Count > wave + 1)
return;
bool playershipDead = false;
var InvaderFire = from invader in invaders
//where invader.Location.Y //+ invader.image.Width / 2 + invader.image.Height / 2
//where invader.Location.X > boundaries.Right //- 500
//orderby invader.Location.Y descending
//select invaderGroup;
group invader by invader.Location.Y into invaderGroup
select invaderGroup; //KeyValuePair.Of
//select new { Value = invaderGroup.Key};
foreach( var invaderColumn in InvaderFire )
{
var q = from invader in invaderColumn
orderby invader.Location.Y descending
select invader;
Invader invaderB = q.First();
if (random.Next(14) < 9 - wave)
{
Point shotPoint = new Point((invaderB.Location.X + invaderB.image.Width / 2 - 2),
(invaderB.Location.Y + invaderB.image.Height));
invaderShots.Add(new Shot(shotPoint, Direction.Down, this.boundaries));
}
//return playershipDead;
}
}//End met
[/code]
But still it doesnt work so good. But that can be later.
I think if counting for invader workst oke then after we can build for invader shooting back on the space ship.
But u are ofcourse right that the in the beginning the score has to be zero.
VulpesPosted Mar 27, 2011, 6:34 PM
albert albertPosted Mar 27, 2011, 6:21 PM
Because there is always for example an: Type.Bug. and an Type.star.
albert albertPosted Mar 27, 2011, 6:02 PM
the problem is if I put this:
[code]
public Invader(Type invaderType, Point location, int score)
{
//this.image = StarInvader2.Properties.Resources.bug1;
this.InvaderType = invaderType;
this.Location = location;
this.Score = score;
this.image = InvaderImage(0);
ScoreInvader(Score);
//gameScore(g);
}//End constructor.
[/code]
then if I run(F5) then already the method scoreInvader activate.
I put a breakpoint for example at this line:
case Type.satelite:
Score += GameConstants.SatelliteScore;
break;
And the compiler stops there before I shut.
VulpesPosted Mar 27, 2011, 5:48 PM
albert albertPosted Mar 27, 2011, 4:40 PM
VulpesPosted Mar 27, 2011, 4:30 PM
I thought it must be within shot.Draw() but evidently it isn't.
albert albertPosted Mar 27, 2011, 4:14 PM
I have done it exactly like u:
[code]
public void Draw(Graphics g, bool gameOver /*int animationCell*/ )
{
stars.Draw(g,boundaries);//Draws the stars on the form
if (!gameOver)
{
playerShip.Draw(g);//Draws the player on the form
foreach (Invader invader in invaders)
{
invader.Draw(g, animationCell);
//gameScore(g, invader);
}
foreach (Shot shot in playerShots)
shot.Draw(g);
foreach (Shot shot in invaderShots)
shot.Draw(g);
foreach (Invader invader in invaders)
{
gameScore(g, invader);
}
//invader.gameScore(g);
}
else
SetupStartScreen(g);
// form1.Invalidate();//To redraw part of the form that is "dirty".The Refresh() method is: Invalidate() + Update().
}//End method
[/code]
But still no change in the score.
VulpesPosted Mar 27, 2011, 4:06 PM
if (!gameOver)
{
playerShip.Draw(g);//Draws the player on the form
foreach (Invader invader in invaders)
{
invader.Draw(g, animationCell); //Draws every invader on the form
}
foreach (Shot shot in playerShots)
shot.Draw(g);
foreach (Shot shot in invaderShots)
shot.Draw(g);
foreach((Invader invader in invaders)
{
gameScore(g, invader);
}
}
albert albertPosted Mar 27, 2011, 3:53 PM
I have now this:
[code]
public void Draw(Graphics g, bool gameOver /*int animationCell*/ )
{
stars.Draw(g,boundaries);//Draws the stars on the form
if (!gameOver)
{
playerShip.Draw(g);//Draws the player on the form
foreach (Invader invader in invaders)
{
invader.Draw(g, animationCell); //Draws every invader on the form
}
foreach(Invader invader in invaders)
{
gameScore(g, invader);
}
foreach (Shot shot in playerShots)
shot.Draw(g);
foreach (Shot shot in invaderShots)
shot.Draw(g);
//invader.gameScore(g);
}
else
SetupStartScreen(g);
// form1.Invalidate();//To redraw part of the form that is "dirty".The Refresh() method is: Invalidate() + Update().
}//End method
[/code]
and for the other method:
[code]
public void gameScore(Graphics g, Invader invader)
{
Font drawfont = new Font("Arial", 16);
g.DrawString(invader.Score.ToString(), drawfont, Brushes.White, 10f, 15f);
}
[/code]
and for score:
[code]
public int ScoreInvader(int Score)
{
switch(InvaderType)
{
case Type.Bug:
//case Type.Bug:
Score += GameConstants.BugScore;
break;
case Type.satelite:
Score += GameConstants.SatelliteScore;
break;
case Type.Saucer:
Score += GameConstants.SaucerScore;
break;
case Type.Spaceship:
Score += GameConstants.SpaceshipScore;
break;
case Type.star:
Score += GameConstants.StarScore;
break;
default:
break;
}
this.Score += Score;
return Score;
}//End method
[/code]
it compiles fine, but the score is not changing if I shoot an invader out of the sky. :(
VulpesPosted Mar 27, 2011, 3:41 PM
gameScore(g);
within a foreach() loop. The following should work:
foreach((Invader invader in invaders)
{
this.invader = invader;
gameScore(g);
}
though it would be tidier to change the gameScore method so that it takes an additional Invader parameter:
foreach((Invader invader in invaders)
{
gameScore(g, invader);
}
public void gameScore(Graphics g, Invader invader) // extra parameter
{
Font drawfont = new Font("Arial", 16);
g.DrawString(invader.Score.ToString(), drawfont, Brushes.White, 10f, 15f); // now uses parameter instead of field
}
albert albertPosted Mar 27, 2011, 3:12 PM
I give u more information.
But to make a new Invader class is not good I think. And not necessary I think.
This is part of my Game class:
[code]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace StarInvader2
{
public class Game
{
public const int InvadersRow = 1;//Shows the rows of invaders.
Form1 form1;
Invader invader;
public int score = 0;
private int livesLeft = 2;
private int wave;
private int framesSkipped = 0;
private Rectangle boundaries;
private Random random;
private Bitmap[] starAnimation;
private Bitmap[] bugAnimation;
private Bitmap[] saucerAnimation;
private Bitmap[] sateliteAnimation;
private Bitmap shipAnimation;
private DateTime lastFireTime;
public Boolean beenHit = false;
private long TimerCounter = 1;
private int TheSpeed = 4;
private Direction direction = Direction.Right;
int vertPos;
private Type invaderType;
private Stars stars;
private PlayerShip playerShip;
private Point Location;
private Shot shot;
public List
//private Direction invaderDirection;
private List
Graphics g;
private int shotNumber;
private List
private List
private List
private DateTime? GameOverTime = null;
protected Rectangle MovingBounds = new Rectangle();
public event EventHandler GameOver;
public Game(Rectangle boundaries /*,Invader invader*/ )
{
this.boundaries = boundaries;
random = new Random();
this.stars = new Stars(boundaries);
this.playerShip = new PlayerShip(new Point(boundaries.Width / 2, boundaries.Height - 45));
//this.shot = new Shot(Location,direction, boundaries);
lastFireTime = DateTime.Now;
invaderShots = new List
//Invader invader = new Invader(invaderType,Location, score);
this.score = score;
}
public void StartGame()
{
// SetupStartScreen(g);
this.playerShip = new PlayerShip(new Point(boundaries.Width / 2, boundaries.Height - 45));
//invader.SetupImage();
InitialPopulateInvaders();
UpdateInvaderCell(animationCell);
AnimateObject();
//MoveInvaders();
// MoveInvaderReal();
//invaders.Clear();
playerShots.Clear();
invaderShots.Clear();
this.score = 0;
this.wave = 0;
}
public void Go()
{
bool gameOverFlag = false;
MoveInvaderReal();
MoveInvaders(); //Moves the invaders!!yoe hoe!!
CheckForInvaderCollision();
CheckInvaderHitsBottum();
//Moveshot(playerShots);
MoveAllShots(playerShots);
MoveAllShots(invaderShots);
// UpdateFireshotPlayer();
ReturnFire();
NextWafe();
//invader.SetupImage();
//AnimateObject();
//InitialPopulateInvaders();
if (gameOverFlag)
OnGameOver();
}//End method
public void Draw(Graphics g, bool gameOver /*int animationCell*/ )
{
stars.Draw(g,boundaries);//Draws the stars on the form
if (!gameOver)
{
playerShip.Draw(g);//Draws the player on the form
foreach (Invader invader in invaders)
invader.Draw(g, animationCell); //Draws every invader on the form
foreach (Shot shot in playerShots)
shot.Draw(g);
foreach (Shot shot in invaderShots)
shot.Draw(g);
//invader.gameScore(g);
gameScore(g);
}
else
SetupStartScreen(g);
// form1.Invalidate();//To redraw part of the form that is "dirty".The Refresh() method is: Invalidate() + Update().
}//End method
[/code]
That is why I am little bit stuck here.
Do u have any other suggestions.
VulpesPosted Mar 27, 2011, 3:08 PM
So, I imagine 'invader' must be a field or property of the Game Class which holds a reference to an Invader object.
The error suggests you haven't new'ed this anywhere and so it's still null.
I can't really tell you any more than that just now.
albert albertPosted Mar 27, 2011, 2:39 PM
I understand that class game has to get the property Score in Class Invader.
But then it would thus like this:
Class: Game:
public void gameScore(Graphics g)
{
Font drawfont = new Font("Arial", 16);
g.DrawString(this.invader.Score.ToString(), drawfont, Brushes.White, 10f, 15f);
}
But then I get this error:
Object reference not set to an instance of an object.
VulpesPosted Mar 27, 2011, 2:13 PM
public int ScoreInvader(int Score)
{
switch(InvaderType)
{
case Type.Bug:
//case Type.Bug:
Score += GameConstants.BugScore;
break;
case Type.satelite:
Score += GameConstants.SatelliteScore;
break;
case Type.Saucer:
Score += GameConstants.SaucerScore;
break;
case Type.Spaceship:
Score += GameConstants.SpaceshipScore;
break;
case Type.star:
Score += GameConstants.StarScore;
break;
default:
break;
}
this.Score += Score; // EDIT: Probably +=
return Score;
}//End method
Then, to draw the current score, you'll need:
g.DrawString(this.Score.ToString(), drawfont, Brushes.White, 10f, 15f);
albert albertPosted Mar 27, 2011, 1:56 PM
I have now this:
[code]
public int ScoreInvader(int Score)
{
switch(InvaderType)
{
case Type.Bug:
//case Type.Bug:
Score += GameConstants.BugScore;
break;
case Type.satelite:
Score += GameConstants.SatelliteScore;
break;
case Type.Saucer:
Score += GameConstants.SaucerScore;
break;
case Type.Spaceship:
Score += GameConstants.SpaceshipScore;
break;
case Type.star:
Score += GameConstants.StarScore;
break;
default:
break;
}
return Score;
}//End method
[/code]
But the score doesn't change.
What I forgot?
Thx for helping anyway.
albert albertPosted Mar 27, 2011, 1:29 PM
yes, I was already little bit bussy with a switch. Like this:
[code]
public int ScoreInvader(int Score)
{
switch (Score)
{
case Type.Bug:
Score += GameConstants.BugScore;
break;
case Type.satelite:
Score += GameConstants.SatelliteScore;
break;
default:
break;
}
return Score;
}//End method
[/code]
VulpesPosted Mar 27, 2011, 1:23 PM
this.Score = score;
this.Score = GameConstants.BugScore;
this.Score = GameConstants.SatelliteScore;
this.Score = GameConstants.SaucerScore;
this.Score = GameConstants.SpaceshipScore;
this.Score = GameConstants.StarScore;
The last 5 lines need to be replaced by a switch statement which increments this.Score (doesn't overwrite it) with the points for the invader type.
You then need to assign the final score back to your 'score' variable:
score = this.Score;
which is the one you're using to print out the score in this line:
g.DrawString(score.ToString(), drawfont, Brushes.White, 10f, 15f);
Perhaps in this last line, you should be using this.Score rather than 'score' as that was just a method parameter?