記事ディレクトリ
1. 基本的な説明
- EasyX は C++ 用のグラフィックス ライブラリであり、C/C++ 初心者がグラフィックスやゲーム プログラミングをすぐに始めるのに役立ちます。
- たとえば、EasyX グラフィック ライブラリに基づいて、幾何学模様のある家や動く車をすばやく描画したり、テトリス、スネーク、リバーシなどの小さなゲームを作成したりできます。
- C言語からプログラミングを学ぶ人も多いですが、現状は
-
- 学校では基本的な文法しか教えないので、黒い窓の中で練習をしていましたが、生徒たちはとても退屈です。
- グラフィックプログラミングを教えている学校があっても、Win32やOpenlGlなどの難しいものを使っていることもあり、まだまだ敷居が高く、初心者は引っかかりやすいです。
- EasyX の導入を開始します。
2. 原則
Windows グラフィック プログラミングに基づいて、Windows での複雑なプログラム プロセスをカプセル化し、Windows でのプログラミング プロセスを隠し、ユーザーにシンプルで使い慣れたインターフェイスを提供します。グラフィックス ライブラリ内の関数に対するユーザーの呼び出しは、最終的には Windows の基盤となる API によって実装されます。
3. インストール
- Easyx グラフィック ライブラリは、さまざまなバージョンの Vs をサポートしています。ダウンロードして解凍した後、インストール プログラムを直接実行するだけです。
- ヘッダー ファイル graphics.h、更新後に使用するのが最善であることに注意してください
easyx.h
。一部のマクロ定義は更新前に追加する必要がありますEW_
。 - ヘルプ ドキュメントEasyX ドキュメント - 基本的な手順
- C++ 用 EasyX グラフィック ライブラリをダウンロード
4. カラー
三原色:赤緑青
RGBマクロによる合成色ですが、実際には合成された色は16進数の整数になります。
各色の部分の値は0~255で、数値が大きいほど色が明るくなります。
RGB(5,5,5);
5. EasyX デバイス
- 座標のデフォルトの原点はウィンドウの左上隅で、X 軸は右が正、Y 軸は下が正で、測定単位はピクセルです。
- デバイス: 簡単に言えば、描画面です。
- EasyX には 2 種類のデバイスがあり、1 つはデフォルトの描画ウィンドウ、もう 1 つは IMAGE オブジェクトです。現在描画に使用されているデバイスは SetWorkingimage() 関数を通じて設定できます。現在描画に使用しているデバイスを設定すると、すべての描画機能がそのデバイス上で描画されます。(後で分かります)
6. 窓関数
ウィンドウ関数はウィンドウ上の一部の操作に使用されます。
closegraph();//关闭绘图窗口
cleardevice();//清空绘图设备
initgraph
説明
描画ウィンドウを初期化します。
定義ステートメント
HWND initgraph(
int width,
int height,
int flag = NULL
);
パラメータ
-
width: 描画ウィンドウの幅。
-
高さ: 描画ウィンドウの高さ。
-
flag: 描画ウィンドウのスタイル。デフォルトは NULL です。次の値を指定できます。
価値 意味 EW_DBLCLKS マウスのダブルクリック イベントは描画ウィンドウでサポートされています。 EW_NOCLOSE 描画ウィンドウの閉じるボタンを無効にします。 EW_NOMINIMIZ プロット ウィンドウの最小化ボタンを無効にします。 EW_SHOWCONSOLE コンソールウィンドウを表示します。 ps: 前のものを書くこともできません
EW_
コンソール: コンソール
戻り値
新しく作成された描画ウィンドウのハンドルを返します。
サンプルコード
次のコード スニペットは、640x480 の寸法の描画ウィンドウを作成します。
initgraph(640, 480);
次のコード スニペットは、640x480 のサイズのプロット ウィンドウを作成し、同時にコンソール ウィンドウを表示します。
initgraph(640, 480, EW_SHOWCONSOLE);
次のコード スニペットは、640x480 のサイズのプロット ウィンドウを作成し、コンソール ウィンドウを表示して、[閉じる] ボタンを無効にします。
initgraph(640, 480, EW_SHOWCONSOLE | EW_NOCLOSE);
closegraph
この関数は描画ウィンドウを閉じるために使用されます。
void closegraph();
cleardevice
この関数は、現在の背景色で描画デバイスをクリアします。
void cleardevice();
7. グラフィックの色とスタイルに関する機能
シート
関数 | 説明 |
---|---|
設定色 | 現在のデバイス描画の背景色を設定します。 |
セットバックモード | 現在のデバイスのパターン塗りつぶしとテキスト出力の背景モードを設定します。 |
塗りつぶしの色を設定 | 現在のデバイスの塗りつぶしの色を設定します。 |
セットフィルスタイル | 現在のデバイスのパディング スタイルを設定します。 |
セットラインカラー | 現在のデバイスの線の色を設定します。 |
セットラインスタイル | 現在のデバイスの線画スタイルを設定します。 |
バックグラウンドbk相関関数
setbkcolor
- 背景色を設定します
この関数は、現在のデバイス描画の背景色を設定するために使用されます。
void setbkcolor(COLORREF color);
パラメータ
色
設定する背景色を指定します。
戻り値
なし
述べる
背景色を設定した後、既存の背景色は変更されず、背景色の値のみが変更され、outtextxy などの描画ステートメントの実行後は、新しく設定された背景色の値が使用されます。
背景色全体を変更する必要がある場合は、背景色を設定した後、cleardevice() 関数を実行できます。
例
次の例では、青い背景に赤い四角形の描画を実装します。
#include <graphics.h>
#include <conio.h>
int main()
{
// 初始化绘图窗口
initgraph(640, 480);
// 设置背景色为蓝色
setbkcolor(BLUE);
// 用背景色清空屏幕
cleardevice();
// 设置绘图色为红色
setcolor(RED);
// 画矩形
rectangle(100, 100, 300, 300);
// 按任意键退出
_getch();
closegraph();
return 0;
}
setbkmode
- パターンテキストの背景を設定します
この関数は、現在のデバイス パターンの塗りつぶしとテキスト出力の背景モードを設定するために使用されます。
void setbkmode(int mode);
パラメータ
モード
パターンの塗りつぶしとテキスト出力の背景モードを指定します。値は次のとおりです。
価値 | 説明 |
---|---|
不透明 | 背景は現在の背景色で塗りつぶされます (デフォルト)。 |
透明 | 背景は透明です。 |
フィルフィル関連関数
setfillcolor
- 塗りつぶしの色を設定する
この関数は、現在のデバイスの塗りつぶしの色を設定するために使用されます。
void setfillcolor(COLORREF color);
パラメータ
色
塗りつぶしの色。
戻り値
なし
例
青の塗りつぶしを設定します。
setfillcolor(BLUE);
setfillstyle
- 塗りつぶしスタイルを設定する
この関数は、現在のデバイスのパディング スタイルを設定するために使用されます。
void setfillstyle(
FILLSTYLE* pstyle
);
void setfillstyle(
int style,
long hatch = NULL,
IMAGE* ppattern = NULL
);
void setfillstyle(
BYTE* ppattern8x8
);
パラメータ
ピースタイル
塗りつぶしスタイルFILLSTYLEへのポインター。
スタイル
塗りつぶしのスタイルを指定します。次のマクロまたは値を使用できます。
大きい | 価値 | 意味 |
---|---|---|
BS_SOLID | 0 | しっかりとした詰め物。 |
BS_NULL | 1 | 満たされていません。 |
BS_HATCHED | 2 | パターンの塗りつぶし。 |
BS_パターン | 3 | カスタムパターンの塗りつぶし。 |
BS_DIBPATTERN | 5 | カスタム画像パディング。 |
ハッチ
ハッチング パターンを指定します。スタイルが BS_HATCHED の場合にのみ有効です。塗りつぶしパターンの色は関数setfillcolorによって設定され、背景領域が背景色を使用するか透明のままにするかは関数setbkmodeによって設定されます。ハッチ引数には、次のマクロまたは値を指定できます。
大きい | 価値 | 意味 |
---|---|---|
HS_HORIZONTAL | 0 | |
HS_VERTICAL | 1 | |
HS_FDIAGONAL | 2 | |
HS_B対角線 | 3 | |
HS_CROSS | 4 | |
HS_DIAGCROSS | 5 |
パターン
カスタムの塗りつぶしパターンまたはイメージを指定します。スタイルが BS_PATTERN または BS_DIBPATTERN の場合にのみ有効です。
スタイルが BS_PATTERN の場合、ppattern が指す IMAGE オブジェクトはカスタム塗りつぶしパターンを表し、IMAGE の黒 (BLACK) が背景領域に対応し、黒以外がパターン領域に対応します。パターンエリアの色は関数[settextcolor](…/5 テキスト出力関連関数/settextcolor.htm)で設定します。
スタイルが BS_DIBPATTERN の場合、ppattern が指す IMAGE オブジェクトはカスタム パディング イメージを表し、パディングを実装するためのパディング ユニットとして使用されます。
パターン8x8
カスタムの塗りつぶしパターンを指定します。効果は BS_PATTERN と同じです。このオーバーロードは、BYTE[8] 配列を使用して 8 x 8 領域の塗りつぶしパターンを定義します。配列では、各要素が行のスタイルを表し、BYTE 型には 8 ビットがあり、各点の状態を左から右、上位から下位までビットごとに表すため、8 x 8 の充填単位が形成され、タイル状に並べられます。充填を実現する充填ユニット。対応する 2 進数のビットは、背景領域の場合は 0、パターン領域の場合は 1 です。
戻り値
なし
例
次のコード スニペットは、ソリッド パディングを設定します。
setfillstyle(BS_SOLID);
次のコード スニペットは、塗りつぶしパターンを対角線塗りつぶしに設定します。
setfillstyle(BS_HATCHED, HS_BDIAGONAL);
次のコード スニペットは、カスタム画像パディング (res\bk.jpg で指定された塗りつぶし画像) を設定します。
IMAGE img;
loadimage(&img, _T("res\\bk.jpg"));
setfillstyle(BS_DIBPATTERN, NULL, &img);
次の完全なコードは、カスタムの塗りつぶしパターン (小さな四角形の塗りつぶし) を設定し、そのパターンで三角形を塗りつぶします。
#include <conio.h>
#include <graphics.h>
int main()
{
// 创建绘图窗口
initgraph(640, 480);
// 定义填充单元
IMAGE img(10, 8);
// 绘制填充单元
SetWorkingImage(&img); // 设置绘图目标为 img 对象
setbkcolor(BLACK); // 黑色区域为背景色
cleardevice();
setfillcolor(WHITE); // 白色区域为自定义图案
solidrectangle(1, 1, 8, 5);
SetWorkingImage(NULL); // 恢复绘图目标为默认绘图窗口
// 设置填充样式为自定义填充图案
setfillstyle(BS_PATTERN, NULL, &img);
// 设置自定义图案的填充颜色
settextcolor(GREEN);
// 绘制无边框填充三角形
POINT pts[] = {
{
50, 50}, {
50, 200}, {
300, 50} };
solidpolygon(pts, 3);
// 按任意键退出
_getch();
closegraph();
}
次のコード スニペットは、カスタムの塗りつぶしパターン (円形のハッチング) を設定します。
setfillstyle((BYTE*)"\x3e\x41\x80\x80\x80\x80\x80\x41");
次のコード スニペットは、カスタム塗りつぶしパターン (細いスラッシュ パターンと太いスラッシュ パターンの塗りつぶし) を設定します。
setfillstyle((BYTE*)"\x5a\x2d\x96\x4b\xa5\xd2\x69\xb4");
直線相関関数
setlinecolor
- 描画線の色を設定する
この関数は、現在のデバイスの線の色を設定するために使用されます。
void setlinecolor(COLORREF color);
パラメータ
色
設定する線の色です。
setlinestyle
-線画スタイルの設定
この関数は、現在のデバイスの線描画スタイルを設定するために使用されます。
void setlinestyle(
const LINESTYLE* pstyle
);
void setlinestyle(
int style,
int thickness = 1,
const DWORD *puserstyle = NULL,
DWORD userstylecount = 0
);
パラメータ
ピースタイル
線画スタイルLINESTYLEへのポインター。
スタイル
線画スタイル (詳細については「備考」を参照)。
厚さ
線の幅 (ピクセル単位)。
プユーザースタイル
ユーザー定義のスタイル配列。このパラメーターは、線種が PS_USERSTYLE の場合にのみ有効です。
配列の最初の要素は描画される線の長さを指定し、2 番目の要素は空白の長さを指定し、3 番目の要素は描画される線の長さを指定し、4 番目の要素は空白の長さを指定します。
ユーザースタイルカウント
ユーザー定義のスタイル配列内の要素の数。
戻り値
なし
述べる
パラメータ style は線の描画スタイルを指定するもので、線のスタイル、端点のスタイル、接続のスタイルの 3 種類で構成されます。1 つのタイプまたは複数のタイプの組み合わせとすることができます。同じ型内で指定できるスタイルは 1 つだけです。
線のスタイルには次の値を指定できます。
価値 | 意味 |
---|---|
PS_SOLID | 線の形状は実線です。 |
PS_DASH | 線の形状は次のとおりです: ------------ |
PS_DOT | 直線形状は次のとおりです。 |
PS_ダッシュドット | 線の形状は、-・-・-・-・-・-・です。 |
PS_DASHDOTDOT | 直線の形状は次のとおりです。 |
PS_NULL | 线形为不可见。 |
PS_USERSTYLE | 线形样式为用户自定义,由参数 puserstyle 和 userstylecount 指定。 |
宏 PS_STYLE_MASK 是直线样式的掩码,可以通过该宏从画线样式中分离出直线样式。
端点样式可以是以下值:
值 | 含义 |
---|---|
PS_ENDCAP_ROUND | 端点为圆形。 |
PS_ENDCAP_SQUARE | 端点为方形。 |
PS_ENDCAP_FLAT | 端点为平坦。 |
宏 PS_ENDCAP_MASK 是端点样式的掩码,可以通过该宏从画线样式中分离出端点样式。
连接样式可以是以下值:
值 | 含义 |
---|---|
PS_JOIN_BEVEL | 连接处为斜面。 |
PS_JOIN_MITER | 连接处为斜接。 |
PS_JOIN_ROUND | 连接处为圆弧。 |
宏 PS_JOIN_MASK 是连接样式的掩码,可以通过该宏从画线样式中分离出连接样式。
掩码宏表示对应样式组所占用的所有位。例如,对于一个已经混合了多种样式的 style 变量,如果希望仅将直线样式修改为点划线,可以这么做:
style = (style & ~PS_STYLE_MASK) | PS_DASHDOT;
8.图形绘制函数
1.圆-circle
声明
void circle( int x, int y, int radius);//画无填充的圆。
void fillcircle( int x, int y, int radius);//有边框的填充圆
void solidcircle( int x, int y, int radius);//画无边框的填充圆。
void clearcircle( int x, int y, int radius);//该函数使用背景色清空圆形区域。
代码样例
#include<stdio.h>
//1.包含图形库头文件,就能使用提供给我的函数
#include<graphics.h>
int main()
{
//2.创建一个窗口,确定窗口大小,show_console(显现控制台)
initgraph(640, 480, SHOWCONSOLE);
//设置背景颜色,one,two两步才能设置背景颜色,位置不能颠倒
setbkcolor(RGB(255,128,192));//one,设置背景颜色
cleardevice();//two,清屏,初始化,清楚原来背景的黑色
//3.画粑粑,圆
setlinestyle(PS_SOLID, 3);//线的类型为实线,粗细为3个像素
setfillcolor(BLUE);//填充颜色为蓝色
setlinecolor(YELLOW);//线的颜色为黄色
circle(50, 50, 50);
fillcircle(50, 150, 50);
solidcircle(50, 250, 50);
/*
setbkcolor(GREEN);//重新设个背景色,更显著
clearcircle(100, 150, 50);
clearcircle(100, 250, 50);
*/
getchar();
//2.1关闭窗口
closegraph();
return 0;
}
输出样例:
//在结尾后面添加清除函数
setbkcolor(GREEN);//重新设个背景色,更显著
clearcircle(100, 150, 50);
clearcircle(100, 250, 50);
2.矩形 - rectangle
声明
void rectangle( int left, int top, int right, int bottom);//画无填充的矩形。
void fillrectangle( int left, int top, int right, int bottom);
void solidrectangle( int left, int top, int right, int bottom);
void clearrectangle( int left, int top, int right, int bottom);
- left:矩形左部 x 坐标。
- top:矩形顶部 y 坐标。
- right:矩形右部 x 坐标。
- bottom:矩形底部 y 坐标。
代码样例
#include<stdio.h>
//1.包含图形库头文件,就能使用提供给我的函数
#include<graphics.h>
int main()
{
//2.创建一个窗口,确定窗口大小,show_console(显现控制台)
initgraph(640, 640, SHOWCONSOLE);
//设置背景颜色,one,two两步才能设置背景颜色,位置不能颠倒
setbkcolor(RGB(255,128,192));//one,设置背景颜色
cleardevice();//two,清屏,初始化,清楚原来背景的黑色
setfillcolor(YELLOW);//设置填充颜色-黄色
setfillstyle(BS_HATCHED, HS_DIAGCROSS);//设置填充模式,自定义填充,交叉网
setlinecolor(RED);//设置线的颜色-红色
setlinestyle(PS_SOLID, 2);//设置线的模式为虚线,粗细为两个像素
rectangle(200, 100, 400, 200);
fillrectangle(200, 250, 400, 350);
solidrectangle(200, 400, 400, 500);
/*setbkcolor(GREEN);//重新设个背景色,更显著
clearrectangle(300, 250,500, 350);
clearrectangle(300, 400,500, 500);*/
getchar();
//2.1关闭窗口
closegraph();
return 0;
}
效果:
加了clear效果:
3.椭圆 - ellipse
声明
void ellipse( int left, int top, int right, int bottom);
void fillellipse( int left, int top, int right, int bottom);
void solidellipse( int left, int top, int right, int bottom);
void clearellipse( int left, int top, int right, int bottom);
- left:椭圆外切矩形的左上角 x 坐标。
- top:椭圆外切矩形的左上角 y 坐标。
- right:椭圆外切矩形的右下角 x 坐标。
- bottom:椭圆外切矩形的右下角 y 坐标。
代码样例
#include<stdio.h>
//1.包含图形库头文件,就能使用提供给我的函数
#include<graphics.h>
int main()
{
//2.创建一个窗口,确定窗口大小,show_console(显现控制台)
initgraph(640, 640, SHOWCONSOLE);
//设置背景颜色,one,two两步才能设置背景颜色,位置不能颠倒
setbkcolor(RGB(255,128,192));//one,设置背景颜色
cleardevice();//two,清屏,初始化,清楚原来背景的黑色
setfillcolor(GREEN);//设置填充颜色
setfillstyle(BS_HATCHED, HS_DIAGCROSS);//设置填充模式,自定义填充,交叉网
setlinecolor(RED);//设置线的颜色
setlinestyle(PS_SOLID, 2);//设置线的模式为虚线,粗细为两个像素
ellipse(200, 100, 400, 200);
fillellipse(200, 250, 400, 350);
solidellipse(200, 400, 400, 500);
//setbkcolor(WHITE);//重新设个背景色,更显著
//clearellipse(300, 250,500, 350);
//clearellipse(300, 400,500, 500);
//
getchar();
//2.1关闭窗口
closegraph();
return 0;
}
clear:
4.圆角矩形 - roundrectangle
声明
void roundrect(int left,int top,int right,int bottom,int ellipsewidth,int ellipseheight);
void fillroundrect(int left,int top,int right,int bottom,int ellipsewidth,int ellipseheight);
void solidroundrect(int left,int top,int right,int bottom,int ellipsewidth,int ellipseheight);
void clearroundrect(int left,int top,int right,int bottom,int ellipsewidth,int ellipseheight);
- left:圆角矩形左部 x 坐标。
- top:圆角矩形顶部 y 坐标。
- right:圆角矩形右部 x 坐标。
- bottom:圆角矩形底部 y 坐标。
- ellipsewidth:构成圆角矩形的圆角的椭圆的宽度。
- ellipseheight:构成圆角矩形的圆角的椭圆的高度。
代码样例
#include<stdio.h>
//1.包含图形库头文件,就能使用提供给我的函数
#include<graphics.h>
int main()
{
//2.创建一个窗口,确定窗口大小,show_console(显现控制台)
initgraph(640, 640, SHOWCONSOLE);
//设置背景颜色,one,two两步才能设置背景颜色,位置不能颠倒
setbkcolor(WHITE);//one,设置背景颜色
cleardevice();//two,清屏,初始化,清楚原来背景的黑色
setfillcolor(GREEN);//设置填充颜色
setfillstyle(BS_HATCHED, HS_DIAGCROSS);//设置填充模式,自定义填充,交叉网
setlinecolor(RED);//设置线的颜色
setlinestyle(PS_SOLID, 3);//设置线的模式为虚线,粗细为两个像素
roundrect(200, 100, 400, 200,50,50);
rectangle(200, 150, 400, 250);
getchar();
//2.1关闭窗口
closegraph();
return 0;
}
- 图形绘制函数用于在窗口上绘制各种图形。
- 绘图函数从填充样式分类可以分为无填充,有边框填充,无边框三种。
- 设置填充颜色:
setfillcolor(颜色)
- 设置线条颜色:
setlinecolor(颜色)
- 设置先调样式:
setlinestyle(线条,粗细)
以画圆为例
setlinestyle(PS_SOLID, 5);//设置线条样式
setlinecolor(YELLOW);//设置线条颜色
setfillcolor(BLUE);//设置填充颜色
circle(50, 50, 50);//有边框
fillcircle(50, 150, 50);//有填充
solidcircle(50, 250, 50);//实心,(无边框)
#include<stdio.h>
//1.包含图形库头文件,就能使用提供给我的函数
#include<graphics.h>
int main()
{
//2.创建一个窗口,确定窗口大小,show_console(显现控制台)
initgraph(640,480,SHOWCONSOLE);
//设置背景颜色,one,two两步才能设置背景颜色,位置不能颠倒
setbkcolor(GREEN);//one
cleardevice();//清屏,初始化,清楚原来背景的黑色,two
//3.画粑粑,圆
setlinestyle(PS_SOLID, 5);
setfillcolor(BLUE);
setlinecolor(YELLOW);
circle(50, 50, 50);
fillcircle(50, 150, 50);
solidcircle(50, 250, 50);
int num = 0;
printf("请输入一个数字:>");
scanf("%d", &num);
printf("%d", num);
getchar();
//2.1关闭窗口
closegraph();
return 0;
}
区别:
9.文字绘制函数
字体属性结构体:logfont
这个结构体定义了字体的属性。
struct LOGFONT {
LONG lfHeight;//指定高度(逻辑单位)
LONG lfWidth //指定字符的平均宽度(逻辑单位)。如果为0,则比例自适应
LONG lfEscapement;//字符串的书写角度,单位0.1度,默认为0
LONG lfOrientation;//每个字符的书写角度,单位 0.1 度,默认为 0。
LONG lfWeight;//字符的笔画粗细,范围 0~1000,0 表示默认粗细,使用数字或下表中定义的宏均可。PS:宏太多就不写了
BYTE lfItalic;//指定字体是否是斜体。
BYTE lfUnderline;//指定字体是否有下划线
BYTE lfStrikeOut;//指定字体是否有删除线
BYTE lfCharSet;//指定字符集
BYTE lfOutPrecision;//指定文字的输出精度
BYTE lfClipPrecision;//指定文字的剪辑精度。
BYTE lfQuality;//指定文字的输出质量。
BYTE lfPitchAndFamily;//指定以常规方式描述字体的字体系列。字体系列描述大致的字体外观。字体系列用于在所需精确字体不可用时指定字体。
TCHAR lfFaceName[LF_FACESIZE];//字体名称,名称不得超过 31 个字符。如果是空字符串,系统将使用第一个满足其它属性的字体。
};
outtextxy
- 在指定位置输出字符串
void outtextxy(int x,int y,LPCTSTR str);
void outtextxy( int x, int y, TCHAR c );
参数:
- x 字符串输出时头字母的 x 轴的坐标值。
- y 字符串输出时头字母的 y 轴的坐标值。
- str 待输出的字符串的指针。
- c 待输出的字符。
注意:
该函数不会改变当前位置。
字符串常见的编码有两种:MBCS 和 Unicode。VC6 新建的项目默认为 MBCS 编码,VC2008 及高版本的 VC 默认为 Unicode 编码。LPCTSTR 可以同时适应两种编码。为了适应两种编码,请使用 TCHAR 字符串及相关函数。
默认情况下,输出字符串的背景会用当前背景色填充。使用函数 setbkmode 可以设置文字的背景部分保持透明或使用背景色填充。
实例
// 输出字符串(MBCS 字符集)
char s[] = "Hello World";
outtextxy(10, 20, s);
// 输出字符串(Unicode 字符集)
wchar_t s[] = L"Hello World";
outtextxy(10, 20, s);
// 输出字符串(项目字符集)
TCHAR s[] = _T("Hello World");
outtextxy(10, 20, s);
// 输出字符(MBCS 字符集)
char c = 'A';
outtextxy(10, 40, c);
// 输出字符(项目字符集)
TCHAR c = _T('A');
outtextxy(10, 40, c);
// 输出数值,先将数字格式化输出为字符串(MBCS 字符集)
char s[5];
sprintf(s, "%d", 1024);
outtextxy(10, 60, s);
// 输出数值 1024,先将数字格式化输出为字符串(项目字符集)
TCHAR s[5];
_stprintf(s, _T("%d"), 1024); // 高版本 VC 推荐使用 _stprintf_s 函数
outtextxy(10, 60, s);
settextcolor
void settextcolor(COLORREF color);
settextstyle
这个函数用于设置当前字体样式。
void settextstyle(
int nHeight,//指定高度(逻辑单位)。
int nWidth,//指定宽度
LPCTSTR lpszFace//字体名称
);
void settextstyle(
int nHeight,
int nWidth,
LPCTSTR lpszFace,
int nEscapement,//字符串倾斜角度
int nOrientation,//每个字符倾斜角度
int nWeight,//字符的笔画粗细,范围 0~1000。0 表示默认粗细。
bool bItalic,//是否斜体
bool bUnderline,//是否下划线
bool bStrikeOut//是否删除线
);
void settextstyle(
int nHeight,
int nWidth,
LPCTSTR lpszFace,
int nEscapement,
int nOrientation,
int nWeight,
bool bItalic,
bool bUnderline,
bool bStrikeOut,
BYTE fbCharSet,//指定字符集
BYTE fbOutPrecision,//输出精度
BYTE fbClipPrecision,//剪辑精度
BYTE fbQuality,//输出质量
BYTE fbPitchAndFamily//指定以常规方式描述字体的字体系列
);
void settextstyle(const LOGFONT *font);
参数
- nHeight:指定高度(逻辑单位)。
- nWidth:字符的平均宽度(逻辑单位)。如果为 0,则比例自适应。
- lpszFace:字体名称。
- nEscapement:字符串的书写角度,单位 0.1 度。
- nOrientation:每个字符的书写角度,单位 0.1 度。
- nWeight:字符的笔画粗细,范围 0~1000。0 表示默认粗细。详见 LOGFONT 结构体。
- bItalic:是否斜体。
- bUnderline:是否有下划线。
- bStrikeOut:是否有删除线。
- fbCharSet:指定字符集。详见 LOGFONT 结构体。
- fbOutPrecision:指定文字的输出精度。详见 LOGFONT 结构体。
- fbClipPrecision:指定文字的剪辑精度。详见 LOGFONT 结构体。
- fbQuality:指定文字的输出质量。详见 LOGFONT 结构体。
- fbPitchAndFamily:指定以常规方式描述字体的字体系列。详见 LOGFONT 结构体。
- font:指向 LOGFONT 结构体的指针。
返回值
无
示例
// 设置当前字体为高 16 像素的“Consolas”。(VC6 / VC2008 / VC2010 / VC2012)
settextstyle(16, 0, _T("Consolas"));
outtextxy(0, 0, _T("测试"));
// 设置输出效果为抗锯齿 (VC6 / VC2008 / VC2010 / VC2012)
LOGFONT f;
gettextstyle(&f); // 获取当前字体设置
f.lfHeight = 48; // 设置字体高度为 48
_tcscpy(f.lfFaceName, _T("黑体")); // 设置字体为“黑体”(高版本 VC 推荐使用 _tcscpy_s 函数)
f.lfQuality = ANTIALIASED_QUALITY; // 设置输出效果为抗锯齿
settextstyle(&f); // 设置字体样式
outtextxy(0, 50, _T("抗锯齿效果"));
10.图像处理函数
loadimage
这个函数用于从文件中读取图片
声明:
// 从图片文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico)
void loadimage(
IMAGE* pDstImg, // 保存图像的 IMAGE 对象指针
LPCTSTR pImgFile, // 图片文件名
int nWidth = 0, // 图片的拉伸宽度
int nHeight = 0, // 图片的拉伸高度
bool bResize = false // 是否调整 IMAGE 的大小以适应图片
);
// 从资源文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico)
void loadimage(
IMAGE* pDstImg, // 保存图像的 IMAGE 对象指针
LPCTSTR pResType, // 资源类型
LPCTSTR pResName, // 资源名称
int nWidth = 0, // 图片的拉伸宽度
int nHeight = 0, // 图片的拉伸高度
bool bResize = false // 是否调整 IMAGE 的大小以适应图片
);
参数:
- pDstImg 保存图像的 IMAGE 对象指针。如果为 NULL,表示图片将读取至绘图窗口。
- pImgFile 图片文件名。支持 bmp / gif / jpg / png / tif / emf / wmf / ico 格式的图片。gif 格式的图片仅加载第一帧;gif 与 png 均不支持透明。
- nWidth 图片的拉伸宽度。加载图片后,会拉伸至该宽度。如果为 0,表示使用原图的宽度。
- nHeight 图片的拉伸高度。加载图片后,会拉伸至该高度。如果为 0,表示使用原图的高度。
- bResize 是否调整 IMAGE 的大小以适应图片。
- pResType 图片资源类型。
- pResName 图片资源名称。
备注:
如果创建 IMAGE 对象的时候没有指定宽高,可以通过 Resize 函数设置。
对于没有设置宽高的 IMAGE 对象,执行 loadimage 会将其宽高设置为和读取的图片一样的尺寸。
代码示例:
以下完整示例实现了加载图片“D:\test.jpg”至绘图窗口:
#include <graphics.h>
#include <conio.h>
// 主函数
int main()
{
// 绘图窗口初始化
initgraph(640, 480);
// 读取图片至绘图窗口
loadimage(NULL, _T("D:\\test.jpg"));
// 按任意键退出
_getch();
closegraph();
}
以下代码片段实现了加载图片“D:\test.jpg”至绘图窗口(MBCS 及 Unicode 自适应):
loadimage(NULL, _T("D:\\test.jpg"));
以下代码片段实现了加载“IMAGE”分类下的图像资源“Player”至 img 对象,并在屏幕的指定位置显示:
IMAGE img;
loadimage(&img, _T("IMAGE"), _T("Player"));
putimage(100, 100, &img); // 在另一个位置再次显示背景
以下代码片段实现了加载“IMAGE”分类下的图像资源 IDR_PLAYER 至 img 对象,并在屏幕的指定位置显示:
IMAGE img;
loadimage(&img, _T("IMAGE"), MAKEINTRESOURCE(IDB_PLAYER));
putimage(100, 100, &img); // 在另一个地方再次显示背景
putimage
这个函数的几个重载用于在当前设备上绘制指定图像。
声明:
// 绘制图像
void putimage(
int dstX, // 绘制位置的 x 坐标
int dstY, // 绘制位置的 y 坐标
IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针
DWORD dwRop = SRCCOPY // 三元光栅操作码
);
// 绘制图像(指定宽高和起始位置)
void putimage(
int dstX, // 绘制位置的 x 坐标
int dstY, // 绘制位置的 y 坐标
int dstWidth, // 绘制的宽度
int dstHeight, // 绘制的高度
IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针
int srcX, // 绘制内容在 IMAGE 对象中的左上角 x 坐标
int srcY, // 绘制内容在 IMAGE 对象中的左上角 y 坐标
DWORD dwRop = SRCCOPY // 三元光栅操作码
);
备注:
三元光栅操作码(即位操作模式),支持全部的 256 种三元光栅操作码,常用的几种如下:
值 | 含义 |
---|---|
DSTINVERT | 目标图像 = NOT 目标图像 |
MERGECOPY | 目标图像 = 源图像 AND 当前填充颜色 |
MERGEPAINT | 目标图像 = 目标图像 OR (NOT 源图像) |
NOTSRCCOPY | 目标图像 = NOT 源图像 |
NOTSRCERASE | 目标图像 = NOT (目标图像 OR 源图像) |
PATCOPY | 目标图像 = 当前填充颜色 |
PATINVERT | 目标图像 = 目标图像 XOR 当前填充颜色 |
PATPAINT | 目标图像 = 目标图像 OR ((NOT 源图像) OR 当前填充颜色) |
SRCAND | 目标图像 = 目标图像 AND 源图像 |
SRCCOPY | 目标图像 = 源图像 |
SRCERASE | 目标图像 = (NOT 目标图像) AND 源图像 |
SRCINVERT | 目标图像 = 目标图像 XOR 源图像 |
SRCPAINT | 目标图像 = 目标图像 OR 源图像 |
注:
- AND / OR / NOT / XOR 为布尔运算。
- "当前填充颜色"是指通过 setfillcolor 设置的用于当前填充的颜色。
- 查看全部的三元光栅操作码请参考这里:三元光栅操作码。
示例:
以下代码片段将屏幕 (0,0) 起始的 100x100 的图像拷贝至 (200,200) 位置:
IMAGE img;
getimage(&img, 0, 0, 100, 100);
putimage(200, 200, &img);
11.消息处理相关函数
消息缓冲区可以缓冲 63 个未处理的消息。每次获取消息时,将从消息缓冲区取出一个最早发生的消息。消息缓冲区满了之后,不再接收任何消息。
ExMessage
- 消息结构体
定义声明:
这个结构体用于保存鼠标消息,定义如下:
struct ExMessage
{
USHORT message; // 消息标识
union
{
// 鼠标消息的数据
struct
{
bool ctrl :1; // Ctrl 键是否按下
bool shift :1; // Shift 键是否按下
bool lbutton :1; // 鼠标左键是否按下
bool mbutton :1; // 鼠标中键是否按下
bool rbutton :1; // 鼠标右键
short x; // 鼠标的 x 坐标
short y; // 鼠标的 y 坐标
short wheel; // 鼠标滚轮滚动值,为 120 的倍数
};
// 按键消息的数据
struct
{
BYTE vkcode; // 按键的虚拟键码
BYTE scancode; // 按键的扫描码(依赖于 OEM)
bool extended :1; // 按键是否是扩展键
bool prevdown :1; // 按键的前一个状态是否按下
};
// 字符消息的数据
TCHAR ch;
// 窗口消息的数据
struct
{
WPARAM wParam;
LPARAM lParam;
};
};
};
成员
message
消息标识,可为以下值:
消息标识 | 消息类别 | 描述 |
---|---|---|
WM_MOUSEMOVE | EM_MOUSE | 鼠标移动消息。 |
WM_MOUSEWHEEL | 鼠标滚轮拨动消息。 | |
WM_LBUTTONDOWN | 左键按下消息。 | |
WM_LBUTTONUP | 左键弹起消息。 | |
WM_LBUTTONDBLCLK | 左键双击消息。 | |
WM_MBUTTONDOWN | 中键按下消息。 | |
WM_MBUTTONUP | 中键弹起消息。 | |
WM_MBUTTONDBLCLK | 中键双击消息。 | |
WM_RBUTTONDOWN | 右键按下消息。 | |
WM_RBUTTONUP | 右键弹起消息。 | |
WM_RBUTTONDBLCLK | 右键双击消息。 | |
WM_KEYDOWN | EM_KEY | 按键按下消息 |
WM_KEYUP | 按键弹起消息。 | |
WM_CHAR | EM_CHAR | 字符消息。 |
WM_ACTIVATE | EM_WINDOW | 窗口激活状态改变消息。 |
WM_MOVE | 窗口移动消息。 | |
WM_SIZE | 窗口大小改变消息。 |
-
ctrl:Ctrl 键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。
-
shift:Shift 键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。
-
lbutton:鼠标左键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。
-
mbutton:鼠标中键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。
-
rbutton:鼠标右键是否按下。仅当消息所属类别为 EM_MOUSE 时有效。
-
x:当前鼠标 x 坐标(物理坐标)。仅当消息所属类别为 EM_MOUSE 时有效。
-
y:当前鼠标 y 坐标(物理坐标)。仅当消息所属类别为 EM_MOUSE 时有效。
-
wheel:鼠标滚轮滚动值,为 120 的倍数。仅当消息所属类别为 EM_MOUSE 时有效。
——————————————————————————————————————————————————
-
vkcode:按键的虚拟键码。仅当消息所属类别为 EM_KEY 时有效。
在微软网站上列出有所有的虚拟键码:https://docs.microsoft.com/windows/win32/inputdev/virtual-key-codes
-
scancode:按键的扫描码(依赖于 OEM)。仅当消息所属类别为 EM_KEY 时有效。
-
extended:按键是否为扩展按键,例如功能键和数字键盘。仅当消息所属类别为 EM_KEY 时有效。
-
prevdown:按键的前一个状态是否为按下。仅当消息所属类别为 EM_KEY 时有效。
-
ch:收到的字符。仅当消息所属类别为 EM_CHAR 时有效。
-
wParam:消息对应的 wParam 参数。仅当消息所属类别为 EM_WINDOW 时有效。
-
lParam:消息对应的 lParam 参数。仅当消息所属类别为 EM_WINDOW 时有效。
flushmessage
- 清空缓冲区
这个函数用于清空消息缓冲区。
void flushmessage(BYTE filter = -1);
参数
filte
指定要清空的消息范围,默认 -1 清空所有类别的消息。可以用以下值或值的组合清空指定类别的消息:
标志 | 描述 |
---|---|
EM_MOUSE | 鼠标消息。 |
EM_KEY | 按键消息。 |
EM_CHAR | 字符消息。 |
EM_WINDOW | 窗口消息。 |
getmessage
- 获取一个消息
这个函数用于获取一个消息。如果当前消息队列中没有,就一直等待。
ExMessage getmessage(BYTE filter = -1);
void getmessage(ExMessage *msg, BYTE filter = -1);
参数
msg
指向消息结构体 ExMessage 的指针,用来保存获取到的消息。
filter
指定要获取的消息范围,默认 -1 获取所有类别的消息。可以用以下值或值的组合获取指定类别的消息:
标志 | 描述 |
---|---|
EM_MOUSE | 鼠标消息。 |
EM_KEY | 按键消息。 |
EM_CHAR | 字符消息。 |
EM_WINDOW | 窗口消息。 |
返回值
重载 1 返回保存有消息 ExMessage 的结构体。
重载 2 没有返回值。
备注
默认情况下,连续的鼠标单击会被识别为一系列的单击事件。如果希望两个连续的鼠标单击识别为双击事件,请在创建绘图窗口的时候指定标志位 EW_DBLCLKS。
peekmessage
- 获取一个消息,并立即返回。
这个函数用于获取一个消息,并立即返回。
bool peekmessage(ExMessage *msg, BYTE filter = -1, bool removemsg = true);
参数
msg
指向消息结构体 ExMessage 的指针,用来保存获取到的消息。
filter
指定要获取的消息范围,默认 -1 获取所有类别的消息。可以用以下值或值的组合获取指定类别的消息:
标志 | 描述 |
---|---|
EM_MOUSE | 鼠标消息。 |
EM_KEY | 按键消息。 |
EM_CHAR | 字符消息。 |
EM_WINDOW | 窗口消息。 |
removemsg
在 peekmessage 处理完消息后,是否将其从消息队列中移除。
返回值
如果获取到了消息,返回 true。
如果当前没有消息,返回 flase。
备注
默认情况下,连续的鼠标单击会被识别为一系列的单击事件。如果希望两个连续的鼠标单击识别为双击事件,请在创建绘图窗口的时候指定标志位 EW_DBLCLKS。
12.我们在使用时一些基本操作:
画图:
代码:画圆圈
#include<stdio.h>
#include<graphics.h>//图形库头文件
int main()
{
//创建一个窗口,确定窗口大小
//initgraph(1024,1024,SHOWCONSOLE | NOCLOSE | NOMINIMIZE);
initgraph(3000, 3000,SHOWCONSOLE);
//下面这两步不能换位置,不能缺少
setbkcolor(WHITE);//设置背景颜色
cleardevice();//清屏
setfillcolor(RED);//设置填充颜色
setlinecolor(BLUE);//设置线条颜色
setlinestyle(PS_SOLID, 5);//设置线条样式:实心,粗度5像素
//画圆
circle(500, 50, 50);
fillcircle(500,200,100);
solidcircle(500,500,200);
//关闭窗口
getchar();
closegraph();
return 0;
}
样例输出:
文字
//1,在字符串前面加上大写的 L
outtextxy(50, 50, L"我是一个小青蛙");
//2,用TEXT()把字符串包起来,_T()
outtextxy(50, 150, _T("我是一个小青蛙"));
//3,不需要添加任何代码,进项目->属性->配置属性->常规->字符集->改为多字节字符集推荐使用介个
outtextxy(50, 150, "我是一个小青蛙");
方法3:
代码:文字居中
#include<stdio.h>
#include<graphics.h>
int main()
{
initgraph(1024, 1024, SHOWCONSOLE);
setbkcolor(YELLOW);
cleardevice();
//先画一个粉色的圆角矩形
setlinecolor(BLACK);//黑框
setfillcolor(RGB(255, 210, 223));//粉底
fillroundrect(100, 100, 400, 300, 50, 50);
//设置文字样式
settextstyle(25, 0, "楷体");//设置字体高度,宽度,字型
setbkmode(TRANSPARENT);//设置字体背景透明,默认不透明
settextcolor(BLUE);//蓝字
//文字居中
char arr[] = "我是一直小青蛙~";
int x_buff = (300 - textwidth(arr)) / 2;//textwidth求字符串所占像素长度
int y_buff = (200 - textheight(arr)) / 2;//textheight求字符串所占像素高度
outtextxy(100 + x_buff, 100 + y_buff, arr);
getchar();
closegraph();
return 0;
}
输出效果:
图像:
- 在使用图像之前,需要定义一个变量(对象),然后把图片加载进变量才能进行使用。
- 平时定义变量都是使用的基础数据类型
- 在使用图像的时候需要使用EasyX提供给我们的类型:
IMAGE
,如:IMAGE img;
- l**oadimage:**从文件中读取图像
- pDstImg, //保存图像的IMAGE对象指针
&img
- pImgFile, //图片文件名
- nWidth = 0, //图片的拉伸宽度(长度),如果为 0,表示使用原图的宽度
- nHeight = 0, //图片的拉伸高度,如果为 0,表示使用原图的高度
- bResize = false, //是否调整IMAGE的大小以适应图片
- **putimage:**在当前设备上绘制指定图像
- destX //绘制位置的x坐标
- destY //绘制位置的y坐标
- pSrcImg //要绘制的IMAGE对象指针
&img
- dwRop = SRCCOPY //三元光栅操作码
代码
#include<stdio.h>
#include<graphics.h>
int main()
{
initgraph(1000, 1000, SHOWCONSOLE);
setbkcolor(YELLOW);
cleardevice();
//输出图片
IMAGE img1;//定义一个(变量)对象
IMAGE img2;//定义一个(变量)对象
loadimage(&img1, "C:\\Users\\LENOVO\\Desktop\\wallpaper\\xx.png",768,432);//绝对路径
loadimage(&img2, "./oo.png",512,288);//相对路径: ./表示当前文件夹下,../表示答盎前文件夹的上一级目录
putimage(0, 0, &img1);
putimage(500, 500, &img2);
getchar();
closegraph();
return 0;
}
输出样例
鼠标操作:
老版:graphics.h
-
鼠标消息需要使用
MOUSEMSG
类型,比如:MOUSEMSG msg;
-
然后使用
MoustHit()
判断是否有鼠标消息(左键,右键, 中间,移动) -
如果有鼠标消息就可以进行接受鼠标消息了:
msg = GetMouseMsg();
-
鼠标消息主要成员:
- uMsg //当前鼠标消息
- x //当前鼠标x坐标
- y //当前鼠标y坐标
-
uMsg可用来判断当前鼠标消息是什么消息
主要的两个消息:
WM_LBUTTONDOWN
左键消息WM_RBUTTONDOWN
右键消息
#include<stdio.h>
#include<graphics.h>
void button(int x, int y, int w, int h, const char* text);
int main()
{
initgraph(1000, 1000, SHOWCONSOLE);//展示控制台
button(50, 50, 150, 50, "按钮");
MOUSEMSG msg;
while (1)
{
if (MouseHit())//有鼠标操作消息返回真
{
msg = GetMouseMsg();//获取鼠标信息
switch (msg.uMsg)//消息分发
{
case WM_LBUTTONDOWN:
if (msg.x >= 50 && msg.x <= 50 + 150 && msg.y >= 50 && msg.y <= 50 + 150)
{
printf("哼哼,被左键点击了\n");
}
break;
case WM_RBUTTONDOWN:
if (msg.x >= 50 && msg.x <= 50 + 150 && msg.y >= 50 && msg.y <= 50 + 150)
{
printf("哈哈哈,被右键点击了\n");
}
break;
default:
break;
}
}
}
getchar();
closegraph();
return 0;
}
void button(int x, int y, int w, int h, const char* text)
{
setlinecolor(WHITE);//设置框边颜色
setbkmode(TRANSPARENT);//设置字体背景透明
setfillcolor(RGB(255, 0, 192));//设置填充颜色
fillroundrect(x, y, x + w, y + h, 10, 10);//画一个按钮框
char text_[50] = {
0 };
strcpy(text_, text);
settextcolor(RED);
settextstyle(40, 0, "黑体");
int tx = x + (w - textwidth(text_)) / 2;
int ty = y + (h - textheight(text_)) / 2;
outtextxy(tx, ty, text_);
}
新版
#include<stdio.h>
#include<easyx.h>
void button(int x, int y, int w, int h,const char* text)
{
setbkmode(TRANSPARENT);//设置字体背景透明
setfillcolor(BROWN);//设置填充颜色
fillroundrect(x,y,x+w,y+h,10,10);//设置按钮
char text_[50] = {
0};//按钮内容物
strcpy(text_,text);//复制
settextstyle(40,0,"黑体");
int tx = x + (w-textwidth(text_))/2;
int ty = y + (h-textheight(text_))/2;
outtextxy(tx,ty,text_);
}
int main ()
{
initgraph(1000,1000,EW_SHOWCONSOLE);
button(50,50,150,50,"按钮");
ExMessage msg;
while(1)
{
if(peekmessage(&msg, EM_MOUSE))//有鼠标消息返回真,没有返回假
{
switch(msg.message)
{
case WM_LBUTTONDOWN:
if(msg.x>=50&&msg.x<=50+150&&msg.y>=50&&msg.y<=50+150)
{
printf("哼哼,被左键点击了\n");
}
break;
case WM_RBUTTONDOWN:
if(msg.x>=50&&msg.x<=50+150&&msg.y>=50&&msg.y<=50+150)
{
printf("哈哈哈,被右键点击了\n");
}
break;
default:
break;
}
}
}
getchar();
closegraph();
return 0;
}
键盘操作
非EastX函数——键盘消息函数
-
用于获取键盘信息的函数有两个
-
getch(); 需要头文件conio.h
-
GetAsyncKeyState(键值); 需要头文件windows.h(EasyX已经帮我们包含了)
-
-
**getch();**需要使用返回值来判断
- 与非ASCII表字符的按键比较,需要使用虚拟按键值,如:
- 上:72
- 下:80
- 左:75
- 右:77
- 如果是与字母比较直接写字母,如
'A'
- 与非ASCII表字符的按键比较,需要使用虚拟按键值,如:
-
**GetAsyncKeyState(键值);**需要传入一个键值(Async:非同步;异步),如:
- 上:VK_UP
- 下:VK_DOWN
- 左:VK_LEFT
- 右:VK_RIGHT
getch()
/_getch()
#include<stdio.h>
#include<graphics.h>
#include<conio.h>//使用_getch();//其实就是getch();
int main()
{
initgraph(1000, 1000, SHOWCONSOLE);
setbkcolor(WHITE);
cleardevice();
IMAGE img;//定义一个(变量)对象
loadimage(&img, "./oo.png", 512, 288);//找一个图片便于观看闪烁
putimage(0, 0, &img);
int x = 0,y = 0;//设置小球坐标
while(1)//不断循环操作
{
setfillcolor(BROWN);//展示一个棕色小球
fillcircle( x, y, 20);
char key = _getch();
switch(key)
{
case 72://上键的虚拟值
case 'W':
case 'w':
y -= 5;
printf("上\n");
break;
case 80://下键的虚拟值
case 'S':
case 's':
y += 5;
printf("下\n");
break;
case 75://左键的虚拟值
case 'A':
case 'a':
x -= 5;
printf("左\n");
break;
case 77://右键的虚拟值
case 'D':
case 'd':
x += 5;
printf("右\n");
break;
}
}
getchar();
closegraph();
return 0;
}
效果展示:
为什么会有尾巴呢?
因为我们没有清楚前一帧背景:所以我们要在循环while
中第一行加上cleardevice()
效果:
出现问题:背景永远消失
解决方案:将原背景的渲染代码放进while()
循环里面:
#include<stdio.h>
#include<graphics.h>
#include<conio.h>//使用_getch();//其实就是getch();
int main()
{
initgraph(1000, 1000, SHOWCONSOLE);
int x = 0,y = 0;//设置小球坐标
while(1)//不断循环操作
{
cleardevice();
//背景区
setbkcolor(WHITE);
IMAGE img;//定义一个(变量)对象
loadimage(&img, "./oo.png", 512, 288);//找一个图片便于观看闪烁
putimage(0, 0, &img);
//小球区
setfillcolor(BROWN);//展示一个棕色小球
fillcircle( x, y, 20);
char key = _getch();
switch(key)
{
case 72://上键的虚拟值
case 'W':
case 'w':
y -= 5;
printf("上\n");
break;
case 80://下键的虚拟值
case 'S':
case 's':
y += 5;
printf("下\n");
break;
case 75://左键的虚拟值
case 'A':
case 'a':
x -= 5;
printf("左\n");
break;
case 77://右键的虚拟值
case 'D':
case 'd':
x += 5;
printf("右\n");
break;
}
}
getchar();
closegraph();
return 0;
}
出现问题:背景闪烁不定
解决方案:
在设备上不断进行绘图操作时,会产生闪屏现象,此时眼睛会受不了,针对这个现象,我们需要用到以下两个函数来处理:
- BeginBatchDraw();开始批量绘图
- ---------中间放绘图代码---------------
- EndBatchDraw(); 结束批量绘制
原理:先在缓存区画,画完再显示
#include<stdio.h>
#include<graphics.h>
#include<conio.h>//使用_getch();//其实就是getch();
int main()
{
initgraph(1000, 1000, SHOWCONSOLE);
int x = 0,y = 0;//设置小球坐标
while(1)//不断循环操作
{
//双缓冲绘图,需要放在绘图代码之前和之后
BeginBatchDraw();//开始批量绘图
//背景区
setbkcolor(WHITE);
cleardevice();
IMAGE img;//定义一个(变量)对象
loadimage(&img, "./oo.png", 512, 288);//找一个图片便于观看闪烁
putimage(0, 0, &img);
//小球区
setfillcolor(BROWN);//展示一个棕色小球
fillcircle( x, y, 20);
FlushBatchDraw();//清空批量绘图
char key = _getch();//阻塞函数,不输入一直在这里等
switch(key)
{
case 72://上键的虚拟值
case 'W':
case 'w':
y -= 5;
printf("上\n");
break;
case 80://下键的虚拟值
case 'S':
case 's':
y += 5;
printf("下\n");
break;
case 75://左键的虚拟值
case 'A':
case 'a':
x -= 5;
printf("左\n");
break;
case 77://右键的虚拟值
case 'D':
case 'd':
x += 5;
printf("右\n");
break;
}
}
getchar();
closegraph();
return 0;
}
效果:
虽然略带延迟,不过解决了闪烁问题。
getAsyncState()
#include<stdio.h>
#include<graphics.h>
#include<conio.h>//使用_getch();//其实就是getch();
int main()
{
initgraph(1000, 1000, SHOWCONSOLE);
int x = 0,y = 0;//设置小球坐标
while(1)//不断循环操作
{
//双缓冲绘图,需要放在绘图代码之前和之后
BeginBatchDraw();//开始批量绘图
//背景区
setbkcolor(WHITE);
cleardevice();
IMAGE img;//定义一个(变量)对象
loadimage(&img, "./oo.png", 512, 288);//找一个图片便于观看闪烁
putimage(0, 0, &img);
//小球区
setfillcolor(BROWN);//展示一个棕色小球
fillcircle( x, y, 20);
FlushBatchDraw();//清空批量绘图
if(GetAsyncKeyState(VK_UP))//上键
{
y-=10;
}
if(GetAsyncKeyState(VK_DOWN))//下键
{
y+=10;
}
if(GetAsyncKeyState(VK_LEFT))//左键
{
x-=10;
}
if(GetAsyncKeyState(VK_RIGHT))//右键
{
x+=10;
}
}
getchar();
closegraph();
return 0;
}
相比getch()
可以进行斜上斜下,比叫顺滑.
音乐播放
#include<stdio.h>
#include<graphics.h>
#include<mmsystem.h>//包含多媒体设备接口头文件,一定放在graphics.h下面
#pragma comment(lib,"winmm.lib")//加载静态库
void BGM()//播放音乐
{
//打开音乐,播放音乐 alias取别名 repeat重复播放
mcisendstring("open ./让我做你的眼睛.mp3 alias BGM",0,0,0);//向多媒体设备接口(mci)发送(send)一个字符串(string)
mcisendstring("play BGM repeat",0,0,0);
if(0)
{
mcisendstring("close BGM ",0,0,0);
}
}
int main ()
{
initgraph(600,600,SHOWCONSOLE);
BGM();
getchar();
closegraph();
return 0;
}
open コマンドは、再生する必要がある音楽を開きます。エイリアスの後には、以前のファイル パスのエイリアスが指定されます。今後このファイルを操作する場合は、このエイリアスを直接使用できます。次の 3 つのパラメータについては、 NULL、0、NULL を忘れずに記入してください。
2 番目のステートメント play コマンドの後には上で定義したエイリアスが続き、repeat は曲がループで再生されることを意味します。音楽の再生中に停止したい場合は、次のコードがあります。
ウィンドウタイトルの変更、ポップアップダイアログボックス
#include<stdio.h>
#include<graphics.h>
#include<mmsystem.h>//包含多媒体设备接口头文件,一定放在graphics.h下面
#pragma comment(lib,"winmm.lib")//加载静态库
void change()
{
//获取窗口句柄
HWND hnd = GetHWnd();
//设置窗口标题
SetWindowText(hnd,"很高兴认识你");
//弹出窗口,提示用户操作
int is_ok = MessageBox(hnd,"我是消息框","要不要关闭我",MB_OKCANCEL);
if(is_ok == IDOK)
{
printf("你点击了OK\n");
}
else if(is_ok == IDCANCEL)
{
printf("你点击了cancel\n");
}
}
int main ()
{
initgraph(600,600,SHOWCONSOLE);
change();
getchar();
closegraph();
return 0;
}