X
Hey c++er,
ich habe mir in letzder Zeit mal GDI+ angesehen, da das GDI ja nicht sehr schön in C++ reinpasst. Nun habe ich mir zur Übung ein Pong gebastelt, wo jedoch gleich mehrere Fehler auftreten.
1. kann ich keinen Kreis malen, stattdessen arbeite ich im Moment mit einem Rechteck.
2. Wenn ich den Smoothing mode auf highqualitiy stelle wird garnichtsmehr gemalt.
3. (Mein Hauptproblem) Wenn ich eine vorher deklariertes Brush benutze kommt immer so ein komisches Muster (bei jeder Farbe anders, es ändert sich bei neuausführng nicht)
Mein Code:
main.cpp:
#include "Main.h"
#include <Windows.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma once;
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "user32.lib")
HWND hWnd;
int winH = 600;
int winW = 1000;
int ballH = 20;
int ballW = 20;
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
DWORD WINAPI DrawFrame(HANDLE handle);
DWORD WINAPI GameEngine(HANDLE handle);
DWORD WINAPI PaddleEngine(HANDLE handle);
//Create PONG object
static PONG MyGame(winW, winH, ballH, ballW);
//END Create
//Frame regulator
int FramesPerSec = 100;
//End Frame
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = "WindowPong";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
"WindowPong", // window class
"Window Pong",// title
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, // window style
300, // x
300, // y
winW, // width
winH, // height
NULL, // parent
NULL, // menu
hInstance, //instance
NULL); //Just NULL
ShowWindow(hWnd, nCmdShow);
MSG msg;
HANDLE GDIThread = CreateThread(NULL,
NULL,
(LPTHREAD_START_ROUTINE)&DrawFrame,
NULL,
NULL,
NULL);
HANDLE GameCore = CreateThread(NULL,
NULL,
(LPTHREAD_START_ROUTINE)&GameEngine,
NULL,
NULL,
NULL);
/*HANDLE PaddleMovement = CreateThread(NULL,
NULL,
(LPTHREAD_START_ROUTINE)&PaddleEngine,
NULL,
NULL,
NULL);*/
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
DWORD WINAPI DrawFrame(HANDLE handle)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HDC hDC = GetDC(hWnd);
HDC hDCbuf = CreateCompatibleDC(hDC);
HBITMAP hBMP = CreateCompatibleBitmap(hDCbuf, winW, winH);
SelectObject(hDCbuf, hBMP);
int DelayToSleep = 1000 / FramesPerSec;
Graphics hGraphics(hDC);
Graphics hBuffer(hDCbuf);
hGraphics.SetSmoothingMode(SmoothingModeHighQuality);
//COLORS
const Color cblack(255, 0, 0, 0);
const Color cwhite(255, 255, 255, 255);
const Color cgreen(255, 0, 255, 0);
const Color cblue(255, 0, 0, 255);
const Color cred(255, 255, 0, 0);
//COLORS_END
//PENS
const Pen pblack(cblack, 1);
const Pen pwhite(cwhite, 1);
const Pen pgreen(cgreen, 1);
const Pen pblue(cblue, 1);
const Pen pred(cred, 1);
//PENS_END
//BRUSHES
const SolidBrush bblack(cblack);
const SolidBrush bwhite(cwhite);
const SolidBrush bgreen(cgreen);
const SolidBrush bblue(cblue);
const SolidBrush bred(cred);
//BRUSHES_END
//hBuffer.TranslateTransform(0, 0);
while (true)
{
hBuffer.Clear(cblack); //Clear Complete In Black
//StartGDIPlusScene
//DrawPlayer1
//hBuffer.FillRectangle(&bred, RectF(0, 0, winW, winH));
hBuffer.FillRectangle(&bred,
5,
MyGame.GetLeft(),
10,
100);
//DrawPlayer2
hBuffer.FillRectangle(&bwhite,
winW-20,
MyGame.GetRight(),
10,
100);
//DrawBall
hBuffer.FillRectangle(&bwhite, MyGame.GetBallX(),
MyGame.GetBallY(),
ballW,
ballH);
//EndGDIPlusScene
//MyGame.SetBall(MyGame.GetBallX()+1, MyGame.GetBallY()+10);
BitBlt(hDC, 0, 0, winW, winH, hDCbuf,
0,
0,
SRCCOPY);//Draw Frame
Sleep(DelayToSleep); //Frame Rate
}
GdiplusShutdown(gdiplusToken);
}
DWORD WINAPI PaddleEngine()
{
if(GetAsyncKeyState(VK_UP)) MyGame.AddRightP(-10);
if(GetAsyncKeyState(VK_DOWN)) MyGame.AddRightP(10);
if(GetAsyncKeyState(0x57)) MyGame.AddLeftP(-10);
if(GetAsyncKeyState(0x53)) MyGame.AddLeftP(10);
return 0;
}
DWORD WINAPI GameEngine(HANDLE handle)
{
int t;
char buf[255];
while(true)
{
t = MyGame.MoveBall();
if (t == 1){
/*MessageBoxA(NULL,
"Links hat gewonnen",
"Gewonnen",
NULL);*/
Sleep(1000);
MyGame.Reset();
sprintf(buf, "left %d : %d right", MyGame.GetLeftPoints(), MyGame.GetRightPoints());
SetWindowTextA(hWnd, buf);
}
else if (t == 2){
/*MessageBoxA(NULL,
"Rechts hat gewonnen",
"Gewonnen",
NULL);*/
Sleep(1000);
MyGame.Reset();
sprintf(buf, "left %d : %d right", MyGame.GetLeftPoints(), MyGame.GetRightPoints());
SetWindowTextA(hWnd, buf);
}
//MyGame.increaseB();
PaddleEngine();
Sleep(1000/FramesPerSec);
}
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// sort through and find what code to run for the message given
switch(message)
{
// this message is read when the window is closed
case WM_DESTROY:
{
// close the application entirely
PostQuitMessage(0);
return 0;
} break;
}
// Handle any messages the switch statement didn't
return DefWindowProc (hWnd, message, wParam, lParam);
}
Main.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LEFT_PLAYER 0x01
#define RIGHT_PLAYER 0x02
class PONG
{
private:
int left[2]; //y_pos + points
float right[2]; //y_pos + points
int ball[4]; // x_pos + y_pos + speed_x + speed_y
int table[4]; //The game Table(w+h+bw+bh)
public:
PONG(int width, int height, int bwidth, int bheight)
{
//Init game table
table[0] = width;
table[1] = height;
table[2] = bwidth;
table[3] = bheight;
//Init player
left[0] = table[1]/2 - 50;
right[0] = table[1]/2 - 50;
//Init ball
srand(time(NULL));
ball[0] = table[0]/2-table[2]/2;
ball[1] = table[1]/2-table[3]/2;
ball[2] = (int)(rand() % 5) - 5;
ball[3] = (int)(rand() % 5) - 5;
if (ball[2] <= ball[3])
{
int temp = ball[2];
ball[2] = ball[3];
ball[3] = temp;
}
}
void SetLeft(int y) {left[0] = y;}
void SetRight(int y){right[0] = y;}
int GetLeft() {return left[0];}
int GetRight() {return right[0];}
void SetBall(int x, int y)
{
ball[0] = x;
ball[1] = y;
}
void Reset()
{
//Init player
left[0] = table[1]/2 - 50;
right[0] = table[1]/2 - 50;
//Init ball
srand(time(NULL));
ball[0] = table[0]/2-table[2]/2;
ball[1] = table[1]/2-table[3]/2;
ball[2] = (int)(rand() % 5) - 5;
ball[3] = (int)(rand() % 5) - 5;
if (ball[2] <= ball[3])
{
int temp = ball[2];
ball[2] = ball[3];
ball[3] = temp;
}
}
int MoveBall()
{
ball[0] += ball[2];
ball[1] += ball[3];
if (ball[0] <= 0 || ball[0]+table[2] >= (table[0]))
ball[2] = -ball[2];
if (ball[1] <= 0 || ball[1]+table[3]*2 >= (table[1]))
ball[3] = -ball[3];
if (ball[0] <= 15)
if(ball[1] >= left[0] && ball[1] <= left[0]+100){
this->invertbX();
return 0;
}
if (ball[0] <= 0)
if(!ball[1] >= left[0] || !ball[1] <= left[0]+100){
right[1] += 1;
return 2;
}
if (ball[0]+table[2] >= table[0]-20)
if(ball[1] >= right[0] && ball[1] <= right[0]+100){
this->invertbX();
return 0;
}
if (ball[0]+table[2] >= table[0])
if(!ball[1] >= right[0] || !ball[1] <= right[0]+100){
left[1] += 1;
return 1;
}
}
void increaseB(){
ball[2] *= 1.000001;
ball[2] *= 1.000001;
}
void invertbX() {ball[2] = -ball[2];}
void AddLeftP(int x) {
if(left[0] >= 0 && left[0] <= table[1]-100){
left[0] += x;
}
if(left[0] <= 0)
left[0] = 0;
if(left[0] >= table[1]-120)
left[0] = table[1]-120;
}
void AddRightP(int x){
if(right[0] >= 0 && right[0] <= table[1]-100){
right[0] += x;
}
if(right[0] <= 0)
right[0] = 0;
if(right[0] >= table[1]-120)
right[0] = table[1]-120;
}
int GetBallX() {return ball[0];}
int GetBallY() {return ball[1];}
int GetLeftPoints() {return left[1];}
int GetRightPoints() {return right[1];}
};
Wär schön wenn ihr die Fehler findet und mir nennt, anstatt sie nur zu korrigieren, ich will wissen was ich falsch mache, denn aus Fehlern lernt man ja...
MfG,
Xyron