📄 displayer.cpp
字号:
// Displayer.cpp : implementation file
//
#include "stdafx.h"
#include "SoccerDoctor.h"
#include "Displayer.h"
#include <math.h>
#include "MainFrm.h"
#include "analyzer.h"
// CDisplayer dialog
IMPLEMENT_DYNAMIC(CDisplayer, CDialog)
CDisplayer::CDisplayer(CWnd* pParent /*=NULL*/)
: CDialog(CDisplayer::IDD, pParent)
{
m_clientRect = CRect(0,0,0,0);
_pCycleInfo = NULL;
m_nDebug = MAX_PLAYER * 2; // 不指向任何球员
m_bShowLogplay = true; // 缺省是播放log
_pMainFrame = NULL;
_pObjectDetailDialog = NULL;
_pDrawingBox = NULL;
_pPresentDlg = NULL;
// Hint Window
_pHintWindow = NULL;
// Control Course
_CurrentControlSide = NEUTRAL;
}
CDisplayer::~CDisplayer()
{
if( _pObjectDetailDialog ){
delete _pObjectDetailDialog;
}
if( _pDrawingBox ){
delete _pDrawingBox;
}
if( _pPresentDlg ){
delete _pPresentDlg;
}
if( _pHintWindow ){
delete _pHintWindow;
}
DeleteAllDC();
for( VOIterator i=_VisualObjects.begin(); i != _VisualObjects.end(); i++ ){
delete (*i);
}
}
BEGIN_MESSAGE_MAP(CDisplayer, CDialog)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_CONTEXTMENU()
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
int CDisplayer::CoordX(double x)
{
return (int) (x * m_dScale);
}
int CDisplayer::CoordY(double y)
{
return (int) (y * m_dScale);
}
double CDisplayer::NormalizeAngleRad(double& angle){
while (angle > PI) angle -= PI*2;
while (angle < -PI) angle += PI*2;
return angle;
}
void CDisplayer::DeleteAllDC()
{
if(m_SoccerDC.m_hDC) {
m_SoccerDC.SelectObject((CFont *)NULL);
m_SoccerDC.SelectObject((CBitmap *)NULL);
m_SoccerBitmap.DeleteObject();
m_SoccerDC.DeleteDC();
}
if(m_FieldDC.m_hDC) {
m_FieldDC.SelectObject((CBitmap *)NULL);
m_FieldBitmap.DeleteObject();
m_FieldDC.DeleteDC();
}
}
void CDisplayer::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect clientRect;
GetClientRect(&clientRect);
if(clientRect.Width() != m_clientRect.Width() || clientRect.Height() != m_clientRect.Height())
{ // 窗口大小改变,需要重新画背景
DeleteAllDC(); // 释放所有资源
if(!m_FieldDC.CreateCompatibleDC(&dc)){
return;
}
if(!m_SoccerDC.CreateCompatibleDC(&dc)){
return;
}
if(!m_FieldBitmap.CreateCompatibleBitmap(&dc, clientRect.Width(), clientRect.Height())){
m_FieldDC.DeleteDC();
return;
}
if(!m_SoccerBitmap.CreateCompatibleBitmap(&dc, clientRect.Width(), clientRect.Height())){
m_SoccerDC.DeleteDC();
return;
}
m_FieldBitmap.SetBitmapDimension(clientRect.Width(), clientRect.Height());
m_FieldDC.SelectObject(&m_FieldBitmap);
m_SoccerBitmap.SetBitmapDimension(clientRect.Width(), clientRect.Height());
m_SoccerDC.SelectObject(&m_SoccerBitmap);
if (((double) clientRect.Width() / (double) clientRect.Height()) < PITCH_LENGTH / (PITCH_WIDTH + TOP_MARGIN)){
m_dScale = (double) clientRect.Width() / (PITCH_LENGTH + PITCH_MARGIN * 2.0);
}else{
m_dScale = (double) clientRect.Height() / (PITCH_WIDTH + PITCH_MARGIN * 2.0 + TOP_MARGIN);
}
m_clientRect = clientRect; // 改变图像大小
/* 调整字体 */
_GDIObjects.ChangeFontSize(CoordX(FONT_SIZE));
m_SoccerDC.SelectObject(getScoreFont());
DrawField(&m_FieldDC); // 画场地
}
// draw the things
m_SoccerDC.BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &m_FieldDC, 0, 0, SRCCOPY);
DrawSoccer(&m_SoccerDC); // 画队员球及比分等
// copy the memory bitmap into the window
dc.BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &m_SoccerDC, 0, 0, SRCCOPY);
// remove the created bitmap
}
void CDisplayer::DrawSoccer(CDC* pDC)
{
DrawBanner(pDC);
if( _Settings.m_bOffsideLine){
DrawOffsideLine(pDC);
}
if( _Settings.m_bControlCourse){
DrawControlCourse(pDC);
}
DrawPlayers(pDC);
DrawBall(pDC);
DrawVisualObjects(pDC);
DrawPresent(pDC);
getObjectDetailDialog()->ShowDetail();
}
void CDisplayer::DrawBanner(CDC *pDC)
{
int x1, x2;
int y1, y2;
CRect field;
CString text;
char* PlayModeString[] = PLAYMODE_STRINGS ;
CString temp;
// draw the heading
// fonts
pDC->SelectObject(getScoreFont());
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(COLOR_BLACK);
// score left
x1 = CoordX(PITCH_MARGIN);
y1 = CoordY(PITCH_MARGIN - 2.0);
x2 = CoordX(PITCH_MARGIN + 15.0);
y2 = CoordY(PITCH_MARGIN + TOP_MARGIN);
field.SetRect(x1, y1, x2,y2);
text.Format("%2d", TeamLScore());
pDC->DrawText(text, field, DT_SINGLELINE | DT_VCENTER);
// score right
x1 = CoordX(PITCH_MARGIN + PITCH_LENGTH - 15.0);
x2 = CoordX(PITCH_MARGIN + PITCH_LENGTH);
field.SetRect(x1, y1, x2,y2);
text.Format("%2d", TeamRScore());
pDC->DrawText(text, field, DT_SINGLELINE | DT_VCENTER | DT_RIGHT);
// teamname left
pDC->SelectObject(getHeadingFont());
x1 = CoordX(PITCH_MARGIN + 8.0);
x2 = CoordX(PITCH_MARGIN + PITCH_LENGTH / 3.0);
field.SetRect(x1, y1, x2, y2);
pDC->DrawText(TeamLName(), field, DT_SINGLELINE | DT_VCENTER);
// teamname right
x2 = CoordX(PITCH_MARGIN + PITCH_LENGTH - 8.0);
x1 = CoordX(PITCH_MARGIN + PITCH_LENGTH / 3.0 * 2.0);
field.SetRect(x1, y1, x2, y2);
pDC->DrawText(TeamRName(), field, DT_SINGLELINE | DT_VCENTER | DT_RIGHT);
// playmode
x1 = CoordX(PITCH_MARGIN + 20.0);
x2 = CoordX(PITCH_MARGIN + PITCH_LENGTH / 2.0 - 2.0);
field.SetRect(x1, y1, x2, y2);
pDC->SelectObject(getTimeFont());
pDC->DrawText(PlayModeString[PlayMode()], field, DT_SINGLELINE | DT_VCENTER | DT_RIGHT);
// time
x1 = CoordX(PITCH_MARGIN + PITCH_LENGTH / 2.0 + 2.0);
x2 = CoordX(PITCH_MARGIN + PITCH_LENGTH - 25.0);
field.SetRect(x1, y1, x2, y2);
text.Format("%4d", GameTime());
pDC->DrawText(text, field, DT_SINGLELINE | DT_VCENTER | DT_LEFT);
}
CString CDisplayer::TeamLName()
{
if( _pCycleInfo ==NULL || _pCycleInfo->bSight ){
return CString("Left");
}
return CString(_pCycleInfo->show.team[0].name);
}
CString CDisplayer::TeamRName()
{
if(_pCycleInfo ==NULL || _pCycleInfo->bSight){
return CString("Right");
}
return CString(_pCycleInfo->show.team[1].name);
}
UINT CDisplayer::TeamLScore()
{
if( _pCycleInfo ==NULL || _pCycleInfo->bSight ){
return 0;
}
return ntohs(_pCycleInfo->show.team[0].score);
}
UINT CDisplayer::TeamRScore()
{
if( _pCycleInfo ==NULL || _pCycleInfo->bSight ){
return 0;
}
return ntohs(_pCycleInfo->show.team[1].score);
}
short CDisplayer::GameTime()
{
if( _pCycleInfo ==NULL ){
return 0;
}
if( _pCycleInfo->bSight ){
return _pCycleInfo->sight.time;
}
return ntohs(_pCycleInfo->show.time);
}
void CDisplayer::DrawField(CDC* pDC)
{
int x1, x2, x3, x5;
int y1, y2, y3, y4, y5, y6, y7;
int radius;
CRect field;
// erase the memory device context
pDC->FillSolidRect(m_clientRect, COLOR_DARKGREEN);
// draw the lines
CBrush* oldBrush = pDC->SelectObject(getBlackBrush());
CPen* oldPen = pDC->SelectObject(getWhitePen());
// outline
x1 = CoordX(PITCH_MARGIN);
y1 = CoordY(PITCH_MARGIN + TOP_MARGIN);
x2 = CoordX(PITCH_MARGIN + PITCH_LENGTH);
y2 = CoordY(PITCH_MARGIN + TOP_MARGIN + PITCH_WIDTH);
pDC->MoveTo(x1, y1);
pDC->LineTo(x2, y1);
pDC->LineTo(x2, y2);
pDC->LineTo(x1, y2);
pDC->LineTo(x1, y1);
// midline and circle
x3 = CoordX(PITCH_MARGIN + PITCH_LENGTH / 2.0);
y3 = CoordY(PITCH_MARGIN + TOP_MARGIN + PITCH_WIDTH / 2.0);
radius = CoordX(CENTER_CIRCLE_R);
pDC->Arc(x3 - radius, y3 - radius, x3 + radius, y3 + radius, x3, y3 - radius, x3, y3 - radius);
pDC->MoveTo(x3, y1);
pDC->LineTo(x3, y2);
// penalty area left
// penalty circle
x3 = CoordX(PITCH_MARGIN + PENALTY_AREA_LENGTH);
y3 = CoordY(TOP_MARGIN + PITCH_MARGIN + (PITCH_WIDTH - PENALTY_AREA_WIDTH) / 2.0);
y4 = CoordY(TOP_MARGIN + PITCH_MARGIN + (PITCH_WIDTH - PENALTY_AREA_WIDTH) / 2.0 + PENALTY_AREA_WIDTH);
x5 = CoordX(PITCH_MARGIN + PENALTY_SPOT_DIST);
y5 = CoordY(TOP_MARGIN + PITCH_MARGIN + PITCH_WIDTH / 2.0);
y6 = CoordY(TOP_MARGIN + PITCH_MARGIN + PITCH_WIDTH / 2.0 - CIRCLE_ARC);
y7 = CoordY(TOP_MARGIN + PITCH_MARGIN + PITCH_WIDTH / 2.0 + CIRCLE_ARC);
radius = CoordX(PENALTY_CIRCLE_R);
pDC->Arc(x5 - radius, y5 - radius, x5 + radius, y5 + radius, x3, y7, x3, y6);
// penalty area
pDC->MoveTo(x1, y3);
pDC->LineTo(x3,y3);
pDC->LineTo(x3,y4);
pDC->LineTo(x1,y4);
// penalty points
pDC->MoveTo(x5, y5 - 1);
pDC->LineTo(x5, y5 + 1);
// penalty area right
// penalty circle
x3 = CoordX(PITCH_MARGIN + PITCH_LENGTH - PENALTY_AREA_LENGTH);
x5 = CoordX(PITCH_MARGIN + PITCH_LENGTH - PENALTY_SPOT_DIST);
pDC->Arc(x5 - radius, y5 - radius, x5 + radius, y5 + radius, x3, y6, x3, y7);
// penalty area
pDC->MoveTo(x2, y3);
pDC->LineTo(x3,y3);
pDC->LineTo(x3,y4);
pDC->LineTo(x2,y4);
// penalty points
pDC->MoveTo(x5, y5 - 1);
pDC->LineTo(x5, y5 + 1);
// goal area left
x3 = CoordX(PITCH_MARGIN + GOAL_AREA_LENGTH);
y3 = CoordY(TOP_MARGIN + PITCH_MARGIN + (PITCH_WIDTH - GOAL_AREA_WIDTH) / 2.0);
y4 = CoordY(TOP_MARGIN + PITCH_MARGIN + (PITCH_WIDTH - GOAL_AREA_WIDTH) / 2.0 + GOAL_AREA_WIDTH);
pDC->MoveTo(x1, y3);
pDC->LineTo(x3, y3);
pDC->LineTo(x3, y4);
pDC->LineTo(x1, y4);
// goal area right
x3 = CoordX(PITCH_MARGIN + PITCH_LENGTH - GOAL_AREA_LENGTH);
pDC->MoveTo(x2, y3);
pDC->LineTo(x3, y3);
pDC->LineTo(x3, y4);
pDC->LineTo(x2, y4);
// draw the goals
pDC->SelectObject(getBlackPen());
// goal left
y3 = CoordY(TOP_MARGIN + PITCH_MARGIN + (PITCH_WIDTH - GOAL_WIDTH) / 2.0);
y4 = CoordY(TOP_MARGIN + PITCH_MARGIN + (PITCH_WIDTH - GOAL_WIDTH) / 2.0 + GOAL_WIDTH);
pDC->MoveTo(x1, y3);
pDC->LineTo(x1, y4);
// goal right
pDC->MoveTo(x2, y3);
pDC->LineTo(x2, y4);
}
void CDisplayer::OnCancel()
{
_pMainFrame->SendMessage(WM_CLOSE);
// CDialog::OnCancel();
}
void CDisplayer::OnOK()
{
// CDialog::OnOK();
}
void CDisplayer::SetDisplayInfo(const cycle_info_t *pInfo)
{
_pCycleInfo = pInfo;
if( pInfo!=NULL && !(pInfo->bSight)){
CDisplayDefines::showinfo_t2disp_showinfo_t(pInfo->show,_CurrentShowInfo);
}
Invalidate();
}
void CDisplayer::DrawBall(CDC* pDC)
{
int r,x,y;
double speed;
bool haveball = false;
CString temp;
if( _pCycleInfo == NULL )
return;
r = CoordX(BALL_SIZE);
if (r < 3) {
r = 3;
}
if ( _pCycleInfo->bSight ){
const SightLog* pLog = &(_pCycleInfo->sight);
if( pLog->ball_conf ){
x = FieldX2ScreenX(pLog->ball_x);
y = FieldY2ScreenY(pLog->ball_y);
if(pLog->ball_velconf && _Settings.m_bVelocity )
temp.Format("(%.2f,%.2f)",pLog->ball_conf,pLog->ball_speed);
else
temp.Format("(%.2f)",pLog->ball_conf);
haveball = true;
}
}else {
x = FieldX2ScreenX(_CurrentShowInfo.ball.x);
y = FieldY2ScreenY(_CurrentShowInfo.ball.y);
if(_Settings.m_bVelocity){
speed = sqrt(_CurrentShowInfo.ball.deltax * _CurrentShowInfo.ball.deltax + _CurrentShowInfo.ball.deltay * _CurrentShowInfo.ball.deltay);
temp.Format("%.2f",speed);
}
haveball = true;
}
if( haveball ) {
pDC->SelectObject(getWhiteBrush());
pDC->Ellipse(x - r, y - r, x + r, y + r);
pDC->SetPixel(x,y,COLOR_BLACK);
pDC->SelectObject(getPlayerFont());
pDC->SetTextColor(COLOR_LIGHTBLUE);
pDC->TextOut(x + r, y - r, temp);
}
}
void CDisplayer::DrawPlayers(CDC* pDC)
{
if(_pCycleInfo == NULL)
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -