今天花了大概8个小时做了个贪吃蛇,主要的时间还是花费在了如何做的更流畅上面,之前的做法是每次移动整数个单位,给自己的感觉是不太流畅,所以后来改成每次移动的部署为double类型的, 但是有潜在的问题,判断无法精准,只能有个大概的判断,可能是我水平不够暂时还无法做到,希望得到指点。
我是有个想法 把UI和实际数据分开来算, 可以将UI刷新的时间设置为实际跑动的时间的1/5,但是目前还有点问题
综上有
1)每次移动整数
2)每次移动double
3)UI分离
贴上暂时的源代码,这个版本是上面说的第二种,第一种因为流畅度还差点就不用了
#pragma once
#include "resource.h"
const int BORDER = 10;
const int SCREEN_WIDTH = 640;
const RECT rc_top = {BORDER,BORDER,SCREEN_WIDTH-BORDER,BORDER+20};
const RECT rc_bottom = {BORDER,BORDER+30,SCREEN_WIDTH-BORDER,SCREEN_WIDTH-BORDER};
const RECT rc_main = {0,0,SCREEN_WIDTH,SCREEN_WIDTH};
int BLOCK_SIZE = 15;
int curX=0,curY=0;
int curDir[4] = {1,0};
int g_blocked[100][100];
int NUM_X = 40;
int NUM_Y = 40;
typedef struct aaa{
double curX;
double curY;
double curDir[2];
struct aaa *pre;
struct aaa *next;
}body;
body *head;
int g_speed = 50;
int g_seed = 1995421;
int SNAKE_STATE = 0;
int SNAKE_SCORE = 0;
int SNAKE_DIFF = 1;
void MoveWindowToCenter(HWND hWnd);
void DrawBackground(HDC hdc);
void DrawBody(HDC hdc);
VOID outPutBoxInt(int num);
VOID outPutBoxString(TCHAR str[1024]);
int CalculatePosition();
void StartTimer(HWND hWnd);
void CALLBACK MoveSnake( HWND hWnd,UINT uMsg,UINT idEvent,DWORD dwTime );
void CALLBACK ShowMove( HWND hWnd,UINT uMsg,UINT idEvent,DWORD dwTime );
int CheckValidate();
void InitGameData();
void DrawBlocked(HDC hdc);
int GenerateFood();
int RandomInt(int _min,int _max);
int CheckForFood(int x,int y);
int GetSnakeLength();
body* GetLast();
void InsertAfterLast(body *newbody);
void SetChildMove();
int SelectDifficulty(int diff);
double GetAbs(double num);
void DrawScore(HDC hdc);
// Snake.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Snake.h"
#define MAX_LOADSTRING 100
// 全局变量:
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(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
InitGameData();
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(