寫程序是1個按部就班的進程,1開始都是加加減減,修修補補,這和我們做企業做創新的原理都是1樣的,沒有一揮而就的成功,最近看了周鴻祎的《我的互聯網方法論》蠻有啟發,分享給大家幾句摘抄:
1.所有的顛覆式創新都不是敲鑼打鼓來的,而是隱藏在1片噪聲里。
2.顛覆式創新,就像自然界的新陳代謝1樣,不斷把老的、舊的公司從行業中擠出去。所以,這類顛覆式創新已成為美國硅谷的1個意味。破壞和顛覆,都是強調打破原本的平衡,建立新秩序。但這兩個詞在中文里都是貶義詞,由于中國文化崇尚平衡、穩定、和諧。1說顛覆式創新,我們的潛意識就會覺得是反動的東西,就不由自主地想到階級敵人弄破壞。我有些時候受邀給1些單位講互聯網里的顛覆式創新。講完后,有的領導就過來跟我握手說:小周,講得挺好的嘛,只不過以后不要講顛覆、講破壞,影響社會和諧。
3.我不同意企業大張旗鼓地弄創新,非要巨額投入資金,非要設立創新研究院,非要做1個整套的創新戰略。我覺得休克式療法的創新很難成功,我主張把創新從神壇上拉下來,從1些細微點上進行延續創新,這樣反而更有效。
4.喬布斯有1天給谷歌高管打電話,說蘋果iOS有1個谷歌地圖圖標,放大多少倍以后,第3行1個像素色彩不對,他認為這影響了iOS的美觀。這就是對細節的1種堅持。
下面我們來看1個貪吃蛇的實現代碼:
主要有兩個大的步驟:
1.界面的繪制
2.蛇的繪制
主要代碼:
// Snake.cpp : 定義利用程序的入口點。
//
#include "stdafx.h"
#include "Snake.h"
#include <vector>
#include<time.h>
#define MAX_LOADSTRING 100
//定義游戲區 和 控制區大小
#define BOUND_SIZE 10
#define SNACK_SIZE 10
#define GAME_WIDTH 80
#define GAME_HEIGHT 60
#define INFO_WIDTH 30
#define INFO_HEIGHT GAME_HEIGHT
#define MAX_NODE 80 //蛇的最大長度 80 節
#define MY_TIMER 1 //定時器ID
#define DEFAULT_INTERVAL 200 //定義貪食蛇的默許移動速度 500毫秒移動1節
#define PAUSE_ID 1
std::vector<POINT> vSnake;
UCHAR g_ucSnakeLen = 4;
UCHAR g_ucSnakeHead = 4; //vSnack[g_ucSnakeHead⑴] 表示蛇頭的坐標
UCHAR g_ucSnakeTail = 0; //vSnack[g_ucSnakeTail] 表示蛇尾的坐標
UINT32 g_uiInterval = DEFAULT_INTERVAL; //移動速度
POINT g_ptDirect = {1, 0}; //移動方向,每次x+1, y不變
POINT g_ptFoodPos;
BOOL g_bState = TRUE; //游戲是不是結束
BOOL g_bNeedFood = TRUE; //是不是要投放食品
BOOL g_bPause = FALSE; //暫停
// 全局變量:
HINSTANCE hInst; // 當前實例
TCHAR szTitle[MAX_LOADSTRING]; // 標題欄文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口類名
// 此代碼模塊中包括的函數的前向聲明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代碼。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SNAKE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 履行利用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SNAKE));
// 主消息循環:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 函數: MyRegisterClass()
//
// 目的: 注冊窗口類。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SNAKE));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SNAKE);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// 函數: InitInstance(HINSTANCE, int)
//
// 目的: 保存實例句柄并創建主窗口
//
// 注釋:
//
// 在此函數中,我們在全局變量中保存實例句柄并
// 創建和顯示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 將實例句柄存儲在全局變量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
VOID InitSnack() //初始化蛇,設定蛇的起始位置
{
int i;
vSnake.clear();
vSnake.resize(MAX_NODE);
g_ucSnakeTail = 0;
g_ucSnakeHead = 4;
g_ucSnakeLen = 4;
g_uiInterval = DEFAULT_INTERVAL;
for (i = 0; i < g_ucSnakeLen; i++)
{
//初始化蛇的各個節點
vSnake[i].x = i;
vSnake[i].y = 1;
}
}
POINT &GetSnakeNode(int index) //獲得蛇節點位置:倒數第幾個節點
{
int i = g_ucSnakeTail + index;
if (i >= MAX_NODE)
{
i -= MAX_NODE;
}
return vSnake[i];
}
VOID DrawSnake(HDC hdc)
{
int i;
POINT ptNode;
HBRUSH hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
SelectObject(hdc, hBrush);
for (i = 0; i < g_ucSnakeLen; i++)
{
//從蛇尾開始畫
ptNode = GetSnakeNode(i);
Rectangle(hdc, ptNode.x * SNACK_SIZE + BOUND_SIZE,
ptNode.y * SNACK_SIZE + BOUND_SIZE,
(ptNode.x + 1) * SNACK_SIZE + BOUND_SIZE,
(ptNode.y + 1) * SNACK_SIZE + BOUND_SIZE);
}
}
//移動蛇坐標
VOID RefreshSnake()
{
//采取翻滾的情勢 比如,vSnake[0], vSnake[1],vSnake[2] vSnake[3] 表示蛇的話
//移動1節后,vSnake[1],vSnake[2] vSnake[3] vSnake[4] 表示蛇
//vSnake[MAX_NODE ⑴ ] 后,蛇頭存入 vSnake[0]
POINT ptNewHead; //新的蛇頭位置
POINT ptNode;
int i;
ptNewHead.x = GetSnakeNode(g_ucSnakeLen - 1).x + g_ptDirect.x;
ptNewHead.y = GetSnakeNode(g_ucSnakeLen - 1).y + g_ptDirect.y;
if (!g_bNeedFood && ptNewHead.x == g_ptFoodPos.x && ptNewHead.y == g_ptFoodPos.y)
{
//吃到食品了
vSnake[g_ucSnakeHead] = ptNewHead;
g_ucSnakeHead++;
if (g_ucSnakeHead == MAX_NODE) g_ucSnakeHead = 0;
g_ucSnakeLen++;
if (g_ucSnakeLen == MAX_NODE)
{
//贏了,事實上,我們不應當等到這個時候才判斷贏了
g_bState = FALSE;
return;
}
g_bNeedFood = TRUE;
return;
}
if (ptNewHead.x < 0 || ptNewHead.x >= GAME_WIDTH || ptNewHead.y < 0 || ptNewHead.y >= GAME_HEIGHT)
{
//蛇撞墻了
g_bState = FALSE;
return;
}
for (i = 1; i < g_ucSnakeLen; i++)
{
ptNode = GetSnakeNode(i);
if (ptNode.x == ptNewHead.x && ptNode.y == ptNewHead.y)
{
//蛇撞到自己了
g_bState = FALSE;
return;
}
}
vSnake[g_ucSnakeHead].x = ptNewHead.x;
vSnake[g_ucSnakeHead].y = ptNewHead.y;//新的蛇頭
g_ucSnakeHead++;
if (g_ucSnakeHead == MAX_NODE) g_ucSnakeHead = 0;
g_ucSnakeTail++;
if (g_ucSnakeTail == MAX_NODE) g_ucSnakeTail = 0;
return;
}
VOID DrawFood(HDC hdc)
{
int x, y;
POINT ptNode;
int i;
HBRUSH hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
if (!g_bNeedFood)
{
SelectObject(hdc, hBrush);
Ellipse(hdc, BOUND_SIZE + g_ptFoodPos.x * SNACK_SIZE,
BOUND_SIZE + g_ptFoodPos.y * SNACK_SIZE,
BOUND_SIZE + (g_ptFoodPos.x + 1) * SNACK_SIZE,
BOUND_SIZE + (g_ptFoodPos.y + 1) * SNACK_SIZE);
return;
}
srand(time(0)); //隨機數種子
//獲得隨機坐標,不能是蛇的位置
while (1)
{
x = rand() % GAME_WIDTH;
y = rand() % GAME_HEIGHT;
for (i = 0; i < g_ucSnakeLen; i++)
{
ptNode = GetSnakeNode(i);
if (ptNode.x == x && ptNode.y == y)
{
break;
}
}
if (i == g_ucSnakeLen) //1直沒有break,表示不重復
{
break;
}
}
g_bNeedFood = FALSE;
g_ptFoodPos.x = x;
g_ptFoodPos.y = y;
SelectObject(hdc, hBrush);
Ellipse(hdc, BOUND_SIZE + x * SNACK_SIZE, BOUND_SIZE + y * SNACK_SIZE,
BOUND_SIZE + (x + 1) * SNACK_SIZE, BOUND_SIZE + (y + 1) * SNACK_SIZE);
return;
}
//
// 函數: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 處理主窗口的消息。
//
// WM_COMMAND - 處理利用程序菜單
// WM_PAINT - 繪制主窗口
// WM_DESTROY - 發送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
int i;
int nWinX, nWinY, nClientX, nClientY;
HBRUSH hBrush;
static HWND hPause;
switch (message)
{
case WM_CREATE: //創建窗口時候履行的代碼
GetWindowRect(hWnd, &rect); //獲得窗口大小
nWinX = rect.right - rect.left;
nWinY = rect.bottom - rect.top;
GetClientRect(hWnd, &rect); //客戶區大小
nClientX = rect.right - rect.left;
nClientY = rect.bottom - rect.top;
//修改窗口大小 客戶區大小 + 邊框大小 (nWinX-nClientX)
MoveWindow(hWnd, 0, 0,
(GAME_WIDTH + INFO_WIDTH)*SNACK_SIZE + BOUND_SIZE * 3 + (nWinX - nClientX),
GAME_HEIGHT*SNACK_SIZE + BOUND_SIZE * 2 + (nWinY - nClientY), TRUE);
hPause = CreateWindow(TEXT("Button"), TEXT("暫停"),
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
3 * BOUND_SIZE + GAME_WIDTH * SNACK_SIZE, 200, 200, 100,
hWnd, (HMENU)PAUSE_ID, hInst, NULL
);
InitSnack();
SetTimer(hWnd, MY_TIMER, g_uiInterval,NULL); //起1個定時器
break;
case WM_TIMER: //定時器到點
//移動蛇
RefreshSnake();
if (!g_bState)
{
KillTimer(hWnd, MY_TIMER); //停止計時器
MessageBox(NULL, TEXT("你輸了"), TEXT("FAIL"), MB_OK);
//InitSnack();
return 0;
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜單選擇:
switch (wmId)
{
case PAUSE_ID:
if (g_bPause)
{
g_bPause = FALSE;
SetWindowText(hPause, TEXT("暫停"));
SetTimer(hWnd, MY_TIMER, g_uiInterval, NULL);
}
else
{
g_bPause = TRUE;
SetWindowText(hPause, TEXT("繼續"));
KillTimer(hWnd, MY_TIMER);
}
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意繪圖代碼...
hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
SelectObject(hdc, hBrush);
Rectangle(hdc, BOUND_SIZE, BOUND_SIZE,
BOUND_SIZE + GAME_WIDTH*SNACK_SIZE,
BOUND_SIZE + GAME_HEIGHT*SNACK_SIZE);
Rectangle(hdc, BOUND_SIZE * 2 + GAME_WIDTH*SNACK_SIZE , BOUND_SIZE,
BOUND_SIZE*2 + (GAME_WIDTH + INFO_WIDTH)*SNACK_SIZE,
BOUND_SIZE + INFO_HEIGHT*SNACK_SIZE);
DrawSnake(hdc);
DrawFood(hdc);
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN:
if (!g_bState || g_bPause)
{
break;
}
switch (wParam)
{
case VK_UP: //調理方向:注意點,原來是往上或往下的話,不做操作
if (g_ptDirect.x != 0)
{
g_ptDirect.x = 0;
g_ptDirect.y = -1;
}
break;
case VK_DOWN:
if (g_ptDirect.x != 0)
{
g_ptDirect.x = 0;
g_ptDirect.y = 1;
}
break;
case VK_LEFT:
if (g_ptDirect.y != 0)
{
g_ptDirect.x = -1;
g_ptDirect.y = 0;
}
break;
case VK_RIGHT:
if (g_ptDirect.y != 0)
{
g_ptDirect.x = 1;
g_ptDirect.y = 0;
}
break;
}
break;
case WM_DESTROY:
KillTimer(hWnd, MY_TIMER);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “關于”框的消息處理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
下一篇 聯合訓練圖論場