初始化内容
@@ -0,0 +1,11 @@
|
||||
/log
|
||||
/*.ilk
|
||||
/*.pdb
|
||||
/*.exe
|
||||
/memory_leak_report.txt
|
||||
/vld.ini
|
||||
/temp
|
||||
/binary
|
||||
/dl
|
||||
/Microsoft.DTfW.DHL.manifest
|
||||
/out
|
||||
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
project ("dl_test")
|
||||
|
||||
set (PATH_SRC ${PROJECT_SOURCE_DIR})
|
||||
set (PATH_RES ${PROJECT_SOURCE_DIR}/res)
|
||||
set (USE_RENDER ON)
|
||||
include ("../project.cmake")
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "新项目",
|
||||
"path": "D:/dl/project/dl_test/editor/",
|
||||
"pathRes": ""
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
#include "game_match.h"
|
||||
|
||||
GameMatch::GameMatch()
|
||||
{
|
||||
GenerateBoard();
|
||||
|
||||
_txt = g_factory->CreateTextDefault();
|
||||
_txt->SetFontSize(24);
|
||||
_txt->SetPositionAlign(toPosition(400, 50), Align::CT);
|
||||
_txt->SetString("Score: 0");
|
||||
}
|
||||
|
||||
GameMatch::~GameMatch()
|
||||
{
|
||||
}
|
||||
|
||||
void GameMatch::Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GameMatch::Update()
|
||||
{
|
||||
if (g_input->KeyDown(MouseCode::LEFT))
|
||||
{
|
||||
Point mousePos = g_input->GetCursorPosition();
|
||||
int x = (mousePos.x - 100) / 60;
|
||||
int y = (mousePos.y - 100) / 60;
|
||||
|
||||
if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE)
|
||||
{
|
||||
if (_selectedPos.x == -1)
|
||||
{
|
||||
_selectedPos = toPosition(static_cast<float>(x), static_cast<float>(y));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((abs(static_cast<int>(_selectedPos.x) - x) == 1 && static_cast<int>(_selectedPos.y) == y) ||
|
||||
(abs(static_cast<int>(_selectedPos.y) - y) == 1 && static_cast<int>(_selectedPos.x) == x))
|
||||
{
|
||||
if (CanSwap(static_cast<int>(_selectedPos.x), static_cast<int>(_selectedPos.y), x, y))
|
||||
{
|
||||
SwapItems(static_cast<int>(_selectedPos.x), static_cast<int>(_selectedPos.y), x, y);
|
||||
CheckMatches();
|
||||
RemoveMatches();
|
||||
DropItems();
|
||||
RefillBoard();
|
||||
CheckMatches();
|
||||
RemoveMatches();
|
||||
}
|
||||
}
|
||||
_selectedPos = toPosition(-1.0f, -1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameMatch::Render()
|
||||
{
|
||||
for (int y = 0; y < BOARD_SIZE; y++)
|
||||
{
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
int type = _board[y][x].type;
|
||||
if (type > 0)
|
||||
{
|
||||
g_gfx->SetCoor(nullptr);
|
||||
g_gfx->SetColor(createColorHSV((type - 1) * 60.0f, 1.0f, 1.0f));
|
||||
g_gfx->RectangleSolid2D(toPosition(100 + x * 60, 100 + y * 60), toPosition(100 + x * 60 + 50, 100 + y * 60 + 50));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_selectedPos.x != -1)
|
||||
{
|
||||
g_gfx->SetCoor(nullptr);
|
||||
g_gfx->SetColor(ColorDef::WHITE);
|
||||
g_gfx->Rectangle2D(toPosition(100 + _selectedPos.x * 60, 100 + _selectedPos.y * 60), toPosition(100 + _selectedPos.x * 60 + 50, 100 + _selectedPos.y * 60 + 50));
|
||||
}
|
||||
|
||||
if(_txt)
|
||||
_txt->Render();
|
||||
}
|
||||
|
||||
void GameMatch::GenerateBoard()
|
||||
{
|
||||
for (int y = 0; y < BOARD_SIZE; y++)
|
||||
{
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
_board[y][x].type = rand() % 5 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameMatch::CheckMatches()
|
||||
{
|
||||
for (int y = 0; y < BOARD_SIZE; y++)
|
||||
{
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
_board[y][x].matched = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < BOARD_SIZE; y++)
|
||||
{
|
||||
int count = 1;
|
||||
int type = _board[y][0].type;
|
||||
for (int x = 1; x < BOARD_SIZE; x++)
|
||||
{
|
||||
if (_board[y][x].type == type)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count >= 3)
|
||||
{
|
||||
for (int i = x - count; i < x; i++)
|
||||
{
|
||||
_board[y][i].matched = true;
|
||||
}
|
||||
}
|
||||
count = 1;
|
||||
type = _board[y][x].type;
|
||||
}
|
||||
}
|
||||
if (count >= 3)
|
||||
{
|
||||
for (int i = BOARD_SIZE - count; i < BOARD_SIZE; i++)
|
||||
{
|
||||
_board[y][i].matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
int count = 1;
|
||||
int type = _board[0][x].type;
|
||||
for (int y = 1; y < BOARD_SIZE; y++)
|
||||
{
|
||||
if (_board[y][x].type == type)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count >= 3)
|
||||
{
|
||||
for (int i = y - count; i < y; i++)
|
||||
{
|
||||
_board[i][x].matched = true;
|
||||
}
|
||||
}
|
||||
count = 1;
|
||||
type = _board[y][x].type;
|
||||
}
|
||||
}
|
||||
if (count >= 3)
|
||||
{
|
||||
for (int i = BOARD_SIZE - count; i < BOARD_SIZE; i++)
|
||||
{
|
||||
_board[i][x].matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameMatch::RemoveMatches()
|
||||
{
|
||||
for (int y = 0; y < BOARD_SIZE; y++)
|
||||
{
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
if (_board[y][x].matched)
|
||||
{
|
||||
_board[y][x].type = 0;
|
||||
_score += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
_txt->SetString("Score: " + to_string(_score));
|
||||
}
|
||||
|
||||
void GameMatch::DropItems()
|
||||
{
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
int emptyCount = 0;
|
||||
for (int y = BOARD_SIZE - 1; y >= 0; y--)
|
||||
{
|
||||
if (_board[y][x].type == 0)
|
||||
{
|
||||
emptyCount++;
|
||||
}
|
||||
else if (emptyCount > 0)
|
||||
{
|
||||
_board[y + emptyCount][x].type = _board[y][x].type;
|
||||
_board[y][x].type = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameMatch::RefillBoard()
|
||||
{
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
for (int y = 0; y < BOARD_SIZE; y++)
|
||||
{
|
||||
if (_board[y][x].type == 0)
|
||||
{
|
||||
_board[y][x].type = rand() % 5 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GameMatch::CanSwap(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
SwapItems(x1, y1, x2, y2);
|
||||
CheckMatches();
|
||||
bool hasMatch = false;
|
||||
for (int y = 0; y < BOARD_SIZE; y++)
|
||||
{
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
{
|
||||
if (_board[y][x].matched)
|
||||
{
|
||||
hasMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasMatch)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
SwapItems(x1, y1, x2, y2);
|
||||
return hasMatch;
|
||||
}
|
||||
|
||||
void GameMatch::SwapItems(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
std::swap(_board[y1][x1].type, _board[y2][x2].type);
|
||||
std::swap(_board[y1][x1].matched, _board[y2][x2].matched);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "head.h"
|
||||
|
||||
class GameMatch : public UI::Scene
|
||||
{
|
||||
public:
|
||||
GameMatch();
|
||||
~GameMatch();
|
||||
|
||||
void Init();
|
||||
void Update() override;
|
||||
void Render() override;
|
||||
|
||||
private:
|
||||
void GenerateBoard();
|
||||
void CheckMatches();
|
||||
void RemoveMatches();
|
||||
void DropItems();
|
||||
void RefillBoard();
|
||||
|
||||
bool CanSwap(int x1, int y1, int x2, int y2);
|
||||
void SwapItems(int x1, int y1, int x2, int y2);
|
||||
|
||||
struct Item
|
||||
{
|
||||
int type = 0;
|
||||
bool matched = false;
|
||||
};
|
||||
|
||||
static constexpr int BOARD_SIZE = 8;
|
||||
Item _board[BOARD_SIZE][BOARD_SIZE];
|
||||
|
||||
Position _selectedPos = { -1, -1 };
|
||||
int _score = 0;
|
||||
gcText _txt;
|
||||
};
|
||||
@@ -0,0 +1,599 @@
|
||||
#pragma once
|
||||
#include "head.h"
|
||||
#include "ui_main.h"
|
||||
|
||||
// trae ai 写的
|
||||
|
||||
constexpr Size MAP_SIZE = { 24,24 };
|
||||
constexpr Size MAP_NODE_SIZE = { 12,12 };
|
||||
constexpr float MOVE_SPEED = 0.15f; // 移动速度(秒/步)
|
||||
|
||||
|
||||
enum class GameSnakeMapNodeState {
|
||||
PASS,
|
||||
FOOD,
|
||||
BODY,
|
||||
WALL
|
||||
};
|
||||
|
||||
enum class GameSnakeDirection {
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
class GameSnakeMapNode {
|
||||
public:
|
||||
void SetNodeXy(const PointU& xy)
|
||||
{
|
||||
_xy = xy;
|
||||
}
|
||||
|
||||
const PointU& GetNodeXy() const
|
||||
{
|
||||
return _xy;
|
||||
}
|
||||
|
||||
void SetCoor(Coor* coor)
|
||||
{
|
||||
_coor = coor;
|
||||
}
|
||||
|
||||
void SetNodeState(GameSnakeMapNodeState s)
|
||||
{
|
||||
_state = s;
|
||||
switch (_state)
|
||||
{
|
||||
case GameSnakeMapNodeState::PASS:
|
||||
_spr.CancelRef();
|
||||
break;
|
||||
case GameSnakeMapNodeState::FOOD:
|
||||
{
|
||||
_spr = g_factory->CreateSprite("snake.apple");
|
||||
_spr->SetOrder(0.8f);
|
||||
// 使用共享的Coor
|
||||
_spr->SetCoor(_coor);
|
||||
// 设置精灵的大小和位置
|
||||
Position pos = toPosition(_xy * MAP_NODE_SIZE);
|
||||
_spr->SetQuad(createQuad(pos, pos + Position{12.0f,12.0f}));
|
||||
}
|
||||
break;
|
||||
case GameSnakeMapNodeState::BODY:
|
||||
{
|
||||
_spr = g_factory->CreateSprite("snake.body");
|
||||
_spr->SetOrder(0.8f);
|
||||
// 使用共享的Coor
|
||||
_spr->SetCoor(_coor);
|
||||
// 设置精灵的大小和位置
|
||||
Position posBody = toPosition(_xy * MAP_NODE_SIZE);
|
||||
_spr->SetQuad(createQuad(posBody, posBody + Position{12.0f,12.0f}));
|
||||
}
|
||||
break;
|
||||
case GameSnakeMapNodeState::WALL:
|
||||
{
|
||||
_spr = g_factory->CreateSpriteDefault(ColorDef::GRAY);
|
||||
_spr->SetOrder(0.8f);
|
||||
// 使用共享的Coor
|
||||
_spr->SetCoor(_coor);
|
||||
// 设置精灵的大小和位置
|
||||
Position posWall = toPosition(_xy * MAP_NODE_SIZE);
|
||||
_spr->SetQuad(createQuad(posWall, posWall + Position{12.0f,12.0f}));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GameSnakeMapNodeState GetNodeState() const
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
|
||||
void RenderNode()
|
||||
{
|
||||
if (_spr)
|
||||
{
|
||||
_spr->Render();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GameSnakeMapNodeState _state;
|
||||
PointU _xy;
|
||||
Coor* _coor; // 共享的Coor对象
|
||||
gcSprite _spr;
|
||||
|
||||
};
|
||||
|
||||
class GameSnakeMap {
|
||||
public:
|
||||
GameSnakeMap()
|
||||
{
|
||||
// 创建一个Coor对象,所有精灵的Coor都指向它
|
||||
_coor = Coor::Create();
|
||||
}
|
||||
|
||||
~GameSnakeMap()
|
||||
{
|
||||
delete _coor;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_vec.resize(MAP_SIZE[0] * MAP_SIZE[1]);
|
||||
for (unsigned j = 0; j< MAP_SIZE[1]; ++j)
|
||||
{
|
||||
for (unsigned i = 0; i < MAP_SIZE[0]; ++i)
|
||||
{
|
||||
unsigned idx = MAP_SIZE[0] * j + i;
|
||||
// 先设置节点的坐标
|
||||
_vec[idx].SetNodeXy({i,j});
|
||||
// 设置共享的Coor对象
|
||||
_vec[idx].SetCoor(_coor);
|
||||
// 边界设置为墙壁
|
||||
if (i == 0 || i == MAP_SIZE[0] - 1 || j == 0 || j == MAP_SIZE[1] - 1)
|
||||
{
|
||||
_vec[idx].SetNodeState(GameSnakeMapNodeState::WALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_vec[idx].SetNodeState(GameSnakeMapNodeState::PASS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetOffset(const Position& offset)
|
||||
{
|
||||
// 只需要更新Coor的位置,所有精灵的位置会自动更新
|
||||
_coor->SetPosition(offset);
|
||||
}
|
||||
|
||||
void CreateFood(const PointU& xy)
|
||||
{
|
||||
unsigned idx = MAP_SIZE[0] * xy[1] + xy[0];
|
||||
if (idx >= _vec.size())
|
||||
{
|
||||
log_err("创建food下标越界:x: {},y: {}", xy[0], xy[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
_vec[idx].SetNodeState(GameSnakeMapNodeState::FOOD);
|
||||
}
|
||||
|
||||
void SetNodeState(const PointU& xy, GameSnakeMapNodeState state)
|
||||
{
|
||||
unsigned idx = MAP_SIZE[0] * xy[1] + xy[0];
|
||||
if (idx < _vec.size())
|
||||
{
|
||||
_vec[idx].SetNodeState(state);
|
||||
}
|
||||
}
|
||||
|
||||
GameSnakeMapNodeState GetNodeState(const PointU& xy) const
|
||||
{
|
||||
unsigned idx = MAP_SIZE[0] * xy[1] + xy[0];
|
||||
if (idx < _vec.size())
|
||||
{
|
||||
return _vec[idx].GetNodeState();
|
||||
}
|
||||
return GameSnakeMapNodeState::PASS;
|
||||
}
|
||||
|
||||
void RenderMap(const std::vector<PointU>& snakeBody)
|
||||
{
|
||||
for (size_t i = 0; i < _vec.size(); ++i)
|
||||
{
|
||||
// 不渲染蛇头的位置,留待Snake::Render()渲染
|
||||
bool isHead = false;
|
||||
if (!snakeBody.empty())
|
||||
{
|
||||
PointU head = snakeBody.front();
|
||||
// 检查head坐标是否有效
|
||||
if (head.x < MAP_SIZE[0] && head.y < MAP_SIZE[1])
|
||||
{
|
||||
unsigned idx = MAP_SIZE[0] * head.y + head.x;
|
||||
if (idx == i)
|
||||
{
|
||||
isHead = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isHead)
|
||||
{
|
||||
_vec[i].RenderNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Coor* GetCoor() const
|
||||
{
|
||||
return _coor;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<GameSnakeMapNode> _vec;
|
||||
Coor* _coor; // 所有精灵共享的Coor
|
||||
};
|
||||
|
||||
class GameSnakeSnake {
|
||||
public:
|
||||
GameSnakeSnake()
|
||||
{
|
||||
// 初始位置
|
||||
_body.push_back({ 8, 8 });
|
||||
_body.push_back({ 7, 8 });
|
||||
_body.push_back({ 6, 8 });
|
||||
_dir = GameSnakeDirection::RIGHT;
|
||||
_nextDir = GameSnakeDirection::RIGHT;
|
||||
_moveTimer = 0.0f;
|
||||
_grow = false;
|
||||
}
|
||||
|
||||
void SetDirection(GameSnakeDirection dir)
|
||||
{
|
||||
// 防止180度反向移动
|
||||
if ((dir == GameSnakeDirection::UP && _dir == GameSnakeDirection::DOWN) ||
|
||||
(dir == GameSnakeDirection::DOWN && _dir == GameSnakeDirection::UP) ||
|
||||
(dir == GameSnakeDirection::LEFT && _dir == GameSnakeDirection::RIGHT) ||
|
||||
(dir == GameSnakeDirection::RIGHT && _dir == GameSnakeDirection::LEFT))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_nextDir = dir;
|
||||
}
|
||||
|
||||
bool Update(float deltaTime, GameSnakeMap& map, int& score)
|
||||
{
|
||||
_moveTimer += deltaTime;
|
||||
if (_moveTimer < MOVE_SPEED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
_moveTimer = 0.0f;
|
||||
|
||||
// 更新方向
|
||||
_dir = _nextDir;
|
||||
|
||||
// 计算新头部位置
|
||||
PointU head = _body.front();
|
||||
switch (_dir)
|
||||
{
|
||||
case GameSnakeDirection::UP:
|
||||
head.y--;
|
||||
break;
|
||||
case GameSnakeDirection::DOWN:
|
||||
head.y++;
|
||||
break;
|
||||
case GameSnakeDirection::LEFT:
|
||||
head.x--;
|
||||
break;
|
||||
case GameSnakeDirection::RIGHT:
|
||||
head.x++;
|
||||
break;
|
||||
}
|
||||
|
||||
// 边界检查
|
||||
if (head.x >= MAP_SIZE[0] || head.y >= MAP_SIZE[1] || head.x < 0 || head.y < 0)
|
||||
{
|
||||
return false; // 碰撞边界,游戏结束
|
||||
}
|
||||
|
||||
// 墙壁碰撞检查
|
||||
if (map.GetNodeState(head) == GameSnakeMapNodeState::WALL)
|
||||
{
|
||||
return false; // 碰撞墙壁,游戏结束
|
||||
}
|
||||
|
||||
// 自身碰撞检查
|
||||
for (const auto& bodyPart : _body)
|
||||
{
|
||||
if (bodyPart == head)
|
||||
{
|
||||
return false; // 碰撞自身,游戏结束
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否吃到食物
|
||||
if (map.GetNodeState(head) == GameSnakeMapNodeState::FOOD)
|
||||
{
|
||||
_grow = true;
|
||||
score += 10; // 增加分数
|
||||
// 播放吃到食物的音效
|
||||
snd_play("eat");
|
||||
// 创建新食物
|
||||
PointU foodPos;
|
||||
do
|
||||
{
|
||||
foodPos = {
|
||||
Random::Uint(1, MAP_SIZE[0] - 2),
|
||||
Random::Uint(1, MAP_SIZE[1] - 2)
|
||||
};
|
||||
}
|
||||
while (map.GetNodeState(foodPos) != GameSnakeMapNodeState::PASS);
|
||||
map.CreateFood(foodPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 移除尾部
|
||||
if (!_grow)
|
||||
{
|
||||
PointU tail = _body.back();
|
||||
map.SetNodeState(tail, GameSnakeMapNodeState::PASS);
|
||||
_body.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
_grow = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新头部
|
||||
_body.insert(_body.begin(), head);
|
||||
map.SetNodeState(head, GameSnakeMapNodeState::BODY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Render(Coor* coor)
|
||||
{
|
||||
// 渲染蛇头
|
||||
if (!_body.empty())
|
||||
{
|
||||
PointU head = _body.front();
|
||||
gcSprite head_sprite = g_factory->RenderSprite("snake.right");
|
||||
|
||||
head_sprite->SetOrder(0.7f);
|
||||
|
||||
// 使用精灵自身的AddCoor方法创建坐标系
|
||||
head_sprite->SetCoor(coor);
|
||||
Coor* head_coor = head_sprite->AddCoor();
|
||||
// 计算蛇头的位置
|
||||
Position pos = toPosition(head * MAP_NODE_SIZE);
|
||||
|
||||
// 根据移动方向旋转蛇头(弧度制)
|
||||
float rotate = 0.0f;
|
||||
switch (_dir)
|
||||
{
|
||||
case GameSnakeDirection::UP:
|
||||
rotate = 3.1415926535f / 2.0f; // 90度
|
||||
// 调整位置,使旋转后蛇头保持在正确位置
|
||||
head_coor->SetPosition(pos + Position{ 12.0f, 0.0f });
|
||||
break;
|
||||
case GameSnakeDirection::DOWN:
|
||||
rotate = 3.0f * 3.1415926535f / 2.0f; // 270度
|
||||
// 调整位置,使旋转后蛇头保持在正确位置
|
||||
head_coor->SetPosition(pos + Position{ 0.0f, 12.0f });
|
||||
break;
|
||||
case GameSnakeDirection::LEFT:
|
||||
rotate = 3.1415926535f; // 180度
|
||||
// 调整位置,使旋转后蛇头保持在正确位置
|
||||
head_coor->SetPosition(pos + Position{ 12.0f, 12.0f });
|
||||
break;
|
||||
case GameSnakeDirection::RIGHT:
|
||||
rotate = 0.0f; // 0度
|
||||
// 不需要调整位置
|
||||
head_coor->SetPosition(pos);
|
||||
break;
|
||||
}
|
||||
|
||||
head_sprite->SetQuad(createQuad(Position{ 0.0f, 0.0f }, Position{ 12.0f, 12.0f }));
|
||||
head_coor->SetRotate(rotate);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<PointU>& GetBody() const
|
||||
{
|
||||
return _body;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<PointU> _body;
|
||||
GameSnakeDirection _dir;
|
||||
GameSnakeDirection _nextDir;
|
||||
float _moveTimer;
|
||||
bool _grow;
|
||||
};
|
||||
|
||||
class GameSnake : public UI::Scene
|
||||
{
|
||||
public:
|
||||
GameSnake()
|
||||
{
|
||||
g_system->SetWindowSize({ 800, 600 });
|
||||
|
||||
Random::SetSeed(0);
|
||||
_sprBg = g_factory->CreateSpriteDefault(createColor(0x2c3e50ff)); // 深蓝色背景
|
||||
_txtFps = g_factory->CreateTextDefault();
|
||||
_txtScore = g_factory->CreateTextDefault();
|
||||
_txtScore->SetFontSize(24);
|
||||
_txtScore->SetString("Score: 0");
|
||||
|
||||
_txtControl = g_factory->CreateTextDefault();
|
||||
_txtControl->SetFontSize(16);
|
||||
_txtControl->SetString("WASD/方向键控制,R开始游戏,ESC返回主菜单");
|
||||
|
||||
_txtStart = g_factory->CreateTextDefault();
|
||||
_txtStart->SetFontSize(36);
|
||||
_txtStart->SetString("按R开始游戏");
|
||||
|
||||
_map.Reset();
|
||||
_score = 0;
|
||||
_gameOver = false;
|
||||
_gameStarted = false;
|
||||
}
|
||||
|
||||
void ResetGame()
|
||||
{
|
||||
_map.Reset();
|
||||
_snake = GameSnakeSnake();
|
||||
_score = 0;
|
||||
_txtScore->SetString("Score: 0");
|
||||
|
||||
// 初始化蛇身
|
||||
for (const auto& bodyPart : _snake.GetBody())
|
||||
{
|
||||
_map.SetNodeState(bodyPart, GameSnakeMapNodeState::BODY);
|
||||
}
|
||||
|
||||
// 创建初始食物
|
||||
PointU foodPos;
|
||||
do
|
||||
{
|
||||
foodPos = {
|
||||
Random::Uint(1, MAP_SIZE[0] - 2),
|
||||
Random::Uint(1, MAP_SIZE[1] - 2)
|
||||
};
|
||||
}
|
||||
while (_map.GetNodeState(foodPos) != GameSnakeMapNodeState::PASS);
|
||||
_map.CreateFood(foodPos);
|
||||
|
||||
// 播放游戏开始音效
|
||||
snd_play("click");
|
||||
|
||||
_gameOver = false;
|
||||
_gameStarted = true;
|
||||
}
|
||||
|
||||
virtual void Update() override
|
||||
{
|
||||
if (g_input->KeyDown(KeyCode::ESCAPE))
|
||||
{
|
||||
g_scene->Del(this);
|
||||
g_scene->Add("ui_main", new UIMain);
|
||||
}
|
||||
|
||||
_sprBg->SetQuad(createQuad(g_system->GetWindowSize(), false));
|
||||
_sprBg->SetOrder(0.9f);
|
||||
|
||||
// 计算地图偏移量,使地图居中显示
|
||||
Size mapSize = MAP_SIZE * MAP_NODE_SIZE;
|
||||
Size windowSize = g_system->GetWindowSize();
|
||||
Position offset;
|
||||
offset[0] = (windowSize[0] - mapSize[0]) / 2.0f;
|
||||
offset[1] = (windowSize[1] - mapSize[1]) / 2.0f;
|
||||
_map.SetOffset(offset);
|
||||
|
||||
_txtFps->SetString("FPS: " + std::to_string(g_time->GetFPS()));
|
||||
_txtFps->GetCoor()->SetPosition({ 10, 10 });
|
||||
_txtFps->SetOrder(0.5f);
|
||||
|
||||
// 放置Score到围墙左上角上方
|
||||
_txtScore->SetString("Score: " + std::to_string(_score));
|
||||
_txtScore->GetCoor()->SetPosition({ offset[0], offset[1] - 30.0f });
|
||||
_txtScore->SetOrder(0.5f);
|
||||
|
||||
// 放置操作提示文本到围墙左下角
|
||||
_txtControl->GetCoor()->SetPosition({ offset[0], offset[1] + mapSize[1] + 10.0f });
|
||||
_txtControl->SetOrder(0.5f);
|
||||
|
||||
// 处理输入
|
||||
HandleInput();
|
||||
|
||||
// 检查是否开始游戏
|
||||
if (!_gameStarted)
|
||||
{
|
||||
// 显示开始游戏提示
|
||||
_txtStart->GetCoor()->SetPosition({ (windowSize[0] - 200.0f) / 2.0f, (windowSize[1] - 40.0f) / 2.0f });
|
||||
_txtStart->SetOrder(0.4f);
|
||||
_txtStart->Render();
|
||||
|
||||
if (g_input->KeyDown(KeyCode::R))
|
||||
{
|
||||
ResetGame();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 更新游戏逻辑
|
||||
if (!_gameOver)
|
||||
{
|
||||
if (!_snake.Update(g_time->GetDelta(), _map, _score))
|
||||
{
|
||||
_gameOver = true;
|
||||
// 播放游戏结束音效
|
||||
snd_play("end");
|
||||
// 显示游戏结束信息
|
||||
_txtGameOver = g_factory->CreateTextDefault();
|
||||
_txtGameOver->SetFontSize(36);
|
||||
_txtGameOver->SetString("Game Over!");
|
||||
_txtGameOver->SetOrder(0.4f);
|
||||
|
||||
_txtRestart = g_factory->CreateTextDefault();
|
||||
_txtRestart->SetFontSize(24);
|
||||
_txtRestart->SetString("Press R to restart");
|
||||
_txtRestart->SetOrder(0.4f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_txtGameOver)
|
||||
{
|
||||
// 每次渲染时重新计算位置,确保在屏幕中间
|
||||
_txtGameOver->GetCoor()->SetPosition({ (windowSize[0] - 150.0f) / 2.0f, (windowSize[1] - 40.0f) / 2.0f });
|
||||
_txtGameOver->Render();
|
||||
}
|
||||
if (_txtRestart)
|
||||
{
|
||||
// 每次渲染时重新计算位置,确保在屏幕中间
|
||||
_txtRestart->GetCoor()->SetPosition({ (windowSize[0] - 180.0f) / 2.0f, (windowSize[1] + 20.0f) / 2.0f });
|
||||
_txtRestart->Render();
|
||||
}
|
||||
if (g_input->KeyDown(KeyCode::R))
|
||||
{
|
||||
ResetGame();
|
||||
// gcText是智能指针,不需要手动释放
|
||||
// 只需要重置游戏状态,下次游戏结束时会重新创建
|
||||
}
|
||||
}
|
||||
|
||||
_map.RenderMap(_snake.GetBody());
|
||||
_snake.Render(_map.GetCoor());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Render() override
|
||||
{
|
||||
_sprBg->Render();
|
||||
_txtFps->Render();
|
||||
_txtScore->Render();
|
||||
_txtControl->Render();
|
||||
}
|
||||
|
||||
private:
|
||||
void HandleInput()
|
||||
{
|
||||
if (g_input->KeyDown(KeyCode::W) || g_input->KeyDown(KeyCode::UP))
|
||||
{
|
||||
_snake.SetDirection(GameSnakeDirection::UP);
|
||||
}
|
||||
else if (g_input->KeyDown(KeyCode::S) || g_input->KeyDown(KeyCode::DOWN))
|
||||
{
|
||||
_snake.SetDirection(GameSnakeDirection::DOWN);
|
||||
}
|
||||
else if (g_input->KeyDown(KeyCode::A) || g_input->KeyDown(KeyCode::LEFT))
|
||||
{
|
||||
_snake.SetDirection(GameSnakeDirection::LEFT);
|
||||
}
|
||||
else if (g_input->KeyDown(KeyCode::D) || g_input->KeyDown(KeyCode::RIGHT))
|
||||
{
|
||||
_snake.SetDirection(GameSnakeDirection::RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
gcSprite _sprBg;
|
||||
gcText _txtFps;
|
||||
gcText _txtScore;
|
||||
gcText _txtGameOver;
|
||||
gcText _txtRestart;
|
||||
gcText _txtControl;
|
||||
gcText _txtStart;
|
||||
GameSnakeMap _map;
|
||||
GameSnakeSnake _snake;
|
||||
int _score;
|
||||
bool _gameOver;
|
||||
bool _gameStarted;
|
||||
};
|
||||
@@ -0,0 +1,634 @@
|
||||
#include "game_sudo.h"
|
||||
|
||||
#include "ui_main.h"
|
||||
|
||||
constexpr std::array<std::string_view, 4> ARR_DIFF = {
|
||||
"简单", "中间", "高级", "高级+"
|
||||
};
|
||||
|
||||
constexpr std::array<std::string_view, 4> TIP_LV0 = {
|
||||
"此处不能填入当前数字。",
|
||||
"请确保横、竖、九宫都没有重复数字。"
|
||||
};
|
||||
constexpr std::array<std::string_view, 4> TIP_LV1 = {
|
||||
"眼花了吧,这里不能放!",
|
||||
"请看仔细一点!"
|
||||
"不要点歪了!"
|
||||
};
|
||||
constexpr std::array<std::string_view, 4> TIP_LV2 = {
|
||||
"你真笨……",
|
||||
"傻了吧,这都不会玩!"
|
||||
"不要乱点!"
|
||||
};
|
||||
|
||||
constexpr Position POS_LT = { 20.0, 20.0 };
|
||||
constexpr Float LENGTH_GRID = 60;
|
||||
constexpr Position SIZE_GRID = toLonger(LENGTH_GRID);
|
||||
constexpr Position SIZE_BOARD = SIZE_GRID * 9.0_f;
|
||||
constexpr Float WIDTH_GRID_LINE_0 = 4;
|
||||
constexpr Float WIDTH_GRID_LINE_1 = 2;
|
||||
constexpr float ORDER_BOARD = 0.5f;
|
||||
constexpr float ORDER_GRID_LINE_0 = Math::OffsetOrder(ORDER_BOARD, -1);
|
||||
constexpr float ORDER_GRID_LINE_1 = Math::OffsetOrder(ORDER_BOARD, -2);
|
||||
constexpr float ORDER_NUMBER = Math::OffsetOrder(ORDER_BOARD, -4);
|
||||
constexpr float ORDER_MOUSE = Math::OffsetOrder(ORDER_BOARD, -5);
|
||||
constexpr float ORDER_MOUSE_TEXT = Math::OffsetOrder(ORDER_BOARD, -6);
|
||||
|
||||
GameSudo::GameSudo() :
|
||||
_diff{ 0 },
|
||||
_curNumber{ 0 },
|
||||
_gameState{ 0 },
|
||||
_tStart{ 0 },
|
||||
_countErr{ 0 }
|
||||
{
|
||||
g_system->SetWindowSize({ 800, 600 });
|
||||
|
||||
_coor = Coor::Create();
|
||||
|
||||
//{
|
||||
// // 安卓
|
||||
// Position offset = toPosition(g_system->GetWindowSize()) - toPosition(800, 600);
|
||||
// _coor->SetPosition(offset);
|
||||
// GetPanelRoot()->SetPosPixel(offset);
|
||||
//}
|
||||
|
||||
// 背景
|
||||
{
|
||||
gcSprite spr = g_factory->CreateSpriteDefault();
|
||||
spr->SetColor(createColor(0x0f0f0fff), 0);
|
||||
spr->SetColor(createColor(0x000000ff), 1);
|
||||
spr->SetColor(createColor(0x0f0f0fff), 2);
|
||||
spr->SetColor(createColor(0x2f2f2fff), 3);
|
||||
UI::Sprite* ui_spr = UI::Sprite::Create(
|
||||
spr, UI::Sprite::AutoSize::PANEL, UI::Sprite::FillMode::STRETCH);
|
||||
GetPanelRoot()->SetOrderMode(UI::Panel::FORCE);
|
||||
GetPanelRoot()->SetOrder(0.9f);
|
||||
GetPanelRoot()->Add(ui_spr);
|
||||
}
|
||||
// 难易度 时间
|
||||
{
|
||||
UI::Text* txt = g_ui->CreateTextDefault();
|
||||
txt->GetText()->SetColor(ColorDef::WHITE);
|
||||
txt->GetText()->SetFormat(true);
|
||||
txt->GetText()->SetLayoutAlign(Align::Direction::ZERO);
|
||||
txt->SetString("[c_green]请选择难度");
|
||||
txt->SetElementData(Align::CT, { 727, 48 });
|
||||
GetPanelRoot()->Add(txt);
|
||||
_uiTxt = txt;
|
||||
}
|
||||
// 返回按钮
|
||||
{
|
||||
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
|
||||
UI::ButtonStyle::NORMAL);
|
||||
btn->SetString("退出");
|
||||
btn->SetElementData(Align::LT, { 600, 500 });
|
||||
GetPanelRoot()->Add(btn);
|
||||
_btnBack = btn;
|
||||
}
|
||||
// 难度菜单
|
||||
{
|
||||
UI::Panel* panel = g_ui->CreatePanel();
|
||||
panel->SetLocator(createLocatorY(32));
|
||||
panel->SetPosPixel({ 600, 50 });
|
||||
g_ui->SetPanelParent(panel, GetPanelRoot());
|
||||
|
||||
for(size_t i = 0;i < ARR_DIFF.size(); ++i)
|
||||
{
|
||||
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
|
||||
UI::ButtonStyle::NORMAL);
|
||||
btn->SetString(ARR_DIFF[i]);
|
||||
if (i != 0)
|
||||
btn->SetDisable(true);
|
||||
panel->Add(btn);
|
||||
}
|
||||
_panelMenu = panel;
|
||||
}
|
||||
// 数字菜单
|
||||
{
|
||||
UI::Panel* panel = g_ui->CreatePanel();
|
||||
panel->SetLocator(createLocatorX(32, 5));
|
||||
panel->SetPosPixel({ 600, 50 + 200 });
|
||||
g_ui->SetPanelParent(panel, GetPanelRoot());
|
||||
|
||||
for (size_t i = 0; i <= 9; ++i)
|
||||
{
|
||||
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
|
||||
UI::ButtonStyle::BOX);
|
||||
btn->SetMode(UI::Button::Mode::RADIO);
|
||||
btn->SetString(std::to_string(i));
|
||||
panel->Add(btn);
|
||||
}
|
||||
_panelNumber = panel;
|
||||
}
|
||||
|
||||
// 文字
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
node._number = 0;
|
||||
node._txt = g_factory->CreateText(0, 40, ColorDef::BLACK);
|
||||
node._txt->GetCoor()->SetParent(_coor);
|
||||
node._txt->SetOrder(ORDER_NUMBER);
|
||||
node._txt->SetPositionAlign(toPosition(60 * i + 20, 60 * j + 8), Align::CC);
|
||||
}
|
||||
}
|
||||
|
||||
// 难度评分,种子值
|
||||
{
|
||||
UI::Panel* panel = g_ui->CreatePanel();
|
||||
panel->SetLocator(createLocatorY(32));
|
||||
panel->SetPosPixel({ 600, 50 + 320 });
|
||||
g_ui->SetPanelParent(panel, GetPanelRoot());
|
||||
_panelDiff = panel;
|
||||
|
||||
UI::Text* txt = g_ui->CreateTextDefault();
|
||||
txt->GetText()->SetColor(ColorDef::WHITE);
|
||||
txt->GetText()->SetFormat(true);
|
||||
txt->GetText()->SetLayoutAlign(Align::Direction::ZERO);
|
||||
txt->SetString("[c_green]难度评分");
|
||||
panel->Add(txt);
|
||||
|
||||
UI::EditBox* edt = g_ui->CreateEditBoxDefault();
|
||||
edt->GetPanel()->ExGetButtonSprite()->SetSpriteQuad(
|
||||
UI::Button::State::MAX_NUM, createQuad(Size{ 80, 16 }, false));
|
||||
panel->Add(edt);
|
||||
|
||||
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
|
||||
UI::ButtonStyle::NORMAL);
|
||||
btn->SetString("生成");
|
||||
panel->Add(btn);
|
||||
}
|
||||
// 种子生成
|
||||
{
|
||||
UI::Panel* panel = _panelDiff->Clone();
|
||||
panel->SetPosPixel({ 600 + 90, 50 + 320 });
|
||||
//panel->ExGetButtonSprite()->SetString("生成1");
|
||||
_panelSeed = panel;
|
||||
}
|
||||
}
|
||||
|
||||
void GameSudo::Update()
|
||||
{
|
||||
// 新游戏
|
||||
std::size_t i = _panelMenu->GetClickIndex();
|
||||
if (i != -1)
|
||||
{
|
||||
_diff = (int)i;
|
||||
if (_diff == 0)
|
||||
CreateSudo(32);
|
||||
else if (_diff == 1)
|
||||
CreateSudo(30);
|
||||
else if (_diff == 2)
|
||||
CreateSudo(27);
|
||||
else if (_diff == 3)
|
||||
CreateSudo(24);
|
||||
_tStart = g_time->GetTimeStamp();
|
||||
_gameState = 1;
|
||||
}
|
||||
|
||||
// 数字操作
|
||||
{
|
||||
int number_old = _curNumber;
|
||||
if (g_input->KeyDown(KeyCode::KEY1))
|
||||
_curNumber = 1;
|
||||
else if (g_input->KeyDown(KeyCode::KEY2))
|
||||
_curNumber = 2;
|
||||
else if (g_input->KeyDown(KeyCode::KEY3))
|
||||
_curNumber = 3;
|
||||
else if (g_input->KeyDown(KeyCode::KEY4))
|
||||
_curNumber = 4;
|
||||
else if (g_input->KeyDown(KeyCode::KEY5))
|
||||
_curNumber = 5;
|
||||
else if (g_input->KeyDown(KeyCode::KEY6))
|
||||
_curNumber = 6;
|
||||
else if (g_input->KeyDown(KeyCode::KEY7))
|
||||
_curNumber = 7;
|
||||
else if (g_input->KeyDown(KeyCode::KEY8))
|
||||
_curNumber = 8;
|
||||
else if (g_input->KeyDown(KeyCode::KEY9))
|
||||
_curNumber = 9;
|
||||
else if (g_input->KeyDown(KeyCode::KEY0)
|
||||
|| g_input->KeyDown(KeyCode::GRAVE_ACCENT))
|
||||
_curNumber = 0;
|
||||
|
||||
if (number_old != _curNumber)
|
||||
{
|
||||
_panelNumber->SetSelect(_curNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i = _panelNumber->GetClickIndex();
|
||||
if (i == -1)
|
||||
;
|
||||
else
|
||||
_curNumber = (int)i;
|
||||
}
|
||||
}
|
||||
|
||||
// 填入操作
|
||||
if (g_input->KeyDown(MouseCode::LEFT))
|
||||
{
|
||||
Position pos = _coor->WorldToThis(toPosition(g_input->GetCursorPosition()));
|
||||
Point xy = Pos2Xy(pos);
|
||||
int x = xy[0];
|
||||
int y = xy[1];
|
||||
if (CheckVaild(x, y, _curNumber)
|
||||
&& !_vecNum[y][x]._bFixed)
|
||||
{
|
||||
_vecNum[y][x]._number = _curNumber;
|
||||
RefreshUI();
|
||||
// 胜利检测
|
||||
bool win = true;
|
||||
for (auto& iter : _vecNum)
|
||||
{
|
||||
if (iter._number == 0)
|
||||
{
|
||||
win = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (win)
|
||||
{
|
||||
_gameState = 2;
|
||||
gcText txt = g_factory->CreateText(0, 64);
|
||||
txt->SetString("恭喜,你过关!");
|
||||
txt->SetPositionAlign(toPosition(g_system->GetWindowSize()) / 2.0f, Align::CC);
|
||||
ActionColor* act = new ActionColor(60, [=](ActionColor* act) mutable {
|
||||
txt->SetColor(act->GetColor());
|
||||
txt->Render();
|
||||
});
|
||||
act->SetColor({ ColorDef::RED, ColorDef::GREEN });
|
||||
g_action->Add(act);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_gameState == 1
|
||||
&& _curNumber
|
||||
&& IsInRange(x, y))
|
||||
{
|
||||
std::string tips;
|
||||
if (_countErr < 10)
|
||||
tips = Random::Select(TIP_LV0);
|
||||
else if (_countErr < 20)
|
||||
tips = Random::Select(TIP_LV1);
|
||||
else
|
||||
tips = Random::Select(TIP_LV2);
|
||||
++_countErr;
|
||||
|
||||
gcText txt = g_factory->CreateText(0, 42);
|
||||
txt->SetString(tips);
|
||||
txt->SetPositionAlign(toPosition(g_input->GetCursorPosition()), Align::CC);
|
||||
ActionColor* act = new ActionColor(3, [=](ActionColor* act) mutable {
|
||||
txt->SetColor(act->GetColor());
|
||||
txt->Render();
|
||||
});
|
||||
act->SetColor({ ColorDef::RED, createColor(0x00ff0000) });
|
||||
g_action->Add(act);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(_gameState == 1)
|
||||
_update_time();
|
||||
|
||||
if (_btnBack->IsClick())
|
||||
{
|
||||
g_scene->Del("game");
|
||||
g_scene->Add("main", new UIMain);
|
||||
}
|
||||
}
|
||||
void GameSudo::Render()
|
||||
{
|
||||
_coor->SetScale(g_ui->GetScale());
|
||||
_coor->SetPosition(POS_LT);
|
||||
|
||||
g_gfx->SetCoor(_coor);
|
||||
// 棋盘背景
|
||||
g_gfx->SetColor(createColor(0xeeeeeeff));
|
||||
g_gfx->SetOrder(ORDER_BOARD);
|
||||
g_gfx->RectangleSolid2D({}, SIZE_BOARD);
|
||||
|
||||
// 网格线条(大)
|
||||
g_gfx->SetColor(createColor(0x0000aaff));
|
||||
g_gfx->SetOrder(ORDER_GRID_LINE_0);
|
||||
for (size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
float y = LENGTH_GRID * 3 * i;
|
||||
g_gfx->StrokeLine({ 0 , y }, { LENGTH_GRID * 9, y }, WIDTH_GRID_LINE_0);
|
||||
}
|
||||
for (size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
float x = LENGTH_GRID * 3 * i;
|
||||
g_gfx->StrokeLine({ x , 0 }, { x, LENGTH_GRID * 9 }, WIDTH_GRID_LINE_0);
|
||||
}
|
||||
// 网格线条(小)
|
||||
g_gfx->SetColor(createColor(0x000077ff));
|
||||
g_gfx->SetOrder(ORDER_GRID_LINE_1);
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
float y = LENGTH_GRID * i;
|
||||
g_gfx->StrokeLine({0 , y }, { LENGTH_GRID * 9, y }, WIDTH_GRID_LINE_1);
|
||||
}
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
float x = LENGTH_GRID * i;
|
||||
g_gfx->StrokeLine({ x, 0 }, { x, LENGTH_GRID * 9 }, WIDTH_GRID_LINE_1);
|
||||
}
|
||||
|
||||
|
||||
// 数字绘制
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
node._txt->Render();
|
||||
|
||||
if (_curNumber
|
||||
&& node._number == _curNumber)
|
||||
{
|
||||
g_gfx->SetColor(toVector(ColorDef::RED, 20));
|
||||
g_gfx->PolygonRegular2D(toPosition(60 * i + 30, 60 * j + 30), 25, 16);
|
||||
g_gfx->PolygonRegular2D(toPosition(60 * i + 30, 60 * j + 30), 26, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 光标绘制
|
||||
Position pos = _coor->WorldToThis(toPosition(g_input->GetCursorPosition()));
|
||||
Point xy = Pos2Xy(pos);
|
||||
int x = xy[0];
|
||||
int y = xy[1];
|
||||
if (_curNumber && IsInRange(x, y))
|
||||
{
|
||||
g_gfx->SetOrder(ORDER_MOUSE);
|
||||
g_gfx->SetColor(toVector(ColorDef::WHITE, 20));
|
||||
g_gfx->PolygonRegularSolid2D(pos, 18, 16);
|
||||
g_gfx->SetColor(toVector(ColorDef::BLUE, 20));
|
||||
g_gfx->PolygonRegular2D(pos, 18, 16);
|
||||
|
||||
// 鼠标悬停
|
||||
_txtMouse = g_factory->CreateText(0, 32, ColorDef::BLUE);
|
||||
_txtMouse->SetOrder(ORDER_MOUSE_TEXT);
|
||||
_txtMouse->GetCoor()->SetParent(_coor);
|
||||
_txtMouse->SetString(std::to_string(_curNumber));
|
||||
_txtMouse->SetPositionAlign(pos, Align::CC);
|
||||
_txtMouse->Render();
|
||||
|
||||
g_system->SetCursorMode(System::CursorMode::HIDE);
|
||||
}
|
||||
else
|
||||
g_system->SetCursorMode(System::CursorMode::NORMAL);
|
||||
|
||||
// UI::Button* btn = UI::Button::GetClickControl();
|
||||
// if (btn)
|
||||
// {
|
||||
// gcText txt = g_factory->RenderText();
|
||||
// txt->GetCoor()->SetParent(btn->GetCoor());
|
||||
// txt->SetString("___________");
|
||||
// }
|
||||
}
|
||||
|
||||
void GameSudo::CreateSudo(int fixed_num)
|
||||
{
|
||||
rebuild:
|
||||
size_t remain_remove_num = 81 - fixed_num;
|
||||
Random::SetSeed(0);
|
||||
// 清空
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
node._number = 0;
|
||||
node._bFixed = true;
|
||||
}
|
||||
}
|
||||
// 铺满
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
|
||||
size_t count = 0;
|
||||
while (true)
|
||||
{
|
||||
int n = Random::Int(1, 9);
|
||||
if (CheckVaild((int)i, (int)j, n))
|
||||
{
|
||||
node._number = n;
|
||||
break;
|
||||
}
|
||||
++count;
|
||||
if (count > 100)
|
||||
goto rebuild;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 减少
|
||||
size_t count = 0;
|
||||
while (remain_remove_num)
|
||||
{
|
||||
int i = Random::Int(0, 8);
|
||||
int j = Random::Int(0, 8);
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
if (node._number != 0)
|
||||
{
|
||||
node._number = 0;
|
||||
node._bFixed = false;
|
||||
--remain_remove_num;
|
||||
continue;
|
||||
}
|
||||
|
||||
++count;
|
||||
if (count > 100)
|
||||
goto rebuild;
|
||||
}
|
||||
|
||||
// 验证解
|
||||
size_t x = CheckSole();
|
||||
if (x == 0)
|
||||
goto rebuild;
|
||||
|
||||
// 去除答案
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
if (!node._bFixed)
|
||||
node._number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto edt = _panelDiff->ExGetEditBox(0);
|
||||
if (edt)
|
||||
edt->SetString(std::to_string(x));
|
||||
}
|
||||
{
|
||||
auto edt = _panelSeed->ExGetEditBox(0);
|
||||
if (edt)
|
||||
edt->SetString(std::to_string(x));
|
||||
}
|
||||
|
||||
RefreshUI();
|
||||
}
|
||||
bool GameSudo::IsInRange(int x, int y)
|
||||
{
|
||||
if (x < 0 || x >= 9 || y < 0 || y >= 9)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
size_t GameSudo::CheckSole()
|
||||
{
|
||||
size_t count = 0;
|
||||
do
|
||||
{
|
||||
// 统计剩余值
|
||||
size_t remain = GetRemain();
|
||||
if (remain == 0)
|
||||
return count;
|
||||
|
||||
// 遍历空格子
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
if (node._number != 0)
|
||||
continue;
|
||||
int val = GetMustNumber((int)i, (int)j);
|
||||
if (val)
|
||||
node._number = val;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
size_t remain_new = GetRemain();
|
||||
if (remain_new == remain)
|
||||
return 0;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
size_t GameSudo::GetRemain()
|
||||
{
|
||||
size_t ret = 0;
|
||||
for (auto& iter : _vecNum)
|
||||
{
|
||||
if (iter._number == 0)
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int GameSudo::GetMustNumber(int x, int y)
|
||||
{
|
||||
Array2<std::list<int>, 9, 9> arr_can;
|
||||
// 计算当前局面,每一个空格子,可以填的数字(1-N个)
|
||||
|
||||
// 遍历空格子
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
if (node._number != 0)
|
||||
continue;
|
||||
|
||||
for (int val = 1; val <= 9; ++val)
|
||||
{
|
||||
if (CheckVaild((int)i, (int)j, val))
|
||||
{
|
||||
arr_can[j][i].push_back(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::list<int>& vec = arr_can[y][x];
|
||||
if (vec.size() == 1)
|
||||
return *vec.begin();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Point GameSudo::Pos2Xy(const Position& pos)
|
||||
{
|
||||
return toPoint(pos / LENGTH_GRID);
|
||||
}
|
||||
|
||||
bool GameSudo::CheckVaild(int x, int y, int val)
|
||||
{
|
||||
if (val < 1 || val > 9)
|
||||
return false;
|
||||
if (!IsInRange(x, y))
|
||||
return false;
|
||||
|
||||
// 行检查
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
if (_vecNum[y][i]._number == val)
|
||||
return false;
|
||||
}
|
||||
// 列检查
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
if (_vecNum[j][x]._number == val)
|
||||
return false;
|
||||
}
|
||||
// 九宫检查
|
||||
size_t start_y = y / 3 * 3;
|
||||
size_t start_x = x / 3 * 3;
|
||||
|
||||
for (size_t j = 0; j < 3; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
{
|
||||
if (_vecNum[j + start_y][i + start_x]._number == val)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GameSudo::RefreshUI()
|
||||
{
|
||||
for (size_t j = 0; j < 9; ++j)
|
||||
{
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
NumberNode& node = _vecNum[j][i];
|
||||
if (node._bFixed)
|
||||
node._txt->SetColor(ColorDef::BLACK);
|
||||
else
|
||||
node._txt->SetColor(createColor(0x00aa00ff));
|
||||
|
||||
if (node._number > 0)
|
||||
node._txt->SetString(std::to_string(node._number));
|
||||
else
|
||||
node._txt->SetString({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameSudo::_update_time()
|
||||
{
|
||||
std::string str_time = "00:00:00";
|
||||
if(_tStart)
|
||||
str_time = g_time->TimeStampDelta2String(g_time->GetTimeStamp() - _tStart);
|
||||
|
||||
std::string str = fmt::format(
|
||||
"[s_32]难易度:\n[c_green]{}\n[c]时间:\n[c_yellow]{}",
|
||||
ARR_DIFF[_diff], str_time
|
||||
);
|
||||
_uiTxt->SetString(str);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "head.h"
|
||||
|
||||
class GameSudo : public UI::Scene
|
||||
{
|
||||
public:
|
||||
GameSudo();
|
||||
|
||||
virtual void Update() override;
|
||||
virtual void Render() override;
|
||||
|
||||
~GameSudo()
|
||||
{
|
||||
delete _coor;
|
||||
}
|
||||
|
||||
// 生成局面
|
||||
void CreateSudo(int remove_num);
|
||||
// 检查是否可填入值
|
||||
bool CheckVaild(int x, int y, int val);
|
||||
// 刷新ui
|
||||
void RefreshUI();
|
||||
// 越界检查
|
||||
bool IsInRange(int x, int y);
|
||||
// 检查局面是否有唯一解,0表示没有,其余表示求解次数
|
||||
size_t CheckSole();
|
||||
// 屏幕坐标 -> 格子坐标
|
||||
Point Pos2Xy(const Position& pos);
|
||||
// 返回剩余未填格子数
|
||||
size_t GetRemain();
|
||||
// 推理当前格子应该填啥,无法判断返回0
|
||||
int GetMustNumber(int x, int y);
|
||||
private:
|
||||
UI::Panel* _panelMenu; // 右侧按钮
|
||||
UI::Panel* _panelNumber;// 数字按钮
|
||||
UI::Panel* _panelDiff; // 难度生成
|
||||
UI::Panel* _panelSeed; // 种子生成
|
||||
|
||||
Coor* _coor;
|
||||
UI::Text* _uiTxt; // 右侧信息
|
||||
gcText _txtMouse;
|
||||
UI::ButtonSprite* _btnBack;
|
||||
size_t _countErr;
|
||||
|
||||
struct NumberNode
|
||||
{
|
||||
int _number;
|
||||
bool _bFixed;
|
||||
gcText _txt;
|
||||
};
|
||||
|
||||
Array2<NumberNode, 9, 9> _vecNum;
|
||||
|
||||
int _diff; // 难度
|
||||
int _curNumber; // 当前选择数字
|
||||
time_t _tStart; // 开始局时
|
||||
int _gameState; // 状态 0.未开始 1.进行中 2.完成
|
||||
|
||||
void _update_time();
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "head.h"
|
||||
|
||||
|
||||
#include "ui_main.h"
|
||||
#include "game_sudo.h"
|
||||
#include "game_match.h"
|
||||
|
||||
void Test()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Tool::Manager* g_Tool;
|
||||
void Init()
|
||||
{
|
||||
g_particle->SetReadOverwirte(true);
|
||||
g_particle->LoadPath("particle/");
|
||||
|
||||
g_Tool = Tool::Manager::Create();
|
||||
|
||||
g_Tool->SetVisible(false);
|
||||
g_Tool->SetSwitchAll(true);
|
||||
|
||||
g_ui->SetStandardSize({ 800, 600 });
|
||||
g_ui->RegisterAll("ui/");
|
||||
g_scene->Add("main", new UIMain);
|
||||
//g_scene->Add("game", new GameSudo);
|
||||
//g_scene->Add("game_match", new GameMatch);
|
||||
//g_scene->SetCurrent("game_match");
|
||||
|
||||
UI::ResExplorer* win = UI::ResExplorer::Create();
|
||||
win->ExFastSet();
|
||||
g_ui->AddWindow("res_exp", win);
|
||||
}
|
||||
|
||||
void Run()
|
||||
{
|
||||
g_Tool->Update();
|
||||
|
||||
auto win = g_ui->GetWindow("res_exp");
|
||||
|
||||
if (g_input->KeyDown(KeyCode::F10))
|
||||
{
|
||||
g_ui->ShowWindow(win, UI::WindowShowMode::TOGGLE);
|
||||
}
|
||||
if (win->IsClickClose())
|
||||
{
|
||||
g_ui->ShowWindow(win, UI::WindowShowMode::HIDE);
|
||||
}
|
||||
|
||||
g_Tool->Render();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
delete g_Tool;
|
||||
}
|
||||
|
||||
int Main()
|
||||
{
|
||||
Position* p_crash = nullptr;
|
||||
log_info("{}", to_string(*p_crash));
|
||||
|
||||
|
||||
g_log->SetLogFile("log/");
|
||||
//Engine::GetParamRef()._test = true;
|
||||
Engine::Init();
|
||||
|
||||
Position p0;
|
||||
Position p1{};
|
||||
|
||||
log_info("{}", to_string(p0));
|
||||
log_info("{}", to_string(p1));
|
||||
p0.x = 100;
|
||||
p0.y = 200;
|
||||
log_info("{}", to_string(p0));
|
||||
|
||||
Size s0;
|
||||
s0.w = 800;
|
||||
s0.h = 600;
|
||||
log_info("{}", to_string(s0));
|
||||
|
||||
Quad q0{};
|
||||
q0.x[0] = 1;
|
||||
q0.y[0] = 2;
|
||||
log_info("{}", to_string(q0));
|
||||
|
||||
{
|
||||
|
||||
FileIni ini;
|
||||
ini.Open("ClientSetup.ini");
|
||||
|
||||
FileIniSection sec = ini.GetSection("Setup");
|
||||
std::string v = sec.Get("HomePage");
|
||||
}
|
||||
Test();
|
||||
|
||||
g_mod->LoadModAll("mod/");
|
||||
g_factory->SetPath("image/", "model/", "binary/", "temp/");
|
||||
//g_factory->SetReleaseMode();
|
||||
g_audio->Init("sound/config.json");
|
||||
g_time->SetFPS(0);
|
||||
g_system->SetFuncInit(Init);
|
||||
g_system->SetFuncRun(Run);
|
||||
#if DL_PLATFORM == DL_PLATFORM_ANDROID
|
||||
//g_system->SetWindowDirection(WindowDirection::RIGHT);
|
||||
#endif
|
||||
ParamWindow p;
|
||||
p._size = { 800, 600 };// { 1920, 1080 };
|
||||
p._fullScreenMode = FullScreenMode::WINDOW;
|
||||
g_system->Start(p);
|
||||
|
||||
Release();
|
||||
Engine::Release();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <dl.h>
|
||||
using namespace dl;
|
||||
|
||||
#include "ui_def.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include <dl_main.h>
|
||||
@@ -0,0 +1,11 @@
|
||||
/log
|
||||
/*.ilk
|
||||
/*.pdb
|
||||
/*.exe
|
||||
/memory_leak_report.txt
|
||||
/vld.ini
|
||||
/temp
|
||||
/binary
|
||||
/dl
|
||||
/Microsoft.DTfW.DHL.manifest
|
||||
/out
|
||||
@@ -0,0 +1,154 @@
|
||||
[Setup]
|
||||
ControlHelpButton=0
|
||||
RankButton=0
|
||||
WhisperButton=1
|
||||
FriendButton=0
|
||||
OpenShopButton=1
|
||||
MissionButton=0
|
||||
UserShopButton=1
|
||||
ActionLogButton=0
|
||||
OpenHeroButton=0
|
||||
ShowMerchantDlgHelp=0
|
||||
WebButton=0
|
||||
ChallengeButton=0
|
||||
GloryButton=1
|
||||
HorseButton=0
|
||||
DBotFuncs0=1
|
||||
DBotFuncs1=1
|
||||
DBotFuncs2=1
|
||||
DBotFuncs3=1
|
||||
DBotFuncs4=1
|
||||
DBotFuncs5=1
|
||||
FullBack=0
|
||||
NpcMemoOffSetX=20
|
||||
NpcMemoOffSetY=54
|
||||
NpcMenuListOffSetX=0
|
||||
NpcMenuListOffSetY=0
|
||||
HomePage=http://www.kp74.com
|
||||
StartGameAuxiliary=1
|
||||
CanOpenGameConfigDlg=1
|
||||
NotCanUseClientConfig=0
|
||||
PlugIn=1
|
||||
ClientConfigTabSheetVisible0=1
|
||||
ClientConfigTabSheetVisible1=1
|
||||
ClientConfigTabSheetVisible2=1
|
||||
ClientConfigTabSheetVisible3=1
|
||||
ClientConfigTabSheetVisible4=1
|
||||
ClientConfigTabSheetVisible5=0
|
||||
ClientConfigTabSheetVisible6=0
|
||||
ClientConfigTabSheetVisible7=0
|
||||
ClientConfigTabSheetVisible8=0
|
||||
ClientConfigTabSheetVisible9=1
|
||||
MoveFrameTime=550
|
||||
AttackFrameTime=430
|
||||
SpellFrameTime=400
|
||||
AutoPickupTime=300
|
||||
TabGetName=0
|
||||
ShowGreenHintStyle=1
|
||||
MouseDownAttackHum=0
|
||||
ShowHintWindowFrame=1
|
||||
ShowHintWindowLine=1
|
||||
HintWindowbackgroundColor=0
|
||||
HintWindowbackgroundAlpha=150
|
||||
SuspensionShowItem=1
|
||||
ShowItemValue=1
|
||||
SuspensionShowItemPosition=0
|
||||
ShowItemProgressBars=1
|
||||
ShowItemNeed=1
|
||||
ShowItemWindowStyle=2
|
||||
ShowMoveItemMakeIndex=0
|
||||
MonStruckShowNumber=1
|
||||
HumStruckShowNumber=1
|
||||
CloseBookProtect=0
|
||||
CloseLogoutProtect=0
|
||||
BagRightkey=1
|
||||
ShowBagGameGold=1
|
||||
ShowBagGameGoldX=45
|
||||
ShowBagGameGoldY=398
|
||||
GetExpMsgAddChatBoardMsg=0
|
||||
AddItemMsgFColor=250
|
||||
AddItemMsgBColor=0
|
||||
AddItemMsgX=10
|
||||
AddItemMsgY=40
|
||||
AddItemMsgXRightToLeft=0
|
||||
GetExpMsgFColor=250
|
||||
GetExpMsgBColor=0
|
||||
GetExpMsgX=10
|
||||
GetExpMsgY=476
|
||||
GetExpMsgXRightToLeft=0
|
||||
UpLevelMsgFColor=250
|
||||
UpLevelMsgBColor=0
|
||||
UpLevelMsgX=10
|
||||
UpLevelMsgY=40
|
||||
UpLevelMsgXRightToLeft=0
|
||||
HeroAddItemMsgFColor=2
|
||||
HeroAddItemMsgBColor=0
|
||||
HeroAddItemMsgX=30
|
||||
HeroAddItemMsgY=40
|
||||
HeroAddItemMsgXRightToLeft=0
|
||||
HeroGetExpMsgFColor=2
|
||||
HeroGetExpMsgBColor=0
|
||||
HeroGetExpMsgX=30
|
||||
HeroGetExpMsgY=40
|
||||
HeroGetExpMsgXRightToLeft=0
|
||||
HeroUpLevelMsgFColor=2
|
||||
HeroUpLevelMsgBColor=0
|
||||
HeroUpLevelMsgX=30
|
||||
HeroUpLevelMsgY=40
|
||||
HeroUpLevelMsgXRightToLeft=0
|
||||
UseFindPath=1
|
||||
ChangeVolume=0
|
||||
|
||||
[Settings]
|
||||
ShowBleed=1
|
||||
NumberBleed=1
|
||||
ShowLevel=1
|
||||
ExpFilter=1
|
||||
TopInfo=1
|
||||
ShowName=1
|
||||
ShowTitle=1
|
||||
Bleed=1
|
||||
ShowItem=1
|
||||
ItemFilter=1
|
||||
NeedTips=0
|
||||
TaiShan=1
|
||||
WeightFree=1
|
||||
MagicLock=1
|
||||
AutoPickUp=1
|
||||
AutoMedicine=1
|
||||
AutoRepair=1
|
||||
Persistent=1
|
||||
NoShift=1
|
||||
HideCorpse=1
|
||||
HideWing=1
|
||||
HideWeaponEffec=1
|
||||
ShowMap=1
|
||||
Highlight=1
|
||||
BGMusic=1
|
||||
ShowMonsterName=1
|
||||
Petrifaction=1
|
||||
OldMoveMode=1
|
||||
Shake=1
|
||||
SmartTracking=1
|
||||
EquipCmp=0
|
||||
HideOtherEffect=1
|
||||
ShowSimplePlayer=1
|
||||
DisplayNPC=1
|
||||
StopTransactions=0
|
||||
AutoHide=0
|
||||
DFQH=1
|
||||
AutoDun=1
|
||||
DDCS=0
|
||||
GWCS=1
|
||||
ZWCS=1
|
||||
ZNBY=1
|
||||
AutoLH=1
|
||||
ZRJF=1
|
||||
SLZ=1
|
||||
LYJF=1
|
||||
LockBPX=0
|
||||
LockBLHY=1
|
||||
LockJFDY=1
|
||||
LockLXHY=1
|
||||
RedGreen=1
|
||||
AutoKTZ=1
|
||||
@@ -0,0 +1,27 @@
|
||||
class UIMod
|
||||
{
|
||||
void CreateUI()
|
||||
{
|
||||
@_panel = g_ui.CreatePanel();
|
||||
|
||||
//UI::ListBox@ lst = g_ui.CreateListBoxDefault();
|
||||
|
||||
|
||||
UI::Text@ txt = g_ui.CreateTextDefault();
|
||||
txt.SetString("mod管理器");//string_view("mod管理器"));
|
||||
_panel.Add(txt);
|
||||
|
||||
}
|
||||
|
||||
UI::Panel@ _panel;
|
||||
}
|
||||
|
||||
UI::Panel@ initUI(string x)
|
||||
{
|
||||
print(x);
|
||||
UIMod mod = UIMod();
|
||||
mod.CreateUI();
|
||||
return mod._panel;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
void main()
|
||||
{
|
||||
string a = "Hello";
|
||||
string b = "World";
|
||||
print(a + ' ' + b + "!");
|
||||
int c = 2;
|
||||
int d = 3;
|
||||
// print(c + d);
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"type": "multi",
|
||||
"format": "{1:0>6}",
|
||||
"dir": 1,
|
||||
"ani":[
|
||||
{
|
||||
"name": "normal",
|
||||
"beg":450,
|
||||
"count":15,
|
||||
"ftime":200
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"split": [3, 3]
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
@@ -0,0 +1,2 @@
|
||||
-39
|
||||
-88
|
||||
@@ -0,0 +1,2 @@
|
||||
-44
|
||||
-93
|
||||
@@ -0,0 +1,2 @@
|
||||
-45
|
||||
-96
|
||||
@@ -0,0 +1,2 @@
|
||||
-49
|
||||
-99
|
||||
@@ -0,0 +1,3 @@
|
||||
-49
|
||||
-102
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-52
|
||||
-102
|
||||
@@ -0,0 +1,2 @@
|
||||
-58
|
||||
-102
|
||||
@@ -0,0 +1,2 @@
|
||||
-62
|
||||
-110
|
||||
@@ -0,0 +1,2 @@
|
||||
-62
|
||||
-110
|
||||
@@ -0,0 +1,2 @@
|
||||
-62
|
||||
-110
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"type": "multi",
|
||||
"format": "{1:0>6}",
|
||||
"dir": 1,
|
||||
"ani":[
|
||||
{
|
||||
"name": "normal",
|
||||
"beg":170,
|
||||
"count":10,
|
||||
"ftime":45
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"split": [3, 1]
|
||||
}
|
||||
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 771 B |
|
After Width: | Height: | Size: 953 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 930 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.1 KiB |