I am trying to make a program so that a red block falls from the top of the screen and the player has to avoid it. When I run the program I can see and move the player(paddle) but I can't see the enemy or "thing" sprite. Please help me because I have tried everything with the code and it still doesn't work :/
things.h
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
using namespace std;
#pragma once
class Thing
{
public:
void thingspawn(RenderWindow &gameDisplay, int &enemystartx, int &enemystarty, int &enemywidth, int &enemyheight, int &blockcolor)
{
RectangleShape thing(Vector2f(enemywidth, enemyheight));
thing.setFillColor(Color(blockcolor));
thing.setPosition(enemystartx, enemystarty);
gameDisplay.clear();
gameDisplay.draw(thing);
}
};
main.cpp
#include <iostream>
#include <SFML/Graphics.hpp>
#include "things.h"
using namespace std;
using namespace sf;
int main()
{
RenderWindow gameDisplay(VideoMode(1366, 768), "Game", Style::Fullscreen);
gameDisplay.setMouseCursorVisible(false);
gameDisplay.clear();
int enemystarty = -200;
int enemystartx = 300;
int enemyheight = 100;
int enemywidth = 100;
int enemyspeed = 0.3f;
int enemycount = 1;
int dodged = 0;
int blockcolor = (255, 0, 0);
RectangleShape player(Vector2f(300, 30));
player.setFillColor(Color(0, 0, 255));
player.setPosition(400, 728);
while (gameDisplay.isOpen())
{
Event evnt;
while (gameDisplay.pollEvent(evnt))
{
switch (evnt.type)
{
case Event::Closed:
gameDisplay.close();
case Event::KeyPressed:
if (Keyboard::isKeyPressed(Keyboard::Q))
gameDisplay.close();
}
}
if (Keyboard::isKeyPressed(Keyboard::Right))
if (player.getPosition().x < 1000)
player.move(0.2f, 0.0f);
if (Keyboard::isKeyPressed(Keyboard::Left))
if (player.getPosition().x > 50)
player.move(-0.2f, 0.0f);
Thing thingobject;
thingobject.thingspawn(gameDisplay, enemystartx, enemystarty, enemywidth, enemyheight, blockcolor);
enemystarty += enemyspeed;
gameDisplay.draw(player);
gameDisplay.display();
}
}
The problem is that you create RectangleShape thing in function Thing::thingspawn(...) and it is destroyed after it ends.
Try to put declaration of it as member of the Thing class
The thing is rendering correctly but in just a bad habit way. like what capi1500 said,
But the real problem is that int blockcolor = (255, 0, 0); results a black color when you pass it to the sf::Color. you wont see a black drawing in a black canvas right?
You can see here on how to construct a color from an integer: How to pack ARGB to one integer uniquely?
for now change the color of the thing using the predefined colors of sf::Color like sf::Color::Green or pass each component using the another constructor Color (Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha=255)
SFML's sf::Color's documentation: http://www.sfml-dev.org/documentation/2.4.2/classsf_1_1Color.php
Related
Sorry for the massive block of code ;w;
I'm learning C++, and this is an assignment I'm stuck on- I'm supposed to be making a brick wall with alternating rows offset by 1/2 bricks, and I'm supposed to be using a nested loop to do so.
I've got the functions to draw the full brick and half bricks, and I've successfully been able to create a full line of 9 bricks(9 being how many bricks can span the window) and I'm stuck on the next step. I need to make the program draw the next line after the first one is finished, but "\n" and "cout << endl;" only affect the main window and not the "TurtleWindow" that OpenCV opens. All I have in that regard is that it has something to do with the "changePosition" command, but I'm not sure how to add that in to my loop. If I set position to some specific (x, y) coords, then wouldn't it just keep setting the "bricks" in that position every loop?
Any help would be appreciated, I feel like I'm so close to the solution but this is stumping me...
// BrickWall.cpp : This file contains the 'main' function. Program execution begins
//and ends there.
//
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>
#include <math.h>
using namespace cv;
using namespace std;
#define M_PI 3.14159265358979323846264338327950288
#define degToRad(angleInDegrees) ((angleInDegrees) * M_PI / 180.0)
char wndname[] = "TurtleWindow";
Mat image = Mat::zeros(500, 500, CV_8UC3);
Scalar WHITE(255, 255, 255);
const int DELAY = 1;
Point _curPosition(250, 250);
int _direction = 0;
void init()
{
imshow(wndname, image);
waitKey(DELAY);
}
//
// Move the pen to the given coordinates without leaving a mark
//
// Note (0,0) refers to the upper left corner
// (500,500) refers to the bottom right corner
//
void changePosition(int x, int y)
{
_curPosition.x = x;
_curPosition.y = y;
}
//
// point in the direction given in degrees
// 0 ==> point right
// 90 ==> point down
// 180 ==> point left
// 270 ==> point up
//
void changeDirection(int direction)
{
_direction = direction;
}
//
// Moves the pen forward the given number of pixels
// Note leaves a mark creating a line from the previous point
// to the new point
//
void moveForward(int nPixels)
{
int x = static_cast<int>(round(nPixels * cos(degToRad(_direction))));
int y = static_cast<int>(round(nPixels * sin(degToRad(_direction))));
Point newPoint = Point(x + _curPosition.x, y + _curPosition.y);
line(image, _curPosition, newPoint, WHITE);
_curPosition = newPoint;
// cout << "moved to " << newPoint.x << "," << newPoint.y << endl;
imshow(wndname, image);
waitKey(DELAY);
}
void fullBrick()
// changePosition(25, 25);
{
changeDirection(0);
moveForward(50);
changeDirection(90);
moveForward(20);
changeDirection(180);
moveForward(50);
changeDirection(270);
moveForward(20);
changeDirection(0);
moveForward(50);
}
void halfBrick()
//changePosition(25, 45);
{
changeDirection(0);
moveForward(25);
changeDirection(90);
moveForward(20);
changeDirection(180);
moveForward(25);
changeDirection(270);
moveForward(20);
}
int main()
{
int counter;
int counterWall;
counterWall = 0;
counter = 0;
init();
changePosition(25, 25);
while (counter < 20)
{
do
{
changeDirection(0);
moveForward(50);
changeDirection(90);
moveForward(20);
changeDirection(180);
moveForward(50);
changeDirection(270);
moveForward(20);
changeDirection(0);
moveForward(50);
counterWall++;
} while (counterWall < 9);
counter++;
}
waitKey();
}
edit: thanks everyone for the advice! I was fully intending to use a nested loop in the end(and did use one, so no lost points there!) and was able to realize there was nothing stopping me from looping the bricks like a snake. I had to turn the assignment in before I could try any of the changes you guys offered, but I'll be sure to keep them in mind for future assignments!
and here's a link to the picture of the final product, I've never been happier to see a brick wall in my life
Brick Wall Picture
When using class ?
This question is probably evident for you but i know and learned how to create class and how it's working but i don't know when using it.
I think i can cut my program with class but i don't know when i must do it.
I would like to share my code but i can't paste it completely in the topic post.
Include
#include <SFML/Graphics.hpp>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
Constantes
//Constantes ecran
int tailleEcranX = 1280;
int tailleEcranY = 720;
//Constantes perso
int scalePerso = 3;
int tailleSpriteX = 32;
int tailleSpriteY = 48;
int speed(4);
int speedSprinte(20);
int milieuSpriteX = (tailleSpriteX/2)*scalePerso;
int milieuSpriteY = (tailleSpriteY/2)*scalePerso;
int pv = 100;
unsigned int pvMax = 100;
Initialisation
//Initiation des dessins
sf::RenderWindow window;
sf::RectangleShape rect;
sf::Texture perso;
sf::Sprite sprite_perso;
sf::View view;
sf::RectangleShape rectCol;
sf::RectangleShape pvBar;
sf::RectangleShape pvMaxBar;
enum Dir{Down,Left,Right,Up};
sf::Vector2i anim (1,Down);
#include "gestion_clavier.h"
Main
int main()
{
//{ Positionnement des objets
window.create(sf::VideoMode(tailleEcranX , tailleEcranY), "The Game I");
window.setPosition(sf::Vector2i(500,250));
window.setFramerateLimit(60);
rect.setFillColor(sf::Color(255,0,0));
rect.setSize(sf::Vector2f(tailleEcranX-10,tailleEcranY-10));
rect.setPosition(5,5);
rect.setOutlineColor(sf::Color(255,255,255));
rect.setOutlineThickness(3);
rectCol.setFillColor(sf::Color(0,0,200));
rectCol.setSize(sf::Vector2f(50,50));
rectCol.setPosition(400,500);
rectCol.setOutlineColor(sf::Color(255,255,255));
rectCol.setOutlineThickness(1);
sf::Clock time;
//}
//{Chargement des Sprites
if (!perso.loadFromFile("link/srpite.png",sf::IntRect(0,0,96,192)))
{
std::cout<<"erreur chargement player image"<<std::endl;
}
sprite_perso.setTexture(perso);
sprite_perso.setPosition(tailleEcranX/2-milieuSpriteX,tailleEcranY/2-milieuSpriteY);
//}
//{ Game Loop
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
ProcessInput();
//gestion_clavier();
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Z)||sf::Keyboard::isKeyPressed(sf::Keyboard::S)||sf::Keyboard::isKeyPressed(sf::Keyboard::D)||sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
{
if (time.getElapsedTime().asMilliseconds()>= 50)
{
anim.x++;
if(anim.x*tailleSpriteX >= perso.getSize().x)
anim.x=0;
time.restart();
}
}
sprite_perso.setTextureRect(sf::IntRect(anim.x*tailleSpriteX,anim.y*tailleSpriteY,tailleSpriteX,tailleSpriteY));
sprite_perso.setScale(scalePerso,scalePerso);
pvBar.setFillColor(sf::Color(20,255,30));
pvBar.setSize(sf::Vector2f(4*pv,10));
pvBar.setPosition(20,20);
pvMaxBar.setFillColor(sf::Color(0,0,0));
pvMaxBar.setSize(sf::Vector2f(4*pvMax,10));
pvMaxBar.setPosition(20,20);
pvMaxBar.setOutlineColor(sf::Color(255,255,255));
pvMaxBar.setOutlineThickness(2);
if(pv>=pvMax)
{
pv=pvMax;
}
if(pv<=0)
{
pv=0;
}
if(
(std::abs((sprite_perso.getPosition().x+milieuSpriteX)-(rectCol.getPosition().x+50/2))<50)
&&
(std::abs((sprite_perso.getPosition().y+milieuSpriteY)-(rectCol.getPosition().y+50/2))<50)
)
{
std::cout<<"collision"<<std::endl;
pv--;
std::cout<<pv<<std::endl;
}
//Dessinage
window.draw(rect);
window.draw(rectCol);
window.draw(sprite_perso);
window.draw(pvMaxBar);
window.draw(pvBar);
window.display();
window.clear();
}
//}
return 0;
}
//}
I struggled to understand a lot of your code, since the variables seem to be written in french, but I can give you some general advice.
When deciding when to use a class, you should first think about the contents of your program in terms of objects. For example: if there is a character/person, or something you would consider an independent object in the real world, there's a reasonable chance that should be its own class. The class should contain whatever is needed to describe the object, like it's position, scale, sprite, etc. Here's an example:
class Person
{
private:
sf::Vector2f position;
sf::Sprite sprite;
public:
void setPosition(sf::Vector2f newPosition);
sf::Vector2f getPosition();
void draw(sf::RenderWindow& window);
}
If you want your class to have position and such, I recommend deriving from the sf::Transformable class to save you some time and effort. You can also derive from sf::Drawable if you want to draw your object using window.draw(person) like many of the default SFML objects can.
class Person : public sf::Transformable, public sf::Drawable
{
private:
sf::Sprite sprite;
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= getTransform();
target.draw(sprite, states);
}
}
You have a number of variables you say are constants. If that is the case, then it's considered good practice to mark them as such using const. For example:
const int scalePerso = 3;
This stops you from changing the value in the future and causing bugs you need to track down.
I also noticed you are defining seperate variables for X and Y positions. This is unnecessary, since SFML defines the sf::Vector2 type. For example:
const sf::Vector2f tailleSpritePosition(32.f, 48.f);
instead of
int tailleSpriteX = 32;
int tailleSpriteY = 48;
You're also mixing types quite a bit by passing integers into functions that accept float values. This is also considered bad practice. If you want to change an integer into a float, you should explicitly cast it using (float) like so:
rect.setSize(sf::Vector2f((float)tailleEcranX - 10.f, (float)tailleEcranY - 10.f));
making sure to add the letter f to the end of your literals to tell the compiler those are floating point values too. Alternatively, you could just define your variables to be of type float to start off with in some cases.
Feel free to ask if there is anything you don't understand.
I have a struct "Layer" and class "LayerHandler". Layer consists only a texture, sprite and two constructors - one default and one with a reference parameter. LayerHandler class is a class that handles the drawing of all the layers we have. I add layers to this class and later I use win.draw(layerhandler_object) to draw everything. LayerHandler inherits from Drawable to do so and it overrides virtual void draw().
LayerHandler.h:
#ifndef LAYERHANDLER_H
#define LAYERHANDLER_H
#include <vector>
#include <SFML\Graphics.hpp>
using namespace std;
using namespace sf;
struct Layer {
Texture tex;
Sprite spr;
Layer() { }
Layer(Layer& l) {
tex = l.tex;
spr = l.spr;
}
};
class LayerHandler : public Drawable {
private:
vector<Layer*> layers;
virtual void draw(RenderTarget& target, RenderStates states) const {
for (int i=0; i<layers.size(); i++)
target.draw(layers[i]->spr, states);
}
public:
LayerHandler();
~LayerHandler();
void Add(Layer& layer);
};
#endif
LayerHandler.cpp:
#include "LayerHandler.h"
LayerHandler::LayerHandler() {
}
LayerHandler::~LayerHandler() {
}
void LayerHandler::Add(Layer& layer) {
layers.push_back(new Layer(layer));
}
and main.cpp:
#include <iostream>
#include <SFML\Graphics.hpp>
#include "LayerHandler.h"
using namespace std;
using namespace sf;
int main() {
RenderWindow win(VideoMode(800, 600), "Raven", Style::Default);
win.setFramerateLimit(60);
win.setVerticalSyncEnabled(true);
win.setMouseCursorVisible(false);
LayerHandler lhandler;
Layer back;
back.tex.loadFromFile("bao/gfx/back.png");
back.spr.setTexture(back.tex);
back.spr.setPosition(0, 50);
lhandler.Add(back);
Event evt;
float dt = 0.f;
Clock clock;
float dwticks = clock.getElapsedTime().asMilliseconds();
float dwnewticks = 0.f;
while (win.isOpen()) {
if (win.pollEvent(evt)) {
if (Keyboard::isKeyPressed(Keyboard::Key::Escape)) {
win.close();
}
} else {
dwnewticks = clock.getElapsedTime().asMilliseconds();
dt = dwnewticks > dwticks ? (dwnewticks - dwticks) / 4000.f : 0.f;
dwticks = dwnewticks;
win.clear();
win.draw(lhandler);
win.display();
}
}
return 0;
}
I think it's not complicated and that I did everything ok, but I get this "The value of ESP was not properly saved across the function call" error. I have no idea why I get this error. I know that it may be caused by mismatched calling conventions, but I don't see anything like that in my code... I've got to say that this is the first time ever I got this error and I'm completely out of ideas how to deal with it. Any help?
Don't know why, but the problem was with SFML libraries. Here I'm using version 2.2 for 32-bit apps. I downloaded version 2.3 32-bit and compiled my app with the new 2.3 libraries and now it works perfect.
new here, so be gentle, I'm currently doing my Major Project for my course and, I'm not asking for homework to be done for me, i just can't wrap my head around a strange problem i am having and have not been able to find an answer for it, even on here. I'm using SDL for my Drawing.
I'm doing Object Orientated Programming with my Project or a "state Machine" (which sounds less painful in a newbies mind, believe me), and in the render part of my Class Game1.cpp i am trying to call a Draw Function of my Player Class, but for some unknown reason that i can not fathom, it just skips this function call completely.
I have no errors, i even used breakpoints to find out what was happening, but it just skipped it completely every time, it is drawing the screen black as well without fail. Any help as t why it is skipping this would be really appreciated.
I honestly feel like it's a simple rookie mistake, but any and all scrutiny is welcome of my code, anything i can do to better myself is appreciated.
Game1.cpp:
#include "Game1.h"
#include "PlayerCharacter.h"
Game1::Game1( World * worldObject )
{
//object setup
this->worldObject = worldObject;
setDone (false);
}
Game1::~Game1()
{
}
void Game1::handle_events()
{
//*******************************************
//**//////////////Call Input///////////////**
//*******************************************
//******Check for Keyboard Input*************
//******Check Keyboard Logic*****************
//******Check for Mouse Input****************
//The mouse offsets
x = 0, y = 0;
//If the mouse moved
if (SDL_PollEvent(&worldObject->event))
{
if( worldObject->event.type == SDL_MOUSEMOTION )
{
//Get the mouse offsets
x = worldObject->event.motion.x;
y = worldObject->event.motion.y;
}
}
//******Check Mouse Logic********************
}
void Game1::logic()
{
//*******************************************
//**//////////Collision Detection//////////**
//*******************************************
//******Check Player Bullet Collision Loop***
//Check for collision with enemies
//Check for collision with bitmap mask (walls)
//******Check Enemy Bullet Collision Loop****
//Check for Collision with Player
//Check for collision with bitmap mask (walls)
}
void Game1::render()
{
//*******************************************
//**////////////////Drawing////////////////**
//*******************************************
//******Blit Black Background****************
SDL_FillRect(worldObject->Screen , NULL , 0xff000000);
//******Blit Bitmap Mask*********************
//******Blit Flashlight**********************
//******Blit Map*****************************
//******Blit Pickups*************************
//******Blit Bullets*************************
//******Blit Player**************************
&PlayerCharacter.Draw; // <----- Skips this line completely, no idea why
//******Blit Enemies*************************
//******Blit Blackened Overlay***************
//******Blit HUD*****************************
//******Flip Screen**************************
SDL_Flip(worldObject->Screen);
}
Game1.h
#ifndef __Game1_H_INLUDED__
#define __Game1_H_INLUDED__
#include "GameState.h"
#include "SDL.h"
#include "ImageLoader.h"
using namespace IMGLoader;
class Game1 : public GameState
{
private:
//Menu Image
World * worldObject;
SDL_Rect PauseMenu,Item1Tile,Item2Tile,Item3Tile;
/*bool bPauseMenu, bItem1Tile, bItem2Tile, bItem3Tile;
int ButtonSpace,ButtonSize;
float x,y;
int Alpha1,Alpha2;*/
//Clipping Window
//SDL_Rect sclip,dclip;
public:
//Loads Menu resources
Game1 (World * worldObject);
//Frees Menu resources
~Game1();
//Main loop functions
void handle_events();
void logic();
void render();
};
#endif
PlayerCharacter.cpp
#include "PlayerCharacter.h"
SDL_Rect psclip,pdclip;
PlayerCharacter::PlayerCharacter ( float X, float Y, float dX, float dY, float Angle, float Speed, bool Existance, int Height, int Width, int Health, int Shield, SDL_Surface* Player ):Characters ( X, Y, dX, dY, Angle, Speed, Existance, Height, Width, Health )
{
this->Player = Player;
this->Shield = Shield;
this->Player = load_image("image\Player1.png");
}
void PlayerCharacter::setShield ( int Shield )
{
this->Shield = Shield;
}
int PlayerCharacter::getShield ( void )
{
return Shield;
}
void PlayerCharacter::Draw( )
{
psclip.x = 0; psclip.y = 0; psclip.w = 64; psclip.h = 64;
pdclip.x = 640; pdclip.y = 318; pdclip.w = 64; pdclip.h = 64;
SDL_BlitSurface(Player, &psclip, worldObject->Screen, &pdclip);
}
PlayerCharacter.h
#ifndef __PlayerCharacter_H_INCLUDED__
#define __PlayerCharacter_H_INCLUDED__
#include "Characters.h"
class PlayerCharacter : public Characters
{
private:
int Shield;
SDL_Surface* Player;
World *worldObject;
public:
PlayerCharacter ( float X, float Y, float dX, float dY, float Angle, float Speed, bool Existance, int Height, int Width, int Health, int Shield, SDL_Surface* Player );
void setShield ( int Shield );
int getShield ( void );
void Draw ( );
};
#endif
The line
&PlayerCharacter.Draw; // <----- Skips this line completely, no idea why
is not actually a function call. It's an expression that take the address of the Draw function in the PlayerCharacter class and does nothing with it.
I'm actually kind of surprised it compiles without errors, or at least tons of warnings.
You need to create a PlayerCharacter object, and then call the function in the object.
&PlayerCharacter.Draw is not a function call. PlayerCharacter::Draw() is not a static class method, so you need a PlayerCharacter object to invoke this method on.
You have a class PlayerCharacter, which defines what a PlayerCharacter is and what can be done with it. But as far as I see, you don't have a single PlayerCharacter object, i.e. no player character. If you had one, let's call him pc, then you could draw him with pc.Draw(). For that, you would have to instantiate the class, e.g. via PlayerCharacter pc( ... ), with the ... replaced by some appropriate values for the multitude of constructor parameters you have there. (You really want a default constructor, initializing all those to zero or other appropriate "start" value...)
I am trying to create a parent class "Shape" with child classes "Circle", "Triangle", "Rectangle". The parent class holds the x pos, y pos, and fill color or all the "shapes" and then each child class holds info specific to that shape. Would anyone mind looking over my code and see why im getting the error "Shapes does not have a member 'setRadius'" when trying to set the radius in the array of objects...
P.S. right now I only have the child class "Circle" until i get it working. Then I will add the other two classes.
Also, if anyone sees any other errors in my code, I would appreciate them being pointed out.
Thanks in advance
#include <allegro.h>
#include <cstdlib>
using namespace std;
#define scrX 640
#define scrY 400
#define WHITE makecol(255,255,255)
#define GRAY makecol(60,60,60)
#define BLUE makecol(17,30,214)
int random(int low, int high);
const int numCircles = random(1,50);
class Shape{
public:
Shape(){x = scrX / 2; y = scrY / 2; fill = WHITE;}
protected:
int x, y, fill;
};
class Circle : public Shape{
public:
Circle(){radius = 0;}
Circle(int r){radius = r;}
void setRadius(int r){radius = r;}
protected:
int radius;
};
int main()
{
// Program Initialization
allegro_init();
install_keyboard();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, scrX, scrY, 0, 0);
// Create and clear the buffer for initial use
BITMAP *buffer = create_bitmap(scrX, scrY);
clear_to_color(buffer, GRAY);
// Set title and create label text in window
set_window_title("Bouncing Balls Ver 1.0");
textout_ex(buffer, font, "Bouncing Balls Ver 1.0", 10, 20, WHITE, GRAY);
// Draw a background box
rectfill(buffer, 50, 50, scrX-50, scrY-50, BLUE);
// Create circles
Shape **GCir;
GCir = new Shape *[numCircles];
for(int i=0;i<numCircles;i++){
GCir[i] = new Circle;
GCir[i]->setRadius(random(1,25)); // THIS IS THE ERROR
}
while(!key[KEY_ESC]){
blit(buffer, screen, 0, 0, 0, 0, scrX, scrY);
}
destroy_bitmap(buffer);
return 0;
}
END_OF_MAIN();
int random(int low, int high)
{
return rand() % (high - low) + low;
}
The type of GCir[i] is Shape* and the Shape class doesn't have a setRadius method, Circle does. So either call setRadius on the Circle object before assign it to GCir[i] or just construct the Circle with the proper radius: GCir[i] = new Circle(random(1,25));
hammer fix :
GCir[i]->setRadius(random(1,25));
should be changed to
((Circle*)GCir[i])->setRadius(random(1,25));
Deeper problems:
you need virtual destructor on BaseClass
a better way to do it is to take the radius in the Circle class constructor.
then either use Shape::draw() as a virtual function to specify shape drawing or implement Shape::getType() and use a switch case to determine drawing logic after proper casting.
Compiler said it. You have an array of Shapes on which you try to call setRadius which is only defined for Circles. You can only call shape methods without casting Shape poonter to circle.