From 6b64eab16b469181123944e776396615fc8f2c2c Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Mon, 8 Aug 2022 10:45:35 +0800 Subject: [PATCH] - fix: can't correctly set project icon --- BUILD_cn.md | 40 ++- NEWS.md | 5 +- RedPandaIDE/project.cpp | 4 +- .../settingsdialog/projectgeneralwidget.cpp | 6 +- windows/templates/sweepminer/app.ico | Bin 0 -> 67646 bytes windows/templates/sweepminer/info.template | 22 ++ windows/templates/sweepminer/main.c | 324 ++++++++++++++++++ 7 files changed, 392 insertions(+), 9 deletions(-) create mode 100644 windows/templates/sweepminer/app.ico create mode 100644 windows/templates/sweepminer/info.template create mode 100644 windows/templates/sweepminer/main.c diff --git a/BUILD_cn.md b/BUILD_cn.md index b9d9c456..48743d96 100644 --- a/BUILD_cn.md +++ b/BUILD_cn.md @@ -15,5 +15,41 @@ # Linux 步骤: - - 安装 gcc 和 qt5 - - 使用qtcreator打开Red_Panda_CPP.pro文件 \ No newline at end of file + - 安装 gcc 和 qt5开发相关包 + - 使用qtcreator打开Red_Panda_CPP.pro文件 + + +## Ubuntu + +### 1.安装编译器 + +```text +apt install gcc g++ make gdb gdbserver +``` + +### 2.安装QT5和依赖包 + +```text +apt install qtbase5-dev qttools5-dev-tools libicu-dev libqt5svg5-dev git qterminal +``` + +### 3.下载源码 + +``` +git clone https://gitee.com/royqh1979/RedPanda-CPP.git +``` + +### 4.编译 + +``` +cd cd RedPanda-CPP/ +qmake Red_Panda_CPP.pro +make -j8 +sudo make install +``` + +### 5.运行 + +``` +RedPandaIDE +``` \ No newline at end of file diff --git a/NEWS.md b/NEWS.md index 88056b1f..7f7ec521 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,8 +2,9 @@ Red Panda C++ Version 1.2 - enhancement: Portuguese Translation ( Thanks for crcpucmg@github) - fix: files in network drive is opened in readonly mode - - change: organization structure of templates - - enhancement: create template + - change: reorganization templates in subfolders + - enhancement: create template from project + - fix: can't correctly set project icon Red Panda C++ Version 1.1.6 diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index c61c8b49..0bb10102 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -900,8 +900,8 @@ bool Project::saveAsTemplate(const QString &templateFolder, if (mOptions.execEncoding!=ENCODING_SYSTEM_DEFAULT) ini->SetValue("Project","ExecEncoding", mOptions.execEncoding); - if (!mOptions.staticLink) - ini->SetBoolValue("Project", "StaticLink",false); +// if (!mOptions.staticLink) +// ini->SetBoolValue("Project", "StaticLink",false); if (!mOptions.addCharset) ini->SetBoolValue("Project", "AddCharset",false); if (mOptions.encoding!=ENCODING_AUTO_DETECT) diff --git a/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp b/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp index 45bb7bc4..8276127a 100644 --- a/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp +++ b/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp @@ -104,9 +104,10 @@ void ProjectGeneralWidget::doSave() project->options().isCpp = ui->cbDefaultCpp->isChecked(); project->options().supportXPThemes = ui->cbSupportXPTheme->isChecked(); + qDebug()<<"iconpath"<= QT_VERSION_CHECK(5,15,0) - || !ui->lbIcon->pixmap(Qt::ReturnByValue).isNull()) { + || ui->lbIcon->pixmap(Qt::ReturnByValue).isNull()) { #else || !ui->lbIcon->pixmap() || ui->lbIcon->pixmap()->isNull()) { #endif @@ -130,7 +131,7 @@ void ProjectGeneralWidget::doSave() ui->lbIcon->pixmap()->save(iconPath,"ico"); #endif } else - QFile::copy(mIconPath, iconPath); + copyFile(mIconPath, iconPath,true); project->options().icon = iconPath; mIconPath = iconPath; refreshIcon(); @@ -148,7 +149,6 @@ void ProjectGeneralWidget::on_btnBrowse_clicked() tr("Image Files (*.ico *.png *.jpg)")); if (!fileName.isEmpty()) { mIconPath = fileName; - QPixmap icon(mIconPath); refreshIcon(); setSettingsChanged(); } diff --git a/windows/templates/sweepminer/app.ico b/windows/templates/sweepminer/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..5a076782890f870311193565fd0b8ae0de6dd869 GIT binary patch literal 67646 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 + +#include +#include +#include +#include + +#if defined(PLATFORM_WEB) +#include +#endif + +//---------------------------------------------------------------------------------- +// Some Defines +//---------------------------------------------------------------------------------- +#define PLAYER_MAX_LIFE 5 +#define LINES_OF_BRICKS 5 +#define BRICKS_PER_LINE 20 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum GameScreen { LOGO, TITLE, GAMEPLAY, ENDING } GameScreen; + +typedef struct Player { + Vector2 position; + Vector2 size; + int life; +} Player; + +typedef struct Ball { + Vector2 position; + Vector2 speed; + int radius; + bool active; +} Ball; + +typedef struct Brick { + Vector2 position; + bool active; +} Brick; + +//------------------------------------------------------------------------------------ +// Global Variables Declaration +//------------------------------------------------------------------------------------ +static const int screenWidth = 800; +static const int screenHeight = 450; + +static bool gameOver = false; +static bool pause = false; + +static Player player = { 0 }; +static Ball ball = { 0 }; +static Brick brick[LINES_OF_BRICKS][BRICKS_PER_LINE] = { 0 }; +static Vector2 brickSize = { 0 }; + +//------------------------------------------------------------------------------------ +// Module Functions Declaration (local) +//------------------------------------------------------------------------------------ +static void InitGame(void); // Initialize game +static void UpdateGame(void); // Update game (one frame) +static void DrawGame(void); // Draw game (one frame) +static void UnloadGame(void); // Unload game +static void UpdateDrawFrame(void); // Update and Draw (one frame) + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization (Note windowTitle is unused on Android) + //--------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "classic game: arkanoid"); + + InitGame(); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 60, 1); +#else + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update and Draw + //---------------------------------------------------------------------------------- + UpdateDrawFrame(); + //---------------------------------------------------------------------------------- + } +#endif + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadGame(); // Unload loaded data (textures, sounds, models...) + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definitions (local) +//------------------------------------------------------------------------------------ + +// Initialize game variables +void InitGame(void) +{ + brickSize = (Vector2){ GetScreenWidth()/BRICKS_PER_LINE, 40 }; + + // Initialize player + player.position = (Vector2){ screenWidth/2, screenHeight*7/8 }; + player.size = (Vector2){ screenWidth/10, 20 }; + player.life = PLAYER_MAX_LIFE; + + // Initialize ball + ball.position = (Vector2){ screenWidth/2, screenHeight*7/8 - 30 }; + ball.speed = (Vector2){ 0, 0 }; + ball.radius = 7; + ball.active = false; + + // Initialize bricks + int initialDownPosition = 50; + + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + brick[i][j].position = (Vector2){ j*brickSize.x + brickSize.x/2, i*brickSize.y + initialDownPosition }; + brick[i][j].active = true; + } + } +} + +// Update game (one frame) +void UpdateGame(void) +{ + if (!gameOver) + { + if (IsKeyPressed('P')) pause = !pause; + + if (!pause) + { + // Player movement logic + if (IsKeyDown(KEY_LEFT)) player.position.x -= 5; + if ((player.position.x - player.size.x/2) <= 0) player.position.x = player.size.x/2; + if (IsKeyDown(KEY_RIGHT)) player.position.x += 5; + if ((player.position.x + player.size.x/2) >= screenWidth) player.position.x = screenWidth - player.size.x/2; + + // Ball launching logic + if (!ball.active) + { + if (IsKeyPressed(KEY_SPACE)) + { + ball.active = true; + ball.speed = (Vector2){ 0, -5 }; + } + } + + // Ball movement logic + if (ball.active) + { + ball.position.x += ball.speed.x; + ball.position.y += ball.speed.y; + } + else + { + ball.position = (Vector2){ player.position.x, screenHeight*7/8 - 30 }; + } + + // Collision logic: ball vs walls + if (((ball.position.x + ball.radius) >= screenWidth) || ((ball.position.x - ball.radius) <= 0)) ball.speed.x *= -1; + if ((ball.position.y - ball.radius) <= 0) ball.speed.y *= -1; + if ((ball.position.y + ball.radius) >= screenHeight) + { + ball.speed = (Vector2){ 0, 0 }; + ball.active = false; + + player.life--; + } + + // Collision logic: ball vs player + if (CheckCollisionCircleRec(ball.position, ball.radius, + (Rectangle){ player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y})) + { + if (ball.speed.y > 0) + { + ball.speed.y *= -1; + ball.speed.x = (ball.position.x - player.position.x)/(player.size.x/2)*5; + } + } + + // Collision logic: ball vs bricks + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) + { + // Hit below + if (((ball.position.y - ball.radius) <= (brick[i][j].position.y + brickSize.y/2)) && + ((ball.position.y - ball.radius) > (brick[i][j].position.y + brickSize.y/2 + ball.speed.y)) && + ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y < 0)) + { + brick[i][j].active = false; + ball.speed.y *= -1; + } + // Hit above + else if (((ball.position.y + ball.radius) >= (brick[i][j].position.y - brickSize.y/2)) && + ((ball.position.y + ball.radius) < (brick[i][j].position.y - brickSize.y/2 + ball.speed.y)) && + ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y > 0)) + { + brick[i][j].active = false; + ball.speed.y *= -1; + } + // Hit left + else if (((ball.position.x + ball.radius) >= (brick[i][j].position.x - brickSize.x/2)) && + ((ball.position.x + ball.radius) < (brick[i][j].position.x - brickSize.x/2 + ball.speed.x)) && + ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x > 0)) + { + brick[i][j].active = false; + ball.speed.x *= -1; + } + // Hit right + else if (((ball.position.x - ball.radius) <= (brick[i][j].position.x + brickSize.x/2)) && + ((ball.position.x - ball.radius) > (brick[i][j].position.x + brickSize.x/2 + ball.speed.x)) && + ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x < 0)) + { + brick[i][j].active = false; + ball.speed.x *= -1; + } + } + } + } + + // Game over logic + if (player.life <= 0) gameOver = true; + else + { + gameOver = true; + + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) gameOver = false; + } + } + } + } + } + else + { + if (IsKeyPressed(KEY_ENTER)) + { + InitGame(); + gameOver = false; + } + } +} + +// Draw game (one frame) +void DrawGame(void) +{ + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (!gameOver) + { + // Draw player bar + DrawRectangle(player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y, BLACK); + + // Draw player lives + for (int i = 0; i < player.life; i++) DrawRectangle(20 + 40*i, screenHeight - 30, 35, 10, LIGHTGRAY); + + // Draw ball + DrawCircleV(ball.position, ball.radius, MAROON); + + // Draw bricks + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) + { + if ((i + j) % 2 == 0) DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, GRAY); + else DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, DARKGRAY); + } + } + } + + if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY); + } + else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY); + + EndDrawing(); +} + +// Unload game variables +void UnloadGame(void) +{ + // TODO: Unload all dynamic loaded data (textures, sounds, models...) +} + +// Update and Draw (one frame) +void UpdateDrawFrame(void) +{ + UpdateGame(); + DrawGame(); +}