windows编程:画线,简单的碰撞检测,简单的帧率锁定

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define WINDOW_CLASS_NAME "WINCLASS1"

#define WINDOW_WIDTH  640
#define WINDOW_HEIGHT 480

#define KEYDOWN(vk_code)    ((GetAsyncKeyState(vk_code) & 0x8000) ? 1:0)
#define KEYUP(vk_code)        ((GetAsyncKeyState(vk_code) & 0x8000) ? 0:1)

//全局变量
HWND main_window_handle = NULL;
HINSTANCE hInstance_App = NULL;

char buffer[80];

//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hwnd,
    UINT msg,
    WPARAM wParam,
    LPARAM lPram)
{
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rect;
    char buffer[80];
    switch (msg)
    {
    case WM_CREATE:
    {
                      return 0;
    }break;
    case WM_PAINT:
    {
                     hdc = GetDC(hwnd);
                     ReleaseDC(hwnd, hdc);
                     GetClientRect(hwnd, &rect);
                     ValidateRect(hwnd, &rect);

                     return 0;
    }break;
    case WM_CLOSE:
    {
                     if (IDYES != MessageBox(hwnd, "确实要退出应用程序?", "退出", MB_YESNO | MB_ICONEXCLAMATION))
                     {
                         return 0;
                     }
                     else
                     {
                         PostQuitMessage(0);
                     }
    }break;
    case WM_SIZE:
    {

    }break;
    case WM_DESTROY:
    {
                       PostQuitMessage(0);
                       return 0;
    }break;
    default:break;
    }
    return DefWindowProc(hwnd, msg, wParam, lPram);
}
void GameMain()
{
    return;
}
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    //定义窗口类
    WNDCLASSEX winClass;
    HWND hWnd;
    MSG msg;

    HPEN pen = NULL;
    int color_change_count = 100;

    //填充窗口类的各成员
    winClass.cbSize = sizeof(WNDCLASSEX);
    winClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winClass.lpfnWndProc = WindowProc;    //窗口消息处理函数
    winClass.cbClsExtra = 0;
    winClass.cbWndExtra = 0;
    winClass.hInstance = hInstance;
    winClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winClass.lpszMenuName = NULL;
    winClass.lpszClassName = WINDOW_CLASS_NAME;        //窗口类名
    winClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    //保存实例句柄到全局变量
    hInstance_App = hInstance;

    //注册窗口类
    if (!RegisterClassEx(&winClass))
    {
        return 0;
    }

    //创建窗口类的一个成员
    if (!(hWnd = CreateWindowEx(NULL,
        WINDOW_CLASS_NAME,
        "时间锁定的屏幕保护程序",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        200, 200,
        WINDOW_WIDTH, WINDOW_HEIGHT,
        NULL,
        NULL,
        hInstance,
        NULL)))
    {
        return 0;
    }

    //保存窗体句柄到全局变量中
    main_window_handle = hWnd;

    //得到设备上下文
    HDC hdc = GetDC(hWnd);

    //设置随机数生成器的种子
    srand(GetTickCount());

    //线段终点坐标
    int x1 = rand() % WINDOW_WIDTH;
    int y1 = rand() % WINDOW_HEIGHT;
    int x2 = rand() % WINDOW_WIDTH;
    int y2 = rand() % WINDOW_HEIGHT;

    //线段终点的速度
    int x1v = -4 + rand() % 8;
    int y1v = -4 + rand() % 8;
    int x2v = -4 + rand() % 8;
    int y2v = -4 + rand() % 8;

    //消息循环
    while (TRUE)
    {
        DWORD start_time = GetTickCount();

        if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
            {
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        //100次变换一次颜色
        if (++color_change_count >= 100)
        {
            color_change_count = 0;
            if (pen)
            {
                DeleteObject(pen);
            }
            pen = CreatePen(PS_SOLID, 1, RGB(rand() % 256, rand() % 256, rand() % 256));
            SelectObject(hdc, pen);
        }
        //移动线段终点
        x1 += x1v;
        y1 += y1v;

        x2 += x2v;
        y2 += y2v;

        //碰撞检测,看是否碰到窗体的边界
        if (x1<0 || x1>WINDOW_WIDTH)
        {
            x1v = -x1v;
            x1 += x1v;
        }
        if (y1<0 || y1>WINDOW_HEIGHT)
        {
            y1v = -y1v;
            y1 += y1v;
        }

        if (x2<0 || x2>WINDOW_WIDTH)
        {
            x2v = -x2v;
            x2 += x2v;
        }
        if (y2<0 || y2>WINDOW_HEIGHT)
        {
            y2v = -y2v;
            y2 += y2v;
        }

        MoveToEx(hdc, x1, y1,NULL);
        LineTo(hdc, x2, y2);

        //锁定帧率为30fps,1/30秒,约等于33毫秒。
        while (GetTickCount() - start_time < 33);
        //如果用户按了ESC,发送WM_CLOSE消息。退出程序。
        if (KEYDOWN(VK_ESCAPE))
            SendMessage(hWnd, WM_CLOSE, 0, 0);
    }
    ReleaseDC(hWnd, hdc);
    return msg.wParam;
}
时间: 2024-08-24 12:38:19

windows编程:画线,简单的碰撞检测,简单的帧率锁定的相关文章

画线代码V1.0.0

画线代码: 最终效果图: 优点: 1.效果还行,计算量也不大(就一点2维直线一般式能有多少运算量). 缺点: 1.每条线怎么也是建模,可能会有点开销. 2.编辑起来很是麻烦. 代码部分: /*************************************** Editor: Tason Version: v1.0 Last Edit Date: 2018-XX-XX Tel: [email protected] Function Doc: 1.自建Mesh划线 ************

CGContextRef 画线简单用法

CGContextRef CGContextMoveToPoint(context,150,50);//圆弧的起始点 CGContextAddArcToPoint(context,100,80,130,150,50); 是说从(150,50)到(100,80)画一条线,然后再从(100,80)到(130,150)画一条线,从这两条线(无限延伸的) 和半径50可以确定一条弧, 而 CGContextAddArc(context, 100, 100, 30, 0, M_PI, 1); 比较简单了,(

[C# 网络编程系列]专题十:实现简单的邮件收发器

转自:http://www.cnblogs.com/zhili/archive/2012/09/24/2689892.html 引言: 在我们的平常工作中,邮件的发送和接收应该是我们经常要使用到的功能的.因此知道电子邮件的应用程序的原理也是非常有必要的,在这一个专题中将介绍电子邮件应用程序的原理.电子邮件应用程序中涉及的协议和实现一个简答的电子邮件收发器程序. 一.邮件应用程序基本知识 1.1 电子邮件原理及相关协议 说到电子邮件的原理,其实和我们现实生活中寄邮件和寄包裹是一样的原理的.就让我们

ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 设置和初始化数据库 上一章节中我们已经设置和配置好了 EF 框架服务,本章节我们就来学习如何使用 EF 框架设置和初始化数据库 初始化数据库 初始化数据库的方法之一是使用 EF 框架来创建数据库,仅仅需要两步就能完成 第一步,给我们的 HelloWorld 项目添加迁移 ( migration ) 代码 迁移代码是 C# 代码,用来在数据库系统中创建数据库

ASP.NET Core 视图 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 视图 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 视图 花了几章节,终于把 ASP.NET Core MVC 中的 C 控制器涉及的七七八八了,本章节我们来学习下 V,也就是视图部分. ASP.NET Core MVC 应用程序中,没有任何内容像页面,并且在 URL 中指定路径时, 它也不包含与页面直接对应的任何内容. ASP.NET Core MVC 应用程序中最接近页面的东西被称为视图 是不是很拗口,哈哈,页面就是

ASP.NET Core 配置 Entity Framework Core - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 配置 Entity Framework Core - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 Entity Framework Core 上一章节学习完了视图,其实我们应该立即着手讲解模型的,但 ASP.NET Core MVC 中的模型和 Entity Framework 有相当大的关系,所以,在此之前,我们先来讲讲 Entity Framework Core 和如何配置它 本章中,我们将设置和配置我们的应用程

ASP.NET Core 配置 EF SQLite 支持 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 配置 EF SQLite 支持 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 EF SQLite 支持 上一章节我有提到 macOS 版的 Visual Studio Community 没有携带 LocalDB,也就是说 LocalDB 暂时不支持 macOS 系统 虽然我可以在 Windows 上继续完成接下来的教程,但我觉得还是感觉不妥,如果其它使用苹果笔记本的人要去哪里找 Windows 的电脑 我临时改变

ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 MVC 前面几章节中,我们都是基于 ASP.NET 空项目 模板创建的 HelloWorld 上做开发 通过这个最基本的 HelloWorld 项目,我们了解了很多知识,初窥了 ASP.NET Core,并对 ASP.NET Core 的运行机制有了一个基本的了解 MVC 模式是 Web 开发中最重要的一个模式之一,通过 MVC,我们可以将控制器.模型和视

ASP.NET Core 动作结果 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 动作结果 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 动作结果 前面的章节中,我们一直使用简单的 C# 类作为控制器. 虽然这些类不是从基类派生的,但仍然可以在 MVC 中使用这种方法. 当然了,对于控制器,但更常见的做法是从 Microsoft.AspNetCore.Mvc 命名空间中提供的控制器基类中派生控制器.本章中,我们将尝试这么做,并且学习动作结果 ( Action Results ). 动作结果 ( Act

ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 EF 框架服务 上一章节中我们了解了 Entity Framework 的基本工作原理和 DbContext ,我们也创建了一个自己的 HelloWorldDBContext. 本章节我们就来讲讲如何设置我们的 EF 框架来链接到 SQLite 数据库 配置 EF 框架服务 要让我们的 EF 框架的 DBContext 能够运行起来,我们需要更改一