RT,迭代器player的velocity因为未知原因自动清零
附:编译需加入命令-lgdi32
#include<iostream>
#include<time.h>
#include<windows.h>
#include<math.h>
#include<algorithm>
#include<list>
#include<map>
BITMAPINFO bmpinfo;
class Vector2 {
public:
double x;
double y;
Vector2(double a, double b) {
x = a;
y = b;
}
Vector2 operator+(Vector2 a) {
return Vector2(x + a.x, y + a.y);
}
Vector2 operator-(Vector2 a) {
return Vector2(x - a.x, y - a.y);
}
Vector2 operator*(double a) {
return Vector2(x * a, y * a);
}
double module(double a) {
return sqrt(x * x + y * y);
}
Vector2 operator+=(Vector2 a) {
x += a.x, y += a.y;
return Vector2(x, y);
}
Vector2 operator-=(Vector2 a) {
x -= a.x, y -= a.y;
return Vector2(x, y);
}
Vector2 operator*=(double a) {
x *= a, y *= a;
return Vector2(x, y);
}
std::string ToString() {
return '(' + std::to_string(x) + ',' + std::to_string(y) + ')';
}
};
typedef Vector2 Vector;
enum class EntityType{
PLAYER,
CAMERA
};
class Entity{
public:
Vector position = Vector(0, 0);
Vector velocity = Vector(0, 0);
bool Invisible = false;
double Health;
std::string custom_name;
EntityType type;
std::map<std::string, std::string> tag;
};
typedef __time64_t Time;
const double tickTime = 1e-6;
Time GetTime() {
FILETIME t;
GetSystemTimeAsFileTime(&t);
return (Time)t.dwHighDateTime << 32 | t.dwLowDateTime;
}
template<typename T1> class DyadicArray {
public:
int width;
T1 a[100000000];
bool set(int x, int y, int value) {
if(x + y * width >= 100000000) return false;
if(x >= width) return false;
if(x < 0 || y < 0) return false;
a[x + y * width] = value;
return true;
}
bool Clear() {
memset(a, 0, sizeof(a));
return true;
}
T1 get(int x, int y) {
return a[x + y * width];
}
};
typedef DyadicArray<COLORREF> ColorMap;
bool Line(ColorMap &a, Vector2 start, Vector2 end, COLORREF color) {
bool result = false;
if(start.x > end.x) std::swap(start, end);
for(int x = start.x; x <= end.x && start.x != end.x; ++x) {
double k = (start.y - end.y) / (start.x - end.x);
result |= a.set(x, (int)(k * (x - start.x) + start.y), color);
}
if(start.y > end.y) std::swap(start, end);
for(int y = start.y; y <= end.y && start.y != end.y; ++y) {
double k = (start.x - end.x) / (start.y - end.y);
result |= a.set((int)(k * (y - start.y) + start.x), y, color);
}
return result;
}
ColorMap cmap;
std::list<Entity> entity;
typedef std::list<Entity>::iterator ExistentEntity;
bool Remove(std::list<Entity> &a, ExistentEntity entity) {
if(entity == a.end()) {
return false;
}
a.erase(entity);
return true;
}
ExistentEntity Spawn(std::list<Entity> &a, EntityType entity_type, Vector position, std::map<std::string, std::string> tag = {}) {
Entity temp_entity;
temp_entity.position = position;
temp_entity.velocity = Vector(0, 0);
temp_entity.type = entity_type;
temp_entity.tag = tag;
a.push_back(temp_entity);
return a.end();
}
ExistentEntity SetTag(ExistentEntity entity, std::string key, std::string value) {
entity -> tag[key] = value;
return entity;
}
ExistentEntity camera = Spawn(entity, EntityType::CAMERA, Vector(0, 0));
ExistentEntity player = Spawn(entity, EntityType::PLAYER, Vector(0, 0));
std::map<DWORD, bool> keyDown;
bool PaintScreen(HWND hwnd) {
cmap.Clear();
RECT rect;
GetWindowRect(hwnd, &rect);
COORD size;
size.X = rect.right - rect.left;
size.Y = rect.bottom - rect.top;
cmap.width = size.X;
bmpinfo.bmiHeader.biWidth = size.X;
bmpinfo.bmiHeader.biHeight = size.Y;
HDC hdc = GetDC(hwnd);
HDC hdcmem = CreateCompatibleDC(hdc);
HBITMAP hbmpmem = CreateCompatibleBitmap(hdc, size.X, size.Y);
for(std::list<Entity>::iterator temp_entity = entity.begin(); temp_entity != entity.end(); ++temp_entity) {
switch(temp_entity -> type) {
case(EntityType::PLAYER): {
Vector position = (*temp_entity).position, temp_list[4] = {Vector(1, 1), Vector(1, -1), Vector(-1, -1), Vector(-1, 1)};
for(int j = 0; j < 4; ++j) {
Line(cmap, (position - (*camera).position + temp_list[j] * 16) + Vector(size.X / 2, size.Y / 2), (position - (*camera).position + temp_list[(j + 1) % 4] * 16) + Vector(size.X / 2, size.Y / 2), 0xFFFFFF);
}
break;
}
default: {
break;
}
}
}
SelectObject(hdcmem, hbmpmem);
SetDIBits(hdcmem, hbmpmem, 0, size.X, cmap.a, &bmpinfo, DIB_RGB_COLORS);
BitBlt(hdc, 0, 0, size.X, size.Y, hdcmem, 0, 0, SRCCOPY);
return true;
}
Time lastCalculate = GetTime();
bool Calculate() {
Time thisCalculate = GetTime();
Time subTime = thisCalculate - lastCalculate;
if(keyDown['W']) {
player -> velocity.y = player -> velocity.y - 1 * subTime * tickTime;
}
if(keyDown['S']) {
player -> velocity.y = player -> velocity.y + 1 * subTime * tickTime;
}
if(keyDown['A']) {
player -> velocity.x = player -> velocity.x + 1 * subTime * tickTime;
}
if(keyDown['D']) {
player -> velocity.x = player -> velocity.x - 1 * subTime * tickTime;
}
std::cout << player -> velocity.ToString() << '\n';
player -> position = player -> position + player -> velocity * subTime * tickTime;
std::cout << player -> velocity.ToString() << '\n';
lastCalculate = thisCalculate;
return true;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_KEYDOWN: {
keyDown[wParam] = true;
break;
}
case WM_KEYUP: {
keyDown[wParam] = false;
break;
}
case WM_MOUSEMOVE: {
break;
}
case WM_DESTROY: {
PostQuitMessage(0);
exit(0);
break;
}
default: {
return DefWindowProc(hwnd, Message, wParam, lParam);
}
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// ShowWindow(GetConsoleWindow(), HIDE_WINDOW);
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biWidth = 100;
bmpinfo.bmiHeader.biHeight = 100;
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biBitCount = 32;
bmpinfo.bmiHeader.biCompression = BI_RGB;
bmpinfo.bmiHeader.biSizeImage = 0;
bmpinfo.bmiHeader.biXPelsPerMeter = 3000;
bmpinfo.bmiHeader.biYPelsPerMeter = 3000;
bmpinfo.bmiHeader.biClrUsed = 0;
bmpinfo.bmiHeader.biClrImportant = 0;
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc; /* insert window procedure function here */
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* use "A" as icon name when you want to use the project icon */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* as above */
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,640,480,NULL,NULL,hInstance,NULL);
if(hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != -1) {
TranslateMessage(&msg);
DispatchMessage(&msg);
Calculate();
PaintScreen(hwnd);
Sleep(1);
}
return msg.wParam;
}