Thread: Making a random color in Allegro.

  1. #1
    Registered User
    Join Date
    Feb 2014
    Posts
    9

    Making a random color in Allegro.

    Hi. I am new here so please don't go all nuts like stack overflow did when i mess up on asking the question.

    So the question of the day is how do i define a new color that is randomly generated in allegro.

    I have this code here in the header file.
    Code:
    //FILE : circledefs.h
    //PURP : Define some constants for circle & background
    
    
    #ifndef CIRCLEDEFS_H
    #define CIRCLEDEFS_H
    
    
    #define NUMCIRCLES 3
    
    
    //The frames per second for the timer
    #define FPS 60
    
    
    //Declare font here so functions/methods can use it
    ALLEGRO_FONT *arial18;
    
    
    //Screen constants for setting up the graphics window
    //and the separator lines
    #define SCRN_W 640
    #define SCRN_H 480
    #define ONE_THIRD_W        SCRN_W*(1.0/3.0)
    #define TWO_THIRDS_W    SCRN_W*(2.0/3.0)
    #define MAX_Y_FOR_CIRCLES    SCRN_H-55
    
    
    //Define colors for the circle and blue for background
    #define SKYBLUE        al_map_rgb(135, 206, 235)
    #define BLACK        al_map_rgb(0, 0, 0)
    #define STEELBLUE    al_map_rgb(70, 130, 180)
    #define LIGHTCYAN    al_map_rgb(224, 255, 255)
    
    
    //make a random number for each one here. 
    #define RANDOM        al_map_rgb(0, 0, 0)
    
    
    #endif

    And what i want to do here is learn how to create a random number gen. Now a few questions if you don't mind telling me is.

    1 - can I create 3 random generators in this header file? Or do I have to do this in main.

    2 - If I do have to do this in main can I still create this defined RANDOM as a color.

    3 - I am sooooo new to this all i know is cin and cout code for C++, so will i need to know more about pointers to do this.

    4 - for fun how hard would it be to make a game in allegro that uses music to define how the enemy moves and attacks. (yes that would be the final project.
    Attached Files Attached Files

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You seem to be overly fond of macros.

    Perhaps you should write a function, e.g.,
    Code:
    ALLEGRO_COLOR generate_random_color()
    {
        return al_map_rgb(rand() % 256, rand() % 256, rand() % 256);
    }
    Remember to seed the PRNG by calling srand near the start of your main function. Also, if you desire, there are a variety of PRNG algorithms available in the standard library as of C++11, available via the <random> header.

    By the way, this is bad:
    Code:
    #define ONE_THIRD_W        SCRN_W*(1.0/3.0)
    To avoid potential problems with precedence, you should write:
    Code:
    #define ONE_THIRD_W        (SCRN_W * (1.0 / 3.0))
    or even:
    Code:
    #define ONE_THIRD_W        ((SCRN_W) * (1.0 / 3.0))
    though that is overkill in this case because we know that SCRN_W is just 640.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    wow thanks.
    I will try this out.

  4. #4
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    Well that worked but when i ran this and declared it it seems to be too much for it and changes color all the time.
    Maybe if i could have a single random number created 3 times at as int.
    but i need to use the range of 0 - 255. How would i do that.

  5. #5
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    So far i got this but it won't do anything random.

    Code:
    
    
    #ifndef CIRCLEDEFS_H
    #define CIRCLEDEFS_H
    
    
    #define NUMCIRCLES 3
    
    
    int r1 = (rand() % 225);
    int r2 = (rand() % 225);
    int r3 = (rand() % 225);
    
    
    ALLEGRO_COLOR generate_random_color()
    {
    	return al_map_rgb(rand() % 256, rand() % 256, rand() % 256);
    }
    //The frames per second for the timer
    #define FPS 60
    
    
    //Declare font here so functions/methods can use it
    ALLEGRO_FONT *arial18;
    
    
    //Screen constants for setting up the graphics window
    //and the separator lines
    #define SCRN_W 640
    #define SCRN_H 480
    #define ONE_THIRD_W		(SCRN_W * (1.0 / 3.0))
    #define TWO_THIRDS_W	(SCRN_W * (2.0 / 3.0))
    #define MAX_Y_FOR_CIRCLES	SCRN_H-55
    
    
    //Define colors for the circle and blue for background
    #define SKYBLUE		al_map_rgb(135, 206, 235)
    #define BLACK		al_map_rgb(0, 0, 0)
    #define STEELBLUE	al_map_rgb(70, 130, 180)
    #define LIGHTCYAN	al_map_rgb(r1, r2, r3)
    //make a random number for each one here. 
    #define RANDOM		 generate_random_color()
    
    
    
    
    #endif

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Decide when you want the colour change, then call the function at those specific times.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    The result is it turns green

  8. #8
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    It is all called here.
    Code:
    void MovingCircle::drawCircle()
    {
    	al_draw_filled_circle(xpos, ypos, radius, STEELBLUE);
    }//END drawCircle

  9. #9
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    Code:
    //FILE : movingCircleClass.h
    //PURP : Class for the circle object, to handle circle updates &
    //       changes in direction
    
    
    #ifndef MOVINGCIRCLECLASS_H
    #define MOVINGCIRCLECLASS_H
    
    
    
    
    class MovingCircle
    {
    private:
    	float xpos, ypos;		//X and Y coordinates on screen
    	float oldX, oldY;		//Previous coordinates on screen
    	float radius;
    	int direction;			//0, 90, 180, 270 for up, right, down, and left
    	int speed;				//How many pixels to move it each time
    public:
    	MovingCircle();		//Constructor
    	~MovingCircle();	//Destructor
    
    
    	void initializeCircle(float, float, float, int, int);
    	void changeCircleDirection(int);
    	void updateCircle();
    	bool checkPosition(int, int);
    	void drawCircle();
    	void updateOldPositions();
    
    
    	//Short methods implemented right here
    	float getXPos()		{return xpos;}
    	float getYPos()		{return ypos;}
    	float getOldX()		{return oldX;}
    	float getOldY()		{return oldY;}
    	float getRadius()	{return radius;}
    	int getSpeed()		{return speed;}
    	int getDirection()	{return direction;}
    	void setXPos(float xIn) {xpos = xIn;}
    	void setYPos(float yIn) {ypos = yIn;}
    };
    
    
    //MovingCircle method implementations, except for simple get/set methods
    //Constructor
    MovingCircle::MovingCircle()
    {
    	//Nothing can be done here, since we are using some circles
    	//in different ways.  All circles are initialized in the
    	//initializeCircle method
    }//END MovingCircle constructor
    
    
    //This destructor has nothing really to accomplish, but in future
    //programs we'll use it wisely
    MovingCircle::~MovingCircle()
    {
    	//In future destructors we will be sure to destroy allocated memory
    }//END MovingCircle destructor
    
    
    //Initialize one circle object
    void MovingCircle::initializeCircle(float xposIn, float yposIn, float radiusIn, int directionIn, int speedIn)
    {
    	xpos = xposIn;
    	ypos = yposIn;
    	radius = radiusIn;
    	direction = directionIn;
    	speed = speedIn;
    }//END initializeCircle
    
    
    //Calculate new position for the middle circle object
    //The outer two circles are controlled by the checkPosition method
    void MovingCircle::updateCircle()
    {
    	//Calculate new position for current direction
    	//Cases reference directions on compass.  EG 0 is up, 180 is down
    	//For any direction calculate the new position, and then
    	//check to make sure the filled circle does not leave its boundary
    	switch (direction)
    	{
    	//Going up.  Check for the top of the screen.
    	case 0:		ypos -= speed;
    				if ((ypos - radius) <= 0)
    				{
    					ypos = radius;		//Set to draw inside window
    					direction = 180;
    				}
    				break;
    	//Going to the right. Check the right side of the screen.
    	case 90:	xpos += speed;
    				if ((xpos + radius) >= TWO_THIRDS_W - 1)
    				{
    					xpos = TWO_THIRDS_W - radius - 5;
    					direction = 270;
    				}
    				break;
    	//Going downwards. Check that the circle doesn't cover up the text.
    	case 180:	ypos += speed;
    				if ((ypos + radius) >= MAX_Y_FOR_CIRCLES)
    				{
    					ypos = MAX_Y_FOR_CIRCLES;	//Set it to draw above text
    					direction = 0;
    				}
    				break;
    	//Going left.  Check the left side of the screen.
    	case 270:	xpos -= speed;
    				if ((xpos - radius) <= ONE_THIRD_W)
    				{
    					xpos = radius + ONE_THIRD_W + 1;
    					direction = 90;
    				}
    				break;
    	} //END case to update circle position
    
    
    } //END UPDATECIRCLE
    
    
    void MovingCircle::changeCircleDirection(int directionKey)
    {
    	switch (directionKey)
    	{
    	case ALLEGRO_KEY_UP:	direction = 0;
    							break;
    	case ALLEGRO_KEY_DOWN:	direction = 180;
    							break;
    	case ALLEGRO_KEY_LEFT:	direction = 270;
    							break;
    	case ALLEGRO_KEY_RIGHT: direction = 90;
    	}
    }//END changeCircleDirection
    
    
    //Check the circles's coordinates with reference to the left &
    //right parameters passed in.
    //Returns true if OK, false if not
    bool MovingCircle::checkPosition(int leftEdge, int rightEdge)
    {
    	bool inPosition = true;
    	if (((xpos - radius) < leftEdge) ||
    		 (xpos + radius) > rightEdge ||
    		 (ypos - radius) < 0     ||
    		 (ypos + radius)  > (SCRN_H - 55))
    		 inPosition = false;
    
    
    	return inPosition;
    }//END checkPosition
    
    
    void MovingCircle::drawCircle()
    {
    	al_draw_filled_circle(xpos, ypos, radius, RANDOM);
    }//END drawCircle
    
    
    //Memorize current X & Y coordinates
    void MovingCircle::updateOldPositions()
    {
    	//Set oldX & oldY
    	oldX = xpos;
    	oldY = ypos;
    }//END updateOldPositions
    #endif

  10. #10
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    to be fair here i don't really know what i am looking at.
    I just know what might work but i don't think that would work either now that i look at it. AHHHH tooo much code....

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Err... why does your header also contain the definitions of the various functions? If you want to do that, then you should either declare them within the class definition or declare them inline, but some of them don't look like good candidates for inlining anyway.

    Concerning the random colour: what do you have in mind? That is, what is the effect that you want? At the moment, your RANDOM macro is just another name for a function call, so if I were you, I would do without it. The function is called every time MovingCircle::drawCircle is called.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    Well i have been looking at this, say i want to use a define and use it the same way it is being used right now.

    Instead of reworking the code. (which i would have to understand it fully first).
    Wouln't it be easier if i was to create a random int 3 times and place each one into a separate int.
    like:
    Code:
    int r1 = (rand() % 225);
    int r2 = (rand() % 225);
    int r3 = (rand() % 225);
    From there I should be able to do as i please with my defined color.
    like:
    Code:
    #define RANDOM   al_map_rgb(r1, r2, r3)
    Sense the #define Random is storing 3 variables it isn't calling the change color function constantly. So if this logic works then it is only calling 3 randomly made variables that are used only one time.

    Now to cap this and make sure it isn't working around the 3 variables constantly i may need to throw r1, r2, r3 through a loop on time to build the variables.

    Would that work? Your the pro, otherwise i would have to rework how that function is working and how to call it.
    Right now all i need to do is to make the circles change into a random solid color when created.

    BTW thanks for the help so far LaserLight.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Hank Bates
    Sense the #define Random is storing 3 variables it isn't calling the change color function constantly.
    Your RANDOM macro does not store anything. When you write this:
    Code:
    #define RANDOM       generate_random_color()
    It merely means that this:
    Code:
    al_draw_filled_circle(xpos, ypos, radius, RANDOM);
    is equivalent to:
    Code:
    al_draw_filled_circle(xpos, ypos, radius, generate_random_color());
    Except that your version is confusing because it looks like RANDOM is a constant when it is actually a function call with a return value that is different on each run. If you write this instead:
    Code:
    #define RANDOM   al_map_rgb(r1, r2, r3)
    Then it would be equivalent to:
    Code:
    al_draw_filled_circle(xpos, ypos, radius, al_map_rgb(r1, r2, r3));
    But you have to define r1, r2 and r3 somewhere. If you define them just before that line, i.e.,
    Code:
    int r1 = (rand() % 256);
    int r2 = (rand() % 256);
    int r3 = (rand() % 256);
    al_draw_filled_circle(xpos, ypos, radius, RANDOM);
    then the net effect would be the same as if you had just written:
    Code:
    al_draw_filled_circle(xpos, ypos, radius, generate_random_color());
    Except that your version is confusing because it looks like RANDOM is a constant when it is actually a function call that relies on specially named variables being in scope.

    From what I see, the circle has a colour. Therefore, it makes sense to store the colour as a member variable. This member variable can be passed as an argument in a constructor, or set by some member function. In this way, your drawCircle member function would be:
    Code:
    void MovingCircle::drawCircle()
    {
        al_draw_filled_circle(xpos, ypos, radius, color);
    }
    In some other function, e.g., the main function, you might create the MovingCircle with the desired colour:
    Code:
    MovingCircle circle(STEELBLUE);
    // ...
    circle.drawCircle();
    or with a random colour:
    Code:
    MovingCircle circle(generate_random_color());
    // ...
    circle.drawCircle();
    This way, no matter how many times drawCircle is called, it will draw the circle with the same colour, as long as the member variable has not been modified.
    Last edited by laserlight; 02-06-2014 at 03:30 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to generate random color names in c ?
    By Islam Assi in forum C Programming
    Replies: 2
    Last Post: 09-07-2013, 01:45 PM
  2. Random Numbers in Allegro.
    By godly 20 in forum C++ Programming
    Replies: 8
    Last Post: 01-27-2011, 05:02 PM
  3. Allegro and color commands
    By campsoup1988 in forum C++ Programming
    Replies: 4
    Last Post: 02-02-2006, 08:20 AM
  4. Replies: 4
    Last Post: 11-16-2004, 07:29 AM
  5. Question on 256 color allegro dos stuff
    By stupid_mutt in forum C Programming
    Replies: 6
    Last Post: 02-02-2002, 09:40 PM

Tags for this Thread