I'm writing a game, and I created a class which inherits from PictureBox
class Mashrooms : System.Windows.Forms.PictureBox
{
public Mashrooms(int x, int y)
{
Name = "mush";
Location = new Point(x, y);
Enabled = true;
//Image = Image.FromFile("mushroom.png");
ImageLocation = #"mushroom.png";
Size = new Size(16,32);
}
}
In form1.Designer.cs I put
Mashrooms m = new Mashrooms (200,50);
this.Controls.Add(m);
Even though the game runs, picture is not displayed.
Related
I'm trying to create picturebox in class and add it to form with method, it doesn't have any errors but it doesn't display picturebox
Class:
class Igrac
{
public int ID;
public string Ime;
public int Polje;
public int Novac;
public Igrac(int id, string ime, int polje, int novac)
{
ID = id;
Ime = ime;
Polje = polje;
Novac = novac;
}
public void Pijun (int LocX,Image image, Form1 form)
{
PictureBox pijun = new PictureBox();
pijun.Size = new Size(20, 40);
pijun.Location = new Point(LocX,655);
pijun.Image = image;
form.Controls.Add(pijun);
}
}
Main program:
private void Form1_Load(object sender, EventArgs e)
{
Igrac igrac1 = new Igrac(1, ImeIgraca1, 0, 10000);
igrac1.Pijun(643, Properties.Resources.Pijun1,this);
}
I have pasted your code and its works fine, but check parameters in new Point(LocX, 655) contructor. If it is larger than form size, control will be outer window, because (0,0) point is on left upper corner.
It was overlapped by another control...
We would like to make a little drawing application and i don't know how to make a class derived from shape or uielement or something else that contains multiple objects like a line and text or multiple lines that are not connected.
How would i do that?
For an ellipse i have this:
public class B_Null : Shape
{
EllipseGeometry eg;
public double Breedte { get; private set; }
public B_Null()
{
Stroke = Brushes.Red;
StrokeThickness = 1;
Fill = Brushes.Red;
eg = new EllipseGeometry(new Point(100, 100), 100, 100);
Breedte = 200;
}
protected override Geometry DefiningGeometry
{
get
{
return eg;
}
}
}
The above works but it cannot handle multiple uielements?
(Or multiple lines that are not connected)
The goal is to have one class that contains multiple elements.
At the end i want to use this code: Canvas.SetTop(MyUiElement,...);
Thank you ver much for the information! I inherited my drawing objects from the Canvas and then add all my objects easily on a canvas.
public class B_Null : Canvas
{
private Ellipse Ellipse = new Ellipse();
public B_Null()
{
Ellipse.Width = 200;
Ellipse.Height = 200;
Ellipse.Stroke = Brushes.Red;
Ellipse.StrokeThickness = 1;
Ellipse.Fill = Brushes.Red;
this.Children.Add(Ellipse);
}
}
I have write a c# class, which contains graphics inside.
this is how I build the class and draw the rectangle. It works perfectly:
public Graphics shape;
public Rectangle rc;
// constructor
public CLASS_NAME(Graphics formGraphics)
{
this.shape = formGraphics;
}
public void draw(int x, int y, int w, int h)
{
SolidBrush myBrush = new SolidBrush(Color.Red);
this.rc = new Rectangle(x, y, w, h);
this.shape.FillRectangle(myBrush, rc);
myBrush.Dispose();
}
then I wanted to add a new method to the object in order to change the color, but when I call this nothing happens:
public void change_color()
{
SolidBrush myBrush = new SolidBrush(Color.Yellow);
this.shapeFillRectangle(myBrush, rc);
myBrush.Dispose();
}
I also tried: rc.Fill = but VS doesn't recognize rc.Fill as a valid method.
THE ERROR I GET IS: it says that in the change() method, this line: this.shapeFillRectangle(myBrush, rc); has a parameter that isn't valid.
OK, let's start with a 'drawRectangle' class. It has enough data to create a simple Pen, holds a Rectangle and also a reference to the Control it will draw on.
I have added a ToString override, so we can display it with all its properties in, say a ListBox..
version 1
public class DrawRectangle
{
public Color color { get; set; }
public float width { get; set; }
public Rectangle rect { get; set; }
public Control surface { get; set; }
public DrawRectangle(Rectangle r, Color c, float w, Control ct)
{
color = c;
width = w;
rect = r;
surface = ct;
}
public override string ToString()
{
return rect.ToString() + " (" + color.ToString() +
" - " + width.ToString("0.00") + ") on " + surface.Name;
}
}
Next we need a list of those rectangles:
public List<DrawRectangle> rectangles = new List<DrawRectangle>();
Now let's add them in a loop in a button click:
private void buttonAddLoop_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
rectangles.Add(new DrawRectangle(new Rectangle(i * 30, i * 30, 22, 22),
Color.Black, 3.5f, drawPanel1));
drawPanel1.Invalidate();
}
Note how I invalidate the control I want them painted on by Invalidating it! (You can use the Form as well, as Form inherits from Control..)
For this to work we need to code the Paint event of each control that needs to paint some of the rectangles; I use only a Panel drawPanel1:
private void drawPanel1_Paint(object sender, PaintEventArgs e)
{
foreach (DrawRectangle dr in rectangles)
{
if (dr.surface == sender)
{
using (Pen pen = new Pen(dr.color, dr.width))
e.Graphics.DrawRectangle(pen, dr.rect);
}
}
}
Now we can change any of our DrawRectangles, maybe in another button click:
private void buttonChangeButton_Click(object sender, EventArgs e)
{
rectangles[3].color = Color.Red;
rectangles[6].width = 7f;
drawPanel1.Invalidate();
}
Update:
The above class was a simple start to show how to encapsulate the things a 'Rectangle' class would need; it was not meant to be perfect!
Here is one flaw it has: It doesn't really care enough about the best way to spread responsibilities. It put the burdon of drawing the rectangles on the controls and if you have more complex drawing code and more controls each of them would have to learn the more complex code. This is not good. Instead the responsibility should stay with the Rectangle class. The control should only tell them to draw themselves..
Here is an updated class that will do just that. As a more complex drawing it will be able to draw filled rectangles as well..:
version 2
public class DrawRectangle
{
public Color color { get; set; }
public float width { get; set; }
public Color fillColor { get; set; }
public Rectangle rect { get; set; }
public Control surface { get; set; }
public DrawRectangle(Rectangle r, Color c, float w, Color fill, Control ct )
{
color = c;
width = w;
fillColor = fill;
rect = r;
surface = ct;
}
public DrawRectangle(Rectangle r, Color c, float w, Control ct)
: this. DrawRectangle(r, c, w, Color.Empty, ct) {}
public override string ToString()
{
return rect.ToString() + " (" + color.ToString() +
" - " + width.ToString("0.00") + ")";
}
public void Draw(Graphics g)
{
if (fillColor != Color.Empty)
using (SolidBrush brush = new SolidBrush(fillColor))
g.FillRectangle(brush, rect);
if (color != Color.Empty)
using (Pen pen = new Pen(color, width)) g.DrawRectangle(pen, rect);
}
}
It uses a second color to determine the filling. (I didn't add the fill color the the ToString method.) It compares the color with the special color values Color.Empty to determine what should and shouldn't be drawn.
The loop to create the new rectangles may now include the fill color. If it doesn't, the old constructor will be called, which now sets the fill color to Color.Empty.
Here is how simple the Paint event gets:
private void drawPanel1_Paint(object sender, PaintEventArgs e)
{
foreach (DrawRectangle dr in rectangles)
if (dr.surface == sender) dr.Draw(e.Graphics);
}
To fill some rectangle we can now write:
rectangles[2].fillColor = Color.Fuchsia;
Aside:
A note an color comparison: It is not obvious, but while the color Color.Empty really is just 'transparent black' (0,0,0,0), color comparison is special: NamedColors as well as KnownColors, including Color.Empty always compare false to normal colors. To make a true color comparison one would have to cast to a 'normal' Color:
bool ok=Color.FromArgb(255,255,255,255) == Color.White; // false
bool ok=Color.FromArgb(255,255,255 255) == Color.FromArgb(Color.White.ToArgb()); // true
Therefore the comparison in the Draw code is safe.
I am working on some school work and I am wondering if you could solve this.
I got my form.cs code and my class apple.cs(some snake fruit generation)
I choosed that my apple is being randomly spawned accros the form width/height, but when I resize that form, It keeps to spawn within old "borders" of the form.
Can I reload it somehow?
class Apple {
Random nc = new Random();
Form1 hl;
//Properties
public Color Color { get; set; }
public Size Size { get; set; }
public Point Pt { get; set; }
//constructors
public Apple()
{
hl = new Form1();
int s = 10;
this.Color = Color.Red;
this.Size = new Size(s,s);
this.Pt = new Point(nc.Next(s,hl.panel1.Width-(2*s-1)),nc.Next(s,hl.panel1.Height-(2*s-1)));
}
//methods
public void drawOutPoint(Graphics kp)
{
kp.FillRectangle(new SolidBrush(Color), new Rectangle(Bod, Size));
}
}
Thank you very much!
or you can try this
public Apple(double width,double height)
{
\\your code and assign the values
}
and in the form you define the object
apple ap=new applw(this.width,this.height);
let the apple get the width and high from the form using
double width= this.width;
and the same for high
I'm looking for a possibiltiy to shape my program in a better way and would like to exploit the object-oriented approach more effectively.
public ScrollingBackground(int width, int height, int speed, string title, Bitmap path)
{
intBreite = width;
intHoehe = height;
intFeinheitDerBewegungen = speed;
stringTitel = title;
bitmapBildpfad = path;
this.Text = title;
this.Size = new Size(this.intBreite, this.intHoehe);
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
timerBewegungImage = new Timer();
timerBewegungImage.Tick += new EventHandler(bewegungImage_XRichtung_Tick);
timerBewegungImage.Interval = constIntInterval;
timerBewegungImage.Start();
////
picBoxImage = new PictureBox();
picBoxImage.Image = global::Flugzeugspiel.Properties.Resources.MyFlugzeug;
picBoxImage.BackColor = Color.Transparent;
picBoxImage.SetBounds(100, 100, 125, 50);
this.Controls.Add(picBoxImage);
////
listPicBoxAufeinanderfolgendeImages = new PictureBox[2];
imageInWinFormLadenBeginn();
this.ShowDialog();
}
As you can see the constructor above that the code enclosed by the slashes is located in the constructor ScrollingBackground.
It is important for me that this contructor should contain code only relating to the Scrolling Background but not the image MyFlugzeug.png.
This image (of course the whole code enclosed by the slashes) should be swapped into my main class Flugzeug.
using System;
using System.Drawing;
using System.Windows.Forms;
public abstract class Flugzeug : Form
{
private PictureBox picBoxImage;
protected int lebensanzeige = 10;
public virtual void nachObenUntenFliegen(string pathOfMovingObject, int xPositionObject, int yPositionObject, int widthOfObject, int heightOfObject)
{
// The code in the upper constructor enclosed by the slashes should stand here. Here I'd like to ensure the control of the airplane which has to be still programmed.
}
public int getLebensanzeige()
{
return lebensanzeige;
}
public int getTreffer(int schussstaerke)
{
return lebensanzeige = lebensanzeige - schussstaerke;
}
}
How is it possible to transfer the code from the constructor to the class Flugzeug?
I've tried something but it didn't work.
I've tried sth. like this:
public class MyFlugzeugspiel
{
public static void Main()
{
MyFlugzeug myPlane = new MyFlugzeug(10);
ScrollingBackground hintergrund = new ScrollingBackground(1000, 650, 5, "THE FLIGHTER", global::Flugzeugspiel.Properties.Resources.Himmel, myPlane);
...
public abstract class Flugzeug : Form
{
private PictureBox picBoxImage;
protected int lebensanzeige = 10;
public virtual void nachObenUntenFliegen(string pathOfMovingObject, int xPositionObject, int yPositionObject, int widthOfObject, int heightOfObject)
{
picBoxImage = new PictureBox();
picBoxImage.Image = global::Flugzeugspiel.Properties.Resources.MyFlugzeug;
picBoxImage.BackColor = Color.Transparent;
picBoxImage.SetBounds(100, 100, 125, 50);
this.Controls.Add(picBoxImage);
}
...
public ScrollingBackground(int width, int height, int speed, string title, Bitmap path, Flugzeug plane)
{
intBreite = width;
intHoehe = height;
intFeinheitDerBewegungen = speed;
stringTitel = title;
bitmapBildpfad = path;
this.plane = plane;
plane.nachObenUntenFliegen("Path", 0, 0, 100, 100);
this.Text = title;
this.Size = new Size(this.intBreite, this.intHoehe);
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
...
But this isn't right, is it? Nothing happens. The airplane won't appear on the Scrolling Background.
Who can help me solving this problem?
You could make a Control or Form out of your ScrollingBackground class, and derive from it (or use it as control) in your Flugzeug form.
If you think deriving is the best option, your class signature should look like this:
public class ScrollingBackground : Form { }
public class Flugzeug : ScrollingBackground { }
If you like a control better, you should expose the required properties from the ScrollingBackground class, so you can access them in your Flugzeug class.