3D+物理引擎
Hjr1141451931 · · 个人记录
这里是我“最前沿”的模拟技术的上传地
放的是我最新整的活
22/9/15 闪屏问题已解决,帧率已获得过优化
#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
#define KeyDown(VK_NONAME) ((GetAsyncKeyState(VK_NONAME)&0x8000) ? 1:0)
using namespace std;
double D=900,sen=0.2;
const double PI=acos(-1),g=9.8;
double cx,cy,cz;
double dirxz=0,diryz=0,mvdir;
double vy=0,ay=0,vx=0,ax=0;
bool ismove=false,isfly=false;
HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE),In=GetStdHandle(STD_INPUT_HANDLE);
HWND hWnd=GetConsoleWindow();
HDC hdc=GetDC(GetConsoleWindow()),Mem;
HBITMAP hBmp;HGDIOBJ hOldSel;
HPEN hpen0 = CreatePen( PS_SOLID, 1, RGB(255,255,255) );
HPEN hpen1 = CreatePen( PS_SOLID, 1, RGB(0,0,0) );
HPEN hpen2 = CreatePen( PS_SOLID, 1, RGB(0,50,255) );
HBRUSH blackbrush=CreateSolidBrush(RGB(200,200,200)),whitebrush=CreateSolidBrush(RGB(255,255,255));
struct line{
double x1,y1,z1,x2,y2,z2;
};
double Hu(double dir){
return dir*PI/180;
}
void Turn(double &x1,double &y1,double ox,double oy,double dir){
double tmpx=x1-ox,tmpy=y1-oy;
double cdir=cos(Hu(dir)),sdir=sin(Hu(dir));
x1=tmpx*cdir-tmpy*sdir;
y1=tmpx*sdir+tmpy*cdir;
}
vector<line> Linelist;
void CursorControl()
{
while(1)
{
POINT p;
GetCursorPos(&p);
double dx=p.x-990,dy=p.y-540;
dirxz+=dx*sen;
diryz-=dy*sen;
SetCursorPos(990,540);
Sleep(10);
}
}
POINT pts[25];
int cnt=0;
void TurnAndPrint(double x1,double y1,double z1,double x2,double y2,double z2,bool issolid){
Turn(x1,z1,cx,cz,dirxz); Turn(x2,z2,cx,cz,dirxz);
z1+=cz,z2+=cz;
Turn(z1,y1,cz,cy,-diryz); Turn(z2,y2,cz,cy,-diryz);
if(z1<0&&z2<0){
if(issolid){
pts[cnt]={pts[cnt-1].x,pts[cnt-1].y}; cnt++;
pts[cnt]={pts[cnt-2].x,pts[cnt-2].y}; cnt++;
}
return;
}
if(z2<0){
x2=x1-z1*((x1-x2)/(z1-z2));
if(y1!=y2) y2=y2-z2*((y1-y2)/(z1-z2));
z2=0;
}
else if(z1<0){
x1=x1-z1*((x1-x2)/(z1-z2));
if(y1!=y2) y1=y1-z1*((y1-y2)/(z1-z2));
z1=0;
}
double X1,Y1,X2,Y2;
if(z1!=0) X1=x1*(D/z1)+989,Y1=-y1*(D/z1)+540;
else X1=x1*D+989,Y1=-y1*D+540;
if(z2!=0) X2=x2*(D/z2)+989,Y2=-y2*(D/z2)+540;
else X2=x2*D+989,Y2=-y2*D+540;
MoveToEx(Mem,X1,Y1,NULL);
LineTo(Mem,X2,Y2);
if(issolid){
pts[cnt]={int(X1),int(Y1)}; cnt++;
pts[cnt]={int(X2),int(Y2)}; cnt++;
}
}
struct cube{
line l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12;
//l1到l12,由上到下,从最左逆时针排列
bool ds[7];//要涂色的面,1为上,2345从最前逆时针排列,6为底
void print(){
TurnAndPrint(l1.x1,l1.y1,l1.z1,l1.x2,l1.y2,l1.z2,1);
TurnAndPrint(l2.x1,l2.y1,l2.z1,l2.x2,l2.y2,l2.z2,1);
TurnAndPrint(l3.x1,l3.y1,l3.z1,l3.x2,l3.y2,l3.z2,1);
TurnAndPrint(l4.x1,l4.y1,l4.z1,l4.x2,l4.y2,l4.z2,1);
TurnAndPrint(l5.x1,l5.y1,l5.z1,l5.x2,l5.y2,l5.z2,1);
TurnAndPrint(l6.x1,l6.y1,l6.z1,l6.x2,l6.y2,l6.z2,1);
TurnAndPrint(l7.x1,l7.y1,l7.z1,l7.x2,l7.y2,l7.z2,1);
TurnAndPrint(l8.x1,l8.y1,l8.z1,l8.x2,l8.y2,l8.z2,1);
TurnAndPrint(l9.x1,l9.y1,l9.z1,l9.x2,l9.y2,l9.z2,1);
TurnAndPrint(l10.x1,l10.y1,l10.z1,l10.x2,l10.y2,l10.z2,1);
TurnAndPrint(l11.x1,l11.y1,l11.z1,l11.x2,l11.y2,l11.z2,1);
TurnAndPrint(l12.x1,l12.y1,l12.z1,l12.x2,l12.y2,l12.z2,1);
SelectObject(Mem,blackbrush);
for(int d=1;d<=7;d++)
if(ds[d])
switch (d) {
case 1:
Polygon(Mem,pts,8);
break;
case 6:
Polygon(Mem,pts+16,8);
break;
POINT nep[8];
case 2:
nep[0]=pts[2],nep[1]=pts[3],nep[2]=pts[10],nep[3]=pts[11],nep[4]=pts[19],nep[5]=pts[18],nep[6]=pts[8],nep[7]=pts[9];
Polygon(Mem,nep,8);
break;
case 3:
nep[0]=pts[4],nep[1]=pts[5],nep[2]=pts[13],nep[3]=pts[12],nep[4]=pts[21],nep[5]=pts[20],nep[6]=pts[10],nep[7]=pts[11];
Polygon(Mem,nep,8);
break;
case 4:
nep[0]=pts[6],nep[1]=pts[7],nep[2]=pts[15],nep[3]=pts[14],nep[4]=pts[23],nep[5]=pts[22],nep[6]=pts[12],nep[7]=pts[13];
Polygon(Mem,nep,8);
break;
case 5:
nep[0]=pts[0],nep[1]=pts[1],nep[2]=pts[9],nep[3]=pts[8],nep[4]=pts[17],nep[5]=pts[14],nep[6]=pts[14],nep[7]=pts[15];
Polygon(Mem,nep,8);
break;
default:
break;
}
SelectObject(Mem,whitebrush);
cnt=0;
}
};
vector<cube> Cubelist;
void print()
{
while(1)
{
Mem=CreateCompatibleDC(hdc);
hBmp=CreateCompatibleBitmap(hdc,1979,1079);
hOldSel = SelectObject(Mem,hBmp);
SelectObject(Mem,hpen0);
Rectangle(Mem,0,0,1980,1080);
SelectObject(Mem,hpen1);
for(int o=0;o<int(Linelist.size());o++){
SelectObject(Mem,hpen1);
TurnAndPrint(Linelist[o].x1,Linelist[o].y1,Linelist[o].z1,Linelist[o].x2,Linelist[o].y2,Linelist[o].z2,0);
}
for(int o=0;o<int(Cubelist.size());o++){
SelectObject(Mem,hpen1);
Cubelist[o].print();
}
BitBlt(hdc,0,0,1979,1079,Mem,0,0,SRCCOPY);
SelectObject(Mem,hOldSel);
DeleteDC(Mem);
Sleep(33);
}
}
void Move()
{
while(1){
if(ismove) ax=5;
else ax=-5;
if(vx<=30&&vx>=0) vx+=0.1*ax;
if(vx<0) vx=0;
if(vx>30) vx=30;
cx+=0.1*vx*sin(Hu(mvdir));
cz+=0.1*vx*cos(Hu(mvdir));
Sleep(10);
}
}
void fv(){
while(1){
if(!isfly){
cy+=0.1*vy;
Sleep(10);
}
}
}
void jump(){
while(1){
if(KeyDown(0x20)&&cy==0&&!isfly){
vy=50,ay=0;
Sleep(500);
}
else if(KeyDown(0x20)&&isfly){
cy+=5;
Sleep(10);
}
else if(KeyDown(0x10)&&isfly){
cy-=5;
Sleep(10);
}
}
}
void Gravity(){
while(1){
if(!isfly){
if(cy<0) vy=0,ay=0,cy=0;
vy+=0.1*ay;
ay-=g*0.1;
Sleep(10);
}
}
}
int main()
{
// cy=1000000;
ShowWindow(hWnd,SW_SHOWMAXIMIZED);
DWORD mode;
GetConsoleMode(In,&mode);
mode &= ~ENABLE_QUICK_EDIT_MODE;
SetConsoleMode(In,mode);
CONSOLE_CURSOR_INFO A;
GetConsoleCursorInfo(Out,&A);
A.bVisible=false;
SetConsoleCursorInfo(Out,&A);
thread t1(print);
thread t2(CursorControl);
thread t3(fv),t4(Gravity),t5(jump);
thread t6(Move);
for(double i=-1000;i<=1000;i+=100)
for(double j=-1000;j<=1000;j+=100){
Cubelist.push_back({
{j,50,i+100,j,50,i},{j,50,i,j+100,50,i},{j+100,50,i,j+100,50,i+100},{j+100,50,i+100,j,50,i+100},
{j,-50,i,j,50,i},{j+100,-50,i,j+100,50,i},{j+100,-50,i+100,j+100,50,i+100},{j,-50,i+100,j,50,i+100},
{j,-50,i+100,j,-50,i},{j,-50,i,j+100,-50,i},{j+100,-50,i,j+100,-50,i+100},{j+100,-50,i+100,j,-50,i+100}
,{0,1,0,0,0,0,1}});//上下两面保证首尾相连,中间从上至下
}
while(1)
{
if(KeyDown(0x41)||KeyDown(0x44)||KeyDown(0x57)||KeyDown(0x53)) ismove=true;
else ismove=false;
if(KeyDown(0x41)) mvdir=dirxz-90.0;
if(KeyDown(0x44)) mvdir=dirxz+90.0;
if(KeyDown(0x57)) mvdir=dirxz;
if(KeyDown(0x53)) mvdir=dirxz-180.0;
if(KeyDown(0x46)) isfly=!isfly,Sleep(100);
if(KeyDown(0x4F)) sen+=0.01;
if(KeyDown(0x50)) sen-=0.01;
if(KeyDown(0xDD)) D+=10;
if(KeyDown(0xDB)) D-=10;
if(KeyDown(0x1B)) exit(0);
Sleep(40);
}
return 0;
}