IGAD Tutorial - Part 8 Assignment

8060f823d3b004e7f088076ae8a159c7
0
TheJjokerR 101 Nov 21, 2010 at 11:07

Hey there!

I’ve started reading the IGAD tutorial yesterday and got to part 8 today. I understand how pointers work, though the assignments at the bottom are quite confusing..

First of all:
1. Draw a dotted line (skip every other dot) from (0, 0) to (400, 400). Do not use the Plot function, use a pointer variable instead. Figure out what the distance between dots in memory is to make this code super simple and fast.
How would I go about doing that and how would it be faster and ‘simpler’ than this:

for ( int i = 0; i < 400; i++ ){
        if( empty ){
            empty = false;
        }else{
            m_Screen->Line( (float) i, (float) i, (float) i, (float) i, 0xffffff );
            empty = true;
        }
    }
  1. Does the second assignment also require me to use pointers?

Thanks!

6 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Nov 21, 2010 at 18:52

You’re not supposed to use any functions like Plot, Line, etc. but use the pointer to the screen buffer to write the desired pixels directly. As a template for the first assignment, you could start with the Game::Tick function mentioned in the text that draws a vertical line:

void Game::Tick( float a_DT )
{
    Pixel* address = m_Screen->GetBuffer() + 100;
    for ( int i = 0; i < 255; i++ ) address[i * 640] = i;
}

This draws a vertical line from (100, 0) to (100, 255) by directly setting values into the buffer. You should modify this to complete the first assignment. Try getting it to draw a diagonal line first, then when that’s working put in the dotted-ness. I’ll just give a hint: the difference between drawing a vertical line, a diagonal line, or a dotted diagonal line is just changing one number in this code.

As for the second assignment, yes, the idea is to keep using the screen buffer pointer to read and write pixels directly. The idea is you’ll load an image into the screen buffer (hopefully there’s a function in the engine to do this for you), then write some code that moves your guy around by erasing him at his current position and drawing him at his next position. Your guy is a one-pixel white dot, and he only moves in areas of the image that are black, so erasing and re-drawing him is easy. You have to look at the pixels of the loaded image in the buffer to figure out where the guy is allowed to move (i.e. where the background is black).

8060f823d3b004e7f088076ae8a159c7
0
TheJjokerR 101 Nov 22, 2010 at 13:08

@Reedbeta

You’re not supposed to use any functions like Plot, Line, etc. but use the pointer to the screen buffer to write the desired pixels directly. As a template for the first assignment, you could start with the Game::Tick function mentioned in the text that draws a vertical line:

void Game::Tick( float a_DT )
{
    Pixel* address = m_Screen->GetBuffer() + 100;
    for ( int i = 0; i < 255; i++ ) address[i * 640] = i;
}

This draws a vertical line from (100, 0) to (100, 255) by directly setting values into the buffer. You should modify this to complete the first assignment. Try getting it to draw a diagonal line first, then when that’s working put in the dotted-ness. I’ll just give a hint: the difference between drawing a vertical line, a diagonal line, or a dotted diagonal line is just changing one number in this code.

Ah, thanks for that. I really need to learn to read because as you’ve shown, it was all in the tutorial \^_\^

Anyways, I got quite far, though I am still having some problems:

Pixel* address = m_Screen->GetBuffer();
    for ( int i = 0; i < 400; i++ ) address[i * (640 + 1)] = 0xffffff;

That works for the diagonal line, though for the dotted line when I replace the 1 with 2, it is in fact dotted but not at the right height.

What did I do wrong, is the code above maybe not the code I am supposed to use?

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Nov 22, 2010 at 18:38

What you’ve got draws a 45-degree diagonal line because you advance down one row (the 640) and across one column (the 1) each iteration of the loop. Changing the 1 to a 2 will certainly make a dotted line because it’ll skip alternate columns, but it will also change the slope because now you’ll go across 2 and down 1 for each iteration. To draw a 45-degree line that’s dotted, what you really want is to go across 2 and down 2 on each iteration.

8060f823d3b004e7f088076ae8a159c7
0
TheJjokerR 101 Nov 24, 2010 at 13:58

Alright, that really helped me. Also, I think I’ve completed the second assignment, though I am unsure if it is the way it should be.

Is this the right way to do this?

Sprite theSprite( new Surface("assets/640x480.tga"), 1 );
double y = 0;
double x = 320;
float nextmove = 0;

void Game::Tick( float a_DT )
{   
    m_Screen->Clear( 0 );
    theSprite.Draw( 0, 0, m_Screen );

    if( y >= 480 ){ y = 0; x = 320; }
    
    Pixel* address = m_Screen->GetBuffer();
    int curAddress = (int) y * 640 + (int) x;
    
    if(address[curAddress] == 0xFF000000){
        y = y + .3;
    }else if((int) y % 2 == 0){
        x = x + .3;
    }else{
        x = x - .3;
    }
    
    address[curAddress] = 0xffffff;
}

Thanks,

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Nov 24, 2010 at 18:06

That’s the basic idea, but it looks like you’re testing the pixel your guy is already on, instead of the one below him. BTW, why did you choose to use double values for the coordinates instead of ints? There’s nothing wrong with it; I’m just curious.

8060f823d3b004e7f088076ae8a159c7
0
TheJjokerR 101 Nov 24, 2010 at 18:43

I’ll check it sooner, yeah.
@Reedbeta

BTW, why did you choose to use double values for the coordinates instead of ints? There’s nothing wrong with it; I’m just curious.

The doubles allow me to make it move slower in a reaaaaaally simple way, adding .3 to it everytime.