446 lines
18 KiB
MQL5
446 lines
18 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Crazy Scalper |
|
||
|
|
//| Copyright 2020, Crazy Scalper |
|
||
|
|
//| https://www.mql5.com/es/users/dayanacubillas |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property copyright "Crazy Scalper"
|
||
|
|
#property link "https://www.mql5.com/es/users/dayanacubillas"
|
||
|
|
#property version "1.00"
|
||
|
|
|
||
|
|
//--- Include the standard MQL5 library for rendering graphics on the screen
|
||
|
|
#include <Canvas\Canvas.mqh>
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Global Variables for the Graphical Engine |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
CCanvas canvas; // The main object that will act as our drawing canvas
|
||
|
|
int g_chartWidth; // Will store the actual chart window width in pixels
|
||
|
|
int g_chartHeight; // Will store the actual chart window height in pixels
|
||
|
|
bool g_isInitialized = false; // Security flag to prevent timer execution before initialization
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Game State Machine |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
enum ENUM_GAME_STATE
|
||
|
|
{
|
||
|
|
START_SCREEN, // Initial screen waiting for user input
|
||
|
|
PLAYING, // Active gameplay state
|
||
|
|
GAME_OVER // Liquidation screen (Margin Call)
|
||
|
|
};
|
||
|
|
ENUM_GAME_STATE g_gameState = START_SCREEN;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Physics and Movement Variables |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double g_playerY; // Current vertical position of the rocket
|
||
|
|
double g_playerX; // Current horizontal position of the rocket
|
||
|
|
double g_velocityY; // Current falling speed
|
||
|
|
const double GRAVITY = 0.6; // Constant downward force applied every frame
|
||
|
|
const double JUMP_STRENGTH = -9.5; // Upward force (negative Y) applied on key press
|
||
|
|
int g_score = 0; // Current game score (Profit)
|
||
|
|
int g_bestScore = 0; // All-Time High score
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Obstacles (Japanese Candles) Structure and Variables |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
struct CandlePipe
|
||
|
|
{
|
||
|
|
double x; // Horizontal position of the candle obstacle
|
||
|
|
double gap_y; // Vertical center of the safe gap for the rocket
|
||
|
|
bool passed; // Flag to avoid counting the same obstacle twice
|
||
|
|
};
|
||
|
|
CandlePipe g_pipes[3]; // Array to hold a maximum of 3 obstacles on screen
|
||
|
|
|
||
|
|
double g_pipeSpeed; // Current moving speed of the obstacles
|
||
|
|
int g_pipeGap; // Vertical space between the upper and lower candles
|
||
|
|
int g_pipeSpacing; // Horizontal distance between one obstacle and the next
|
||
|
|
|
||
|
|
//--- Base difficulty constants
|
||
|
|
const double BASE_PIPE_SPEED = 6.0; // Starting speed
|
||
|
|
const int BASE_PIPE_GAP = 220; // Starting vertical gap
|
||
|
|
const int BASE_PIPE_SPACING = 450; // Starting horizontal distance
|
||
|
|
const int PIPE_WIDTH = 45; // Fixed width of the candlestick obstacles
|
||
|
|
|
||
|
|
//--- Variable to animate the background grid (Parallax effect)
|
||
|
|
double g_gridOffsetX = 0.0;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Cyberpunk Color Palette using Alpha Channel (ARGB) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
uint CLR_BG = ColorToARGB(C'15,17,20', 255); // Dark solid background (Alpha 255)
|
||
|
|
uint CLR_GRID = ColorToARGB(C'25,28,32', 255); // Grid lines color
|
||
|
|
uint CLR_ACCENT = ColorToARGB(C'0,240,240', 255); // Neon Cyan for details
|
||
|
|
uint CLR_BULL = ColorToARGB(C'40,167,69', 255); // Institutional Green (Bull candle)
|
||
|
|
uint CLR_BEAR = ColorToARGB(C'242,54,69', 255); // Institutional Red (Bear candle)
|
||
|
|
uint CLR_ROCKET = ColorToARGB(C'255,160,0', 255); // Orange/Gold for the rocket body
|
||
|
|
uint CLR_FIRECORE = ColorToARGB(C'255,255,100', 255); // Yellow for the engine fire
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Expert initialization function |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
int OnInit()
|
||
|
|
{
|
||
|
|
//--- Initialize the random number generator using the system tick count
|
||
|
|
MathSrand(GetTickCount());
|
||
|
|
|
||
|
|
//--- Hide the standard MT5 candlestick chart to provide a clean visual space
|
||
|
|
ChartSetInteger(0, CHART_SHOW, false);
|
||
|
|
|
||
|
|
//--- Get the actual screen dimensions in pixels from the user's terminal
|
||
|
|
g_chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
|
||
|
|
g_chartHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
|
||
|
|
|
||
|
|
//--- Create the canvas using COLOR_FORMAT_ARGB_NORMALIZE to support true Alpha transparency
|
||
|
|
if(!canvas.CreateBitmapLabel(0, 0, "FlappyScreen", 0, 0, g_chartWidth, g_chartHeight, COLOR_FORMAT_ARGB_NORMALIZE))
|
||
|
|
{
|
||
|
|
return(INIT_FAILED);
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Setup initial game variables
|
||
|
|
ResetGame();
|
||
|
|
|
||
|
|
//--- Set a high-frequency timer to 12 milliseconds (approx. 83 Frames Per Second)
|
||
|
|
EventSetMillisecondTimer(12);
|
||
|
|
g_isInitialized = true;
|
||
|
|
|
||
|
|
return(INIT_SUCCEEDED);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Expert deinitialization function |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnDeinit(const int reason)
|
||
|
|
{
|
||
|
|
//--- Stop the game loop
|
||
|
|
EventKillTimer();
|
||
|
|
|
||
|
|
//--- Destroy the canvas to free up RAM
|
||
|
|
canvas.Destroy();
|
||
|
|
|
||
|
|
//--- Restore the standard MT5 chart view
|
||
|
|
ChartSetInteger(0, CHART_SHOW, true);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Reset the game to initial state |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void ResetGame()
|
||
|
|
{
|
||
|
|
//--- Position the rocket vertically in the center and horizontally to the left
|
||
|
|
g_playerX = g_chartWidth * 0.2;
|
||
|
|
g_playerY = g_chartHeight / 2.0;
|
||
|
|
g_velocityY = 0.0;
|
||
|
|
g_score = 0;
|
||
|
|
|
||
|
|
//--- Restore base difficulty parameters
|
||
|
|
g_pipeSpeed = BASE_PIPE_SPEED;
|
||
|
|
g_pipeGap = BASE_PIPE_GAP;
|
||
|
|
g_pipeSpacing = BASE_PIPE_SPACING;
|
||
|
|
|
||
|
|
//--- Generate the first 3 obstacles outside the right edge of the screen
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
g_pipes[i].x = g_chartWidth + (i * g_pipeSpacing);
|
||
|
|
g_pipes[i].gap_y = (double)(MathRand() % (g_chartHeight - 300) + 150);
|
||
|
|
g_pipes[i].passed = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Timer function (Main Game Loop) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnTimer()
|
||
|
|
{
|
||
|
|
//--- Prevent execution if initialization failed
|
||
|
|
if(!g_isInitialized)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Check if the user resized the MT5 window
|
||
|
|
int curr_w = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
|
||
|
|
int curr_h = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
|
||
|
|
|
||
|
|
if(curr_w != g_chartWidth || curr_h != g_chartHeight)
|
||
|
|
{
|
||
|
|
g_chartWidth = curr_w;
|
||
|
|
g_chartHeight = curr_h;
|
||
|
|
canvas.Resize(g_chartWidth, g_chartHeight);
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- STEP 1: CLEAR THE SCREEN (Erase the previous frame to avoid infinite trails)
|
||
|
|
canvas.Erase(CLR_BG);
|
||
|
|
|
||
|
|
//--- Calculate the Parallax background offset
|
||
|
|
if(g_gameState == PLAYING)
|
||
|
|
{
|
||
|
|
g_gridOffsetX -= (g_pipeSpeed * 0.5); // Move background slower than obstacles
|
||
|
|
if(g_gridOffsetX <= -40.0)
|
||
|
|
{
|
||
|
|
g_gridOffsetX += 40.0; // Infinite loop reset
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Draw the dynamic background grid
|
||
|
|
for(int x = (int)g_gridOffsetX; x < g_chartWidth + 40; x += 40)
|
||
|
|
{
|
||
|
|
canvas.LineVertical(x, 0, g_chartHeight, CLR_GRID);
|
||
|
|
}
|
||
|
|
for(int y = 0; y < g_chartHeight; y += 40)
|
||
|
|
{
|
||
|
|
canvas.LineHorizontal(0, g_chartWidth, y, CLR_GRID);
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- STEP 2: CALCULATE AND DRAW BASED ON CURRENT STATE
|
||
|
|
if(g_gameState == START_SCREEN)
|
||
|
|
{
|
||
|
|
DrawStartScreen();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(g_gameState == PLAYING)
|
||
|
|
{
|
||
|
|
UpdatePhysics();
|
||
|
|
DrawPipes();
|
||
|
|
DrawRocket();
|
||
|
|
DrawScore();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(g_gameState == GAME_OVER)
|
||
|
|
{
|
||
|
|
DrawPipes();
|
||
|
|
DrawRocket();
|
||
|
|
DrawGameOver();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- STEP 3: UPDATE DISPLAY (Send the rendered graphics to the monitor)
|
||
|
|
canvas.Update();
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Physics and Collision Updates |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void UpdatePhysics()
|
||
|
|
{
|
||
|
|
//--- Apply gravity to the falling speed
|
||
|
|
g_velocityY += GRAVITY;
|
||
|
|
//--- Move the rocket along the Y axis
|
||
|
|
g_playerY += g_velocityY;
|
||
|
|
|
||
|
|
//--- Detect collision with the ceiling or the floor
|
||
|
|
if(g_playerY < 0.0 || g_playerY > g_chartHeight)
|
||
|
|
{
|
||
|
|
TriggerGameOver();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Update obstacles and check for collisions
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
g_pipes[i].x -= g_pipeSpeed;
|
||
|
|
|
||
|
|
//--- If the obstacle leaves the screen, recycle it to the right
|
||
|
|
if(g_pipes[i].x < -PIPE_WIDTH)
|
||
|
|
{
|
||
|
|
g_pipes[i].x += g_pipeSpacing * 3.0;
|
||
|
|
g_pipes[i].gap_y = (double)(MathRand() % (g_chartHeight - 300) + 150); // New random gap height
|
||
|
|
g_pipes[i].passed = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- AABB Collision Detection (Hitbox evaluation)
|
||
|
|
// Horizontal check
|
||
|
|
if(g_playerX + 15.0 > g_pipes[i].x && g_playerX - 15.0 < g_pipes[i].x + PIPE_WIDTH)
|
||
|
|
{
|
||
|
|
//--- Vertical check (Did it hit the upper bear candle or lower bull candle?)
|
||
|
|
if(g_playerY - 12.0 < g_pipes[i].gap_y - g_pipeGap / 2.0 || g_playerY + 12.0 > g_pipes[i].gap_y + g_pipeGap / 2.0)
|
||
|
|
{
|
||
|
|
TriggerGameOver();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Score counter (Executed only once when passing an obstacle)
|
||
|
|
if(!g_pipes[i].passed && g_playerX > g_pipes[i].x + PIPE_WIDTH)
|
||
|
|
{
|
||
|
|
g_score++;
|
||
|
|
g_pipes[i].passed = true;
|
||
|
|
PlaySound("ok.wav");
|
||
|
|
|
||
|
|
//--- DYNAMIC DIFFICULTY RAMP-UP (Triggered every 10 points)
|
||
|
|
if(g_score % 10 == 0)
|
||
|
|
{
|
||
|
|
if(g_pipeSpeed < 12.0)
|
||
|
|
{
|
||
|
|
g_pipeSpeed += 1.5; // Increase market volatility (speed)
|
||
|
|
}
|
||
|
|
|
||
|
|
if(g_pipeGap > 110)
|
||
|
|
{
|
||
|
|
g_pipeGap -= 20; // Decrease safety gap
|
||
|
|
}
|
||
|
|
|
||
|
|
if(g_pipeSpacing > 250)
|
||
|
|
{
|
||
|
|
g_pipeSpacing -= 30; // Decrease distance between candles
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Trigger Game Over State |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void TriggerGameOver()
|
||
|
|
{
|
||
|
|
g_gameState = GAME_OVER;
|
||
|
|
|
||
|
|
//--- Save the All-Time High score in memory
|
||
|
|
if(g_score > g_bestScore)
|
||
|
|
{
|
||
|
|
g_bestScore = g_score;
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Play the classic MT5 disconnection sound as a Margin Call alert
|
||
|
|
PlaySound("disconnect.wav");
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Vector Engine: Draw the Rocket |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void DrawRocket()
|
||
|
|
{
|
||
|
|
int px = (int)g_playerX;
|
||
|
|
int py = (int)g_playerY;
|
||
|
|
|
||
|
|
//--- 1. Draw dynamic engine fire if the rocket is jumping (negative velocity)
|
||
|
|
if(g_velocityY < 0.0)
|
||
|
|
{
|
||
|
|
int fire_len = (MathRand() % 15) + 15;
|
||
|
|
uchar flicker_alpha = (uchar)((MathRand() % 100) + 100);
|
||
|
|
uint clrFireOuter = ColorToARGB(C'255,80,30', flicker_alpha);
|
||
|
|
|
||
|
|
//--- Transparent outer flame (Aura)
|
||
|
|
canvas.FillTriangle(px - 10, py - 8, px - 10, py + 8, px - 10 - fire_len - 5, py, clrFireOuter);
|
||
|
|
//--- Solid inner core flame
|
||
|
|
canvas.FillTriangle(px - 10, py - 4, px - 10, py + 4, px - 10 - fire_len, py, CLR_FIRECORE);
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- 2. Draw the main fuselage using basic geometry
|
||
|
|
canvas.FillRectangle(px - 10, py - 6, px + 8, py + 6, CLR_ROCKET);
|
||
|
|
canvas.FillTriangle(px + 8, py - 6, px + 8, py + 6, px + 18, py, CLR_ACCENT);
|
||
|
|
|
||
|
|
//--- 3. Draw upper and lower aerodynamic fins
|
||
|
|
canvas.FillTriangle(px - 10, py - 6, px - 2, py - 6, px - 10, py - 12, CLR_ACCENT);
|
||
|
|
canvas.FillTriangle(px - 10, py + 6, px - 2, py + 6, px - 10, py + 12, CLR_ACCENT);
|
||
|
|
|
||
|
|
//--- 4. Draw the cockpit window
|
||
|
|
canvas.FillCircle(px, py, 3, CLR_BG);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Vector Engine: Draw the Candles (Obstacles) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void DrawPipes()
|
||
|
|
{
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
int px = (int)g_pipes[i].x;
|
||
|
|
int gap_top = (int)(g_pipes[i].gap_y - g_pipeGap / 2.0);
|
||
|
|
int gap_bot = (int)(g_pipes[i].gap_y + g_pipeGap / 2.0);
|
||
|
|
|
||
|
|
//--- BEAR CANDLE (Dropping from the ceiling)
|
||
|
|
canvas.FillRectangle(px, 0, px + PIPE_WIDTH, gap_top, CLR_BEAR);
|
||
|
|
canvas.LineVertical(px + PIPE_WIDTH / 2, gap_top, gap_top + 20, ColorToARGB(C'150,150,150', 255));
|
||
|
|
canvas.Rectangle(px, 0, px + PIPE_WIDTH, gap_top, ColorToARGB(clrBlack, 255));
|
||
|
|
|
||
|
|
//--- BULL CANDLE (Rising from the floor)
|
||
|
|
canvas.FillRectangle(px, gap_bot, px + PIPE_WIDTH, g_chartHeight, CLR_BULL);
|
||
|
|
canvas.LineVertical(px + PIPE_WIDTH / 2, gap_bot - 20, gap_bot, ColorToARGB(C'150,150,150', 255));
|
||
|
|
canvas.Rectangle(px, gap_bot, px + PIPE_WIDTH, g_chartHeight, ColorToARGB(clrBlack, 255));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Draw the Score Text (Profit) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void DrawScore()
|
||
|
|
{
|
||
|
|
canvas.FontSet("Arial", 40, FW_BOLD);
|
||
|
|
string profit_text = "Profit: +$" + IntegerToString(g_score);
|
||
|
|
|
||
|
|
//--- Render text with Alpha 220 to create a slight transparency effect
|
||
|
|
canvas.TextOut(g_chartWidth / 2, 50, profit_text, ColorToARGB(C'40,167,69', 220), TA_CENTER|TA_VCENTER);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Draw the Start Screen UI |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void DrawStartScreen()
|
||
|
|
{
|
||
|
|
canvas.FontSet("Trebuchet MS", 60, FW_BOLD);
|
||
|
|
canvas.TextOut(g_chartWidth / 2, g_chartHeight / 2 - 80, "CRAZY SCALPER", CLR_ACCENT, TA_CENTER|TA_VCENTER);
|
||
|
|
|
||
|
|
//--- Use a Sine wave function based on system ticks to create a pulsing animation
|
||
|
|
uchar pulse_alpha = (uchar)(155.0 + 100.0 * MathSin(GetTickCount() * 0.005));
|
||
|
|
canvas.FontSet("Arial", 20, FW_NORMAL);
|
||
|
|
canvas.TextOut(g_chartWidth / 2, g_chartHeight / 2 + 20, "Press SPACE or UP ARROW to trade", ColorToARGB(clrWhite, pulse_alpha), TA_CENTER|TA_VCENTER);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Draw the Game Over Screen UI |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void DrawGameOver()
|
||
|
|
{
|
||
|
|
//--- Draw a semi-transparent black rectangle over the entire screen for dramatic effect
|
||
|
|
canvas.FillRectangle(0, 0, g_chartWidth, g_chartHeight, ColorToARGB(C'0,0,0', 180));
|
||
|
|
|
||
|
|
canvas.FontSet("Arial", 60, FW_BOLD);
|
||
|
|
canvas.TextOut(g_chartWidth / 2, g_chartHeight / 2 - 100, "MARGIN CALL", CLR_BEAR, TA_CENTER|TA_VCENTER);
|
||
|
|
|
||
|
|
canvas.FontSet("Arial", 25, FW_NORMAL);
|
||
|
|
string stats = "Final Profit: +$" + IntegerToString(g_score) + " | ATH: +$" + IntegerToString(g_bestScore);
|
||
|
|
canvas.TextOut(g_chartWidth / 2, g_chartHeight / 2 - 20, stats, CLR_ROCKET, TA_CENTER|TA_VCENTER);
|
||
|
|
|
||
|
|
canvas.FontSet("Arial", 16, FW_NORMAL);
|
||
|
|
canvas.TextOut(g_chartWidth / 2, g_chartHeight / 2 + 80, "(Press SPACE to deposit new funds... I mean, try again)", ColorToARGB(C'150,150,150', 255), TA_CENTER|TA_VCENTER);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Chart Event Handler (Keyboard Inputs) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
|
||
|
|
{
|
||
|
|
//--- Check if the event is a keyboard key press
|
||
|
|
if(id == CHARTEVENT_KEYDOWN)
|
||
|
|
{
|
||
|
|
//--- Check if the pressed key is SPACE (32) or UP ARROW (38)
|
||
|
|
if(lparam == 32 || lparam == 38)
|
||
|
|
{
|
||
|
|
if(g_gameState == START_SCREEN)
|
||
|
|
{
|
||
|
|
ResetGame();
|
||
|
|
g_gameState = PLAYING;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(g_gameState == PLAYING)
|
||
|
|
{
|
||
|
|
//--- Apply upward thrust fighting gravity
|
||
|
|
g_velocityY = JUMP_STRENGTH;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(g_gameState == GAME_OVER)
|
||
|
|
{
|
||
|
|
g_gameState = START_SCREEN;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|