C++急速赛车小游戏(注释几天后更新)

简介: C++急速赛车小游戏(注释几天后更新)

成品展示



项目链接(带配图)


https://download.csdn.net/download/weixin_45525272/14946034


源代码


tools.h


#ifndef _TOOLS_H_
#define _TOOLS_H_
#include<graphics.h>
typedef unsigned long COLORREF;
typedef unsigned char byte;
typedef struct ARGB
{
  byte a;
  byte r;
  byte g;
  byte b;
}ARGB;
/// <summary>
/// 分解RGB合成的颜色
/// </summary>
/// <param name="c">待分解的颜色</param>
ARGB DecompositionColor(COLORREF c)
{
  byte r = (byte)c;
  byte g = (byte)(c >> 8);
  byte b = (byte)(c >> 16);
  byte a = (byte)(c >> 24);
  ARGB res = { a,r,g,b };
  return res;
}
/// <summary>
/// 绘制PNG透明图片
/// </summary>
/// <param name="x">图片左上角横坐标</param>
/// <param name="y">图片左上角纵坐标</param>
/// <param name="img">要绘制的图片指针</param>
void showimage(int x, int y, IMAGE* img)
{
  DWORD* pdraw = GetImageBuffer();
  DWORD* pImg = GetImageBuffer(img);
  int win_w = getwidth();
  int win_h = getheight();
  int img_w = img->getwidth();
  int img_h = img->getheight();
  int imgx = 0;
  for (int i = 0; i < img->getwidth(); i++)
  {
    for (int k = 0; k < img->getheight(); k++)
    {
      int index = k * img_w + i;//当前IMG操作位置
      ARGB img_argb = DecompositionColor(pImg[index]);
      imgx = (y + k) * win_w + (i + x);
      if (img_argb.a != 0 && imgx >= 0 && imgx < win_w * win_h)
      {
        pdraw[imgx] = pImg[index];
      }
    }
  }
}
#endif // !_TOOLS_H_


racingGame.cpp


#define _CRT_SECURE_NO_WARNINGS
#include "tool.h"
#include <stdio.h>
#include <time.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define COLS 4
#define ROW  6
#define IMGW 128
#define IMGH 128
#define WINDOWW IMGW*COLS
#define WINDOWH IMGH*ROW
#define isMoveL(i) (carInfo[i].carX>IMGW)
#define isMoveR(i) (carInfo[i].carX<IMGW*3-40)
#define isMoveU(i) (carInfo[i].carY>=0)
#define isMoveD(i) (carInfo[i].carY<=WINDOWH-65)
#define isInitD(i) (carInfo[i].carY>=WINDOWH)
IMAGE background;
IMAGE track;
IMAGE car[4];
struct Line
{
  int FL_x;
  int FL_y;
  int SL_x;
  int SL_y;
  int height;
};
enum Dir {down,up};
struct Car
{
  int carX;
  int carY;
  int carDir;
};
//40*62
struct Car carInfo[4] =
{
  IMGH * 2,WINDOWH-100,up,
  IMGH * 1 + 10,-62,down,     //1
  IMGH * 2 + 10,-62*2,down,   //2
  //IMGH*2+64+10,-62*2,down,    //2-2
  IMGH * 1 + 64+10,-62*3,down   //1-2
};
struct Car carEmemy[4] = { 
  IMGH * 1 + 10,-62,down ,
  IMGH * 1 + 64 + 10,-62 ,down,
  IMGH * 2 + 10, -62,down , 
  IMGH * 2 + 64 + 10,-62,down
};
void initCarEmemy(int index) 
{
  carInfo[index] = carEmemy[rand() % 4];
  carInfo[index].carY = rand() %8*-128;
}
int Timer(time_t m, int id)
{
  static time_t start[5] = { clock(),clock(),clock(),clock(),clock()};
  time_t end = clock();
  if (end - start[id] >= m)
  {
    start[id] = end;
    return 1;
  }
  return 0;
}
void showCar(int index) 
{
  showimage(carInfo[index].carX, carInfo[index].carY, car+index);
}
void moveCar(int index) 
{
  if (carInfo[index].carDir == down&&Timer(10,index))
  {
    carInfo[index].carY += 1;
  }
  if (carInfo[index].carDir == up&&Timer(25,0))
  {
    if(GetAsyncKeyState('A')||GetAsyncKeyState(VK_LEFT)&& isMoveL(index))
    {
      carInfo[index].carX -= 5;
    }
    if (GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)&& isMoveR(index))
    {
      carInfo[index].carX+= 5;
    }
    if (GetAsyncKeyState('W') || GetAsyncKeyState(VK_UP)&& isMoveU(index))
    {
      carInfo[index].carY -= 5;
    }
    if (GetAsyncKeyState('S') || GetAsyncKeyState(VK_DOWN) &&isMoveD(index))
    {
      carInfo[index].carY += 5;
    }
  }
}
struct Line lineSegment[16];
void initLine(int index) 
{
    lineSegment[index].FL_x = IMGW + 64;
    lineSegment[index].SL_x = IMGW * 2 + 64;
    lineSegment[index].FL_y = index * IMGH + 32;
    lineSegment[index].height = 32;
    lineSegment[index].SL_y = index * IMGH + 32;
}
void reInitLine(int index)
{
  lineSegment[index].FL_x = IMGW + 64;
  lineSegment[index].SL_x = IMGW * 2 + 64;
  lineSegment[index].FL_y = IMGH*-1 + 32;
  lineSegment[index].height = 32;
  lineSegment[index].SL_y = IMGH *-1 + 32;
}
void loadResource() 
{
  loadimage(&background, "background.png");
  loadimage(&track, "track.png");
  for (int i = 0; i < 4; i++) 
  {
    char fileName[20] = "";
    sprintf(fileName, "%03d.png", i);
    loadimage(car + i, fileName);
  }
}
void drawLayout()
{
  for (int i = 0; i < ROW; i++) 
  {
    for (int j = 0; j < COLS; j++)
    {
      int x = IMGW * j;
      int y = IMGH * i;
      if (j == 1 || j == 2)
      {
        putimage(x, y, &track);
      }
      else 
      {
        putimage(x, y, &background);
      }   
    }
  }
  setlinecolor(BLACK);
  setlinestyle(PS_SOLID, 4);
  line(IMGW, 0, IMGW, WINDOWH);
  line(IMGW*3, 0, IMGW * 3, WINDOWH);
  setlinecolor(WHITE);
  line(IMGW*2, 0, IMGW * 2, WINDOWH);
}
void drawLine(int i) 
{
  setlinecolor(WHITE);
  line(lineSegment[i].FL_x, lineSegment[i].FL_y, lineSegment[i].FL_x, lineSegment[i].FL_y + lineSegment[i].height);
  line(lineSegment[i].SL_x, lineSegment[i].SL_y, lineSegment[i].SL_x, lineSegment[i].SL_y + lineSegment[i].height);
}
void moveLine(int index)
{
  lineSegment[index].FL_y += 10;
  lineSegment[index].SL_y += 10;
}
int main() 
{
  mciSendString("open racing.mp3", 0, 0, 0);
  mciSendString("play racing.mp3 repeat", 0, 0, 0);
  srand((unsigned int)time(NULL));
  loadResource();
  initgraph(WINDOWW,WINDOWH,1);
  for (int i = 0; i < 16; i++)
  {
    initLine(i);
  }
  for (int i = 1; i < 4; i++) 
  {
    initCarEmemy(i);
  }
  while (1) 
  {
    BeginBatchDraw();
    drawLayout();
    for (int i = 0; i < 16; i++)
    {
      drawLine(i);
    }
    if (Timer(25,4)) 
    {
      for (int i = 15; i >=0; i--)
      {
        moveLine(i);
        if (lineSegment[i].FL_y >= WINDOWH) 
        {
          reInitLine(i);
        }
      }
    } 
    for (int i = 1; i < 4; i++) 
    {
      showCar(i);
      moveCar(i);
      if (isInitD(i)) 
      {
        initCarEmemy(i);
      }
    }
    showCar(0);
    moveCar(0);
    EndBatchDraw();
  }
  closegraph();
  return 0;
}
相关文章
|
6月前
|
自然语言处理 算法 Java
C/C++ 程序员编程规范之注释
C/C++ 程序员编程规范之注释
174 1
|
3月前
|
存储 数据可视化 C++
【C++】C++-机房收费管理系统(源码+注释)【独一无二】
【C++】C++-机房收费管理系统(源码+注释)【独一无二】
|
5月前
|
C++ 编译器
C++中的注释作用
C++ 代码中的注释可提高可读性,有单行和多行两种形式。单行注释以 `//` 开始,多行注释用 `/* ... */` 包裹。`#if 0 ... #endif` 用于条件编译,可实现可屏蔽的代码块,常用于调试。`#if` 后可跟条件表达式,在满足条件时执行相应代码。
|
6月前
|
C++
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
|
6月前
|
算法 编译器 C++
C++注释
C++注释
37 2
|
6月前
|
Serverless C++ 容器
【期末不挂科-C++考前速过系列P5】大二C++实验作业-多态性(3道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P5】大二C++实验作业-多态性(3道代码题)【解析,注释】
|
6月前
|
C++ 芯片
【期末不挂科-C++考前速过系列P4】大二C++实验作业-继承和派生(3道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P4】大二C++实验作业-继承和派生(3道代码题)【解析,注释】
|
6月前
|
编译器 C++
【期末不挂科-C++考前速过系列P3】大二C++第3次过程考核(20道选择题&12道判断题&2道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P3】大二C++第3次过程考核(20道选择题&12道判断题&2道代码题)【解析,注释】
|
5月前
|
编译器 C++
C++中的注释作用
C++ 中的注释用于提高代码可读性,有单行和多行两种形式。单行注释以 `//` 开始,多行注释用 `/* ... */` 包裹。`#if 0 ... #endif` 用于条件编译,可实现代码的临时屏蔽,适用于调试和测试。
|
6月前
|
C++
【期末不挂科-C++考前速过系列P2】大二C++第2次过程考核(20道选择题&10道判断题&3道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P2】大二C++第2次过程考核(20道选择题&10道判断题&3道代码题)【解析,注释】