贪吃蛇吧 关注:21,647贴子:143,695
  • 2回复贴,共1

Win32贪吃蛇源代码。背景非常简单

只看楼主收藏回复

这是头文件block.h
#ifndef BLOCK_H
#define BLOCK_H #define SNAKE_DOWN DVector(0,1)
#define SNAKE_UP DVector(0,-1)
#define SNAKE_RIGHT DVector(1,0)
#define SNAKE_LEFT DVector(-1,0)
#define SNAKE_DRECTION DVector #define GAME_RESULT int
#define GAME_OVER 0
#define GAME_SUCCEED 1
#define GAME_CONTINUE 2 #define Egg Block
#define MAX_SNAKE_SIZE 25 #include "windows.h"
#include <vector>
#include <time.h> using namespace std; class DVector{
public:
int x;
int y;
public:
DVector(int x = 0,int y = 0):x(x),y(y){}
bool operator==(const DVector dve) const{
if(x == dve.x && y == dve.y)
return true;
return false;
}
bool operator!=(const DVector dve) const{
return !(*this == dve);
}
const DVector operator+(const DVector dve) const{
int x1 = x +dve.x;
int y1 = y +dve.y;
return DVector(x1,y1);
}
const DVector operator-(const DVector dve) const{
int x1 = x - dve.x;
int y1 = y - dve.y;
return DVector(x1,y1);
}
}; class Block{
public:
DVector position;
int side;
public:
Block(DVector position = DVector()):position(position){
side = 20;
}
void SetSide(int side = 20){
this->side = side;
}
int bottom(){
return (position.y+1) * side;
}
int top(){
return position.y*side;
}
int left(){
return position.x*side;
}
int right(){
return (position.x+1)*side;
}
void show(HDC hdc){
Rectangle(hdc,left(),top(),right(),bottom());
Rectangle(hdc,left()+5,top()+5,right()-5,bottom()-5);
}
}; class Snake{
private:
HDC hdc;
vector<Block> veb;
DVector snakehead;
Egg egg; //Egg为Block类型
bool movestate;
SNAKE_DRECTION drection;
int size;
private:
bool isSnakeBody(DVector dve,int k){
vector<Block>::iterator bit;
for(bit = veb.begin()+k; bit != veb.end(); bit++){
if(bit->position == dve)
return true;
}
return false;
}
bool overBound(){
if( snakehead.x >= 20 || snakehead.x < 0 ||
snakehead.y >= 20 || snakehead.y < 0)
return true;
return false;
}
bool SnakeDead(){
if(overBound()||isSnakeBody(snakehead,1))
return true;
return false;
}
public:
Snake(){
srand(time(0));
}
void InitSnake(){
movestate = true;
drection = SNAKE_RIGHT; //初始方向为SNAKE_RIGHT
veb.clear(); //清空蛇
veb.push_back(Block(DVector(3,0)));
veb.push_back(Block(DVector(2,0)));
veb.push_back(Block(DVector(1,0))); //初始长度为3
snakehead = veb.front().position;
getEgg();
size = 3;
}
void SetHDC(HDC hdc){


1楼2013-01-31 23:53回复
    this -> hdc = hdc;
    } void getEgg(){
    egg.position.x = rand()%20;
    egg.position.y = rand()%20;
    while(isSnakeBody(egg.position,0)){
    egg.position.x = rand()%20;
    egg.position.y = rand()%20;
    }
    // showEgg(hdc);
    }
    void eatEgg(){
    veb.push_back(egg);
    size++;
    getEgg();
    } void showEgg(){
    Ellipse(hdc,egg.left(),egg.top(),egg.right(),egg.bottom());
    }
    void showSnake(){
    vector<Block>::iterator bit;
    for(bit = veb.begin(); bit != veb.end(); bit++){
    bit->show(hdc);
    }
    }
    //GAME_RESULT游戏结果类型为int,返回结果有GAME_OVER,GAME_CONTINUE,GAME_SUCCEED
    GAME_RESULT move(){
    movestate = true;
    vector<Block>::iterator bit;
    DVector temp1,temp2;
    for(bit = veb.begin();bit!=veb.end();bit++){
    if(bit->position == snakehead){
    temp1 = snakehead;
    bit->position = snakehead + drection;
    snakehead = veb.front().position;
    }
    else{
    temp2 = bit->position;
    bit->position = temp1;
    temp1 = temp2;
    }
    }
    // showSnake(hdc);
    if(snakehead == egg.position){
    eatEgg();
    if(size == MAX_SNAKE_SIZE)
    return GAME_SUCCEED;
    return GAME_CONTINUE; //这句不能省略,否则一吃蛋就game over!
    }
    if(SnakeDead())
    return GAME_OVER;
    return GAME_CONTINUE;
    } void turn(SNAKE_DRECTION drection)
    {
    if(movestate&&drection+this->drection != DVector()){
    this->drection = drection;
    movestate = false;
    }
    }
    };
    #endif
    下面是一个win32窗口一个模板代码文件名snakegame.cpp
    // SnakeGame.cpp : Defines the entry point for the application.
    // #include "stdafx.h"
    #include "Block.h"
    #include "resource.h" #define SPEED_STATE int
    #define SLOW 400
    #define NORMAL 200
    #define FAST 100 #define SNAKE_STATE int
    #define SNAKE_STOP 0
    #define SNAKE_MOVE 1
    #define SNAKE_DEAD 2 Snake snake;
    HINSTANCE g_hInstance = 0;
    SPEED_STATE speedstate = NORMAL;
    SNAKE_STATE snakestate = SNAKE_STOP;
    bool timerstate = true; VOID OnCommand(HWND hWnd,WPARAM wParam)
    {
    KillTimer(hWnd,1);
    switch(LOWORD(wParam)){
    case ID_START:
    snake.InitSnake();
    snakestate = SNAKE_MOVE;
    case ID_MOVE:
    if(snakestate == SNAKE_STOP)
    snakestate = SNAKE_MOVE;
    break;
    case ID_STOP:
    if(snakestate == SNAKE_MOVE)
    snakestate = SNAKE_STOP;
    return;
    case ID_SLOW:
    speedstate = SLOW;
    break;
    case ID_NORMAL:
    speedstate = NORMAL;
    break;
    case ID_FAST:
    speedstate = FAST;
    break;
    case ID_EXIT:
    PostQuitMessage(0);
    break;
    }
    if(snakestate != SNAKE_MOVE)
    return;
    SetTimer(hWnd,1,speedstate,NULL);


    2楼2013-01-31 23:53
    回复
      }
      VOID OnTimer(HWND hWnd){
      GAME_RESULT res = snake.move();
      if(res != GAME_CONTINUE){
      KillTimer(hWnd,1); //0
      snakestate = SNAKE_DEAD;
      if(res == GAME_SUCCEED){
      InvalidateRect(hWnd,NULL,TRUE); //吃下最后一个蛋再结束,不加上这句,但没吃下去直接完了
      MessageBox(hWnd,"Succeed!","Infor",MB_OK);
      }
      else
      MessageBox(hWnd,"Game Over!","Infor",MB_OK); //1
      //阻塞函数,如果先执行1,后执行0,则进入阻塞,点击了ok之后才会杀死计时器1
      //而每normal时间后会再次弹出消息盒子,只有点击一个Ok之后才会停止继续弹出消息盒子
      return;
      }
      InvalidateRect(hWnd,NULL,TRUE);
      }
      VOID OnPaint(HWND hWnd){
      PAINTSTRUCT ps = {0};
      HDC hdc = BeginPaint(hWnd,&ps);
      Rectangle(hdc,0,0,400,400);
      snake.SetHDC(hdc);
      snake.showEgg();
      snake.showSnake();
      EndPaint(hWnd,&ps);
      } void OnKeyDown(HWND hWnd,WPARAM wParam){
      switch(wParam)
      {
      case VK_UP:
      snake.turn(SNAKE_UP);
      break;
      case VK_DOWN:
      snake.turn(SNAKE_DOWN);
      break;
      case VK_LEFT:
      snake.turn(SNAKE_LEFT);
      break;
      case VK_RIGHT:
      snake.turn(SNAKE_RIGHT);
      break;
      case VK_SPACE:
      if(snakestate == SNAKE_MOVE){
      snakestate = SNAKE_STOP;
      KillTimer(hWnd,1);
      }else if(snakestate == SNAKE_STOP){
      snakestate = SNAKE_MOVE;
      SetTimer(hWnd,1,speedstate,NULL);
      }else{;}
      break;
      }
      }
      HRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam){
      switch(nMsg){
      case WM_CREATE:
      snake.InitSnake();
      break;
      case WM_KEYDOWN:
      OnKeyDown(hWnd,wParam);
      break;
      case WM_COMMAND:
      OnCommand(hWnd,wParam);
      break;
      case WM_PAINT:
      OnPaint(hWnd);
      break;
      case WM_TIMER:
      OnTimer(hWnd);
      break;
      case WM_DESTROY:
      PostQuitMessage(0);
      break;
      }
      return DefWindowProc(hWnd,nMsg,wParam,lParam);
      }
      BOOL Register(LPSTR lpClsName, WNDPROC WndProc)
      {
      WNDCLASSEX wce = {0};
      wce.cbSize = sizeof wce;
      wce.cbClsExtra = 0;
      wce.cbWndExtra = 0;
      wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
      wce.hCursor = NULL;
      wce.hIcon = NULL;
      wce.hIconSm = NULL;
      wce.hInstance = g_hInstance;
      wce.lpfnWndProc = WndProc;
      wce.lpszClassName = lpClsName;
      wce.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
      wce.style = CS_HREDRAW|CS_VREDRAW;
      ATOM nAtom = RegisterClassEx(&wce);
      if(nAtom == -1)
      return FALSE;
      return TRUE;
      } HWND CreateMain(LPSTR lpClsName,LPSTR lpWndName)
      {
      HWND hWnd = CreateWindowEx(0,lpClsName,lpWndName,WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,g_hInstance,0);
      return hWnd;
      } VOID DisPlay(HWND hWnd)
      {
      ShowWindow(hWnd,SW_SHOW);
      UpdateWindow(hWnd);
      } VOID Message()
      {
      MSG nMsg = {0};
      while(GetMessage(&nMsg,NULL,0,0))
      {
      TranslateMessage(&nMsg);
      DispatchMessage(&nMsg);
      }
      } int APIENTRY WinMain(HINSTANCE hInstance,
      HINSTANCE hPrevInstance,
      LPSTR lpCmdLine,
      int nCmdShow)
      {
      // TODO: Place code here.
      g_hInstance = hInstance;
      if(!Register("Wnd",WndProc))
      {
      MessageBox(0,"Register failed!","Infor",MB_OK);
      return 0;
      }
      HWND hWnd = CreateMain("Wnd","Window");
      DisPlay(hWnd);
      Message();
      return 0;
      }
      同时再插入一个menu,即可以运行,插入menu,下面是系统自动生成的resouce.h
      #define IDR_MENU1 101
      #define ID_MOVE 40001
      #define ID_STOP 40002
      #define ID_EXIT 40003
      #define ID_SLOW 40004
      #define ID_NOMAL 40005
      #define ID_NORMAL 40005
      #define ID_FAST 40006
      #define ID_ABOUT 40007
      #define ID_START 40008 // Next default values for new objects
      //
      #ifdef APSTUDIO_INVOKED
      #ifndef APSTUDIO_READONLY_SYMBOLS
      #define _APS_NEXT_RESOURCE_VALUE 102
      #define _APS_NEXT_COMMAND_VALUE 40009
      #define _APS_NEXT_CONTROL_VALUE 1000
      #define _APS_NEXT_SYMED_VALUE 101
      #endif
      #endif


      3楼2013-01-31 23:53
      回复