【Visual C++】游戏编程学习笔记之五:单一背景滚动
本系列文章由@二货梦想家张程 所写,转载请注明出处。
本文章链接:http://blog.csdn.net/terence1212/article/details/44224963
作者:ZeeCoder 微博链接:http://weibo.com/zc463717263
我的邮箱:michealfloyd@126.com 欢迎大家发邮件来和我交流编程心得
you are what you read!与大家共勉!
-----------------------------------------------------------分割线:ZeeCoder--------------------------------------------------------
一、本笔记要实现利用键盘响应来控制单一背景滚动
首先单一背景滚动的方法是:准备一张相当大的背景图,当游戏进行时,随着画面中人物的移动,背景的显示区域也跟着移动,相信玩过LOL的都知道,游戏中画面移动的方式有两种(1)跟随人物移动(2)鼠标移动到边界来控制背景滚动。
要制作单一背景滚动的方法很简单,看下图:
图中矩形框为我们要显示的背景区域,(x,y)为矩形框左上角坐标。那么我们不难发现,在每次利用BitBlt进行贴图的时候只需要改变x,y的值就可以实现单一背景滚动。
在消息队列中加入WM_KEYDOWN代表了按下键盘的处理,在此处更新x,y的值即可。
二、程序代码:
相信大家如果看了前几篇笔记会发现博主在写代码的时候相当凌乱,所以今天特意将代码理了理,以便日后复习起来能够更加方便,也方便读者阅读。
#include "stdafx.h" #include "RunBg.h" #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name HDC hdc,mdc; HWND hWnd; HBITMAP bg; DWORD tNow , tPre; int x = 0 , y = 0 ; // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); void MyPaint(HDC hdc); /***************************主函数**********************************/ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_RUNBG, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // Main message loop: GetMessage(&msg , NULL , NULL , NULL); while (msg.message != WM_QUIT) { if ( PeekMessage( &msg , NULL ,0 ,0 ,PM_REMOVE))//PM_REMOVE消息从队列里除掉 { TranslateMessage( &msg); DispatchMessage(&msg); } else { tNow = GetTickCount();//实现游戏循环 if (tNow - tPre >= 100) { MyPaint(hdc); } } } return (int) msg.wParam; } /***************************窗口类函数函数**********************************/ 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_RUNBG)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_RUNBG); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } /***************************初始化函数**********************************/ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(_T("RunBg"), _T("背景滚动"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } MoveWindow(hWnd , 10 , 10 , 640 ,360 ,true ); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); hdc = GetDC(hWnd); mdc = CreateCompatibleDC(hdc); bg = (HBITMAP)LoadImage(NULL , _T("res.bmp") , IMAGE_BITMAP , 900 , 506 , LR_LOADFROMFILE);//加载背景图 MyPaint(hdc); return TRUE; } //***************************消息响应函数********************************** //按下【↑】【↓】【←】【→】使背景滚动 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_KEYDOWN: switch (wParam) { case VK_LEFT: //响应【←】按键 x -= 20; if (x <0) { x = 0; } break; case VK_RIGHT://响应【→】按键 x += 20; if (x > 900) { x = 900; } break; case VK_UP://响应【↑】按键 y -= 20 ; if (y < 0) { y = 0; } break;//响应【↓】按键 case VK_DOWN: y += 20; if (y >= 506) { y = 506; } break; } break; case WM_DESTROY: DeleteDC(mdc); DeleteObject(bg); ReleaseDC(hWnd , hdc); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } //***************************自定义绘图函数********************************* //按照x,y来实现背景图的剪裁贴图 void MyPaint(HDC hdc) { SelectObject(mdc , bg); BitBlt(hdc , 0 , 0 ,640 , 360 , mdc , x , y , SRCCOPY);//x,y代表背景图的左上角坐标 tPre = GetTickCount(); }
三、实现效果
哈哈,特意在背景中p上一个人物让背景移动更直观。
笔记五就写到这了。今天最大的感悟就是:在书上看到这些程序,往往只是看看,而不去动手实现的话,你就永远只是知其然而不知其所以然。特别是在最开始学习的时候,必须每个小程序都要自己亲自码代码,跑程序,要重视这一过程,相信只有这样才能学到更多,学得更扎实。
还是那句老话,希望大家在看了我的笔记能留下宝贵的意见,也欢迎志同道合之人给我发邮件讨论游戏编程,互助才能学得更快。
---end!
本笔记配套使用代码已上传,欢迎下载查阅:【Visual C++】游戏编程笔记五配套代码
【Visual C++】游戏编程学习笔记之五:单一背景滚动的更多相关文章
- 【Visual C++】游戏编程学习笔记之四:透明动画实现
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...
- 【Visual C++】游戏编程学习笔记之八:鼠标输入消息(小demo)
本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder 微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...
- 【Visual C++】游戏编程学习笔记之七:键盘输入消息
本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder 微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...
- 【Visual C++】游戏编程学习笔记之六:多背景循环动画
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44264153 作者:ZeeCod ...
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- 【Visual C++】游戏编程学习笔记之三:游戏循环的使用
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44208419 作者:Zee ...
- 【Visual C++】游戏编程学习笔记之九:回合制游戏demo(剑侠客VS巡游天神)
本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder 微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.com ...
- 【Visual C++】游戏编程学习笔记之二:定时器的使用
本系列文章由@二货梦想家张程所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44195831 作者:ZeeCode ...
随机推荐
- Android开发之手把手教你写ButterKnife框架(一)
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52662376 本文出自:[余志强的博客] 一.概述 JakeWhar ...
- [Python]多个装饰器合并
django程序,需要写很多api,每个函数都需要几个装饰器,例如 @csrf_exempt @require_POST def foo(request): pass 既然那么多个方法都需要写2个装饰 ...
- 自制Linux 终端 锁屏防窃助手
很多时候我们不能一直守护在自己的电脑旁边,而且有些文件并不想让别人知道.那么这时候来个锁屏,是再合适不过的了.今天分享一个自制的锁屏工具,如下. 准备 操作系统 : 我这里是ElementaryOS虚 ...
- Android 在 SElinux下 如何获得对一个内核节点的访问权限
点击打开链接 Android 5.0下,因为采取了SEAndroid/SElinux的安全机制,即使拥有root权限,或者对某内核节点设置为777的权限,仍然无法在JNI层访问. 本文将以用户自定义的 ...
- 21 RadioGroup ListFragment
结构 MainActivity.java package com.qf.day21_radiogroupfragment_demo3; import java.util.ArrayList; impo ...
- Android实现系统下拉栏的消息提示——Notification
Android实现系统下拉栏的消息提示--Notification 系统默认样式 默认通知(通用) 效果图 按钮 <Button android:layout_width="match ...
- GDB调试工具入门
从windows转到linux下已经有一段时间了,每次刷算法题碰到问题需要调试的时候,就分分钟想关机,切换到windows上调试.于是,花了一点时间来搜索一下linux下常见的调试工具,这不搜不知道, ...
- Dynamics CRM2015 非基础语言环境下产品无法新建的问题
该现象出现在2015版本上,之前从没注意过这个问题不知道以前的版本是否存在. 我的安装包的基础语言是中文,第一张图有添加产品的按钮,切换到英文环境下后就没有了,一开始以为是系统做了隐藏处理,但用工具查 ...
- Android项目开发填坑记-Fragment的onBackPressed
Github版 CSDN版 知识背景 Fragment在当前的Android开发中,有两种引用方式,一个是 Android 3.0 时加入的,一个是supportV4包中的.这里简称为Fragment ...
- Java基础---Java---IO流-----BufferedReader、BufferedWriter、缓冲区、装饰设计模式及和继承的区别
IO流 IO流用来处理设备之间的数据传输 java对数据的操作是过流的方式 流按操作数据分为两种:字节流与字符流 流按流向分为:输入流,输出流. IO流常用基类 字节流的抽象基类:InputStrea ...