質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

1回答

1070閲覧

dxlib 線同士をつなげないようにしたい

papu12

総合スコア2

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2021/05/14 10:21

c言語

前提・実現したいこと

dxlibを使って簡単なマウスを使って線を引けるプログラム

発生している問題・エラーメッセージ

dxlibを使って簡単なマウスを使って絵(線)をかけるプログラムを作っているのですが 線を引くこと自体はできているのですがその線同士が繋がってしまってしまいます(線を 引き終わって別の場所に線を引こうとすると前の線の終点から今引こうとしてる始点が繋 がってしまう) 一応線と線の距離を求めて一定距離離れたら描画できないようにすればいいかなと思った んですがそれだとマウスを速く動かした時、線が描画されません どうすれば線同士が繋がらないようにできるのでしょうか

該当のソースコード

#include "DxLib.h" #include<math.h> const char TITLE[] = ""; const int WIN_WIDTH = 600; //ウィンドウ横幅 const int WIN_HEIGHT = 400;//ウィンドウ縦幅 int PrevMouseInput = 0; int MouseInput; bool isdown(int MouseBotton) { if (((MouseInput & MouseBotton) != (PrevMouseInput & MouseBotton)) && ((MouseInput & MouseBotton) != 0)) return true; return false; } #define BC 20000//黒線の制限 #define EC 20000//消しゴムの制限 int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { ChangeWindowMode(TRUE); //ウィンドウモードに設定 //ウィンドウサイズを手動では変更できず、かつウィンドウサイズに合わせて拡大できないようにする SetWindowSizeChangeEnableFlag(FALSE, FALSE); SetMainWindowText(TITLE); // タイトルを変更 SetGraphMode(WIN_WIDTH, WIN_HEIGHT, 32); //画面サイズの最大サイズ、カラービット数を設定(モニターの解像度に合わせる) SetWindowSizeExtendRate(1.0); //画面サイズを設定(解像度との比率で設定) SetBackgroundColor(255,255,255); // 画面の背景色を設定する //Dxライブラリの初期化 if (DxLib_Init() == -1) { return -1; } //(ダブルバッファ)描画先グラフィック領域は裏面を指定 SetDrawScreen(DX_SCREEN_BACK); //画像などのリソースデータの変数宣言と読み込み int BlackPenX = 0, BlackPenY = 0, Blackradiuss = 1;//書き始めのところ //線の構造体x,y座標、半径、色情報、切り替えフラグ typedef struct lineseg { int BlackLineX; int BlackLineY; int radius; int cr; int flag; }lines; lines bline[BC]; float px, py; int mousex = 0, mousey = 0;//mouse座標の取得 //int BlackPenX, BlackPenY, Blackradiuss; // //黒線の初期化位置をBlackPenX,yに for (int i = 0; i < BC; i++) { bline[i].BlackLineX = BlackPenX, bline[i].BlackLineY = BlackPenY, bline[i].radius = Blackradiuss, bline[i].flag = 0,bline[i].cr=GetColor(0,128,0); } int clickX, clickY; int counttimer = 0;//描画数 int Ecounttimer = 0; int hanareflag = 0; int type = 0; int mousetouch = 0; //ゲームループで使う変数の宣言 char keys[256] = { 0 }; //最新のキーボード情報用 char oldkeys[256] = { 0 };//1ループ(フレーム)前のキーボード情報 // ゲームループ while (1) { //最新のキーボード情報だったものは1フレーム前のキーボード情報として保存 //最新のキーボード情報を取得 GetHitKeyStateAll(keys); //画面クリア ClearDrawScreen(); //--------- ここからプログラムを記述 ----------// //更新処理 //mouseがタッチ去れた時に建てる if ((GetMouseInput() & MOUSE_INPUT_LEFT) == 1) { mousetouch = 1; } if ((GetMouseInput() & MOUSE_INPUT_LEFT) == 0) { mousetouch = 0; } //消しゴムとペンの切り替えフラグ if (keys[KEY_INPUT_1] == 1) { type = 1; } else if (keys[KEY_INPUT_R] == 1) { type = 3; } else if (keys[KEY_INPUT_G] == 1) { type = 4; } else if (keys[KEY_INPUT_B] == 1) { type = 5; } if (type !=0) { //kaeflag = 1; if (keys[KEY_INPUT_2] == 1) { type = 0; } } //for (int i = 0; i < BC; i++) { if (type == 0) { bline[counttimer].cr = GetColor(0, 0, 0); } else if (type == 1) { bline[counttimer].cr = GetColor(255, 255, 255); bline[counttimer].radius = 13; } else if (type == 3) { bline[counttimer].cr = GetColor(255, 0, 0); } else if (type == 4) { bline[counttimer].cr = GetColor(0, 255, 0); } else if (type == 5) { bline[counttimer].cr = GetColor(0, 0, 255);; } //全部消すやつ if (keys[KEY_INPUT_0] == 1) { counttimer = 0; Ecounttimer = 0; } //黒線の方の処理 GetMousePoint(&mousex, &mousey); //GetMouseInput(); MouseInput = GetMouseInput(); //mouseが押されたらフラグを1に if ((GetMouseInput() & MOUSE_INPUT_LEFT) == 1){ GetMousePoint(&clickX, &clickY); for (int i = 0; i < BC; i++) { bline[i].flag = 1; } } //カーソル座標をクリック位置に for (int i = 0; i < BC; i++) { if (bline[i].flag == 1) { BlackPenX = clickX; BlackPenY = clickY; } //if (mousetouch == 0) break; } //点をmouse位置に if (BlackPenX != 0 && BlackPenY != 0) { bline[counttimer].BlackLineX = BlackPenX; bline[counttimer].BlackLineY = BlackPenY; //制限時間内であれば残像の描画を1ずつ増やす if (counttimer < BC&&mousetouch!=0) { counttimer++; } DrawFormatString(80, 5, GetColor(0, 0, 0), "%d", counttimer); } //線描画処理 点 for (int i = 1; i < counttimer; i++) { DrawPixel(bline[i].BlackLineX, bline[i].BlackLineY, bline[i].cr); //線と線の距離を求める double length = sqrt(((bline[i].BlackLineX - bline[i - 1].BlackLineX) * (bline[i].BlackLineX - bline[i - 1].BlackLineX)) + ((bline[i].BlackLineY - bline[i - 1].BlackLineY) * (bline[i].BlackLineY - bline[i - 1].BlackLineY))); //今はある程度距離が離れたら線結ばないようにしてるがmouseを速く動かしたときも線が途切れてしまう if (length < 6) { //前の点と今の点を結ぶ DrawLine(bline[i - 1].BlackLineX, bline[i - 1].BlackLineY, bline[i].BlackLineX, bline[i].BlackLineY, bline[i].cr, 3); } } if (type == 0) { DrawLine(BlackPenX, BlackPenY, BlackPenX + Blackradiuss, BlackPenY + Blackradiuss, GetColor(0, 0, 0)); } if (isdown(MOUSE_INPUT_LEFT)) { DrawFormatString(300, 200, GetColor(0, 0, 0), "osareta"); } //説明書きのところ DrawFormatString(0, 0, GetColor(0, 0, 0), "全削除:0"); if (type == 0) { DrawFormatString(0, 50, GetColor(0, 0, 0), "消しゴム:1 OFF"); } else { DrawFormatString(0, 50, GetColor(0, 0, 0), "消しゴム:1 ON"); } //--------- ここまでにプログラムを記述 ---------// ScreenFlip();//(ダブルバッファ)裏面 // 20ミリ秒待機(疑似60FPS) WaitTimer(20); // Windows システムからくる情報を処理する if (ProcessMessage() == -1) { break; } // ESCキーが押されたらループから抜ける if (CheckHitKey(KEY_INPUT_ESCAPE) == 1) { break; } } //Dxライブラリ終了処理 DxLib_End(); return 0; }

試したこと

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

マウスをドラッグしてる時だけ線を引きたいという事ですか?
それならドラッグ中かどうか判断して線を引けばいいのでは?

↓ドラッグ中だけ線を引くサンプル

C++

1#include "DxLib.h" 2 3const int WIN_WIDTH = 600; //ウィンドウ横幅 4const int WIN_HEIGHT = 400;//ウィンドウ縦幅 5 6int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 7{ 8 //初期化前の設定 9 ChangeWindowMode(TRUE); 10 SetGraphMode(WIN_WIDTH, WIN_HEIGHT, 32); 11 12 //DXライブラリ初期化 13 if (DxLib_Init() == -1)return -1; 14 15 //線描画画面作成 16 int Handle = MakeScreen(640, 480, TRUE); 17 if (SetDrawScreen(Handle) == -1)return -1; 18 SetBackgroundColor(255, 255, 255); 19 ClearDrawScreen(); 20 21 //背景色設定 22 SetDrawScreen(DX_SCREEN_BACK); 23 SetBackgroundColor(255, 255, 255); 24 ClearDrawScreen(); 25 26 //マウス情報用変数 27 int posX, posY, BposX, BposY; 28 bool Drag = false, Pen = true; 29 30 //キー入力用変数 31 char KeyBuf[256]; 32 33 //メインループ 34 while (!ProcessMessage()) 35 { 36 //線描画用画面 37 SetDrawScreen(Handle); 38 39 //キー入力 40 GetHitKeyStateAll(KeyBuf); 41 if (KeyBuf[KEY_INPUT_1] == 1) { Pen = true; } 42 if (KeyBuf[KEY_INPUT_2] == 1) { Pen = false; Drag = false; } 43 if (KeyBuf[KEY_INPUT_0] == 1) { ClearDrawScreen(); } 44 45 //マウス座標取得 46 GetMousePoint(&posX, &posY); 47 48 //マウス入力処理 49 if (GetMouseInput() & MOUSE_INPUT_LEFT) { 50 if (Pen) {//ペンモード 51 if (Drag) {//ドラッグ中は線を引く 52 DrawLine(BposX, BposY, posX, posY, 0x0, 3); 53 BposX = posX; 54 BposY = posY; 55 } 56 else {//ドラッグ開始 57 Drag = true; //ドラッグフラグをオンにする 58 BposX = posX; //線の開始座標を記録 59 BposY = posY; 60 } 61 } 62 else {//消しゴムモード 63 DrawBox(posX - 20, posY - 20, posX + 20, posY + 20, 0xffffff, TRUE); 64 } 65 } 66 else {//マウスのキーは押されていない 67 if (Drag)Drag = false; //ドラッグフラグをオフにする 68 } 69 70 //裏画面に描画 71 SetDrawScreen(DX_SCREEN_BACK); 72 73 //線描画用画面コピー 74 DrawGraph(0, 0, Handle, FALSE); 75 76 //文字等描画 77 DrawString(0, 0, "キー操作:0=全削除 1=ペン 2=消しゴム", 0x0); 78 if (Pen) { 79 DrawString(0, 16, "現在のモード:ペン", 0x0); 80 DrawLine(posX, posY - 10, posX, posY + 10, 0x0); 81 DrawLine(posX - 10, posY, posX + 10, posY, 0x0); 82 } 83 else { 84 DrawString(0, 16, "現在のモード:消しゴム", 0x0); 85 DrawBox(posX - 20, posY - 20, posX + 20, posY + 20, 0xffffff, TRUE); 86 DrawBox(posX - 20, posY - 20, posX + 20, posY + 20, 0x0, FALSE); 87 } 88 //表画面に転送 89 ScreenFlip(); 90 } 91 92 DeleteGraph(Handle); 93 DxLib_End(); 94 95 return 0; 96}

追記でさらにヒント↓

C++

1#include "DxLib.h" 2#include <stdlib.h> 3 4const int WIN_WIDTH = 600; //ウィンドウ横幅 5const int WIN_HEIGHT = 400;//ウィンドウ縦幅 6 7enum PTYPE 8{ 9 Non, 10 Pen, 11 Eraser, 12}; 13 14struct lineseg 15{ 16 int BlackLineX; 17 int BlackLineY; 18 PTYPE Ptype; 19}; 20 21int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 22{ 23 //初期化前の設定 24 ChangeWindowMode(TRUE); 25 SetGraphMode(WIN_WIDTH, WIN_HEIGHT, 32); 26 27 //DXライブラリ初期化 28 if (DxLib_Init() == -1)return -1; 29 30 //背景色設定 31 SetDrawScreen(DX_SCREEN_BACK); 32 SetBackgroundColor(255, 255, 255); 33 34 int linesegMaX = 1000; 35 int linesegCnt = 0; 36 37 lineseg *bline; 38 bline = (lineseg*)malloc(linesegMaX * sizeof(lineseg)); 39 if (bline == NULL) { 40 return -1; 41 } 42 43 //マウス情報用変数 44 int posX, posY; 45 bool Drag = false, PenF = true; 46 47 //キー入力用変数 48 char KeyBuf[256]; 49 50 //メインループ 51 while (!ProcessMessage()) 52 { 53 54 //キー入力 55 GetHitKeyStateAll(KeyBuf); 56 if (KeyBuf[KEY_INPUT_1] == 1) { PenF= true; } 57 if (KeyBuf[KEY_INPUT_2] == 1) { PenF = false; Drag = false; } 58 if (KeyBuf[KEY_INPUT_0] == 1) { linesegCnt = 0; }//メモリ解放はしていない… 59 60 //マウス座標取得 61 GetMousePoint(&posX, &posY); 62 63 //マウス入力処理 64 if (GetMouseInput() & MOUSE_INPUT_LEFT) { 65 //ドラッグ中は座標を追加 66 //(前と座標が同じでも追加されるので、メモリ節約したい場合は移動した時だけ追加するようにした方がいい…) 67 bline[linesegCnt].BlackLineX = posX; 68 bline[linesegCnt].BlackLineY = posY; 69 if(PenF){ 70 if (Drag) {//ドラッグ中は線を引く 71 bline[linesegCnt].Ptype = Pen; 72 } 73 else {//ドラッグ開始 74 Drag = true; //ドラッグフラグをオンにする 75 bline[linesegCnt].Ptype = Non; 76 } 77 } 78 else { 79 bline[linesegCnt].Ptype = Eraser; 80 } 81 linesegCnt++; 82 //メモリが足りなくなったら拡大 83 if (linesegCnt == linesegMaX) { 84 linesegMaX += 1000; 85 lineseg* tmp = (lineseg*)realloc(bline, linesegMaX * sizeof(lineseg)); 86 if (tmp == NULL) { 87 free(bline); 88 return -1; 89 } 90 bline = tmp; 91 } 92 } 93 else {//マウスのキーは押されていない 94 if (Drag)Drag = false; //ドラッグフラグをオフにする 95 } 96 97 //画面クリア 98 ClearDrawScreen(); 99 100 //bline配列の情報を描画 101 for (int i = 0;i< linesegCnt;i++) { 102 switch (bline[i].Ptype) 103 { 104 case Pen: 105 DrawLine(bline[i - 1].BlackLineX, bline[i - 1].BlackLineY, bline[i].BlackLineX, bline[i].BlackLineY, 0x0, 3); 106 break; 107 case Eraser: 108 DrawBox(bline[i].BlackLineX-20, bline[i].BlackLineY-20, bline[i].BlackLineX+20, bline[i].BlackLineY+20, 0xffffff, TRUE); 109 break; 110 } 111 } 112 113 //文字等描画 114 DrawString(0, 0, "キー操作:0=全削除 1=ペン 2=消しゴム", 0x0); 115 DrawFormatString(0, 32, GetColor(0, 0, 0), "現在の配列使用数:%d(確保数:%d)", linesegCnt, linesegMaX); 116 if (PenF) { 117 DrawString(0, 16, "現在のモード:ペン", 0x0); 118 DrawLine(posX, posY - 10, posX, posY + 10, 0x0); 119 DrawLine(posX - 10, posY, posX + 10, posY, 0x0); 120 } 121 else { 122 DrawString(0, 16, "現在のモード:消しゴム", 0x0); 123 DrawBox(posX - 20, posY - 20, posX + 20, posY + 20, 0xffffff, TRUE); 124 DrawBox(posX - 20, posY - 20, posX + 20, posY + 20, 0x0, FALSE); 125 } 126 127 //表画面に転送 128 ScreenFlip(); 129 } 130 131 free(bline); 132 DxLib_End(); 133 134 return 0; 135}

投稿2021/05/14 14:46

編集2021/05/14 20:22
kousatu

総合スコア225

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papu12

2021/05/14 16:34

ご丁寧にサンプルコードまでありがとうございます。線を引くだけならこんなシンプルなコードでできてしまうんですね 貼ってくれたコードを基に自分のコードの方でも出来るんじゃないかと思いやってみたのですがどうもうまくいきません 自分のコードの原型をとどめたままドラッグした時だけ線を引く処理というのはできないものなんでしょうか 今やりたいこととしては DrawLine(bline[i - 1].BlackLineX, bline[i - 1].BlackLineY, bline[i].BlackLineX, bline[i].BlackLineY, bline[i].cr, 3); この部分の[i-1]から[i]にひかれる線をドラッグした時のみ引かれるようにしたいです 要求が多くて申し訳ないです
kousatu

2021/05/14 18:44

>>自分のコードの方でも出来るんじゃないかと思いやってみたのですがどうもうまくいきません 流石に諦めるの早すぎませんか? 回答してから返信まで二時間もたってませんが…。 申し訳ないですけど、完璧な答えのコードを書くつもりはないですよ。 ヒントしか書きません。 追記でさらにヒント書きました。 lineseg構造体に線を引くか、消しゴムかなどの判断をするPtype変数を追加して描画してます。 あと、bline配列をmallocで動的確保して足りなくなったらrealloc()で拡大するようにしました。 更に言うと、もう一つ別の構造体の配列を作り線を引くたびに、そこに線の先頭のポインタとペンのタイプを入れていくような設計にした方が、メモリ効率はよくなると思いますよ。
papu12

2021/05/15 01:53

自分が浅はかでした ヒントを基にもうちょっと自分で考えてみようと思います。追記のヒントまで書かせてしまって申し訳ありません。まずは書いてくれているmallocやrellocについて学びその上でまた分からないことがあったら質問させていただきます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問