Merge branch 'master' of github.com:royqh1979/RedPanda-CPP
2
NEWS.md
|
@ -15,6 +15,8 @@ Red Panda C++ Version 1.1.0
|
||||||
- fix: can't remove a shortcut
|
- fix: can't remove a shortcut
|
||||||
- enhancement: hide all menu actions in the option dialog's shortcut panel
|
- enhancement: hide all menu actions in the option dialog's shortcut panel
|
||||||
- enhancement: add 'run all problem cases' / 'run current problem case' / 'batch set cases' to the option dialog's shortcut panel
|
- enhancement: add 'run all problem cases' / 'run current problem case' / 'batch set cases' to the option dialog's shortcut panel
|
||||||
|
- enhancement: more templates for raylib
|
||||||
|
- fix: compiler settings not correctly saved
|
||||||
|
|
||||||
Red Panda C++ Version 1.0.10
|
Red Panda C++ Version 1.0.10
|
||||||
- fix: modify watch doesn't work
|
- fix: modify watch doesn't work
|
||||||
|
|
|
@ -1064,7 +1064,7 @@ void MainWindow::updateShortcuts()
|
||||||
{
|
{
|
||||||
ShortcutManager manager;
|
ShortcutManager manager;
|
||||||
manager.load();
|
manager.load();
|
||||||
manager.applyTo(findChildren<QAction*>());
|
manager.applyTo(listShortCutableActions());
|
||||||
}
|
}
|
||||||
|
|
||||||
QPlainTextEdit *MainWindow::txtLocals()
|
QPlainTextEdit *MainWindow::txtLocals()
|
||||||
|
@ -2263,10 +2263,12 @@ void MainWindow::buildContextMenus()
|
||||||
this, &MainWindow::onLstProblemSetContextMenu);
|
this, &MainWindow::onLstProblemSetContextMenu);
|
||||||
mProblem_Properties = createActionFor(
|
mProblem_Properties = createActionFor(
|
||||||
tr("Properties..."),
|
tr("Properties..."),
|
||||||
ui->lstProblemSet
|
this
|
||||||
);
|
);
|
||||||
|
mProblem_Properties->setObjectName("actionProbelm_Properties");
|
||||||
connect(mProblem_Properties, &QAction::triggered, this,
|
connect(mProblem_Properties, &QAction::triggered, this,
|
||||||
&MainWindow::onProblemProperties);
|
&MainWindow::onProblemProperties);
|
||||||
|
|
||||||
mProblem_OpenSource=createActionFor(
|
mProblem_OpenSource=createActionFor(
|
||||||
tr("Open Source File"),
|
tr("Open Source File"),
|
||||||
ui->lstProblemSet
|
ui->lstProblemSet
|
||||||
|
@ -2280,19 +2282,24 @@ void MainWindow::buildContextMenus()
|
||||||
this, &MainWindow::onTableProblemCasesContextMenu);
|
this, &MainWindow::onTableProblemCasesContextMenu);
|
||||||
mProblem_RunAllCases = createActionFor(
|
mProblem_RunAllCases = createActionFor(
|
||||||
tr("Run All Cases"),
|
tr("Run All Cases"),
|
||||||
ui->tblProblemCases
|
this
|
||||||
);
|
);
|
||||||
|
mProblem_RunAllCases->setObjectName("Problem_RunAllCases");
|
||||||
connect(mProblem_RunAllCases, &QAction::triggered, this,
|
connect(mProblem_RunAllCases, &QAction::triggered, this,
|
||||||
&MainWindow::on_btnRunAllProblemCases_clicked);
|
&MainWindow::on_btnRunAllProblemCases_clicked);
|
||||||
|
|
||||||
mProblem_RunCurrentCase = createActionFor(
|
mProblem_RunCurrentCase = createActionFor(
|
||||||
tr("Run Current Case"),
|
tr("Run Current Case"),
|
||||||
ui->tblProblemCases
|
this
|
||||||
);
|
);
|
||||||
|
mProblem_RunCurrentCase->setObjectName("Problem_RunCurrentCases");
|
||||||
connect(mProblem_RunCurrentCase, &QAction::triggered, this,
|
connect(mProblem_RunCurrentCase, &QAction::triggered, this,
|
||||||
&MainWindow::onProblemRunCurrentCase);
|
&MainWindow::onProblemRunCurrentCase);
|
||||||
|
|
||||||
mProblem_batchSetCases = createActionFor(
|
mProblem_batchSetCases = createActionFor(
|
||||||
tr("Batch Set Cases"),
|
tr("Batch Set Cases"),
|
||||||
ui->tblProblemCases);
|
this);
|
||||||
|
mProblem_batchSetCases->setObjectName("Problem_BatchSetCases");
|
||||||
connect(mProblem_batchSetCases, &QAction::triggered, this,
|
connect(mProblem_batchSetCases, &QAction::triggered, this,
|
||||||
&MainWindow::onProblemBatchSetCases);
|
&MainWindow::onProblemBatchSetCases);
|
||||||
|
|
||||||
|
@ -3288,12 +3295,16 @@ void MainWindow::onProblemNameChanged(int index)
|
||||||
|
|
||||||
void MainWindow::onProblemRunCurrentCase()
|
void MainWindow::onProblemRunCurrentCase()
|
||||||
{
|
{
|
||||||
|
if (!ui->tblProblemCases->currentIndex().isValid())
|
||||||
|
return;
|
||||||
|
showHideMessagesTab(ui->tabProblem,ui->actionProblem);
|
||||||
applyCurrentProblemCaseChanges();
|
applyCurrentProblemCaseChanges();
|
||||||
runExecutable(RunType::CurrentProblemCase);
|
runExecutable(RunType::CurrentProblemCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onProblemBatchSetCases()
|
void MainWindow::onProblemBatchSetCases()
|
||||||
{
|
{
|
||||||
|
showHideMessagesTab(ui->tabProblem,ui->actionProblem);
|
||||||
if (mOJProblemModel.count()>0 && QMessageBox::question(this,tr("Batch Set Cases"),
|
if (mOJProblemModel.count()>0 && QMessageBox::question(this,tr("Batch Set Cases"),
|
||||||
tr("This operation will remove all cases for the current problem.")
|
tr("This operation will remove all cases for the current problem.")
|
||||||
+"<br />"
|
+"<br />"
|
||||||
|
@ -3550,6 +3561,7 @@ void MainWindow::onFilesViewRename() {
|
||||||
|
|
||||||
void MainWindow::onProblemProperties()
|
void MainWindow::onProblemProperties()
|
||||||
{
|
{
|
||||||
|
showHideMessagesTab(ui->tabProblem,ui->actionProblem);
|
||||||
QModelIndex idx = ui->lstProblemSet->currentIndex();
|
QModelIndex idx = ui->lstProblemSet->currentIndex();
|
||||||
if (!idx.isValid())
|
if (!idx.isValid())
|
||||||
return;
|
return;
|
||||||
|
@ -6891,7 +6903,10 @@ void MainWindow::on_btnAddProblemCase_clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_btnRunAllProblemCases_clicked()
|
void MainWindow::on_btnRunAllProblemCases_clicked()
|
||||||
{
|
{
|
||||||
|
if (mOJProblemModel.count()<=0)
|
||||||
|
return;
|
||||||
|
showHideMessagesTab(ui->tabProblem,ui->actionProblem);
|
||||||
applyCurrentProblemCaseChanges();
|
applyCurrentProblemCaseChanges();
|
||||||
runExecutable(RunType::ProblemCases);
|
runExecutable(RunType::ProblemCases);
|
||||||
}
|
}
|
||||||
|
@ -6935,10 +6950,6 @@ bool MainWindow::openningFiles() const
|
||||||
QList<QAction *> MainWindow::listShortCutableActions()
|
QList<QAction *> MainWindow::listShortCutableActions()
|
||||||
{
|
{
|
||||||
QList<QAction*> actions = findChildren<QAction *>(QString(), Qt::FindDirectChildrenOnly);
|
QList<QAction*> actions = findChildren<QAction *>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
actions.append(mProblem_RunAllCases);
|
|
||||||
actions.append(mProblem_RunCurrentCase);
|
|
||||||
actions.append(mProblem_batchSetCases);
|
|
||||||
actions.append(mProblem_Properties);
|
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2682,6 +2682,9 @@ void Settings::CompilerSets::saveSet(int index)
|
||||||
savePath("profiler", pSet->profiler());
|
savePath("profiler", pSet->profiler());
|
||||||
|
|
||||||
mSettings->mSettings.remove("Options");
|
mSettings->mSettings.remove("Options");
|
||||||
|
foreach(const PCompilerOption& option, pCompilerInfoManager->getCompilerOptions(pSet->compilerType())) {
|
||||||
|
mSettings->mSettings.remove(option->key);
|
||||||
|
}
|
||||||
// Save option string
|
// Save option string
|
||||||
for (const QString& optionKey : pSet->compileOptions().keys()) {
|
for (const QString& optionKey : pSet->compileOptions().keys()) {
|
||||||
mSettings->mSettings.setValue(optionKey, pSet->compileOptions().value(optionKey));
|
mSettings->mSettings.setValue(optionKey, pSet->compileOptions().value(optionKey));
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="settingTabs">
|
<widget class="QTabWidget" name="settingTabs">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="movable">
|
<property name="movable">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 66 KiB |
|
@ -2,9 +2,9 @@
|
||||||
ver=2
|
ver=2
|
||||||
Name=raylib
|
Name=raylib
|
||||||
Name[zh_CN]=raylib
|
Name[zh_CN]=raylib
|
||||||
Icon=raylib.ico
|
Icon=raylib-game.ico
|
||||||
Description=A simple program using raylib ( https://raylib.com )
|
Description=A simple interactive animation using raylib ( https://raylib.com )
|
||||||
Description[zh_CN]=简单的raylib绘图程序 ( https://raylib.com )
|
Description[zh_CN]=简单的raylib交互动画 ( https://raylib.com )
|
||||||
Category=Multimedia
|
Category=Multimedia
|
||||||
Category[zh_CN]=多媒体
|
Category[zh_CN]=多媒体
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=snake
|
||||||
|
Name[zh_CN]=吞食蛇
|
||||||
|
Icon=raylib-snake.ico
|
||||||
|
Description=snake game using raylib ( https://raylib.com )
|
||||||
|
Description[zh_CN]=经典的吞食蛇游戏(基于raylib) ( https://raylib.com )
|
||||||
|
Category=Game
|
||||||
|
Category[zh_CN]=游戏
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=raylib_snake_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lraylib -lGL -lm -lpthread -ldl -lrt -lX11
|
||||||
|
|
|
@ -0,0 +1,286 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib - classic game: snake
|
||||||
|
*
|
||||||
|
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
|
||||||
|
*
|
||||||
|
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||||
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Some Defines
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define SNAKE_LENGTH 256
|
||||||
|
#define SQUARE_SIZE 31
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef struct Snake {
|
||||||
|
Vector2 position;
|
||||||
|
Vector2 size;
|
||||||
|
Vector2 speed;
|
||||||
|
Color color;
|
||||||
|
} Snake;
|
||||||
|
|
||||||
|
typedef struct Food {
|
||||||
|
Vector2 position;
|
||||||
|
Vector2 size;
|
||||||
|
bool active;
|
||||||
|
Color color;
|
||||||
|
} Food;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Global Variables Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static const int screenWidth = 800;
|
||||||
|
static const int screenHeight = 450;
|
||||||
|
|
||||||
|
static int framesCounter = 0;
|
||||||
|
static bool gameOver = false;
|
||||||
|
static bool pause = false;
|
||||||
|
|
||||||
|
static Food fruit = { 0 };
|
||||||
|
static Snake snake[SNAKE_LENGTH] = { 0 };
|
||||||
|
static Vector2 snakePosition[SNAKE_LENGTH] = { 0 };
|
||||||
|
static bool allowMove = false;
|
||||||
|
static Vector2 offset = { 0 };
|
||||||
|
static int counterTail = 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: snake");
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
framesCounter = 0;
|
||||||
|
gameOver = false;
|
||||||
|
pause = false;
|
||||||
|
|
||||||
|
counterTail = 1;
|
||||||
|
allowMove = false;
|
||||||
|
|
||||||
|
offset.x = screenWidth%SQUARE_SIZE;
|
||||||
|
offset.y = screenHeight%SQUARE_SIZE;
|
||||||
|
|
||||||
|
for (int i = 0; i < SNAKE_LENGTH; i++)
|
||||||
|
{
|
||||||
|
snake[i].position = (Vector2){ offset.x/2, offset.y/2 };
|
||||||
|
snake[i].size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE };
|
||||||
|
snake[i].speed = (Vector2){ SQUARE_SIZE, 0 };
|
||||||
|
|
||||||
|
if (i == 0) snake[i].color = DARKBLUE;
|
||||||
|
else snake[i].color = BLUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < SNAKE_LENGTH; i++)
|
||||||
|
{
|
||||||
|
snakePosition[i] = (Vector2){ 0.0f, 0.0f };
|
||||||
|
}
|
||||||
|
|
||||||
|
fruit.size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE };
|
||||||
|
fruit.color = SKYBLUE;
|
||||||
|
fruit.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update game (one frame)
|
||||||
|
void UpdateGame(void)
|
||||||
|
{
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
if (IsKeyPressed('P')) pause = !pause;
|
||||||
|
|
||||||
|
if (!pause)
|
||||||
|
{
|
||||||
|
// Player control
|
||||||
|
if (IsKeyPressed(KEY_RIGHT) && (snake[0].speed.x == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ SQUARE_SIZE, 0 };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
if (IsKeyPressed(KEY_LEFT) && (snake[0].speed.x == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ -SQUARE_SIZE, 0 };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
if (IsKeyPressed(KEY_UP) && (snake[0].speed.y == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ 0, -SQUARE_SIZE };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
if (IsKeyPressed(KEY_DOWN) && (snake[0].speed.y == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ 0, SQUARE_SIZE };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snake movement
|
||||||
|
for (int i = 0; i < counterTail; i++) snakePosition[i] = snake[i].position;
|
||||||
|
|
||||||
|
if ((framesCounter%5) == 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < counterTail; i++)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
snake[0].position.x += snake[0].speed.x;
|
||||||
|
snake[0].position.y += snake[0].speed.y;
|
||||||
|
allowMove = true;
|
||||||
|
}
|
||||||
|
else snake[i].position = snakePosition[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wall behaviour
|
||||||
|
if (((snake[0].position.x) > (screenWidth - offset.x)) ||
|
||||||
|
((snake[0].position.y) > (screenHeight - offset.y)) ||
|
||||||
|
(snake[0].position.x < 0) || (snake[0].position.y < 0))
|
||||||
|
{
|
||||||
|
gameOver = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collision with yourself
|
||||||
|
for (int i = 1; i < counterTail; i++)
|
||||||
|
{
|
||||||
|
if ((snake[0].position.x == snake[i].position.x) && (snake[0].position.y == snake[i].position.y)) gameOver = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fruit position calculation
|
||||||
|
if (!fruit.active)
|
||||||
|
{
|
||||||
|
fruit.active = true;
|
||||||
|
fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
|
||||||
|
|
||||||
|
for (int i = 0; i < counterTail; i++)
|
||||||
|
{
|
||||||
|
while ((fruit.position.x == snake[i].position.x) && (fruit.position.y == snake[i].position.y))
|
||||||
|
{
|
||||||
|
fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collision
|
||||||
|
if ((snake[0].position.x < (fruit.position.x + fruit.size.x) && (snake[0].position.x + snake[0].size.x) > fruit.position.x) &&
|
||||||
|
(snake[0].position.y < (fruit.position.y + fruit.size.y) && (snake[0].position.y + snake[0].size.y) > fruit.position.y))
|
||||||
|
{
|
||||||
|
snake[counterTail].position = snakePosition[counterTail - 1];
|
||||||
|
counterTail += 1;
|
||||||
|
fruit.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
framesCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IsKeyPressed(KEY_ENTER))
|
||||||
|
{
|
||||||
|
InitGame();
|
||||||
|
gameOver = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw game (one frame)
|
||||||
|
void DrawGame(void)
|
||||||
|
{
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
// Draw grid lines
|
||||||
|
for (int i = 0; i < screenWidth/SQUARE_SIZE + 1; i++)
|
||||||
|
{
|
||||||
|
DrawLineV((Vector2){SQUARE_SIZE*i + offset.x/2, offset.y/2}, (Vector2){SQUARE_SIZE*i + offset.x/2, screenHeight - offset.y/2}, LIGHTGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < screenHeight/SQUARE_SIZE + 1; i++)
|
||||||
|
{
|
||||||
|
DrawLineV((Vector2){offset.x/2, SQUARE_SIZE*i + offset.y/2}, (Vector2){screenWidth - offset.x/2, SQUARE_SIZE*i + offset.y/2}, LIGHTGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw snake
|
||||||
|
for (int i = 0; i < counterTail; i++) DrawRectangleV(snake[i].position, snake[i].size, snake[i].color);
|
||||||
|
|
||||||
|
// Draw fruit to pick
|
||||||
|
DrawRectangleV(fruit.position, fruit.size, fruit.color);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=Tetris
|
||||||
|
Name[zh_CN]=俄罗斯方块
|
||||||
|
Icon=raylib-tetris.ico
|
||||||
|
Description=Tetris game using raylib ( https://raylib.com )
|
||||||
|
Description[zh_CN]=经典的俄罗斯方块游戏(基于raylib) ( https://raylib.com )
|
||||||
|
Category=Game
|
||||||
|
Category[zh_CN]=游戏
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=raylib_tetris_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lraylib -lGL -lm -lpthread -ldl -lrt -lX11
|
||||||
|
|
|
@ -0,0 +1,791 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib - classic game: tetris
|
||||||
|
*
|
||||||
|
* Sample game developed by Marc Palau and Ramon Santamaria
|
||||||
|
*
|
||||||
|
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||||
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Some Defines
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define SQUARE_SIZE 20
|
||||||
|
|
||||||
|
#define GRID_HORIZONTAL_SIZE 12
|
||||||
|
#define GRID_VERTICAL_SIZE 20
|
||||||
|
|
||||||
|
#define LATERAL_SPEED 10
|
||||||
|
#define TURNING_SPEED 12
|
||||||
|
#define FAST_FALL_AWAIT_COUNTER 30
|
||||||
|
|
||||||
|
#define FADING_TIME 33
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef enum GridSquare { EMPTY, MOVING, FULL, BLOCK, FADING } GridSquare;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Global Variables Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static const int screenWidth = 800;
|
||||||
|
static const int screenHeight = 450;
|
||||||
|
|
||||||
|
static bool gameOver = false;
|
||||||
|
static bool pause = false;
|
||||||
|
|
||||||
|
// Matrices
|
||||||
|
static GridSquare grid [GRID_HORIZONTAL_SIZE][GRID_VERTICAL_SIZE];
|
||||||
|
static GridSquare piece [4][4];
|
||||||
|
static GridSquare incomingPiece [4][4];
|
||||||
|
|
||||||
|
// Theese variables keep track of the active piece position
|
||||||
|
static int piecePositionX = 0;
|
||||||
|
static int piecePositionY = 0;
|
||||||
|
|
||||||
|
// Game parameters
|
||||||
|
static Color fadingColor;
|
||||||
|
//static int fallingSpeed; // In frames
|
||||||
|
|
||||||
|
static bool beginPlay = true; // This var is only true at the begining of the game, used for the first matrix creations
|
||||||
|
static bool pieceActive = false;
|
||||||
|
static bool detection = false;
|
||||||
|
static bool lineToDelete = false;
|
||||||
|
|
||||||
|
// Statistics
|
||||||
|
static int level = 1;
|
||||||
|
static int lines = 0;
|
||||||
|
|
||||||
|
// Counters
|
||||||
|
static int gravityMovementCounter = 0;
|
||||||
|
static int lateralMovementCounter = 0;
|
||||||
|
static int turnMovementCounter = 0;
|
||||||
|
static int fastFallMovementCounter = 0;
|
||||||
|
|
||||||
|
static int fadeLineCounter = 0;
|
||||||
|
|
||||||
|
// Based on level
|
||||||
|
static int gravitySpeed = 30;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// Additional module functions
|
||||||
|
static bool Createpiece();
|
||||||
|
static void GetRandompiece();
|
||||||
|
static void ResolveFallingMovement(bool *detection, bool *pieceActive);
|
||||||
|
static bool ResolveLateralMovement();
|
||||||
|
static bool ResolveTurnMovement();
|
||||||
|
static void CheckDetection(bool *detection);
|
||||||
|
static void CheckCompletion(bool *lineToDelete);
|
||||||
|
static void DeleteCompleteLines();
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization (Note windowTitle is unused on Android)
|
||||||
|
//---------------------------------------------------------
|
||||||
|
InitWindow(screenWidth, screenHeight, "classic game: tetris");
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Game Module Functions Definition
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Initialize game variables
|
||||||
|
void InitGame(void)
|
||||||
|
{
|
||||||
|
// Initialize game statistics
|
||||||
|
level = 1;
|
||||||
|
lines = 0;
|
||||||
|
|
||||||
|
fadingColor = GRAY;
|
||||||
|
|
||||||
|
piecePositionX = 0;
|
||||||
|
piecePositionY = 0;
|
||||||
|
|
||||||
|
pause = false;
|
||||||
|
|
||||||
|
beginPlay = true;
|
||||||
|
pieceActive = false;
|
||||||
|
detection = false;
|
||||||
|
lineToDelete = false;
|
||||||
|
|
||||||
|
// Counters
|
||||||
|
gravityMovementCounter = 0;
|
||||||
|
lateralMovementCounter = 0;
|
||||||
|
turnMovementCounter = 0;
|
||||||
|
fastFallMovementCounter = 0;
|
||||||
|
|
||||||
|
fadeLineCounter = 0;
|
||||||
|
gravitySpeed = 30;
|
||||||
|
|
||||||
|
// Initialize grid matrices
|
||||||
|
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
|
||||||
|
{
|
||||||
|
if ((j == GRID_VERTICAL_SIZE - 1) || (i == 0) || (i == GRID_HORIZONTAL_SIZE - 1)) grid[i][j] = BLOCK;
|
||||||
|
else grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize incoming piece matrices
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j< 4; j++)
|
||||||
|
{
|
||||||
|
incomingPiece[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update game (one frame)
|
||||||
|
void UpdateGame(void)
|
||||||
|
{
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
if (IsKeyPressed('P')) pause = !pause;
|
||||||
|
|
||||||
|
if (!pause)
|
||||||
|
{
|
||||||
|
if (!lineToDelete)
|
||||||
|
{
|
||||||
|
if (!pieceActive)
|
||||||
|
{
|
||||||
|
// Get another piece
|
||||||
|
pieceActive = Createpiece();
|
||||||
|
|
||||||
|
// We leave a little time before starting the fast falling down
|
||||||
|
fastFallMovementCounter = 0;
|
||||||
|
}
|
||||||
|
else // Piece falling
|
||||||
|
{
|
||||||
|
// Counters update
|
||||||
|
fastFallMovementCounter++;
|
||||||
|
gravityMovementCounter++;
|
||||||
|
lateralMovementCounter++;
|
||||||
|
turnMovementCounter++;
|
||||||
|
|
||||||
|
// We make sure to move if we've pressed the key this frame
|
||||||
|
if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_RIGHT)) lateralMovementCounter = LATERAL_SPEED;
|
||||||
|
if (IsKeyPressed(KEY_UP)) turnMovementCounter = TURNING_SPEED;
|
||||||
|
|
||||||
|
// Fall down
|
||||||
|
if (IsKeyDown(KEY_DOWN) && (fastFallMovementCounter >= FAST_FALL_AWAIT_COUNTER))
|
||||||
|
{
|
||||||
|
// We make sure the piece is going to fall this frame
|
||||||
|
gravityMovementCounter += gravitySpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gravityMovementCounter >= gravitySpeed)
|
||||||
|
{
|
||||||
|
// Basic falling movement
|
||||||
|
CheckDetection(&detection);
|
||||||
|
|
||||||
|
// Check if the piece has collided with another piece or with the boundings
|
||||||
|
ResolveFallingMovement(&detection, &pieceActive);
|
||||||
|
|
||||||
|
// Check if we fullfilled a line and if so, erase the line and pull down the the lines above
|
||||||
|
CheckCompletion(&lineToDelete);
|
||||||
|
|
||||||
|
gravityMovementCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move laterally at player's will
|
||||||
|
if (lateralMovementCounter >= LATERAL_SPEED)
|
||||||
|
{
|
||||||
|
// Update the lateral movement and if success, reset the lateral counter
|
||||||
|
if (!ResolveLateralMovement()) lateralMovementCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn the piece at player's will
|
||||||
|
if (turnMovementCounter >= TURNING_SPEED)
|
||||||
|
{
|
||||||
|
// Update the turning movement and reset the turning counter
|
||||||
|
if (ResolveTurnMovement()) turnMovementCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game over logic
|
||||||
|
for (int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == FULL)
|
||||||
|
{
|
||||||
|
gameOver = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Animation when deleting lines
|
||||||
|
fadeLineCounter++;
|
||||||
|
|
||||||
|
if (fadeLineCounter%8 < 4) fadingColor = MAROON;
|
||||||
|
else fadingColor = GRAY;
|
||||||
|
|
||||||
|
if (fadeLineCounter >= FADING_TIME)
|
||||||
|
{
|
||||||
|
DeleteCompleteLines();
|
||||||
|
fadeLineCounter = 0;
|
||||||
|
lineToDelete = false;
|
||||||
|
|
||||||
|
lines++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IsKeyPressed(KEY_ENTER))
|
||||||
|
{
|
||||||
|
InitGame();
|
||||||
|
gameOver = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw game (one frame)
|
||||||
|
void DrawGame(void)
|
||||||
|
{
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
// Draw gameplay area
|
||||||
|
Vector2 offset;
|
||||||
|
offset.x = screenWidth/2 - (GRID_HORIZONTAL_SIZE*SQUARE_SIZE/2) - 50;
|
||||||
|
offset.y = screenHeight/2 - ((GRID_VERTICAL_SIZE - 1)*SQUARE_SIZE/2) + SQUARE_SIZE*2;
|
||||||
|
|
||||||
|
offset.y -= 50; // NOTE: Harcoded position!
|
||||||
|
|
||||||
|
int controller = offset.x;
|
||||||
|
|
||||||
|
for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
|
||||||
|
{
|
||||||
|
// Draw each square of the grid
|
||||||
|
if (grid[i][j] == EMPTY)
|
||||||
|
{
|
||||||
|
DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == FULL)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, DARKGRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == BLOCK)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, LIGHTGRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == FADING)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, fadingColor);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset.x = controller;
|
||||||
|
offset.y += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw incoming piece (hardcoded)
|
||||||
|
offset.x = 500;
|
||||||
|
offset.y = 45;
|
||||||
|
|
||||||
|
int controler = offset.x;
|
||||||
|
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (incomingPiece[i][j] == EMPTY)
|
||||||
|
{
|
||||||
|
DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (incomingPiece[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset.x = controler;
|
||||||
|
offset.y += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawText("INCOMING:", offset.x, offset.y - 100, 10, GRAY);
|
||||||
|
DrawText(TextFormat("LINES: %04i", lines), offset.x, offset.y + 20, 10, GRAY);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Additional module functions
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
static bool Createpiece()
|
||||||
|
{
|
||||||
|
piecePositionX = (int)((GRID_HORIZONTAL_SIZE - 4)/2);
|
||||||
|
piecePositionY = 0;
|
||||||
|
|
||||||
|
// If the game is starting and you are going to create the first piece, we create an extra one
|
||||||
|
if (beginPlay)
|
||||||
|
{
|
||||||
|
GetRandompiece();
|
||||||
|
beginPlay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assign the incoming piece to the actual piece
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j< 4; j++)
|
||||||
|
{
|
||||||
|
piece[i][j] = incomingPiece[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assign a random piece to the incoming one
|
||||||
|
GetRandompiece();
|
||||||
|
|
||||||
|
// Assign the piece to the grid
|
||||||
|
for (int i = piecePositionX; i < piecePositionX + 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
if (piece[i - (int)piecePositionX][j] == MOVING) grid[i][j] = MOVING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetRandompiece()
|
||||||
|
{
|
||||||
|
int random = GetRandomValue(0, 6);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
incomingPiece[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (random)
|
||||||
|
{
|
||||||
|
case 0: { incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; } break; //Cube
|
||||||
|
case 1: { incomingPiece[1][0] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; } break; //L
|
||||||
|
case 2: { incomingPiece[1][2] = MOVING; incomingPiece[2][0] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[2][2] = MOVING; } break; //L inversa
|
||||||
|
case 3: { incomingPiece[0][1] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[3][1] = MOVING; } break; //Recta
|
||||||
|
case 4: { incomingPiece[1][0] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][1] = MOVING; } break; //Creu tallada
|
||||||
|
case 5: { incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[2][2] = MOVING; incomingPiece[3][2] = MOVING; } break; //S
|
||||||
|
case 6: { incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[3][1] = MOVING; } break; //S inversa
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResolveFallingMovement(bool *detection, bool *pieceActive)
|
||||||
|
{
|
||||||
|
// If we finished moving this piece, we stop it
|
||||||
|
if (*detection)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j] = FULL;
|
||||||
|
*detection = false;
|
||||||
|
*pieceActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // We move down the piece
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j+1] = MOVING;
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
piecePositionY++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ResolveLateralMovement()
|
||||||
|
{
|
||||||
|
bool collision = false;
|
||||||
|
|
||||||
|
// Piece movement
|
||||||
|
if (IsKeyDown(KEY_LEFT)) // Move left
|
||||||
|
{
|
||||||
|
// Check if is possible to move to left
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
// Check if we are touching the left wall or we have a full square at the left
|
||||||
|
if ((i-1 == 0) || (grid[i-1][j] == FULL)) collision = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If able, move left
|
||||||
|
if (!collision)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) // We check the matrix from left to right
|
||||||
|
{
|
||||||
|
// Move everything to the left
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i-1][j] = MOVING;
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
piecePositionX--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsKeyDown(KEY_RIGHT)) // Move right
|
||||||
|
{
|
||||||
|
// Check if is possible to move to right
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
// Check if we are touching the right wall or we have a full square at the right
|
||||||
|
if ((i+1 == GRID_HORIZONTAL_SIZE - 1) || (grid[i+1][j] == FULL))
|
||||||
|
{
|
||||||
|
collision = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If able move right
|
||||||
|
if (!collision)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = GRID_HORIZONTAL_SIZE - 1; i >= 1; i--) // We check the matrix from right to left
|
||||||
|
{
|
||||||
|
// Move everything to the right
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i+1][j] = MOVING;
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
piecePositionX++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ResolveTurnMovement()
|
||||||
|
{
|
||||||
|
// Input for turning the piece
|
||||||
|
if (IsKeyDown(KEY_UP))
|
||||||
|
{
|
||||||
|
GridSquare aux;
|
||||||
|
bool checker = false;
|
||||||
|
|
||||||
|
// Check all turning possibilities
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if (!checker)
|
||||||
|
{
|
||||||
|
aux = piece[0][0];
|
||||||
|
piece[0][0] = piece[3][0];
|
||||||
|
piece[3][0] = piece[3][3];
|
||||||
|
piece[3][3] = piece[0][3];
|
||||||
|
piece[0][3] = aux;
|
||||||
|
|
||||||
|
aux = piece[1][0];
|
||||||
|
piece[1][0] = piece[3][1];
|
||||||
|
piece[3][1] = piece[2][3];
|
||||||
|
piece[2][3] = piece[0][2];
|
||||||
|
piece[0][2] = aux;
|
||||||
|
|
||||||
|
aux = piece[2][0];
|
||||||
|
piece[2][0] = piece[3][2];
|
||||||
|
piece[3][2] = piece[1][3];
|
||||||
|
piece[1][3] = piece[0][1];
|
||||||
|
piece[0][1] = aux;
|
||||||
|
|
||||||
|
aux = piece[1][1];
|
||||||
|
piece[1][1] = piece[2][1];
|
||||||
|
piece[2][1] = piece[2][2];
|
||||||
|
piece[2][2] = piece[1][2];
|
||||||
|
piece[1][2] = aux;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = piecePositionX; i < piecePositionX + 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = piecePositionY; j < piecePositionY + 4; j++)
|
||||||
|
{
|
||||||
|
if (piece[i - piecePositionX][j - piecePositionY] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j] = MOVING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckDetection(bool *detection)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if ((grid[i][j] == MOVING) && ((grid[i][j+1] == FULL) || (grid[i][j+1] == BLOCK))) *detection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckCompletion(bool *lineToDelete)
|
||||||
|
{
|
||||||
|
int calculator = 0;
|
||||||
|
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
calculator = 0;
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
// Count each square of the line
|
||||||
|
if (grid[i][j] == FULL)
|
||||||
|
{
|
||||||
|
calculator++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we completed the whole line
|
||||||
|
if (calculator == GRID_HORIZONTAL_SIZE - 2)
|
||||||
|
{
|
||||||
|
*lineToDelete = true;
|
||||||
|
calculator = 0;
|
||||||
|
// points++;
|
||||||
|
|
||||||
|
// Mark the completed line
|
||||||
|
for (int z = 1; z < GRID_HORIZONTAL_SIZE - 1; z++)
|
||||||
|
{
|
||||||
|
grid[z][j] = FADING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeleteCompleteLines()
|
||||||
|
{
|
||||||
|
// Erase the completed line
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
while (grid[1][j] == FADING)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j2 = j-1; j2 >= 0; j2--)
|
||||||
|
{
|
||||||
|
for (int i2 = 1; i2 < GRID_HORIZONTAL_SIZE - 1; i2++)
|
||||||
|
{
|
||||||
|
if (grid[i2][j2] == FULL)
|
||||||
|
{
|
||||||
|
grid[i2][j2+1] = FULL;
|
||||||
|
grid[i2][j2] = EMPTY;
|
||||||
|
}
|
||||||
|
else if (grid[i2][j2] == FADING)
|
||||||
|
{
|
||||||
|
grid[i2][j2+1] = FADING;
|
||||||
|
grid[i2][j2] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 66 KiB |
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=rdrawing
|
||||||
|
Name[zh_CN]=rdrawing
|
||||||
|
Icon=rdrawing.ico
|
||||||
|
Description=A simple 2d drawing app using raylib and rdrawing
|
||||||
|
Description[zh_CN]=基于raylib和rdrawing的2维绘图程序 (https://github.com/royqh1979/raylib-drawing)
|
||||||
|
Category=Multimedia
|
||||||
|
Category[zh_CN]=多媒体
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=rdrawing_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lrdrawing -lraylib -lGL -lm -lpthread -ldl -lrt -lX11
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <rdrawing.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
void paintstar(Image* pImage, double x, double y, double r, double a)
|
||||||
|
{
|
||||||
|
int vx[5];
|
||||||
|
int vy[5];
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
vx[i] = (int)( -cos( PI * 4 / 5 * i + a ) * r + x );
|
||||||
|
vy[i] = (int)( sin( PI * 4 / 5 * i + a) * r + y );
|
||||||
|
}
|
||||||
|
ImageFillPolygonEx(pImage,vx,vy,5,LIGHTRED);
|
||||||
|
ImageDrawPolygonEx(pImage,vx,vy,5,2,DARKBROWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
InitWindow(640,480,"rdrawing");
|
||||||
|
SetTraceLogLevel(LOG_WARNING);
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
|
Image img=GenImageColor(640,480,BLANK);
|
||||||
|
|
||||||
|
double r = 0;
|
||||||
|
while(!WindowShouldClose()) {
|
||||||
|
//update datas
|
||||||
|
r += 0.02;
|
||||||
|
if (r > PI * 2) r -= PI * 2;
|
||||||
|
|
||||||
|
//update image (in CPU)
|
||||||
|
ImageClearBackground(&img,BLANK);
|
||||||
|
paintstar(&img,320,240,200,r);
|
||||||
|
|
||||||
|
//Drawing in GPU
|
||||||
|
Texture texture = LoadTextureFromImage(img);
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
DrawTexture(texture,0,0,WHITE);
|
||||||
|
EndDrawing();
|
||||||
|
UnloadTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clean up
|
||||||
|
UnloadImage(img);
|
||||||
|
CloseWindow();
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=Doraemon
|
||||||
|
Name[zh_CN]=哆啦A梦
|
||||||
|
Icon=rdrawing-doraemon.ico
|
||||||
|
Description=A simple doraemon app using rdrawing (https://github.com/royqh1979/raylib-drawing)
|
||||||
|
Description[zh_CN]=使用rdrawing制作的哆啦A梦 (https://github.com/royqh1979/raylib-drawing)
|
||||||
|
Category=Game
|
||||||
|
Category[zh_CN]=游戏
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=rdrawing_doraemon_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lrdrawing -lraylib -lGL -lm -lpthread -ldl -lrt -lX11
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <rdrawing.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define SHRINK_FRAMES 2
|
||||||
|
|
||||||
|
Image genBodyImage();
|
||||||
|
Image genShrinkImage0();
|
||||||
|
Image genShrinkImage1();
|
||||||
|
Image genShrinkImage2();
|
||||||
|
Image genShrinkImage3();
|
||||||
|
Image genShrinkImage4();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
InitWindow(800,600,"Doraemon");
|
||||||
|
SetTraceLogLevel(LOG_WARNING);
|
||||||
|
SetTargetFPS(30);
|
||||||
|
|
||||||
|
SetRandomSeed(time(NULL));
|
||||||
|
|
||||||
|
Image img=genBodyImage();
|
||||||
|
Image shrinkImages[9];
|
||||||
|
shrinkImages[0]=genShrinkImage0();
|
||||||
|
shrinkImages[1]=genShrinkImage1();
|
||||||
|
shrinkImages[2]=genShrinkImage2();
|
||||||
|
shrinkImages[3]=genShrinkImage3();
|
||||||
|
shrinkImages[4]=genShrinkImage4();
|
||||||
|
shrinkImages[5]=genShrinkImage3();
|
||||||
|
shrinkImages[6]=genShrinkImage2();
|
||||||
|
shrinkImages[7]=genShrinkImage1();
|
||||||
|
shrinkImages[8]=genShrinkImage0();
|
||||||
|
|
||||||
|
Texture texture = LoadTextureFromImage(img);
|
||||||
|
Texture shrinkTexture;
|
||||||
|
int stage = -1;
|
||||||
|
int repeats = 0;
|
||||||
|
|
||||||
|
while(!WindowShouldClose()) {
|
||||||
|
if (stage==-1) {
|
||||||
|
int r = GetRandomValue(1,30);
|
||||||
|
if (r==1) {
|
||||||
|
stage=0;
|
||||||
|
repeats=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int idx=0;
|
||||||
|
if (stage>=0) {
|
||||||
|
idx=stage / SHRINK_FRAMES;
|
||||||
|
if (idx<9) {
|
||||||
|
shrinkTexture=LoadTextureFromImage(shrinkImages[idx]);
|
||||||
|
} else {
|
||||||
|
idx=0;
|
||||||
|
stage=0;
|
||||||
|
repeats++;
|
||||||
|
if (repeats>=3)
|
||||||
|
stage=-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stage>=0) {
|
||||||
|
stage++;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
DrawTexture(texture,0,0,WHITE);
|
||||||
|
DrawTexture(shrinkTexture,0,0,WHITE);
|
||||||
|
EndDrawing();
|
||||||
|
UnloadTexture(shrinkTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clean up
|
||||||
|
UnloadTexture(texture);
|
||||||
|
UnloadImage(img);
|
||||||
|
for (int i=0;i<9;i++) {
|
||||||
|
UnloadImage(shrinkImages[i]);
|
||||||
|
}
|
||||||
|
CloseWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genBodyImage(){
|
||||||
|
Image img=GenImageColor(800,600,WHITE);
|
||||||
|
// 画头
|
||||||
|
Color fillColor = (Color){7,190,234,255};
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,265, 94, 270, 260, 124, 124,fillColor);
|
||||||
|
ImageDrawRoundRectEx(&img,265, 94, 270, 260, 124, 124,1,color);
|
||||||
|
|
||||||
|
fillColor = WHITE; // 脸
|
||||||
|
ImageFillEllipseEx(&img, 400, 256, 115, 95, fillColor);
|
||||||
|
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
|
||||||
|
fillColor = BLACK;
|
||||||
|
ImageFillCircleEx(&img,384,184,6, fillColor); // 右眼球
|
||||||
|
ImageFillCircleEx(&img,416,184,6, fillColor); // 左眼球
|
||||||
|
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,400,223,400,296,1,color); // 人中
|
||||||
|
ImageDrawArcEx(&img,400, 192, 108, 108, PI * 5 / 4, PI * 7 / 4,1,color); // 嘴
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,358, 227, 310, 209,1,color); // 胡子
|
||||||
|
ImageDrawLineEx(&img,442, 227, 490, 209,1,color);
|
||||||
|
ImageDrawLineEx(&img,359, 235, 308, 235,1,color);
|
||||||
|
ImageDrawLineEx(&img,441, 235, 492, 235,1,color);
|
||||||
|
ImageDrawLineEx(&img,358, 243, 310, 261,1,color);
|
||||||
|
ImageDrawLineEx(&img,442, 243, 490, 261,1,color);
|
||||||
|
|
||||||
|
// 画身体
|
||||||
|
ImageDrawLineEx(&img, 319, 332, 262, 372,1,color); // 手臂(上)
|
||||||
|
ImageDrawLineEx(&img, 481, 332, 538, 372,1,color);
|
||||||
|
ImageDrawLineEx(&img, 304, 396, 284, 410,1,color); // 手臂(下)
|
||||||
|
ImageDrawLineEx(&img, 496, 396, 516, 410,1,color);
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img, 304, 385, 304, 478,1,color); // 腿外侧
|
||||||
|
ImageDrawLineEx(&img, 496, 385, 496, 478,1,color);
|
||||||
|
ImageDrawArcEx(&img, 400, 479, 15,11,0,PI,1,color); // 腿内侧
|
||||||
|
|
||||||
|
fillColor=WHITE; // 手
|
||||||
|
ImageFillCircleEx(&img, 260,399,27, fillColor);
|
||||||
|
ImageDrawCircleEx(&img, 260,399,27, 1, color);
|
||||||
|
ImageFillCircleEx(&img, 540,399,27, fillColor);
|
||||||
|
ImageDrawCircleEx(&img, 540,399,27, 1, color);
|
||||||
|
ImageFillRoundRectEx(&img,288,478,110,27,12,12,fillColor); // 脚
|
||||||
|
ImageDrawRoundRectEx(&img,288,478,110,27,12,12,1,color);
|
||||||
|
ImageFillRoundRectEx(&img,402,478,110,27,12,12,fillColor);
|
||||||
|
ImageDrawRoundRectEx(&img,402,478,110,27,12,12,1,color);
|
||||||
|
|
||||||
|
fillColor=(Color){7,190,234,255}; // 身体填充蓝色
|
||||||
|
ImageFloodFill(&img,400,400,BLACK,fillColor);
|
||||||
|
|
||||||
|
fillColor=WHITE; // 肚皮
|
||||||
|
ImageFillCircleEx(&img,400,381,75,fillColor);
|
||||||
|
ImageFillRectangleEx(&img,340,304,120,20,fillColor); // 用白色矩形擦掉多余的肚皮
|
||||||
|
|
||||||
|
ImageDrawSectorEx(&img,400,381,58, 58,PI,2*PI,1,color); // 口袋
|
||||||
|
|
||||||
|
// 画铃铛
|
||||||
|
fillColor=(Color){169, 38, 0,255}; // 绳子
|
||||||
|
ImageFillRoundRectEx(&img,300,323,200,19,12,12,fillColor);
|
||||||
|
|
||||||
|
fillColor=(Color){245, 237, 38,255}; // 铃铛外形
|
||||||
|
ImageFillCircleEx(&img,400,349,19,fillColor);
|
||||||
|
|
||||||
|
fillColor=BLACK; // 铃铛上的洞
|
||||||
|
ImageFillEllipseEx(&img,400,354,4,4,fillColor);
|
||||||
|
ImageDrawLineEx(&img,400,357,400,368,3,color);
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,384,340,416,340,1,color); // 铃铛上的纹路
|
||||||
|
ImageDrawLineEx(&img,384,344,418,344,1,color);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage0() {
|
||||||
|
Image img = GenImageColor(800,600, BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
|
||||||
|
fillColor = BLACK;
|
||||||
|
ImageFillCircleEx(&img,384,184,6, fillColor); // 右眼球
|
||||||
|
ImageFillCircleEx(&img,416,184,6, fillColor); // 左眼球
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage1() {
|
||||||
|
Image img = GenImageColor(800,600, BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
|
||||||
|
ImageFillRectangleEx(&img,337,168,63,19,fillColor);
|
||||||
|
ImageFillRectangleEx(&img,400,168,63,19,fillColor);
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
|
||||||
|
fillColor = BLACK;
|
||||||
|
ImageFillCircleEx(&img,384,184,6, fillColor); // 右眼球
|
||||||
|
ImageFillCircleEx(&img,416,184,6, fillColor); // 左眼球
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage2() {
|
||||||
|
Image img=GenImageColor(800,600,BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,337,168,399,168,1,color);
|
||||||
|
ImageDrawLineEx(&img,400,168,462,168,1,color);
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage3(){
|
||||||
|
Image img=GenImageColor(800,600,BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
|
||||||
|
ImageFillRectangleEx(&img,337,150,63,19,fillColor);
|
||||||
|
ImageFillRectangleEx(&img,400,150,63,19,fillColor);
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage4() {
|
||||||
|
Image img=GenImageColor(800,600,BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
|
@ -1,3 +1,9 @@
|
||||||
|
redpanda-cpp (1.1.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Update to 1.1.0
|
||||||
|
|
||||||
|
-- Roy Qu (瞿华) <royqh1979@gmail.com> Sun, 13 Jun 2022 19:19:00 +0800
|
||||||
|
|
||||||
redpanda-cpp (1.0.10-1) unstable; urgency=medium
|
redpanda-cpp (1.0.10-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Update to 1.0.10
|
* Update to 1.0.10
|
||||||
|
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 66 KiB |
|
@ -2,9 +2,9 @@
|
||||||
ver=2
|
ver=2
|
||||||
Name=raylib
|
Name=raylib
|
||||||
Name[zh_CN]=raylib
|
Name[zh_CN]=raylib
|
||||||
Icon=raylib.ico
|
Icon=raylib-game.ico
|
||||||
Description=A simple program using raylib ( https://raylib.com )
|
Description=A simple interactive animation using raylib ( https://raylib.com )
|
||||||
Description[zh_CN]=简单的raylib绘图程序 ( https://raylib.com )
|
Description[zh_CN]=简单的raylib交互动画 ( https://raylib.com )
|
||||||
Category=Multimedia
|
Category=Multimedia
|
||||||
Category[zh_CN]=多媒体
|
Category[zh_CN]=多媒体
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=snake
|
||||||
|
Name[zh_CN]=吞食蛇
|
||||||
|
Icon=raylib-snake.ico
|
||||||
|
Description=snake game using raylib ( https://raylib.com )
|
||||||
|
Description[zh_CN]=经典的吞食蛇游戏(基于raylib) ( https://raylib.com )
|
||||||
|
Category=Game
|
||||||
|
Category[zh_CN]=游戏
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=raylib_snake_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lraylib -lopengl32 -lgdi32 -lwinmm
|
||||||
|
|
|
@ -0,0 +1,286 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib - classic game: snake
|
||||||
|
*
|
||||||
|
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
|
||||||
|
*
|
||||||
|
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||||
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Some Defines
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define SNAKE_LENGTH 256
|
||||||
|
#define SQUARE_SIZE 31
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef struct Snake {
|
||||||
|
Vector2 position;
|
||||||
|
Vector2 size;
|
||||||
|
Vector2 speed;
|
||||||
|
Color color;
|
||||||
|
} Snake;
|
||||||
|
|
||||||
|
typedef struct Food {
|
||||||
|
Vector2 position;
|
||||||
|
Vector2 size;
|
||||||
|
bool active;
|
||||||
|
Color color;
|
||||||
|
} Food;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Global Variables Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static const int screenWidth = 800;
|
||||||
|
static const int screenHeight = 450;
|
||||||
|
|
||||||
|
static int framesCounter = 0;
|
||||||
|
static bool gameOver = false;
|
||||||
|
static bool pause = false;
|
||||||
|
|
||||||
|
static Food fruit = { 0 };
|
||||||
|
static Snake snake[SNAKE_LENGTH] = { 0 };
|
||||||
|
static Vector2 snakePosition[SNAKE_LENGTH] = { 0 };
|
||||||
|
static bool allowMove = false;
|
||||||
|
static Vector2 offset = { 0 };
|
||||||
|
static int counterTail = 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: snake");
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
framesCounter = 0;
|
||||||
|
gameOver = false;
|
||||||
|
pause = false;
|
||||||
|
|
||||||
|
counterTail = 1;
|
||||||
|
allowMove = false;
|
||||||
|
|
||||||
|
offset.x = screenWidth%SQUARE_SIZE;
|
||||||
|
offset.y = screenHeight%SQUARE_SIZE;
|
||||||
|
|
||||||
|
for (int i = 0; i < SNAKE_LENGTH; i++)
|
||||||
|
{
|
||||||
|
snake[i].position = (Vector2){ offset.x/2, offset.y/2 };
|
||||||
|
snake[i].size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE };
|
||||||
|
snake[i].speed = (Vector2){ SQUARE_SIZE, 0 };
|
||||||
|
|
||||||
|
if (i == 0) snake[i].color = DARKBLUE;
|
||||||
|
else snake[i].color = BLUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < SNAKE_LENGTH; i++)
|
||||||
|
{
|
||||||
|
snakePosition[i] = (Vector2){ 0.0f, 0.0f };
|
||||||
|
}
|
||||||
|
|
||||||
|
fruit.size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE };
|
||||||
|
fruit.color = SKYBLUE;
|
||||||
|
fruit.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update game (one frame)
|
||||||
|
void UpdateGame(void)
|
||||||
|
{
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
if (IsKeyPressed('P')) pause = !pause;
|
||||||
|
|
||||||
|
if (!pause)
|
||||||
|
{
|
||||||
|
// Player control
|
||||||
|
if (IsKeyPressed(KEY_RIGHT) && (snake[0].speed.x == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ SQUARE_SIZE, 0 };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
if (IsKeyPressed(KEY_LEFT) && (snake[0].speed.x == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ -SQUARE_SIZE, 0 };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
if (IsKeyPressed(KEY_UP) && (snake[0].speed.y == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ 0, -SQUARE_SIZE };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
if (IsKeyPressed(KEY_DOWN) && (snake[0].speed.y == 0) && allowMove)
|
||||||
|
{
|
||||||
|
snake[0].speed = (Vector2){ 0, SQUARE_SIZE };
|
||||||
|
allowMove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snake movement
|
||||||
|
for (int i = 0; i < counterTail; i++) snakePosition[i] = snake[i].position;
|
||||||
|
|
||||||
|
if ((framesCounter%5) == 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < counterTail; i++)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
snake[0].position.x += snake[0].speed.x;
|
||||||
|
snake[0].position.y += snake[0].speed.y;
|
||||||
|
allowMove = true;
|
||||||
|
}
|
||||||
|
else snake[i].position = snakePosition[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wall behaviour
|
||||||
|
if (((snake[0].position.x) > (screenWidth - offset.x)) ||
|
||||||
|
((snake[0].position.y) > (screenHeight - offset.y)) ||
|
||||||
|
(snake[0].position.x < 0) || (snake[0].position.y < 0))
|
||||||
|
{
|
||||||
|
gameOver = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collision with yourself
|
||||||
|
for (int i = 1; i < counterTail; i++)
|
||||||
|
{
|
||||||
|
if ((snake[0].position.x == snake[i].position.x) && (snake[0].position.y == snake[i].position.y)) gameOver = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fruit position calculation
|
||||||
|
if (!fruit.active)
|
||||||
|
{
|
||||||
|
fruit.active = true;
|
||||||
|
fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
|
||||||
|
|
||||||
|
for (int i = 0; i < counterTail; i++)
|
||||||
|
{
|
||||||
|
while ((fruit.position.x == snake[i].position.x) && (fruit.position.y == snake[i].position.y))
|
||||||
|
{
|
||||||
|
fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collision
|
||||||
|
if ((snake[0].position.x < (fruit.position.x + fruit.size.x) && (snake[0].position.x + snake[0].size.x) > fruit.position.x) &&
|
||||||
|
(snake[0].position.y < (fruit.position.y + fruit.size.y) && (snake[0].position.y + snake[0].size.y) > fruit.position.y))
|
||||||
|
{
|
||||||
|
snake[counterTail].position = snakePosition[counterTail - 1];
|
||||||
|
counterTail += 1;
|
||||||
|
fruit.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
framesCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IsKeyPressed(KEY_ENTER))
|
||||||
|
{
|
||||||
|
InitGame();
|
||||||
|
gameOver = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw game (one frame)
|
||||||
|
void DrawGame(void)
|
||||||
|
{
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
// Draw grid lines
|
||||||
|
for (int i = 0; i < screenWidth/SQUARE_SIZE + 1; i++)
|
||||||
|
{
|
||||||
|
DrawLineV((Vector2){SQUARE_SIZE*i + offset.x/2, offset.y/2}, (Vector2){SQUARE_SIZE*i + offset.x/2, screenHeight - offset.y/2}, LIGHTGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < screenHeight/SQUARE_SIZE + 1; i++)
|
||||||
|
{
|
||||||
|
DrawLineV((Vector2){offset.x/2, SQUARE_SIZE*i + offset.y/2}, (Vector2){screenWidth - offset.x/2, SQUARE_SIZE*i + offset.y/2}, LIGHTGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw snake
|
||||||
|
for (int i = 0; i < counterTail; i++) DrawRectangleV(snake[i].position, snake[i].size, snake[i].color);
|
||||||
|
|
||||||
|
// Draw fruit to pick
|
||||||
|
DrawRectangleV(fruit.position, fruit.size, fruit.color);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=Tetris
|
||||||
|
Name[zh_CN]=俄罗斯方块
|
||||||
|
Icon=raylib-tetris.ico
|
||||||
|
Description=Tetris game using raylib ( https://raylib.com )
|
||||||
|
Description[zh_CN]=经典的俄罗斯方块游戏(基于raylib) ( https://raylib.com )
|
||||||
|
Category=Game
|
||||||
|
Category[zh_CN]=游戏
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=raylib_tetris_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lraylib -lopengl32 -lgdi32 -lwinmm
|
||||||
|
|
|
@ -0,0 +1,791 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib - classic game: tetris
|
||||||
|
*
|
||||||
|
* Sample game developed by Marc Palau and Ramon Santamaria
|
||||||
|
*
|
||||||
|
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||||
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Some Defines
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define SQUARE_SIZE 20
|
||||||
|
|
||||||
|
#define GRID_HORIZONTAL_SIZE 12
|
||||||
|
#define GRID_VERTICAL_SIZE 20
|
||||||
|
|
||||||
|
#define LATERAL_SPEED 10
|
||||||
|
#define TURNING_SPEED 12
|
||||||
|
#define FAST_FALL_AWAIT_COUNTER 30
|
||||||
|
|
||||||
|
#define FADING_TIME 33
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef enum GridSquare { EMPTY, MOVING, FULL, BLOCK, FADING } GridSquare;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Global Variables Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static const int screenWidth = 800;
|
||||||
|
static const int screenHeight = 450;
|
||||||
|
|
||||||
|
static bool gameOver = false;
|
||||||
|
static bool pause = false;
|
||||||
|
|
||||||
|
// Matrices
|
||||||
|
static GridSquare grid [GRID_HORIZONTAL_SIZE][GRID_VERTICAL_SIZE];
|
||||||
|
static GridSquare piece [4][4];
|
||||||
|
static GridSquare incomingPiece [4][4];
|
||||||
|
|
||||||
|
// Theese variables keep track of the active piece position
|
||||||
|
static int piecePositionX = 0;
|
||||||
|
static int piecePositionY = 0;
|
||||||
|
|
||||||
|
// Game parameters
|
||||||
|
static Color fadingColor;
|
||||||
|
//static int fallingSpeed; // In frames
|
||||||
|
|
||||||
|
static bool beginPlay = true; // This var is only true at the begining of the game, used for the first matrix creations
|
||||||
|
static bool pieceActive = false;
|
||||||
|
static bool detection = false;
|
||||||
|
static bool lineToDelete = false;
|
||||||
|
|
||||||
|
// Statistics
|
||||||
|
static int level = 1;
|
||||||
|
static int lines = 0;
|
||||||
|
|
||||||
|
// Counters
|
||||||
|
static int gravityMovementCounter = 0;
|
||||||
|
static int lateralMovementCounter = 0;
|
||||||
|
static int turnMovementCounter = 0;
|
||||||
|
static int fastFallMovementCounter = 0;
|
||||||
|
|
||||||
|
static int fadeLineCounter = 0;
|
||||||
|
|
||||||
|
// Based on level
|
||||||
|
static int gravitySpeed = 30;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// Additional module functions
|
||||||
|
static bool Createpiece();
|
||||||
|
static void GetRandompiece();
|
||||||
|
static void ResolveFallingMovement(bool *detection, bool *pieceActive);
|
||||||
|
static bool ResolveLateralMovement();
|
||||||
|
static bool ResolveTurnMovement();
|
||||||
|
static void CheckDetection(bool *detection);
|
||||||
|
static void CheckCompletion(bool *lineToDelete);
|
||||||
|
static void DeleteCompleteLines();
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization (Note windowTitle is unused on Android)
|
||||||
|
//---------------------------------------------------------
|
||||||
|
InitWindow(screenWidth, screenHeight, "classic game: tetris");
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Game Module Functions Definition
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Initialize game variables
|
||||||
|
void InitGame(void)
|
||||||
|
{
|
||||||
|
// Initialize game statistics
|
||||||
|
level = 1;
|
||||||
|
lines = 0;
|
||||||
|
|
||||||
|
fadingColor = GRAY;
|
||||||
|
|
||||||
|
piecePositionX = 0;
|
||||||
|
piecePositionY = 0;
|
||||||
|
|
||||||
|
pause = false;
|
||||||
|
|
||||||
|
beginPlay = true;
|
||||||
|
pieceActive = false;
|
||||||
|
detection = false;
|
||||||
|
lineToDelete = false;
|
||||||
|
|
||||||
|
// Counters
|
||||||
|
gravityMovementCounter = 0;
|
||||||
|
lateralMovementCounter = 0;
|
||||||
|
turnMovementCounter = 0;
|
||||||
|
fastFallMovementCounter = 0;
|
||||||
|
|
||||||
|
fadeLineCounter = 0;
|
||||||
|
gravitySpeed = 30;
|
||||||
|
|
||||||
|
// Initialize grid matrices
|
||||||
|
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
|
||||||
|
{
|
||||||
|
if ((j == GRID_VERTICAL_SIZE - 1) || (i == 0) || (i == GRID_HORIZONTAL_SIZE - 1)) grid[i][j] = BLOCK;
|
||||||
|
else grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize incoming piece matrices
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j< 4; j++)
|
||||||
|
{
|
||||||
|
incomingPiece[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update game (one frame)
|
||||||
|
void UpdateGame(void)
|
||||||
|
{
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
if (IsKeyPressed('P')) pause = !pause;
|
||||||
|
|
||||||
|
if (!pause)
|
||||||
|
{
|
||||||
|
if (!lineToDelete)
|
||||||
|
{
|
||||||
|
if (!pieceActive)
|
||||||
|
{
|
||||||
|
// Get another piece
|
||||||
|
pieceActive = Createpiece();
|
||||||
|
|
||||||
|
// We leave a little time before starting the fast falling down
|
||||||
|
fastFallMovementCounter = 0;
|
||||||
|
}
|
||||||
|
else // Piece falling
|
||||||
|
{
|
||||||
|
// Counters update
|
||||||
|
fastFallMovementCounter++;
|
||||||
|
gravityMovementCounter++;
|
||||||
|
lateralMovementCounter++;
|
||||||
|
turnMovementCounter++;
|
||||||
|
|
||||||
|
// We make sure to move if we've pressed the key this frame
|
||||||
|
if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_RIGHT)) lateralMovementCounter = LATERAL_SPEED;
|
||||||
|
if (IsKeyPressed(KEY_UP)) turnMovementCounter = TURNING_SPEED;
|
||||||
|
|
||||||
|
// Fall down
|
||||||
|
if (IsKeyDown(KEY_DOWN) && (fastFallMovementCounter >= FAST_FALL_AWAIT_COUNTER))
|
||||||
|
{
|
||||||
|
// We make sure the piece is going to fall this frame
|
||||||
|
gravityMovementCounter += gravitySpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gravityMovementCounter >= gravitySpeed)
|
||||||
|
{
|
||||||
|
// Basic falling movement
|
||||||
|
CheckDetection(&detection);
|
||||||
|
|
||||||
|
// Check if the piece has collided with another piece or with the boundings
|
||||||
|
ResolveFallingMovement(&detection, &pieceActive);
|
||||||
|
|
||||||
|
// Check if we fullfilled a line and if so, erase the line and pull down the the lines above
|
||||||
|
CheckCompletion(&lineToDelete);
|
||||||
|
|
||||||
|
gravityMovementCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move laterally at player's will
|
||||||
|
if (lateralMovementCounter >= LATERAL_SPEED)
|
||||||
|
{
|
||||||
|
// Update the lateral movement and if success, reset the lateral counter
|
||||||
|
if (!ResolveLateralMovement()) lateralMovementCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn the piece at player's will
|
||||||
|
if (turnMovementCounter >= TURNING_SPEED)
|
||||||
|
{
|
||||||
|
// Update the turning movement and reset the turning counter
|
||||||
|
if (ResolveTurnMovement()) turnMovementCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game over logic
|
||||||
|
for (int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == FULL)
|
||||||
|
{
|
||||||
|
gameOver = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Animation when deleting lines
|
||||||
|
fadeLineCounter++;
|
||||||
|
|
||||||
|
if (fadeLineCounter%8 < 4) fadingColor = MAROON;
|
||||||
|
else fadingColor = GRAY;
|
||||||
|
|
||||||
|
if (fadeLineCounter >= FADING_TIME)
|
||||||
|
{
|
||||||
|
DeleteCompleteLines();
|
||||||
|
fadeLineCounter = 0;
|
||||||
|
lineToDelete = false;
|
||||||
|
|
||||||
|
lines++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IsKeyPressed(KEY_ENTER))
|
||||||
|
{
|
||||||
|
InitGame();
|
||||||
|
gameOver = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw game (one frame)
|
||||||
|
void DrawGame(void)
|
||||||
|
{
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
if (!gameOver)
|
||||||
|
{
|
||||||
|
// Draw gameplay area
|
||||||
|
Vector2 offset;
|
||||||
|
offset.x = screenWidth/2 - (GRID_HORIZONTAL_SIZE*SQUARE_SIZE/2) - 50;
|
||||||
|
offset.y = screenHeight/2 - ((GRID_VERTICAL_SIZE - 1)*SQUARE_SIZE/2) + SQUARE_SIZE*2;
|
||||||
|
|
||||||
|
offset.y -= 50; // NOTE: Harcoded position!
|
||||||
|
|
||||||
|
int controller = offset.x;
|
||||||
|
|
||||||
|
for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
|
||||||
|
{
|
||||||
|
// Draw each square of the grid
|
||||||
|
if (grid[i][j] == EMPTY)
|
||||||
|
{
|
||||||
|
DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == FULL)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, DARKGRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == BLOCK)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, LIGHTGRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (grid[i][j] == FADING)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, fadingColor);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset.x = controller;
|
||||||
|
offset.y += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw incoming piece (hardcoded)
|
||||||
|
offset.x = 500;
|
||||||
|
offset.y = 45;
|
||||||
|
|
||||||
|
int controler = offset.x;
|
||||||
|
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (incomingPiece[i][j] == EMPTY)
|
||||||
|
{
|
||||||
|
DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
else if (incomingPiece[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
|
||||||
|
offset.x += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset.x = controler;
|
||||||
|
offset.y += SQUARE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawText("INCOMING:", offset.x, offset.y - 100, 10, GRAY);
|
||||||
|
DrawText(TextFormat("LINES: %04i", lines), offset.x, offset.y + 20, 10, GRAY);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Additional module functions
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
static bool Createpiece()
|
||||||
|
{
|
||||||
|
piecePositionX = (int)((GRID_HORIZONTAL_SIZE - 4)/2);
|
||||||
|
piecePositionY = 0;
|
||||||
|
|
||||||
|
// If the game is starting and you are going to create the first piece, we create an extra one
|
||||||
|
if (beginPlay)
|
||||||
|
{
|
||||||
|
GetRandompiece();
|
||||||
|
beginPlay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assign the incoming piece to the actual piece
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j< 4; j++)
|
||||||
|
{
|
||||||
|
piece[i][j] = incomingPiece[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assign a random piece to the incoming one
|
||||||
|
GetRandompiece();
|
||||||
|
|
||||||
|
// Assign the piece to the grid
|
||||||
|
for (int i = piecePositionX; i < piecePositionX + 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
if (piece[i - (int)piecePositionX][j] == MOVING) grid[i][j] = MOVING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetRandompiece()
|
||||||
|
{
|
||||||
|
int random = GetRandomValue(0, 6);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
incomingPiece[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (random)
|
||||||
|
{
|
||||||
|
case 0: { incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; } break; //Cube
|
||||||
|
case 1: { incomingPiece[1][0] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; } break; //L
|
||||||
|
case 2: { incomingPiece[1][2] = MOVING; incomingPiece[2][0] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[2][2] = MOVING; } break; //L inversa
|
||||||
|
case 3: { incomingPiece[0][1] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[3][1] = MOVING; } break; //Recta
|
||||||
|
case 4: { incomingPiece[1][0] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][1] = MOVING; } break; //Creu tallada
|
||||||
|
case 5: { incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[2][2] = MOVING; incomingPiece[3][2] = MOVING; } break; //S
|
||||||
|
case 6: { incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[3][1] = MOVING; } break; //S inversa
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResolveFallingMovement(bool *detection, bool *pieceActive)
|
||||||
|
{
|
||||||
|
// If we finished moving this piece, we stop it
|
||||||
|
if (*detection)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j] = FULL;
|
||||||
|
*detection = false;
|
||||||
|
*pieceActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // We move down the piece
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j+1] = MOVING;
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
piecePositionY++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ResolveLateralMovement()
|
||||||
|
{
|
||||||
|
bool collision = false;
|
||||||
|
|
||||||
|
// Piece movement
|
||||||
|
if (IsKeyDown(KEY_LEFT)) // Move left
|
||||||
|
{
|
||||||
|
// Check if is possible to move to left
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
// Check if we are touching the left wall or we have a full square at the left
|
||||||
|
if ((i-1 == 0) || (grid[i-1][j] == FULL)) collision = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If able, move left
|
||||||
|
if (!collision)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) // We check the matrix from left to right
|
||||||
|
{
|
||||||
|
// Move everything to the left
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i-1][j] = MOVING;
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
piecePositionX--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsKeyDown(KEY_RIGHT)) // Move right
|
||||||
|
{
|
||||||
|
// Check if is possible to move to right
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
// Check if we are touching the right wall or we have a full square at the right
|
||||||
|
if ((i+1 == GRID_HORIZONTAL_SIZE - 1) || (grid[i+1][j] == FULL))
|
||||||
|
{
|
||||||
|
collision = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If able move right
|
||||||
|
if (!collision)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = GRID_HORIZONTAL_SIZE - 1; i >= 1; i--) // We check the matrix from right to left
|
||||||
|
{
|
||||||
|
// Move everything to the right
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i+1][j] = MOVING;
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
piecePositionX++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ResolveTurnMovement()
|
||||||
|
{
|
||||||
|
// Input for turning the piece
|
||||||
|
if (IsKeyDown(KEY_UP))
|
||||||
|
{
|
||||||
|
GridSquare aux;
|
||||||
|
bool checker = false;
|
||||||
|
|
||||||
|
// Check all turning possibilities
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY] == MOVING) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 3][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY + 3] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 3][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 3] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 3] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY + 1] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 1][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 2][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 1] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 1] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if ((grid[piecePositionX + 1][piecePositionY + 2] == MOVING) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 2] != EMPTY) &&
|
||||||
|
(grid[piecePositionX + 2][piecePositionY + 2] != MOVING)) checker = true;
|
||||||
|
|
||||||
|
if (!checker)
|
||||||
|
{
|
||||||
|
aux = piece[0][0];
|
||||||
|
piece[0][0] = piece[3][0];
|
||||||
|
piece[3][0] = piece[3][3];
|
||||||
|
piece[3][3] = piece[0][3];
|
||||||
|
piece[0][3] = aux;
|
||||||
|
|
||||||
|
aux = piece[1][0];
|
||||||
|
piece[1][0] = piece[3][1];
|
||||||
|
piece[3][1] = piece[2][3];
|
||||||
|
piece[2][3] = piece[0][2];
|
||||||
|
piece[0][2] = aux;
|
||||||
|
|
||||||
|
aux = piece[2][0];
|
||||||
|
piece[2][0] = piece[3][2];
|
||||||
|
piece[3][2] = piece[1][3];
|
||||||
|
piece[1][3] = piece[0][1];
|
||||||
|
piece[0][1] = aux;
|
||||||
|
|
||||||
|
aux = piece[1][1];
|
||||||
|
piece[1][1] = piece[2][1];
|
||||||
|
piece[2][1] = piece[2][2];
|
||||||
|
piece[2][2] = piece[1][2];
|
||||||
|
piece[1][2] = aux;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if (grid[i][j] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = piecePositionX; i < piecePositionX + 4; i++)
|
||||||
|
{
|
||||||
|
for (int j = piecePositionY; j < piecePositionY + 4; j++)
|
||||||
|
{
|
||||||
|
if (piece[i - piecePositionX][j - piecePositionY] == MOVING)
|
||||||
|
{
|
||||||
|
grid[i][j] = MOVING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckDetection(bool *detection)
|
||||||
|
{
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
if ((grid[i][j] == MOVING) && ((grid[i][j+1] == FULL) || (grid[i][j+1] == BLOCK))) *detection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckCompletion(bool *lineToDelete)
|
||||||
|
{
|
||||||
|
int calculator = 0;
|
||||||
|
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
calculator = 0;
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
// Count each square of the line
|
||||||
|
if (grid[i][j] == FULL)
|
||||||
|
{
|
||||||
|
calculator++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we completed the whole line
|
||||||
|
if (calculator == GRID_HORIZONTAL_SIZE - 2)
|
||||||
|
{
|
||||||
|
*lineToDelete = true;
|
||||||
|
calculator = 0;
|
||||||
|
// points++;
|
||||||
|
|
||||||
|
// Mark the completed line
|
||||||
|
for (int z = 1; z < GRID_HORIZONTAL_SIZE - 1; z++)
|
||||||
|
{
|
||||||
|
grid[z][j] = FADING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeleteCompleteLines()
|
||||||
|
{
|
||||||
|
// Erase the completed line
|
||||||
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
while (grid[1][j] == FADING)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
|
||||||
|
{
|
||||||
|
grid[i][j] = EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j2 = j-1; j2 >= 0; j2--)
|
||||||
|
{
|
||||||
|
for (int i2 = 1; i2 < GRID_HORIZONTAL_SIZE - 1; i2++)
|
||||||
|
{
|
||||||
|
if (grid[i2][j2] == FULL)
|
||||||
|
{
|
||||||
|
grid[i2][j2+1] = FULL;
|
||||||
|
grid[i2][j2] = EMPTY;
|
||||||
|
}
|
||||||
|
else if (grid[i2][j2] == FADING)
|
||||||
|
{
|
||||||
|
grid[i2][j2+1] = FADING;
|
||||||
|
grid[i2][j2] = EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 66 KiB |
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=rdrawing
|
||||||
|
Name[zh_CN]=rdrawing
|
||||||
|
Icon=rdrawing.ico
|
||||||
|
Description=A simple 2d drawing app using raylib and rdrawing
|
||||||
|
Description[zh_CN]=基于raylib和rdrawing的2维绘图程序 (https://github.com/royqh1979/raylib-drawing)
|
||||||
|
Category=Multimedia
|
||||||
|
Category[zh_CN]=多媒体
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=rdrawing_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lrdrawing -lraylib -lopengl32 -lgdi32 -lwinmm
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <rdrawing.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
void paintstar(Image* pImage, double x, double y, double r, double a)
|
||||||
|
{
|
||||||
|
int vx[5];
|
||||||
|
int vy[5];
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
vx[i] = (int)( -cos( PI * 4 / 5 * i + a ) * r + x );
|
||||||
|
vy[i] = (int)( sin( PI * 4 / 5 * i + a) * r + y );
|
||||||
|
}
|
||||||
|
ImageFillPolygonEx(pImage,vx,vy,5,LIGHTRED);
|
||||||
|
ImageDrawPolygonEx(pImage,vx,vy,5,2,DARKBROWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
InitWindow(640,480,"rdrawing");
|
||||||
|
SetTraceLogLevel(LOG_WARNING);
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
|
Image img=GenImageColor(640,480,BLANK);
|
||||||
|
|
||||||
|
double r = 0;
|
||||||
|
while(!WindowShouldClose()) {
|
||||||
|
//update datas
|
||||||
|
r += 0.02;
|
||||||
|
if (r > PI * 2) r -= PI * 2;
|
||||||
|
|
||||||
|
//update image (in CPU)
|
||||||
|
ImageClearBackground(&img,BLANK);
|
||||||
|
paintstar(&img,320,240,200,r);
|
||||||
|
|
||||||
|
//Drawing in GPU
|
||||||
|
Texture texture = LoadTextureFromImage(img);
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
DrawTexture(texture,0,0,WHITE);
|
||||||
|
EndDrawing();
|
||||||
|
UnloadTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clean up
|
||||||
|
UnloadImage(img);
|
||||||
|
CloseWindow();
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
[Template]
|
||||||
|
ver=2
|
||||||
|
Name=Doraemon
|
||||||
|
Name[zh_CN]=哆啦A梦
|
||||||
|
Icon=rdrawing-doraemon.ico
|
||||||
|
Description=A simple doraemon app using rdrawing (https://github.com/royqh1979/raylib-drawing)
|
||||||
|
Description[zh_CN]=使用rdrawing制作的哆啦A梦 (https://github.com/royqh1979/raylib-drawing)
|
||||||
|
Category=Game
|
||||||
|
Category[zh_CN]=游戏
|
||||||
|
|
||||||
|
[Unit0]
|
||||||
|
CName=main.c
|
||||||
|
C=rdrawing_doraemon_c.txt
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
UnitCount=1
|
||||||
|
Type=1
|
||||||
|
IsCpp=0
|
||||||
|
linker=-lrdrawing -lraylib -lopengl32 -lgdi32 -lwinmm
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <rdrawing.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define SHRINK_FRAMES 2
|
||||||
|
|
||||||
|
Image genBodyImage();
|
||||||
|
Image genShrinkImage0();
|
||||||
|
Image genShrinkImage1();
|
||||||
|
Image genShrinkImage2();
|
||||||
|
Image genShrinkImage3();
|
||||||
|
Image genShrinkImage4();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
InitWindow(800,600,"Doraemon");
|
||||||
|
SetTraceLogLevel(LOG_WARNING);
|
||||||
|
SetTargetFPS(30);
|
||||||
|
|
||||||
|
SetRandomSeed(time(NULL));
|
||||||
|
|
||||||
|
Image img=genBodyImage();
|
||||||
|
Image shrinkImages[9];
|
||||||
|
shrinkImages[0]=genShrinkImage0();
|
||||||
|
shrinkImages[1]=genShrinkImage1();
|
||||||
|
shrinkImages[2]=genShrinkImage2();
|
||||||
|
shrinkImages[3]=genShrinkImage3();
|
||||||
|
shrinkImages[4]=genShrinkImage4();
|
||||||
|
shrinkImages[5]=genShrinkImage3();
|
||||||
|
shrinkImages[6]=genShrinkImage2();
|
||||||
|
shrinkImages[7]=genShrinkImage1();
|
||||||
|
shrinkImages[8]=genShrinkImage0();
|
||||||
|
|
||||||
|
Texture texture = LoadTextureFromImage(img);
|
||||||
|
Texture shrinkTexture;
|
||||||
|
int stage = -1;
|
||||||
|
int repeats = 0;
|
||||||
|
|
||||||
|
while(!WindowShouldClose()) {
|
||||||
|
if (stage==-1) {
|
||||||
|
int r = GetRandomValue(1,30);
|
||||||
|
if (r==1) {
|
||||||
|
stage=0;
|
||||||
|
repeats=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int idx=0;
|
||||||
|
if (stage>=0) {
|
||||||
|
idx=stage / SHRINK_FRAMES;
|
||||||
|
if (idx<9) {
|
||||||
|
shrinkTexture=LoadTextureFromImage(shrinkImages[idx]);
|
||||||
|
} else {
|
||||||
|
idx=0;
|
||||||
|
stage=0;
|
||||||
|
repeats++;
|
||||||
|
if (repeats>=3)
|
||||||
|
stage=-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stage>=0) {
|
||||||
|
stage++;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
DrawTexture(texture,0,0,WHITE);
|
||||||
|
DrawTexture(shrinkTexture,0,0,WHITE);
|
||||||
|
EndDrawing();
|
||||||
|
UnloadTexture(shrinkTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clean up
|
||||||
|
UnloadTexture(texture);
|
||||||
|
UnloadImage(img);
|
||||||
|
for (int i=0;i<9;i++) {
|
||||||
|
UnloadImage(shrinkImages[i]);
|
||||||
|
}
|
||||||
|
CloseWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genBodyImage(){
|
||||||
|
Image img=GenImageColor(800,600,WHITE);
|
||||||
|
// 画头
|
||||||
|
Color fillColor = (Color){7,190,234,255};
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,265, 94, 270, 260, 124, 124,fillColor);
|
||||||
|
ImageDrawRoundRectEx(&img,265, 94, 270, 260, 124, 124,1,color);
|
||||||
|
|
||||||
|
fillColor = WHITE; // 脸
|
||||||
|
ImageFillEllipseEx(&img, 400, 256, 115, 95, fillColor);
|
||||||
|
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
|
||||||
|
fillColor = BLACK;
|
||||||
|
ImageFillCircleEx(&img,384,184,6, fillColor); // 右眼球
|
||||||
|
ImageFillCircleEx(&img,416,184,6, fillColor); // 左眼球
|
||||||
|
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,400,223,400,296,1,color); // 人中
|
||||||
|
ImageDrawArcEx(&img,400, 192, 108, 108, PI * 5 / 4, PI * 7 / 4,1,color); // 嘴
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,358, 227, 310, 209,1,color); // 胡子
|
||||||
|
ImageDrawLineEx(&img,442, 227, 490, 209,1,color);
|
||||||
|
ImageDrawLineEx(&img,359, 235, 308, 235,1,color);
|
||||||
|
ImageDrawLineEx(&img,441, 235, 492, 235,1,color);
|
||||||
|
ImageDrawLineEx(&img,358, 243, 310, 261,1,color);
|
||||||
|
ImageDrawLineEx(&img,442, 243, 490, 261,1,color);
|
||||||
|
|
||||||
|
// 画身体
|
||||||
|
ImageDrawLineEx(&img, 319, 332, 262, 372,1,color); // 手臂(上)
|
||||||
|
ImageDrawLineEx(&img, 481, 332, 538, 372,1,color);
|
||||||
|
ImageDrawLineEx(&img, 304, 396, 284, 410,1,color); // 手臂(下)
|
||||||
|
ImageDrawLineEx(&img, 496, 396, 516, 410,1,color);
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img, 304, 385, 304, 478,1,color); // 腿外侧
|
||||||
|
ImageDrawLineEx(&img, 496, 385, 496, 478,1,color);
|
||||||
|
ImageDrawArcEx(&img, 400, 479, 15,11,0,PI,1,color); // 腿内侧
|
||||||
|
|
||||||
|
fillColor=WHITE; // 手
|
||||||
|
ImageFillCircleEx(&img, 260,399,27, fillColor);
|
||||||
|
ImageDrawCircleEx(&img, 260,399,27, 1, color);
|
||||||
|
ImageFillCircleEx(&img, 540,399,27, fillColor);
|
||||||
|
ImageDrawCircleEx(&img, 540,399,27, 1, color);
|
||||||
|
ImageFillRoundRectEx(&img,288,478,110,27,12,12,fillColor); // 脚
|
||||||
|
ImageDrawRoundRectEx(&img,288,478,110,27,12,12,1,color);
|
||||||
|
ImageFillRoundRectEx(&img,402,478,110,27,12,12,fillColor);
|
||||||
|
ImageDrawRoundRectEx(&img,402,478,110,27,12,12,1,color);
|
||||||
|
|
||||||
|
fillColor=(Color){7,190,234,255}; // 身体填充蓝色
|
||||||
|
ImageFloodFill(&img,400,400,BLACK,fillColor);
|
||||||
|
|
||||||
|
fillColor=WHITE; // 肚皮
|
||||||
|
ImageFillCircleEx(&img,400,381,75,fillColor);
|
||||||
|
ImageFillRectangleEx(&img,340,304,120,20,fillColor); // 用白色矩形擦掉多余的肚皮
|
||||||
|
|
||||||
|
ImageDrawSectorEx(&img,400,381,58, 58,PI,2*PI,1,color); // 口袋
|
||||||
|
|
||||||
|
// 画铃铛
|
||||||
|
fillColor=(Color){169, 38, 0,255}; // 绳子
|
||||||
|
ImageFillRoundRectEx(&img,300,323,200,19,12,12,fillColor);
|
||||||
|
|
||||||
|
fillColor=(Color){245, 237, 38,255}; // 铃铛外形
|
||||||
|
ImageFillCircleEx(&img,400,349,19,fillColor);
|
||||||
|
|
||||||
|
fillColor=BLACK; // 铃铛上的洞
|
||||||
|
ImageFillEllipseEx(&img,400,354,4,4,fillColor);
|
||||||
|
ImageDrawLineEx(&img,400,357,400,368,3,color);
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,384,340,416,340,1,color); // 铃铛上的纹路
|
||||||
|
ImageDrawLineEx(&img,384,344,418,344,1,color);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage0() {
|
||||||
|
Image img = GenImageColor(800,600, BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
|
||||||
|
fillColor = BLACK;
|
||||||
|
ImageFillCircleEx(&img,384,184,6, fillColor); // 右眼球
|
||||||
|
ImageFillCircleEx(&img,416,184,6, fillColor); // 左眼球
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage1() {
|
||||||
|
Image img = GenImageColor(800,600, BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
|
||||||
|
ImageFillRectangleEx(&img,337,168,63,19,fillColor);
|
||||||
|
ImageFillRectangleEx(&img,400,168,63,19,fillColor);
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
|
||||||
|
fillColor = BLACK;
|
||||||
|
ImageFillCircleEx(&img,384,184,6, fillColor); // 右眼球
|
||||||
|
ImageFillCircleEx(&img,416,184,6, fillColor); // 左眼球
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage2() {
|
||||||
|
Image img=GenImageColor(800,600,BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
|
||||||
|
ImageDrawLineEx(&img,337,168,399,168,1,color);
|
||||||
|
ImageDrawLineEx(&img,400,168,462,168,1,color);
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage3(){
|
||||||
|
Image img=GenImageColor(800,600,BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
ImageDrawRoundRectEx(&img,337, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 150, 63, 37, 28, 28, 1, color);
|
||||||
|
|
||||||
|
ImageFillRectangleEx(&img,337,150,63,19,fillColor);
|
||||||
|
ImageFillRectangleEx(&img,400,150,63,19,fillColor);
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image genShrinkImage4() {
|
||||||
|
Image img=GenImageColor(800,600,BLANK);
|
||||||
|
Color fillColor=WHITE;
|
||||||
|
Color color=BLACK;
|
||||||
|
ImageFillRoundRectEx(&img,337, 131, 63, 74, 28, 28, fillColor); // 右眼
|
||||||
|
ImageFillRoundRectEx(&img,400, 131, 63, 74, 28, 28, fillColor); // 左眼
|
||||||
|
|
||||||
|
ImageDrawRoundRectEx(&img,337, 131, 63, 74, 28, 28,1, color);
|
||||||
|
ImageDrawRoundRectEx(&img,400, 131, 63, 74, 28, 28,1, color);
|
||||||
|
fillColor = (Color){201, 62, 0, 255}; // 鼻子
|
||||||
|
ImageFillCircleEx(&img, 400, 208, 15, fillColor);
|
||||||
|
return img;
|
||||||
|
}
|