Sign in to follow this  
littletray26

Things aren't drawing to the screen

Recommended Posts

Hey GameDev

 

I'm just a bit stuck here. For some reason the ball doesn't draw to the screen, but the paddle does. Here's the code:

 

 

 
LPDIRECT3DTEXTURE9 sprites;
Player* players;
Ball* balls;
 
void LoadContent(LPDIRECT3DDEVICE9* d3dDevice)
{
D3DXCreateTextureFromFile(*d3dDevice, L"resources\\graphics\\sprites.png", &sprites);
players = new Player(0, 0, 114, 13);
balls = new Ball(116, 0, 128, 13);
}
 
void Update(DWORD delta)
{
players->Update();
balls->Update(&players->GetCollisionBox(), 1);
}
 
void Draw(LPD3DXSPRITE sprite)
{
players->Draw(sprite, sprites);
balls->Draw(sprite, sprites);
}
 
void Cleanup()
{
sprites->Release();
delete[] players;
delete[] balls;
}
 

 

and heres the code for ball.Draw:

 

 
class Ball
{
private:
RECT collisionBox;
RECT textureBox;
D3DXVECTOR3 position;
D3DXVECTOR2 velocity;
int ballSpeed;
int ballWidth;
int ballHeight;
 
public:
RECT GetCollisionBox();
void Draw(LPD3DXSPRITE sprite, LPDIRECT3DTEXTURE9 texture);
void Update(RECT* playerCollision, int players);
 
Ball(int x, int y, int xx, int yy)
{
textureBox.bottom = yy;
textureBox.left = x;
textureBox.right = xx;
textureBox.top = y;
ballSpeed = 2;
ballWidth = xx - x;
ballHeight = yy - y;
position.x = (WINDOWWIDTH / 2) - (ballWidth / 2);
position.y = (WINDOWHEIGHT / 2) - (ballHeight / 2);
velocity = D3DXVECTOR2(rand() % ballSpeed + -ballSpeed, ballSpeed);
}
};
 
RECT Ball::GetCollisionBox()
{
return collisionBox;
}
 
void Ball::Draw(LPD3DXSPRITE sprite, LPDIRECT3DTEXTURE9 texture) //here
{
sprite->Draw(texture, &textureBox, &D3DXVECTOR3(0, 0, 0), &position, D3DCOLOR_ARGB(255,255,255,255));
}
 
void Ball::Update(RECT* playerCollision, int players)
{
position.x += velocity.x;
position.y += velocity.y;
 
collisionBox.bottom = position.y + ballHeight;
collisionBox.left = position.x;
collisionBox.right = position.x + ballWidth;
collisionBox.top = position.y;
 
for (int i = 0; i < players; i++)
{
if (IsCollide(playerCollision[i], collisionBox))
velocity.y *= -1;
}
 
if (position.x < 0)
velocity.x *= -1;
else if (position.x > WINDOWWIDTH - ballWidth)
velocity.x *= -1;
 
if (position.y < 0)
velocity.y *= -1;
}
 

 

But for some reason it DOES draw when the code is like this:

 

 
LPDIRECT3DTEXTURE9 sprites;
Player* players;
Ball ball1(116, 0, 128, 13); //changed
 
void LoadContent(LPDIRECT3DDEVICE9* d3dDevice)
{
D3DXCreateTextureFromFile(*d3dDevice, L"resources\\graphics\\sprites.png", &sprites);
players = new Player(0, 0, 114, 13);
}
 
void Update(DWORD delta)
{
players[0].Update();
ball1.Update(&players[0].GetCollisionBox(), 1); //changed
}
 
void Draw(LPD3DXSPRITE sprite)
{
players[0].Draw(sprite, sprites);
ball1.Draw(sprite, sprites); //changed
}
 
void Cleanup()
{
sprites->Release();
delete[] players;
}
 
Edited by littletray26

Share this post


Link to post
Share on other sites

Perhaps you could explain something to me...

You have, effectively: 

 

Ball* balls;
balls = new Ball(116, 0, 128, 13);
balls[0].Update(&players[0].GetCollisionBox(), 1);
 

 

What I think you want is:

 

Ball* balls;
balls = new Ball(116, 0, 128, 13);
balls->Update(&players[0].GetCollisionBox(), 1);

 

I'm no expert in C++, but I know a bit... I know you can use pointer syntax to instantiate arrays, but you're newing up an instance of Ball and treating it as an array of Ball.

It could be true that there is some sorcery that allows it to work as you've written it and that there's a bug somewhere else, but that's the issue that jumps out at me.

Share this post


Link to post
Share on other sites

Perhaps you could explain something to me...

You have, effectively: 

 

Ball* balls;
balls = new Ball(116, 0, 128, 13);
balls[0].Update(&players[0].GetCollisionBox(), 1);
 

 

What I think you want is:

 

Ball* balls;
balls = new Ball(116, 0, 128, 13);
balls->Update(&players[0].GetCollisionBox(), 1);

 

I'm no expert in C++, but I know a bit... I know you can use pointer syntax to instantiate arrays, but you're newing up an instance of Ball and treating it as an array of Ball.

It could be true that there is some sorcery that allows it to work as you've written it and that there's a bug somewhere else, but that's the issue that jumps out at me.

 

I tried what you said, and it seemed to make no difference. Also you'll find the player class is done the same way as the ball class, but it works exactly as it should.

 

Any other suggestions? smile.png

 

Edit: I've updated the OP code to reflect the changes you suggested as well :)

Edited by littletray26

Share this post


Link to post
Share on other sites

I'm no expert in C++, but I know a bit... I know you can use pointer syntax to instantiate arrays, but you're newing up an instance of Ball and treating it as an array of Ball.

It could be true that there is some sorcery that allows it to work as you've written it and that there's a bug somewhere else, but that's the issue that jumps out at me.

 

It's legal. Array indexing just adds to the base address, so if you index a pointer with zero you're referring to the base address. C/C++ doesn't do any kind of checking to see whether a pointer refers to one piece of data, many pieces of data or even undefined data (a pointer to God-knows-what). This is why STL features are preferred, since they do the legwork to make sure that access and allocation are a little more sane.

 

I'm wondering about what's going on with your depth sorting here, since sprite batching in DX can change the render order. Are you running DirectX in debug mode? You may want to see if there's actually a problem with the rendering or if you're somehow just rendering the ball underneath something else.

Share this post


Link to post
Share on other sites

I'm wondering about what's going on with your depth sorting here, since sprite batching in DX can change the render order. Are you running DirectX in debug mode? You may want to see if there's actually a problem with the rendering or if you're somehow just rendering the ball underneath something else.

 

DirectX is indeed running in Debug mode, and the ball is not behind anything. I'm only drawing 2 things to the screen at the moment; the paddle, and the ball. The paddle is at the bottom of the screen, whereas the ball SHOULD be drawing to the middle. There is nothing in the way. As I said in the first post as well, if I change the code to 

LPDIRECT3DTEXTURE9 sprites;
Player* players;
Ball ball1(116, 0, 128, 13); //changed
 
void LoadContent(LPDIRECT3DDEVICE9* d3dDevice)
{
D3DXCreateTextureFromFile(*d3dDevice, L"resources\\graphics\\sprites.png", &sprites);
players = new Player(0, 0, 114, 13);
}
 
void Update(DWORD delta)
{
players[0].Update();
ball1.Update(&players[0].GetCollisionBox(), 1); //changed
}
 
void Draw(LPD3DXSPRITE sprite)
{
players[0].Draw(sprite, sprites);
ball1.Draw(sprite, sprites); //changed
}
 
void Cleanup()
{
sprites->Release();
delete[] players;
} 

 

It draws fine. So I'm confident it's not a depth issue

Share this post


Link to post
Share on other sites

I'll take a look at it when I get home.

 

Thank you very much. If it helps I can post the full source code;

 

main.h

 
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <ctime>
#include <iostream>
 
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
#pragma comment (lib, "winmm.lib")
 
#ifndef once
 
const int WINDOWWIDTH = 800;
const int WINDOWHEIGHT = 600;
 
int Clamp(int value, int min, int max)
{
if (value < min)
return min;
else if (value > max)
return max;
 
else return value;
}
 
bool IsCollide(RECT a, RECT b)
{
if (a.left < b.right && a.right > b.left)
if (a.top < b.bottom && a.bottom > b.top)
return true;
return false;
}
 
class Player
{
private:
int points;
int paddleSpeed;
int paddleWidth;
int paddleHeight;
D3DXVECTOR3 position;
RECT collisionBox;
RECT textureBox;
 
public:
void Draw(LPD3DXSPRITE sprite, LPDIRECT3DTEXTURE9 texture);
void Update();
void GivePoints(int p);
int GetPoints();
RECT GetCollisionBox();
 
Player(int x, int y, int xx, int yy)
{
textureBox.left = x;
textureBox.bottom = yy;
textureBox.right = xx;
textureBox.top = y;
paddleWidth = xx - x;
paddleHeight = yy - y;
points = 0;
paddleSpeed = 8;
position = D3DXVECTOR3((WINDOWWIDTH / 2) - (paddleWidth /2), (WINDOWHEIGHT - paddleHeight - 10), 0);
}
};
 
int Player::GetPoints()
{
return points;
}
 
RECT Player::GetCollisionBox()
{
return collisionBox;
}
 
void Player::Draw(LPD3DXSPRITE sprite, LPDIRECT3DTEXTURE9 texture)
{
sprite->Draw(texture, &textureBox, &D3DXVECTOR3(0, 0, 0), &position, D3DCOLOR_ARGB(255, 255, 255, 255));
}
 
void Player::Update()
{
collisionBox.bottom = position.y + paddleHeight;
collisionBox.left = position.x;
collisionBox.right = position.x + paddleWidth;
collisionBox.top = position.y;
 
if(GetAsyncKeyState(VK_LEFT))
position.x -= paddleSpeed;
else if(GetAsyncKeyState(VK_RIGHT))
position.x += paddleSpeed;
 
position.x = Clamp(position.x, 0, WINDOWWIDTH - paddleWidth);
}
 
void Player::GivePoints(int p)
{
points += p;
}
 
class Ball
{
private:
RECT collisionBox;
RECT textureBox;
D3DXVECTOR3 position;
D3DXVECTOR2 velocity;
int ballSpeed;
int ballWidth;
int ballHeight;
 
public:
RECT GetCollisionBox();
void Draw(LPD3DXSPRITE sprite, LPDIRECT3DTEXTURE9 texture);
void Update(RECT* playerCollision, int players);
 
Ball(int x, int y, int xx, int yy)
{
textureBox.bottom = yy;
textureBox.left = x;
textureBox.right = xx;
textureBox.top = y;
ballSpeed = 2;
ballWidth = xx - x;
ballHeight = yy - y;
position.x = (WINDOWWIDTH / 2) - (ballWidth / 2);
position.y = (WINDOWHEIGHT / 2) - (ballHeight / 2);
//velocity = D3DXVECTOR2(rand() % ballSpeed + -ballSpeed, ballSpeed);
}
};
 
RECT Ball::GetCollisionBox()
{
return collisionBox;
}
 
void Ball::Draw(LPD3DXSPRITE sprite, LPDIRECT3DTEXTURE9 texture)
{
sprite->Draw(texture, &textureBox, &D3DXVECTOR3(0, 0, 0), &position, D3DCOLOR_ARGB(255,255,255,255));
}
 
void Ball::Update(RECT* playerCollision, int players)
{
//position.x += velocity.x;
//position.y += velocity.y;
 
collisionBox.bottom = position.y + ballHeight;
collisionBox.left = position.x;
collisionBox.right = position.x + ballWidth;
collisionBox.top = position.y;
 
for (int i = 0; i < players; i++)
{
if (IsCollide(playerCollision[i], collisionBox))
velocity.y *= -1;
}
 
if (position.x < 0)
velocity.x *= -1;
else if (position.x > WINDOWWIDTH - ballWidth)
velocity.x *= -1;
 
if (position.y < 0)
velocity.y *= -1;
}
 
class Brick
{
};
 
#define once
#endif

 

gameskel.h

 
#include "main.h"
 
LPDIRECT3DTEXTURE9 sprites;
Player* players;
Ball* balls;
 
void LoadContent(LPDIRECT3DDEVICE9* d3dDevice)
{
D3DXCreateTextureFromFile(*d3dDevice, L"resources\\graphics\\sprites.png", &sprites);
players = new Player(0, 0, 114, 13);
balls = new Ball(116, 0, 128, 13);
}
 
void Update(DWORD delta)
{
players->Update();
balls->Update(&players->GetCollisionBox(), 1);
}
 
void Draw(LPD3DXSPRITE sprite)
{
balls->Draw(sprite, sprites);
players->Draw(sprite, sprites);
}
 
void Cleanup()
{
sprites->Release();
delete[] players;
delete[] balls;
}

 

WinMain.cpp

 
//Winmain cpp
#include "main.h"
#include "gameskel.h"
 
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;
LPD3DXSPRITE spriteMachine;
 
LPARAM CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void InitializeD3D(HWND hWnd);
void Pulse(DWORD delta);
void KillD3D();
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
srand(time(0));
 
HWND hWnd;
WNDCLASSEX wc;
DWORD delta = 0;
DWORD prevFrameTime = 0;
DWORD thisFrameTime = 0;
 
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"WINDOW";
wc.style = CS_HREDRAW | CS_VREDRAW;
 
RegisterClassEx(&wc);
 
hWnd = CreateWindowEx(
NULL, L"WINDOW", L"Smashout!",
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, 400, 300, WINDOWWIDTH, WINDOWHEIGHT,
NULL, NULL, hInstance, NULL);
 
ShowWindow(hWnd, nShowCmd);
 
MSG msg = {0};
InitializeD3D(hWnd);
 
while (true)
{
thisFrameTime = timeGetTime();
 
if(prevFrameTime != 0)
delta = thisFrameTime - prevFrameTime;
else delta = 0;
 
prevFrameTime = thisFrameTime;
 
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
 
if (msg.message == WM_QUIT)
break;
} 
 
Pulse(delta);
}
 
KillD3D();
return msg.wParam;
}
 
LPARAM CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
break;
}
}
 
return DefWindowProc(hWnd, msg, wParam, lParam);
}
 
void InitializeD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dPP;
 
ZeroMemory(&d3dPP, sizeof(D3DPRESENT_PARAMETERS));
d3dPP.BackBufferWidth = WINDOWWIDTH;
d3dPP.BackBufferHeight = WINDOWHEIGHT;
d3dPP.BackBufferCount = 1;
d3dPP.hDeviceWindow = hWnd;
d3dPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dPP.Windowed = true;
 
d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dPP, &d3dDevice);
D3DXCreateSprite(d3dDevice, &spriteMachine);
 
LoadContent(&d3dDevice);
}
 
void Pulse(DWORD delta)
{
Update(delta);
d3dDevice->Clear(0, 0, D3DCLEAR_TARGET, 0x427AFF, 1, 0);
d3dDevice->BeginScene();
spriteMachine->Begin(D3DXSPRITE_ALPHABLEND);
 
Draw(spriteMachine);
 
spriteMachine->End();
d3dDevice->EndScene();
d3dDevice->Present(NULL, NULL, NULL, NULL);
}
 
void KillD3D()
{
Cleanup();
spriteMachine->Release();
d3dDevice->Release();
d3d->Release();
}
Edited by littletray26

Share this post


Link to post
Share on other sites

It's the z value. You're leaving it uninitialized, so the behavior is undefined. Sometimes it will work, usually it won't. When I walked through the ball's update function I saw that the z value in the d3dvector was 4e-23452 or something. I set the z to 0.5f in the ctor and now I can see the ball. Always initialize values, even if you don't think you're using them. You can fix this for now by setting the z value for both the paddle and the ball to 0.5f, but eventually you'll probably want to assign meaningful z values so you can put a background or show text or menus on top of the game space.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this